1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com> |
5 | ** Copyright (C) 2016 Intel Corporation. |
6 | ** Contact: https://www.qt.io/licensing/ |
7 | ** |
8 | ** This file is part of the test suite of the Qt Toolkit. |
9 | ** |
10 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
11 | ** Commercial License Usage |
12 | ** Licensees holding valid commercial Qt licenses may use this file in |
13 | ** accordance with the commercial license agreement provided with the |
14 | ** Software or, alternatively, in accordance with the terms contained in |
15 | ** a written agreement between you and The Qt Company. For licensing terms |
16 | ** and conditions see https://www.qt.io/terms-conditions. For further |
17 | ** information use the contact form at https://www.qt.io/contact-us. |
18 | ** |
19 | ** GNU General Public License Usage |
20 | ** Alternatively, this file may be used under the terms of the GNU |
21 | ** General Public License version 3 as published by the Free Software |
22 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
23 | ** included in the packaging of this file. Please review the following |
24 | ** information to ensure the GNU General Public License requirements will |
25 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
26 | ** |
27 | ** $QT_END_LICENSE$ |
28 | ** |
29 | ****************************************************************************/ |
30 | |
31 | #include <QtTest/QtTest> |
32 | |
33 | #include <qvariant.h> |
34 | #include <QtCore/private/qvariant_p.h> |
35 | #include <qbitarray.h> |
36 | #include <qbytearraylist.h> |
37 | #include <qdatetime.h> |
38 | #include <qmap.h> |
39 | #include <qiodevice.h> |
40 | #include <qurl.h> |
41 | #include <qlocale.h> |
42 | #include <qdebug.h> |
43 | #include <qjsondocument.h> |
44 | #include <quuid.h> |
45 | |
46 | #include <limits.h> |
47 | #include <float.h> |
48 | #include <cmath> |
49 | #if __has_include(<variant>) && __cplusplus >= 201703L |
50 | #include <variant> |
51 | #endif |
52 | #include <QLinkedList> |
53 | #include <QRegularExpression> |
54 | #include <QDir> |
55 | #include <QBuffer> |
56 | #include "qnumeric.h" |
57 | |
58 | #include <private/qlocale_p.h> |
59 | #include "tst_qvariant_common.h" |
60 | |
61 | class CustomNonQObject; |
62 | |
63 | class tst_QVariant : public QObject |
64 | { |
65 | Q_OBJECT |
66 | |
67 | public: |
68 | tst_QVariant(QObject *parent = 0) |
69 | : QObject(parent), customNonQObjectPointer(0) |
70 | { |
71 | |
72 | } |
73 | |
74 | |
75 | enum MetaEnumTest_Enum0 { MetaEnumTest_Enum0_dummy = 2, MetaEnumTest_Enum0_value = 42, MetaEnsureSignedEnum0 = -1 }; |
76 | Q_ENUM(MetaEnumTest_Enum0) |
77 | enum MetaEnumTest_Enum1 : qint64 { MetaEnumTest_Enum1_value = 42, MetaEnumTest_Enum1_bigValue = (Q_INT64_C(1) << 33) + 50 }; |
78 | Q_ENUM(MetaEnumTest_Enum1) |
79 | |
80 | enum MetaEnumTest_Enum3 : qint64 { MetaEnumTest_Enum3_value = -47, MetaEnumTest_Enum3_bigValue = (Q_INT64_C(1) << 56) + 5, MetaEnumTest_Enum3_bigNegValue = -(Q_INT64_C(1) << 56) - 3 }; |
81 | Q_ENUM(MetaEnumTest_Enum3) |
82 | enum MetaEnumTest_Enum4 : quint64 { MetaEnumTest_Enum4_value = 47, MetaEnumTest_Enum4_bigValue = (Q_INT64_C(1) << 52) + 45 }; |
83 | Q_ENUM(MetaEnumTest_Enum4) |
84 | enum MetaEnumTest_Enum5 : uint { MetaEnumTest_Enum5_value = 47 }; |
85 | Q_ENUM(MetaEnumTest_Enum5) |
86 | enum MetaEnumTest_Enum6 : uchar { MetaEnumTest_Enum6_value = 47 }; |
87 | Q_ENUM(MetaEnumTest_Enum6) |
88 | enum MetaEnumTest_Enum8 : short { MetaEnumTest_Enum8_value = 47 }; |
89 | Q_ENUM(MetaEnumTest_Enum8) |
90 | |
91 | private slots: |
92 | void cleanupTestCase(); |
93 | |
94 | void constructor(); |
95 | void copy_constructor(); |
96 | void constructor_invalid_data(); |
97 | void constructor_invalid(); |
98 | void isNull(); |
99 | void swap(); |
100 | |
101 | void canConvert_data(); |
102 | void canConvert(); |
103 | |
104 | void toSize_data(); |
105 | void toSize(); |
106 | |
107 | void toSizeF_data(); |
108 | void toSizeF(); |
109 | |
110 | void toPoint_data(); |
111 | void toPoint(); |
112 | |
113 | void toRect_data(); |
114 | void toRect(); |
115 | |
116 | void toChar_data(); |
117 | void toChar(); |
118 | |
119 | void toLine_data(); |
120 | void toLine(); |
121 | |
122 | void toLineF_data(); |
123 | void toLineF(); |
124 | |
125 | void toInt_data(); |
126 | void toInt(); |
127 | |
128 | void toUInt_data(); |
129 | void toUInt(); |
130 | |
131 | void toBool_data(); |
132 | void toBool(); |
133 | |
134 | void toLongLong_data(); |
135 | void toLongLong(); |
136 | |
137 | void toULongLong_data(); |
138 | void toULongLong(); |
139 | |
140 | void toByteArray_data(); |
141 | void toByteArray(); |
142 | |
143 | void toString_data(); |
144 | void toString(); |
145 | |
146 | void toDate_data(); |
147 | void toDate(); |
148 | |
149 | void toTime_data(); |
150 | void toTime(); |
151 | |
152 | void toDateTime_data(); |
153 | void toDateTime(); |
154 | |
155 | void toDouble_data(); |
156 | void toDouble(); |
157 | |
158 | void toFloat_data(); |
159 | void toFloat(); |
160 | |
161 | void toPointF_data(); |
162 | void toPointF(); |
163 | |
164 | void toRectF_data(); |
165 | void toRectF(); |
166 | |
167 | void qvariant_cast_QObject_data(); |
168 | void qvariant_cast_QObject(); |
169 | void qvariant_cast_QObject_derived(); |
170 | void qvariant_cast_QObject_wrapper(); |
171 | void qvariant_cast_QSharedPointerQObject(); |
172 | |
173 | void toLocale(); |
174 | |
175 | void toRegExp(); |
176 | void toRegularExpression(); |
177 | |
178 | void url(); |
179 | |
180 | void userType(); |
181 | void basicUserType(); |
182 | |
183 | void variant_to(); |
184 | |
185 | void writeToReadFromDataStream_data(); |
186 | void writeToReadFromDataStream(); |
187 | void writeToReadFromOldDataStream(); |
188 | void checkDataStream(); |
189 | |
190 | void operator_eq_eq_data(); |
191 | void operator_eq_eq(); |
192 | void operator_eq_eq_rhs(); |
193 | void compareNumbers_data() const; |
194 | void compareNumbers() const; |
195 | |
196 | void typeName_data(); |
197 | void typeName(); |
198 | void typeToName(); |
199 | |
200 | void streamInvalidVariant(); |
201 | |
202 | void podUserType(); |
203 | |
204 | void data(); |
205 | void constData(); |
206 | |
207 | void saveLoadCustomTypes(); |
208 | |
209 | void variantMap(); |
210 | void variantHash(); |
211 | |
212 | void convertToQUint8() const; |
213 | void comparePointers() const; |
214 | void voidStar() const; |
215 | void dataStar() const; |
216 | void canConvertQStringList() const; |
217 | void canConvertQStringList_data() const; |
218 | void canConvertMetaTypeToInt() const; |
219 | void variantToDateTimeWithoutWarnings() const; |
220 | void invalidDateTime() const; |
221 | |
222 | void loadUnknownUserType(); |
223 | void loadBrokenUserType(); |
224 | |
225 | void invalidDate() const; |
226 | void compareCustomTypes() const; |
227 | void timeToDateTime() const; |
228 | void copyingUserTypes() const; |
229 | void convertBoolToByteArray() const; |
230 | void convertBoolToByteArray_data() const; |
231 | void convertByteArrayToBool() const; |
232 | void convertByteArrayToBool_data() const; |
233 | void convertIterables() const; |
234 | void toIntFromQString() const; |
235 | void toIntFromDouble() const; |
236 | void setValue(); |
237 | void fpStringRoundtrip_data() const; |
238 | void fpStringRoundtrip() const; |
239 | |
240 | void numericalConvert_data(); |
241 | void numericalConvert(); |
242 | void moreCustomTypes(); |
243 | void movabilityTest(); |
244 | void variantInVariant(); |
245 | void userConversion(); |
246 | void modelIndexConversion(); |
247 | |
248 | void forwardDeclare(); |
249 | void debugStream_data(); |
250 | void debugStream(); |
251 | void debugStreamType_data(); |
252 | void debugStreamType(); |
253 | |
254 | void loadQt4Stream_data(); |
255 | void loadQt4Stream(); |
256 | void saveQt4Stream_data(); |
257 | void saveQt4Stream(); |
258 | void loadQt5Stream_data(); |
259 | void loadQt5Stream(); |
260 | void saveQt5Stream_data(); |
261 | void saveQt5Stream(); |
262 | void saveInvalid_data(); |
263 | void saveInvalid(); |
264 | void saveNewBuiltinWithOldStream(); |
265 | |
266 | void implicitConstruction(); |
267 | |
268 | void iterateContainerElements(); |
269 | void pairElements(); |
270 | |
271 | void enums(); |
272 | void metaEnums(); |
273 | void compareSanity_data(); |
274 | void compareSanity(); |
275 | void compareRich(); |
276 | |
277 | void nullConvert(); |
278 | |
279 | void accessSequentialContainerKey(); |
280 | void shouldDeleteVariantDataWorksForSequential(); |
281 | void shouldDeleteVariantDataWorksForAssociative(); |
282 | void fromStdVariant(); |
283 | void qt4UuidDataStream(); |
284 | void sequentialIterableEndianessSanityCheck(); |
285 | void sequentialIterableAppend(); |
286 | |
287 | void preferDirectConversionOverInterfaces(); |
288 | |
289 | private: |
290 | void dataStream_data(QDataStream::Version version); |
291 | void loadQVariantFromDataStream(QDataStream::Version version); |
292 | void saveQVariantFromDataStream(QDataStream::Version version); |
293 | |
294 | CustomNonQObject *customNonQObjectPointer; |
295 | QVector<QObject*> objectPointerTestData; |
296 | }; |
297 | |
298 | const qlonglong intMax1 = (qlonglong)INT_MAX + 1; |
299 | const qulonglong uintMax1 = (qulonglong)UINT_MAX + 1; |
300 | |
301 | void tst_QVariant::constructor() |
302 | { |
303 | QVariant variant; |
304 | QVERIFY( !variant.isValid() ); |
305 | QVERIFY( variant.isNull() ); |
306 | |
307 | QVariant var2(variant); |
308 | QVERIFY( !var2.isValid() ); |
309 | QVERIFY( variant.isNull() ); |
310 | |
311 | QVariant varll(intMax1); |
312 | QVariant varll2(varll); |
313 | QCOMPARE(varll2, varll); |
314 | |
315 | QVariant var3(QVariant::String); |
316 | QCOMPARE(var3.typeName(), "QString" ); |
317 | QVERIFY(var3.isNull()); |
318 | QVERIFY(var3.isValid()); |
319 | |
320 | QVariant var4(QVariant::Invalid); |
321 | QCOMPARE(var4.type(), QVariant::Invalid); |
322 | QVERIFY(var4.isNull()); |
323 | QVERIFY(!var4.isValid()); |
324 | |
325 | QVariant var5(QLatin1String("hallo" )); |
326 | QCOMPARE(var5.type(), QVariant::String); |
327 | QCOMPARE(var5.typeName(), "QString" ); |
328 | |
329 | QVariant var6(qlonglong(0)); |
330 | QCOMPARE(var6.type(), QVariant::LongLong); |
331 | QCOMPARE(var6.typeName(), "qlonglong" ); |
332 | |
333 | QVariant var7 = 5; |
334 | QVERIFY(var7.isValid()); |
335 | QVERIFY(!var7.isNull()); |
336 | QVariant var8; |
337 | var8.setValue<int>(5); |
338 | QVERIFY(var8.isValid()); |
339 | QVERIFY(!var8.isNull()); |
340 | } |
341 | |
342 | void tst_QVariant::constructor_invalid_data() |
343 | { |
344 | QTest::addColumn<uint>(name: "typeId" ); |
345 | |
346 | QTest::newRow(dataTag: "-1" ) << uint(-1); |
347 | QTest::newRow(dataTag: "-122234567" ) << uint(-122234567); |
348 | QTest::newRow(dataTag: "0xfffffffff" ) << uint(0xfffffffff); |
349 | QTest::newRow(dataTag: "LastCoreType + 1" ) << uint(QMetaType::LastCoreType + 1); |
350 | QVERIFY(!QMetaType::isRegistered(QMetaType::LastCoreType + 1)); |
351 | } |
352 | |
353 | void tst_QVariant::constructor_invalid() |
354 | { |
355 | |
356 | QFETCH(uint, typeId); |
357 | { |
358 | QTest::ignoreMessage(type: QtWarningMsg, messagePattern: QRegularExpression("^Trying to construct an instance of an invalid type, type id:" )); |
359 | QVariant variant(static_cast<QVariant::Type>(typeId)); |
360 | QVERIFY(!variant.isValid()); |
361 | QCOMPARE(variant.userType(), int(QMetaType::UnknownType)); |
362 | } |
363 | { |
364 | QTest::ignoreMessage(type: QtWarningMsg, messagePattern: QRegularExpression("^Trying to construct an instance of an invalid type, type id:" )); |
365 | QVariant variant(typeId, /* copy */ 0); |
366 | QVERIFY(!variant.isValid()); |
367 | QCOMPARE(variant.userType(), int(QMetaType::UnknownType)); |
368 | } |
369 | } |
370 | |
371 | void tst_QVariant::copy_constructor() |
372 | { |
373 | QVariant var7(QVariant::Int); |
374 | QVariant var8(var7); |
375 | QCOMPARE(var8.type(), QVariant::Int); |
376 | QVERIFY(var8.isNull()); |
377 | } |
378 | |
379 | Q_DECLARE_METATYPE(int*) |
380 | |
381 | void tst_QVariant::isNull() |
382 | { |
383 | QVariant var; |
384 | QVERIFY( var.isNull() ); |
385 | |
386 | QString str1; |
387 | QVariant var1( str1 ); |
388 | QVERIFY( var1.isNull() ); |
389 | #if QT_DEPRECATED_SINCE(5, 9) |
390 | QT_WARNING_PUSH |
391 | QT_WARNING_DISABLE_DEPRECATED |
392 | QVariant var2( QString::null ); |
393 | QT_WARNING_POP |
394 | QVERIFY( var2.isNull() ); |
395 | #endif |
396 | |
397 | QVariant var3( QString( "blah" ) ); |
398 | QVERIFY( !var3.isNull() ); |
399 | |
400 | QVariant var4( 0 ); |
401 | QVERIFY( !var4.isNull() ); |
402 | |
403 | QVariant var5 = QString(); |
404 | QVERIFY( var5.isNull() ); |
405 | |
406 | QVariant var6( QString( "blah" ) ); |
407 | QVERIFY( !var6.isNull() ); |
408 | var6 = QVariant(); |
409 | QVERIFY( var6.isNull() ); |
410 | var6.convert( targetTypeId: QVariant::String ); |
411 | QVERIFY( var6.isNull() ); |
412 | QVariant varLL( (qlonglong)0 ); |
413 | QVERIFY( !varLL.isNull() ); |
414 | |
415 | #if QT_DEPRECATED_SINCE(5, 9) |
416 | QT_WARNING_PUSH |
417 | QT_WARNING_DISABLE_DEPRECATED |
418 | QVariant var7(QString::null); |
419 | QT_WARNING_POP |
420 | QVERIFY(var7.isNull()); |
421 | QT_WARNING_PUSH |
422 | QT_WARNING_DISABLE_DEPRECATED |
423 | var7 = QVariant::fromValue<QString>(value: QString::null); |
424 | QT_WARNING_POP |
425 | QVERIFY(var7.isNull()); |
426 | #endif |
427 | |
428 | QVariant var8(QMetaType::Nullptr, nullptr); |
429 | QVERIFY(var8.isNull()); |
430 | var8 = QVariant::fromValue<std::nullptr_t>(value: nullptr); |
431 | QVERIFY(var8.isNull()); |
432 | QVariant var9 = QVariant(QJsonValue(QJsonValue::Null)); |
433 | QVERIFY(var9.isNull()); |
434 | var9 = QVariant::fromValue<QJsonValue>(value: QJsonValue(QJsonValue::Null)); |
435 | QVERIFY(var9.isNull()); |
436 | |
437 | QVariant var10(QMetaType::VoidStar, nullptr); |
438 | QVERIFY(var10.isNull()); |
439 | var10 = QVariant::fromValue<void*>(value: nullptr); |
440 | QVERIFY(var10.isNull()); |
441 | |
442 | QVariant var11(QMetaType::QObjectStar, nullptr); |
443 | QVERIFY(var11.isNull()); |
444 | var11 = QVariant::fromValue<QObject*>(value: nullptr); |
445 | QVERIFY(var11.isNull()); |
446 | |
447 | QVERIFY(QVariant::fromValue<int*>(nullptr).isNull()); |
448 | |
449 | QVariant var12(QVariant::fromValue<QString>(value: QString())); |
450 | QVERIFY(var12.isNull()); |
451 | } |
452 | |
453 | void tst_QVariant::swap() |
454 | { |
455 | QVariant v1 = 1, v2 = 2.0; |
456 | v1.swap(other&: v2); |
457 | QCOMPARE(v1.type(),QVariant::Double); |
458 | QCOMPARE(v1.toDouble(),2.0); |
459 | QCOMPARE(v2.type(),QVariant::Int); |
460 | QCOMPARE(v2.toInt(),1); |
461 | } |
462 | |
463 | void tst_QVariant::canConvert_data() |
464 | { |
465 | TST_QVARIANT_CANCONVERT_DATATABLE_HEADERS |
466 | |
467 | |
468 | #ifdef Y |
469 | #undef Y |
470 | #endif |
471 | #ifdef N |
472 | #undef N |
473 | #endif |
474 | #define Y true |
475 | #define N false |
476 | // bita bitm bool brsh byta col curs date dt dbl font img int inv kseq list ll map pal pen pix pnt rect reg size sp str strl time uint ull |
477 | |
478 | |
479 | QVariant var(QBitArray(0)); |
480 | QTest::newRow(dataTag: "BitArray" ) |
481 | << var << Y << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N; |
482 | var = QVariant(QByteArray()); |
483 | QTest::newRow(dataTag: "ByteArray" ) |
484 | << var << N << N << Y << N << Y << Y << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
485 | var = QVariant(QDate()); |
486 | QTest::newRow(dataTag: "Date" ) |
487 | << var << N << N << N << N << N << N << N << Y << Y << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N; |
488 | var = QVariant(QDateTime()); |
489 | QTest::newRow(dataTag: "DateTime" ) |
490 | << var << N << N << N << N << N << N << N << Y << Y << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << Y << N << N; |
491 | var = QVariant((double)0.1); |
492 | QTest::newRow(dataTag: "Double" ) |
493 | << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
494 | var = QVariant(0.1f); |
495 | QTest::newRow(dataTag: "Float" ) |
496 | << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
497 | var = QVariant((int)1); |
498 | QTest::newRow(dataTag: "Int" ) |
499 | << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
500 | var = QVariant(); |
501 | QTest::newRow(dataTag: "Invalid" ) |
502 | << var << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N; |
503 | var = QVariant(QList<QVariant>()); |
504 | QTest::newRow(dataTag: "List" ) |
505 | << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N; |
506 | var = QVariant((qlonglong)1); |
507 | QTest::newRow(dataTag: "LongLong" ) |
508 | << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
509 | var = QVariant(QMap<QString,QVariant>()); |
510 | QTest::newRow(dataTag: "Map" ) |
511 | << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N << N << N << N; |
512 | var = QVariant(QPoint()); |
513 | QTest::newRow(dataTag: "Point" ) |
514 | << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N; |
515 | var = QVariant(QRect()); |
516 | QTest::newRow(dataTag: "Rect" ) |
517 | << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N; |
518 | var = QVariant(QSize()); |
519 | QTest::newRow(dataTag: "Size" ) |
520 | << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N; |
521 | var = QVariant(QString()); |
522 | QTest::newRow(dataTag: "String" ) |
523 | << var << N << N << Y << N << Y << Y << N << Y << Y << Y << Y << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << Y << Y << Y << Y; |
524 | var = QVariant(QStringList("entry" )); |
525 | QTest::newRow(dataTag: "StringList" ) |
526 | << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N << Y << Y << N << N << N; |
527 | var = QVariant(QTime()); |
528 | QTest::newRow(dataTag: "Time" ) |
529 | << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << Y << N << N; |
530 | var = QVariant((uint)1); |
531 | QTest::newRow(dataTag: "UInt" ) |
532 | << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
533 | var = QVariant((int)1); |
534 | QTest::newRow(dataTag: "Int" ) |
535 | << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
536 | var = QVariant((qulonglong)1); |
537 | QTest::newRow(dataTag: "ULongLong" ) |
538 | << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
539 | var = QVariant::fromValue(value: 'a'); |
540 | QTest::newRow(dataTag: "Char" ) |
541 | << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
542 | var = QVariant::fromValue<signed char>(value: -1); |
543 | QTest::newRow(dataTag: "SChar" ) |
544 | << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
545 | var = QVariant((short)-3); |
546 | QTest::newRow(dataTag: "Short" ) |
547 | << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
548 | var = QVariant((ushort)7); |
549 | QTest::newRow(dataTag: "UShort" ) |
550 | << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
551 | var = QVariant::fromValue<QJsonValue>(value: QJsonValue(QStringLiteral("hello" ))); |
552 | QTest::newRow(dataTag: "JsonValue" ) |
553 | << var << N << N << Y << N << N << N << N << N << N << Y << N << N << Y << N << N << Y << Y << Y << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; |
554 | var = QVariant::fromValue<QJsonArray>(value: QJsonArray()); |
555 | QTest::newRow(dataTag: "JsonArray" ) |
556 | << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N; |
557 | var = QVariant::fromValue<QJsonObject>(value: QJsonObject()); |
558 | QTest::newRow(dataTag: "JsonObject" ) |
559 | << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N << N << N << N; |
560 | |
561 | #undef N |
562 | #undef Y |
563 | } |
564 | |
565 | void tst_QVariant::canConvert() |
566 | { |
567 | TST_QVARIANT_CANCONVERT_FETCH_DATA |
568 | |
569 | TST_QVARIANT_CANCONVERT_COMPARE_DATA |
570 | |
571 | // Invalid type ids |
572 | QCOMPARE(val.canConvert(-1), false); |
573 | QCOMPARE(val.canConvert(-23), false); |
574 | QCOMPARE(val.canConvert(-23876), false); |
575 | QCOMPARE(val.canConvert(23876), false); |
576 | } |
577 | |
578 | void tst_QVariant::toInt_data() |
579 | { |
580 | QTest::addColumn<QVariant>(name: "value" ); |
581 | QTest::addColumn<int>(name: "result" ); |
582 | QTest::addColumn<bool>(name: "valueOK" ); |
583 | |
584 | QTest::newRow( dataTag: "invalid" ) << QVariant() << 0 << false; |
585 | QTest::newRow( dataTag: "int" ) << QVariant( 123 ) << 123 << true; |
586 | QTest::newRow( dataTag: "char" ) << QVariant::fromValue(value: 'a') << int('a') << true; |
587 | signed char signedChar = -13; |
588 | QTest::newRow( dataTag: "signed char" ) << QVariant::fromValue(value: signedChar) << -13 << true; |
589 | QTest::newRow( dataTag: "short" ) << QVariant::fromValue(value: short(-7)) << int(-7) << true; |
590 | QTest::newRow( dataTag: "ushort" ) << QVariant::fromValue(value: ushort(30000)) << 30000 << true; |
591 | QTest::newRow( dataTag: "double" ) << QVariant( 3.1415927 ) << 3 << true; |
592 | QTest::newRow( dataTag: "float" ) << QVariant( 3.1415927f ) << 3 << true; |
593 | QTest::newRow( dataTag: "uint" ) << QVariant( 123u ) << 123 << true; |
594 | QTest::newRow( dataTag: "int-string" ) << QVariant( QString("123" ) ) << 123 << true; |
595 | QTest::newRow( dataTag: "string" ) << QVariant( QString("Unicode String" ) ) << 0 << false; |
596 | QTest::newRow( dataTag: "longlong0" ) << QVariant( (qlonglong)34 ) << 34 << true; |
597 | QTest::newRow( dataTag: "longlong1" ) << QVariant( intMax1 ) << (int)INT_MIN << true; |
598 | QTest::newRow( dataTag: "ulonglong0" ) << QVariant( (qulonglong)34 ) << 34 << true; |
599 | QTest::newRow( dataTag: "ulonglong1" ) << QVariant( uintMax1 ) << 0 << true; |
600 | QTest::newRow( dataTag: "signedint" ) << QVariant( -123 ) << -123 << true; |
601 | QTest::newRow( dataTag: "signeddouble" ) << QVariant( -3.1415927 ) << -3 << true; |
602 | QTest::newRow( dataTag: "signedfloat" ) << QVariant( -3.1415927f ) << -3 << true; |
603 | QTest::newRow( dataTag: "signedint-string" ) << QVariant( QString("-123" ) ) << -123 << true; |
604 | QTest::newRow( dataTag: "signedlonglong0" ) << QVariant( (qlonglong)-34 ) << -34 << true; |
605 | QTest::newRow( dataTag: "QChar" ) << QVariant(QChar('a')) << int('a') << true; |
606 | QByteArray bytearray(4, ' '); |
607 | bytearray[0] = 'T'; |
608 | bytearray[1] = 'e'; |
609 | bytearray[2] = 's'; |
610 | bytearray[3] = 't'; |
611 | QTest::newRow( dataTag: "QByteArray1" ) << QVariant( bytearray ) << 0 << false; |
612 | bytearray[0] = '4'; |
613 | bytearray[1] = '5'; |
614 | bytearray[2] = '0'; |
615 | bytearray[3] = '0'; |
616 | QTest::newRow( dataTag: "QByteArray2" ) << QVariant( bytearray ) << 4500 << true; |
617 | QTest::newRow(dataTag: "int-QJsonValue" ) << QVariant(QJsonValue(321)) << 321 << true; |
618 | QTest::newRow(dataTag: "undefined-QJsonValue" ) << QVariant(QJsonValue(QJsonValue::Undefined)) << 0 << false; |
619 | } |
620 | |
621 | void tst_QVariant::toInt() |
622 | { |
623 | QFETCH( QVariant, value ); |
624 | QFETCH( int, result ); |
625 | QFETCH( bool, valueOK ); |
626 | QVERIFY( value.isValid() == value.canConvert( QVariant::Int ) ); |
627 | bool ok; |
628 | int i = value.toInt( ok: &ok ); |
629 | QCOMPARE( i, result ); |
630 | QVERIFY( ok == valueOK ); |
631 | } |
632 | |
633 | void tst_QVariant::toUInt_data() |
634 | { |
635 | QTest::addColumn<QVariant>(name: "value" ); |
636 | QTest::addColumn<uint>(name: "result" ); |
637 | QTest::addColumn<bool>(name: "valueOK" ); |
638 | |
639 | QTest::newRow( dataTag: "int" ) << QVariant( 123 ) << (uint)123 << true; |
640 | QTest::newRow( dataTag: "char" ) << QVariant::fromValue(value: 'a') << uint('a') << true; |
641 | signed char signedChar = 12; |
642 | QTest::newRow( dataTag: "signed char" ) << QVariant::fromValue(value: signedChar) << uint(12) << true; |
643 | QTest::newRow( dataTag: "double" ) << QVariant( 3.1415927 ) << (uint)3 << true; |
644 | QTest::newRow( dataTag: "float" ) << QVariant( 3.1415927f ) << (uint)3 << true; |
645 | QTest::newRow( dataTag: "uint" ) << QVariant( 123u ) << (uint)123 << true; |
646 | QTest::newRow( dataTag: "int-string" ) << QVariant( QString("123" ) ) << (uint)123 << true; |
647 | QTest::newRow( dataTag: "string" ) << QVariant( QString("Unicode String" ) ) << (uint)0 << false; |
648 | QTest::newRow( dataTag: "string2" ) << QVariant( QString("4" ) ) << (uint)4 << true; |
649 | QTest::newRow( dataTag: "longlong0" ) << QVariant( (qlonglong)34 ) << (uint)34 << true; |
650 | QTest::newRow( dataTag: "longlong1" ) << QVariant( intMax1 ) << (uint)INT_MIN << true; |
651 | QTest::newRow( dataTag: "ulonglong0" ) << QVariant( (qulonglong)34 ) << (uint)34 << true; |
652 | QTest::newRow( dataTag: "ulonglong1" ) << QVariant( uintMax1 ) << (uint)0 << true; |
653 | QTest::newRow( dataTag: "negativeint" ) << QVariant( -123 ) << (uint)-123 << true; |
654 | QTest::newRow( dataTag: "negativedouble" ) << QVariant( -3.1415927 ) << (uint)-3 << true; |
655 | QTest::newRow( dataTag: "negativefloat" ) << QVariant( -3.1415927f ) << (uint)-3 << true; |
656 | QTest::newRow( dataTag: "negativeint-string" ) << QVariant( QString("-123" ) ) << (uint)0 << false; |
657 | QTest::newRow( dataTag: "negativelonglong0" ) << QVariant( (qlonglong)-34 ) << (uint)-34 << true; |
658 | QTest::newRow( dataTag: "QChar" ) << QVariant(QChar('a')) << uint('a') << true; |
659 | QByteArray bytearray(4, ' '); |
660 | bytearray[0] = '4'; |
661 | bytearray[1] = '3'; |
662 | bytearray[2] = '2'; |
663 | bytearray[3] = '1'; |
664 | QTest::newRow( dataTag: "QByteArray" ) << QVariant( bytearray ) << (uint)4321 << true; |
665 | QTest::newRow(dataTag: "int-QJsonValue" ) << QVariant(QJsonValue(321)) << (uint)321 << true; |
666 | QTest::newRow(dataTag: "null-QJsonValue" ) << QVariant(QJsonValue(QJsonValue::Null)) << (uint)0 << false; |
667 | } |
668 | |
669 | void tst_QVariant::toUInt() |
670 | { |
671 | QFETCH( QVariant, value ); |
672 | QFETCH( uint, result ); |
673 | QFETCH( bool, valueOK ); |
674 | QVERIFY( value.isValid() ); |
675 | QVERIFY( value.canConvert( QVariant::UInt ) ); |
676 | |
677 | bool ok; |
678 | uint i = value.toUInt( ok: &ok ); |
679 | QVERIFY( ok == valueOK ); |
680 | QCOMPARE( i, result ); |
681 | } |
682 | |
683 | |
684 | void tst_QVariant::toSize_data() |
685 | { |
686 | QTest::addColumn<QVariant>(name: "value" ); |
687 | QTest::addColumn<QSize>(name: "result" ); |
688 | QTest::newRow( dataTag: "qsizef4" ) << QVariant( QSizeF(4, 2) ) << QSize(4, 2); |
689 | QTest::newRow( dataTag: "qsizef1" ) << QVariant( QSizeF(0, 0) ) << QSize(0, 0); |
690 | QTest::newRow( dataTag: "qsizef2" ) << QVariant( QSizeF(-5, -1) ) << QSize(-5, -1); |
691 | QTest::newRow( dataTag: "qsizef3" ) << QVariant( QSizeF() ) << QSize(); |
692 | } |
693 | |
694 | void tst_QVariant::toSize() |
695 | { |
696 | QFETCH( QVariant, value ); |
697 | QFETCH( QSize, result ); |
698 | QVERIFY( value.isValid() ); |
699 | QVERIFY( value.canConvert( QVariant::Size ) ); |
700 | |
701 | QSize i = value.toSize(); |
702 | QCOMPARE( i, result ); |
703 | } |
704 | |
705 | void tst_QVariant::toSizeF_data() |
706 | { |
707 | QTest::addColumn<QVariant>(name: "value" ); |
708 | QTest::addColumn<QSizeF>(name: "result" ); |
709 | QTest::newRow( dataTag: "qsize1" ) << QVariant( QSize(0, 0) ) << QSizeF(0, 0); |
710 | QTest::newRow( dataTag: "qsize2" ) << QVariant( QSize(-5, -1) ) << QSizeF(-5, -1); |
711 | QTest::newRow( dataTag: "qsize3" ) << QVariant( QSize() ) << QSizeF(); |
712 | QTest::newRow( dataTag: "qsize4" ) << QVariant(QSize(4,2)) << QSizeF(4,2); |
713 | } |
714 | |
715 | void tst_QVariant::toSizeF() |
716 | { |
717 | QFETCH( QVariant, value ); |
718 | QFETCH( QSizeF, result ); |
719 | QVERIFY( value.isValid() ); |
720 | QVERIFY( value.canConvert( QVariant::SizeF ) ); |
721 | |
722 | QSizeF i = value.toSizeF(); |
723 | QCOMPARE( i, result ); |
724 | } |
725 | |
726 | void tst_QVariant::toLine_data() |
727 | { |
728 | QTest::addColumn<QVariant>(name: "value" ); |
729 | QTest::addColumn<QLine>(name: "result" ); |
730 | QTest::newRow( dataTag: "linef1" ) << QVariant( QLineF(1, 2, 3, 4) ) << QLine(1, 2, 3, 4); |
731 | QTest::newRow( dataTag: "linef2" ) << QVariant( QLineF(-1, -2, -3, -4) ) << QLine(-1, -2, -3, -4); |
732 | QTest::newRow( dataTag: "linef3" ) << QVariant( QLineF(0, 0, 0, 0) ) << QLine(0, 0, 0, 0); |
733 | QTest::newRow( dataTag: "linef4" ) << QVariant( QLineF() ) << QLine(); |
734 | } |
735 | |
736 | void tst_QVariant::toLine() |
737 | { |
738 | QFETCH( QVariant, value ); |
739 | QFETCH( QLine, result ); |
740 | QVERIFY( value.isValid() ); |
741 | QVERIFY( value.canConvert( QVariant::Line ) ); |
742 | |
743 | QLine i = value.toLine(); |
744 | QCOMPARE( i, result ); |
745 | } |
746 | |
747 | void tst_QVariant::toLineF_data() |
748 | { |
749 | QTest::addColumn<QVariant>(name: "value" ); |
750 | QTest::addColumn<QLineF>(name: "result" ); |
751 | QTest::newRow( dataTag: "line1" ) << QVariant( QLine(-1, -2, -3, -4) ) << QLineF(-1, -2, -3, -4); |
752 | QTest::newRow( dataTag: "line2" ) << QVariant( QLine(0, 0, 0, 0) ) << QLineF(0, 0, 0, 0); |
753 | QTest::newRow( dataTag: "line3" ) << QVariant( QLine() ) << QLineF(); |
754 | QTest::newRow( dataTag: "line4" ) << QVariant( QLine(1, 2, 3, 4) ) << QLineF(1, 2, 3, 4); |
755 | } |
756 | |
757 | void tst_QVariant::toLineF() |
758 | { |
759 | QFETCH( QVariant, value ); |
760 | QFETCH( QLineF, result ); |
761 | QVERIFY( value.isValid() ); |
762 | QVERIFY( value.canConvert( QVariant::LineF ) ); |
763 | |
764 | QLineF i = value.toLineF(); |
765 | QCOMPARE( i, result ); |
766 | } |
767 | |
768 | void tst_QVariant::toPoint_data() |
769 | { |
770 | QTest::addColumn<QVariant>(name: "value" ); |
771 | QTest::addColumn<QPoint>(name: "result" ); |
772 | QTest::newRow( dataTag: "pointf1" ) << QVariant( QPointF(4, 2) ) << QPoint(4, 2); |
773 | QTest::newRow( dataTag: "pointf2" ) << QVariant( QPointF(0, 0) ) << QPoint(0, 0); |
774 | QTest::newRow( dataTag: "pointf3" ) << QVariant( QPointF(-4, -2) ) << QPoint(-4, -2); |
775 | QTest::newRow( dataTag: "pointf4" ) << QVariant( QPointF() ) << QPoint(); |
776 | QTest::newRow( dataTag: "pointf5" ) << QVariant( QPointF(-4.2f, -2.3f) ) << QPoint(-4, -2); |
777 | } |
778 | |
779 | void tst_QVariant::toPoint() |
780 | { |
781 | QFETCH( QVariant, value ); |
782 | QFETCH( QPoint, result ); |
783 | QVERIFY( value.isValid() ); |
784 | QVERIFY( value.canConvert( QVariant::Point ) ); |
785 | QPoint i = value.toPoint(); |
786 | QCOMPARE( i, result ); |
787 | } |
788 | |
789 | void tst_QVariant::toRect_data() |
790 | { |
791 | QTest::addColumn<QVariant>(name: "value" ); |
792 | QTest::addColumn<QRect>(name: "result" ); |
793 | QTest::newRow( dataTag: "rectf1" ) << QVariant(QRectF(1, 2, 3, 4)) << QRect(1, 2, 3, 4); |
794 | QTest::newRow( dataTag: "rectf2" ) << QVariant(QRectF(0, 0, 0, 0)) << QRect(0, 0, 0, 0); |
795 | QTest::newRow( dataTag: "rectf3" ) << QVariant(QRectF(-1, -2, -3, -4)) << QRect(-1, -2, -3, -4); |
796 | QTest::newRow( dataTag: "rectf4" ) << QVariant(QRectF(-1.3f, 0, 3.9f, -4.0)) << QRect(-1, 0, 4, -4); |
797 | QTest::newRow( dataTag: "rectf5" ) << QVariant(QRectF()) << QRect(); |
798 | } |
799 | |
800 | void tst_QVariant::toRect() |
801 | { |
802 | QFETCH( QVariant, value ); |
803 | QFETCH( QRect, result ); |
804 | QVERIFY( value.isValid() ); |
805 | QVERIFY( value.canConvert( QVariant::Rect ) ); |
806 | QRect i = value.toRect(); |
807 | QCOMPARE( i, result ); |
808 | } |
809 | |
810 | void tst_QVariant::toChar_data() |
811 | { |
812 | QTest::addColumn<QVariant>(name: "value" ); |
813 | QTest::addColumn<QChar>(name: "result" ); |
814 | QTest::newRow( dataTag: "longlong" ) << QVariant(qlonglong('6')) << QChar('6'); |
815 | QTest::newRow( dataTag: "ulonglong" ) << QVariant(qulonglong('7')) << QChar('7'); |
816 | } |
817 | |
818 | void tst_QVariant::toChar() |
819 | { |
820 | QFETCH( QVariant, value ); |
821 | QFETCH( QChar, result ); |
822 | QVERIFY( value.isValid() ); |
823 | QVERIFY( value.canConvert( QVariant::Char ) ); |
824 | |
825 | QChar i = value.toChar(); |
826 | QCOMPARE( i, result ); |
827 | } |
828 | |
829 | void tst_QVariant::toBool_data() |
830 | { |
831 | QTest::addColumn<QVariant>(name: "value" ); |
832 | QTest::addColumn<bool>(name: "result" ); |
833 | |
834 | QTest::newRow( dataTag: "int0" ) << QVariant( 0 ) << false; |
835 | QTest::newRow( dataTag: "int1" ) << QVariant( 123 ) << true; |
836 | QTest::newRow( dataTag: "uint0" ) << QVariant( 0u ) << false; |
837 | QTest::newRow( dataTag: "uint1" ) << QVariant( 123u ) << true; |
838 | QTest::newRow( dataTag: "double0" ) << QVariant( 0.0 ) << false; |
839 | QTest::newRow( dataTag: "float0" ) << QVariant( 0.0f ) << false; |
840 | QTest::newRow( dataTag: "double1" ) << QVariant( 3.1415927 ) << true; |
841 | QTest::newRow( dataTag: "float1" ) << QVariant( 3.1415927f ) << true; |
842 | QTest::newRow( dataTag: "string0" ) << QVariant( QString("3" ) ) << true; |
843 | QTest::newRow( dataTag: "string1" ) << QVariant( QString("true" ) ) << true; |
844 | QTest::newRow( dataTag: "string2" ) << QVariant( QString("0" ) ) << false; |
845 | QTest::newRow( dataTag: "string3" ) << QVariant( QString("fAlSe" ) ) << false; |
846 | QTest::newRow( dataTag: "longlong0" ) << QVariant( (qlonglong)0 ) << false; |
847 | QTest::newRow( dataTag: "longlong1" ) << QVariant( (qlonglong)1 ) << true; |
848 | QTest::newRow( dataTag: "ulonglong0" ) << QVariant( (qulonglong)0 ) << false; |
849 | QTest::newRow( dataTag: "ulonglong1" ) << QVariant( (qulonglong)1 ) << true; |
850 | QTest::newRow( dataTag: "QChar" ) << QVariant(QChar('a')) << true; |
851 | QTest::newRow( dataTag: "Null_QChar" ) << QVariant(QChar(0)) << false; |
852 | QTest::newRow(dataTag: "QJsonValue(true)" ) << QVariant(QJsonValue(true)) << true; |
853 | QTest::newRow(dataTag: "QJsonValue(false)" ) << QVariant(QJsonValue(false)) << false; |
854 | } |
855 | |
856 | void tst_QVariant::toBool() |
857 | { |
858 | QFETCH( QVariant, value ); |
859 | QFETCH( bool, result ); |
860 | QVERIFY( value.isValid() ); |
861 | QVERIFY( value.canConvert( QVariant::Bool ) ); |
862 | |
863 | bool i = value.toBool(); |
864 | QCOMPARE( i, result ); |
865 | } |
866 | |
867 | void tst_QVariant::toPointF_data() |
868 | { |
869 | QTest::addColumn<QVariant>(name: "value" ); |
870 | QTest::addColumn<QPointF>(name: "result" ); |
871 | |
872 | QTest::newRow( dataTag: "QPoint" ) << QVariant( QPointF( 19, 84) ) << QPointF( 19, 84 ); |
873 | } |
874 | |
875 | void tst_QVariant::toPointF() |
876 | { |
877 | QFETCH( QVariant, value ); |
878 | QFETCH( QPointF, result ); |
879 | QVERIFY( value.isValid() ); |
880 | QVERIFY( value.canConvert( QVariant::PointF ) ); |
881 | QPointF d = value.toPointF(); |
882 | QCOMPARE( d, result ); |
883 | } |
884 | |
885 | void tst_QVariant::toRectF_data() |
886 | { |
887 | QTest::addColumn<QVariant>(name: "value" ); |
888 | QTest::addColumn<QRectF>(name: "result" ); |
889 | |
890 | QRect r( 1, 9, 8, 4 ); |
891 | QRectF rf( 1.0, 9.0, 8.0, 4.0 ); |
892 | QTest::newRow( dataTag: "QRect" ) << QVariant( r ) << rf; |
893 | } |
894 | |
895 | void tst_QVariant::toRectF() |
896 | { |
897 | QFETCH( QVariant, value ); |
898 | QFETCH( QRectF, result ); |
899 | QVERIFY( value.isValid() ); |
900 | QVERIFY( value.canConvert( QVariant::RectF ) ); |
901 | QRectF d = value.toRectF(); |
902 | QCOMPARE( d, result ); |
903 | } |
904 | |
905 | void tst_QVariant::toDouble_data() |
906 | { |
907 | QTest::addColumn<QVariant>(name: "value" ); |
908 | QTest::addColumn<double>(name: "result" ); |
909 | QTest::addColumn<bool>(name: "valueOK" ); |
910 | |
911 | QByteArray bytearray(4, ' '); |
912 | bytearray[0] = '3'; |
913 | bytearray[1] = '2'; |
914 | bytearray[2] = '.'; |
915 | bytearray[3] = '1'; |
916 | QTest::newRow( dataTag: "bytearray" ) << QVariant( bytearray ) << 32.1 << true; |
917 | QTest::newRow(dataTag: "double-QJsonValue" ) << QVariant(QJsonValue(32.1)) << 32.1 << true; |
918 | QTest::newRow(dataTag: "null-QJsonValue" ) << QVariant(QJsonValue(QJsonValue::Null)) << 0.0 << false; |
919 | } |
920 | |
921 | void tst_QVariant::toDouble() |
922 | { |
923 | QFETCH( QVariant, value ); |
924 | QFETCH( double, result ); |
925 | QFETCH( bool, valueOK ); |
926 | QVERIFY( value.isValid() ); |
927 | QVERIFY( value.canConvert( QVariant::Double ) ); |
928 | bool ok; |
929 | double d = value.toDouble( ok: &ok ); |
930 | QCOMPARE( d, result ); |
931 | QVERIFY( ok == valueOK ); |
932 | } |
933 | |
934 | void tst_QVariant::toFloat_data() |
935 | { |
936 | QTest::addColumn<QVariant>(name: "value" ); |
937 | QTest::addColumn<float>(name: "result" ); |
938 | QTest::addColumn<bool>(name: "valueOK" ); |
939 | |
940 | QByteArray bytearray(4, ' '); |
941 | bytearray[0] = '3'; |
942 | bytearray[1] = '2'; |
943 | bytearray[2] = '.'; |
944 | bytearray[3] = '1'; |
945 | QTest::newRow(dataTag: "QByteArray" ) << QVariant(bytearray) << float(32.1) << true; |
946 | QTest::newRow(dataTag: "double-QJsonValue" ) << QVariant(QJsonValue(32.1)) << float(32.1) << true; |
947 | QTest::newRow(dataTag: "undefined-QJsonValue" ) << QVariant(QJsonValue(QJsonValue::Undefined)) << float(0.0) << false; |
948 | } |
949 | |
950 | void tst_QVariant::toFloat() |
951 | { |
952 | QFETCH(QVariant, value ); |
953 | QFETCH(float, result); |
954 | QFETCH(bool, valueOK); |
955 | QVERIFY(value.isValid()); |
956 | QVERIFY(value.canConvert(QMetaType::Float)); |
957 | bool ok; |
958 | float d = value.toFloat(ok: &ok); |
959 | QCOMPARE(d, result); |
960 | QCOMPARE(ok, valueOK); |
961 | } |
962 | |
963 | void tst_QVariant::toLongLong_data() |
964 | { |
965 | QTest::addColumn<QVariant>(name: "value" ); |
966 | QTest::addColumn<qlonglong>(name: "result" ); |
967 | QTest::addColumn<bool>(name: "valueOK" ); |
968 | |
969 | QTest::newRow( dataTag: "int0" ) << QVariant( 123 ) << (qlonglong)123 << true; |
970 | QTest::newRow( dataTag: "double" ) << QVariant( 3.1415927 ) << (qlonglong)3 << true; |
971 | QTest::newRow( dataTag: "float" ) << QVariant( 3.1415927f ) << (qlonglong)3 << true; |
972 | QTest::newRow( dataTag: "uint" ) << QVariant( 123u ) << (qlonglong)123 << true; |
973 | QTest::newRow( dataTag: "int-string" ) << QVariant( QString("123" ) ) |
974 | << (qlonglong)123 << true; |
975 | QTest::newRow( dataTag: "string" ) << QVariant( QString("Unicode fun" ) ) << (qlonglong)0 |
976 | << false; |
977 | QTest::newRow( dataTag: "longlong" ) << QVariant( intMax1 ) << intMax1 << true; |
978 | QTest::newRow( dataTag: "ulonglong" ) << QVariant( uintMax1 ) << (qlonglong)uintMax1 << true; |
979 | QTest::newRow( dataTag: "QChar" ) << QVariant(QChar('a')) << qlonglong('a') << true; |
980 | QByteArray bytearray(4, ' '); |
981 | bytearray[0] = '3'; |
982 | bytearray[1] = '2'; |
983 | bytearray[2] = '0'; |
984 | bytearray[3] = '0'; |
985 | QTest::newRow( dataTag: "QByteArray" ) << QVariant( bytearray ) << (qlonglong) 3200 << true; |
986 | QTest::newRow(dataTag: "int-QJsonValue" ) << QVariant(QJsonValue(321)) << (qlonglong)321 << true; |
987 | QTest::newRow(dataTag: "string-QJsonValue" ) << QVariant(QJsonValue(QString("string" ))) << (qlonglong)0 << false; |
988 | |
989 | qint64 value64 = (Q_INT64_C(12) << 35) + 8; |
990 | QTest::newRow(dataTag: "qint64" ) << QVariant::fromValue(value: value64) << qlonglong(value64) << true; |
991 | QTest::newRow(dataTag: "-qint64" ) << QVariant::fromValue(value: -value64) << qlonglong(-value64) << true; |
992 | QTest::newRow(dataTag: "long" ) << QVariant::fromValue(value: long(464646)) << qlonglong(464646) << true; |
993 | QTest::newRow(dataTag: "LONG_MAX" ) << QVariant::fromValue( LONG_MAX ) << qlonglong(LONG_MAX) << true; |
994 | QTest::newRow(dataTag: "LONG_MIN" ) << QVariant::fromValue( LONG_MIN ) << qlonglong(LONG_MIN) << true; |
995 | |
996 | QTest::newRow( dataTag: "short" ) << QVariant(short(12)) << qlonglong(12) << true; |
997 | QTest::newRow( dataTag: "-short" ) << QVariant(short(-24)) << qlonglong(-24) << true; |
998 | QTest::newRow( dataTag: "ushort" ) << QVariant(ushort(15)) << qlonglong(15) << true; |
999 | } |
1000 | |
1001 | void tst_QVariant::toLongLong() |
1002 | { |
1003 | QFETCH( QVariant, value ); |
1004 | QFETCH( qlonglong, result ); |
1005 | QFETCH( bool, valueOK ); |
1006 | QVERIFY( value.isValid() ); |
1007 | QVERIFY( value.canConvert( QVariant::LongLong ) ); |
1008 | bool ok; |
1009 | qlonglong ll = value.toLongLong( ok: &ok ); |
1010 | QCOMPARE( ll, result ); |
1011 | QVERIFY( ok == valueOK ); |
1012 | } |
1013 | |
1014 | void tst_QVariant::toULongLong_data() |
1015 | { |
1016 | QTest::addColumn<QVariant>(name: "value" ); |
1017 | QTest::addColumn<qulonglong>(name: "result" ); |
1018 | QTest::addColumn<bool>(name: "valueOK" ); |
1019 | |
1020 | QTest::newRow( dataTag: "int0" ) << QVariant( 123 ) << (qulonglong)123 << true; |
1021 | QTest::newRow( dataTag: "double" ) << QVariant( 3.1415927 ) << (qulonglong)3 << true; |
1022 | QTest::newRow( dataTag: "float" ) << QVariant( 3.1415927f ) << (qulonglong)3 << true; |
1023 | QTest::newRow( dataTag: "uint" ) << QVariant( 123u ) << (qulonglong)123 << true; |
1024 | QTest::newRow( dataTag: "int-string" ) << QVariant( QString("123" ) ) |
1025 | << (qulonglong)123 << true; |
1026 | QTest::newRow( dataTag: "string" ) << QVariant( QString("Unicode fun" ) ) << (qulonglong)0 |
1027 | << false; |
1028 | QTest::newRow( dataTag: "ulonglong-string" ) << QVariant( QString("18446744073709551615" ) ) |
1029 | << Q_UINT64_C(18446744073709551615) |
1030 | << true; |
1031 | QTest::newRow( dataTag: "bytaa-string" ) << QVariant( QString("18446744073709551615" ) ) |
1032 | << Q_UINT64_C(18446744073709551615) |
1033 | << true; |
1034 | QTest::newRow( dataTag: "longlong" ) << QVariant( intMax1 ) << (qulonglong)intMax1 << true; |
1035 | QTest::newRow( dataTag: "ulonglong" ) << QVariant( uintMax1 ) << uintMax1 << true; |
1036 | QTest::newRow( dataTag: "QChar" ) << QVariant(QChar('a')) << qulonglong('a') << true; |
1037 | QByteArray bytearray(4, ' '); |
1038 | bytearray[0] = '3'; |
1039 | bytearray[1] = '2'; |
1040 | bytearray[2] = '0'; |
1041 | bytearray[3] = '1'; |
1042 | QTest::newRow( dataTag: "QByteArray" ) << QVariant( bytearray ) << (qulonglong) 3201 << true; |
1043 | QTest::newRow(dataTag: "int-QJsonValue" ) << QVariant(QJsonValue(321)) << (qulonglong)321 << true; |
1044 | QTest::newRow(dataTag: "bool-QJsonValue" ) << QVariant(QJsonValue(true)) << (qulonglong)0 << false; |
1045 | |
1046 | quint64 value64 = (Q_INT64_C(12) << 35) + 8; |
1047 | QTest::newRow(dataTag: "qint64" ) << QVariant::fromValue(value: value64) << qulonglong(value64) << true; |
1048 | QTest::newRow(dataTag: "long" ) << QVariant::fromValue(value: long(464646)) << qulonglong(464646) << true; |
1049 | QTest::newRow(dataTag: "LONG_MAX" ) << QVariant::fromValue( LONG_MAX ) << qulonglong(LONG_MAX) << true; |
1050 | QTest::newRow(dataTag: "ULONG_MAX" ) << QVariant::fromValue( ULONG_MAX ) << qulonglong(ULONG_MAX) << true; |
1051 | QTest::newRow( dataTag: "short" ) << QVariant(short(12)) << qulonglong(12) << true; |
1052 | QTest::newRow( dataTag: "-short" ) << QVariant(short(-24)) << qulonglong(-24) << true; |
1053 | QTest::newRow( dataTag: "ushort" ) << QVariant(ushort(15)) << qulonglong(15) << true; |
1054 | } |
1055 | |
1056 | void tst_QVariant::toULongLong() |
1057 | { |
1058 | QFETCH( QVariant, value ); |
1059 | QFETCH( qulonglong, result ); |
1060 | QFETCH( bool, valueOK ); |
1061 | QVERIFY( value.isValid() ); |
1062 | QVERIFY( value.canConvert( QVariant::ULongLong ) ); |
1063 | bool ok; |
1064 | qulonglong ll = value.toULongLong( ok: &ok ); |
1065 | QCOMPARE( ll, result ); |
1066 | QVERIFY( ok == valueOK ); |
1067 | } |
1068 | |
1069 | void tst_QVariant::toByteArray_data() |
1070 | { |
1071 | QTest::addColumn<QVariant>(name: "value" ); |
1072 | QTest::addColumn<QByteArray>(name: "result" ); |
1073 | |
1074 | QByteArray ba(5, ' '); |
1075 | ba[0] = 'T'; |
1076 | ba[1] = 'e'; |
1077 | ba[2] = 's'; |
1078 | ba[3] = 't'; |
1079 | ba[4] = '\0'; |
1080 | |
1081 | QByteArray variantBa = ba; |
1082 | |
1083 | QTest::newRow( dataTag: "qbytearray" ) << QVariant( variantBa ) << ba; |
1084 | QTest::newRow( dataTag: "int" ) << QVariant( -123 ) << QByteArray( "-123" ); |
1085 | QTest::newRow( dataTag: "uint" ) << QVariant( (uint)123 ) << QByteArray( "123" ); |
1086 | QTest::newRow( dataTag: "double" ) << QVariant( 123.456 ) << QByteArray( "123.456" ); |
1087 | |
1088 | // Conversion from float to double adds bits of which the double-to-string converter doesn't |
1089 | // know they're insignificant |
1090 | QTest::newRow( dataTag: "float" ) << QVariant( 123.456f ) << QByteArray( "123.45600128173828" ); |
1091 | |
1092 | QTest::newRow( dataTag: "longlong" ) << QVariant( (qlonglong)34 ) << QByteArray( "34" ); |
1093 | QTest::newRow( dataTag: "ulonglong" ) << QVariant( (qulonglong)34 ) << QByteArray( "34" ); |
1094 | QTest::newRow( dataTag: "nullptr" ) << QVariant::fromValue(value: nullptr) << QByteArray(); |
1095 | } |
1096 | |
1097 | void tst_QVariant::toByteArray() |
1098 | { |
1099 | QFETCH( QVariant, value ); |
1100 | QFETCH( QByteArray, result ); |
1101 | QVERIFY( value.isValid() ); |
1102 | QVERIFY( value.canConvert( QVariant::ByteArray ) ); |
1103 | QByteArray ba = value.toByteArray(); |
1104 | QCOMPARE( ba.isNull(), result.isNull() ); |
1105 | QCOMPARE( ba, result ); |
1106 | |
1107 | QVERIFY( value.convert( QVariant::ByteArray ) ); |
1108 | QCOMPARE( value.isNull(), result.isNull() ); |
1109 | QCOMPARE( value.toByteArray().isNull(), result.isNull() ); |
1110 | QCOMPARE( value.toByteArray(), result ); |
1111 | } |
1112 | |
1113 | void tst_QVariant::toString_data() |
1114 | { |
1115 | QTest::addColumn<QVariant>(name: "value" ); |
1116 | QTest::addColumn<QString>(name: "result" ); |
1117 | |
1118 | QTest::newRow( dataTag: "qstring" ) << QVariant( QString( "Test" ) ) << QString( "Test" ); |
1119 | QTest::newRow( dataTag: "charstar" ) << QVariant(QLatin1String("Test" )) << QString("Test" ); |
1120 | QTest::newRow( dataTag: "qbytearray" ) << QVariant( QByteArray( "Test\0" ) ) << QString( "Test" ); |
1121 | QTest::newRow( dataTag: "int" ) << QVariant( -123 ) << QString( "-123" ); |
1122 | QTest::newRow( dataTag: "uint" ) << QVariant( (uint)123 ) << QString( "123" ); |
1123 | QTest::newRow( dataTag: "double" ) << QVariant( 123.456 ) << QString( "123.456" ); |
1124 | |
1125 | // Conversion from float to double adds bits of which the double-to-string converter doesn't |
1126 | // know they're insignificant |
1127 | QTest::newRow( dataTag: "float" ) << QVariant( 123.456f ) << QString( "123.45600128173828" ); |
1128 | |
1129 | QTest::newRow( dataTag: "bool" ) << QVariant( true ) << QString( "true" ); |
1130 | QTest::newRow( dataTag: "qdate" ) << QVariant( QDate( 2002, 1, 1 ) ) << QString( "2002-01-01" ); |
1131 | QTest::newRow( dataTag: "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56.000" ); |
1132 | QTest::newRow( dataTag: "qtime-with-ms" ) << QVariant( QTime( 12, 34, 56, 789 ) ) << QString( "12:34:56.789" ); |
1133 | QTest::newRow( dataTag: "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56, 789 ) ) ) << QString( "2002-01-01T12:34:56.789" ); |
1134 | QTest::newRow( dataTag: "llong" ) << QVariant( (qlonglong)Q_INT64_C(123456789012) ) << |
1135 | QString( "123456789012" ); |
1136 | QTest::newRow(dataTag: "QJsonValue" ) << QVariant(QJsonValue(QString("hello" ))) << QString("hello" ); |
1137 | QTest::newRow(dataTag: "QJsonValue(Null)" ) << QVariant(QJsonValue(QJsonValue::Null)) << QString(); |
1138 | QTest::newRow(dataTag: "nullptr" ) << QVariant::fromValue(value: nullptr) << QString(); |
1139 | } |
1140 | |
1141 | void tst_QVariant::toString() |
1142 | { |
1143 | QFETCH( QVariant, value ); |
1144 | QFETCH( QString, result ); |
1145 | QVERIFY( value.isValid() ); |
1146 | QVERIFY( value.canConvert( QVariant::String ) ); |
1147 | QString str = value.toString(); |
1148 | QCOMPARE( str.isNull(), result.isNull() ); |
1149 | QCOMPARE( str, result ); |
1150 | |
1151 | QVERIFY( value.convert( QVariant::String ) ); |
1152 | QCOMPARE( value.isNull(), result.isNull() ); |
1153 | QCOMPARE( value.toString().isNull(), result.isNull() ); |
1154 | QCOMPARE( value.toString(), result ); |
1155 | } |
1156 | |
1157 | void tst_QVariant::toDate_data() |
1158 | { |
1159 | QTest::addColumn<QVariant>(name: "value" ); |
1160 | QTest::addColumn<QDate>(name: "result" ); |
1161 | |
1162 | QTest::newRow( dataTag: "qdate" ) << QVariant( QDate( 2002, 10, 10 ) ) << QDate( 2002, 10, 10 ); |
1163 | QTest::newRow( dataTag: "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ) ) << QDate( 2002, 10, 10 ); |
1164 | QTest::newRow( dataTag: "qstring" ) << QVariant( QString( "2002-10-10" ) ) << QDate( 2002, 10, 10 ); |
1165 | } |
1166 | |
1167 | void tst_QVariant::toDate() |
1168 | { |
1169 | QFETCH( QVariant, value ); |
1170 | QFETCH( QDate, result ); |
1171 | QVERIFY( value.isValid() ); |
1172 | QVERIFY( value.canConvert( QVariant::Date ) ); |
1173 | QCOMPARE( value.toDate(), result ); |
1174 | } |
1175 | |
1176 | void tst_QVariant::toTime_data() |
1177 | { |
1178 | QTest::addColumn<QVariant>(name: "value" ); |
1179 | QTest::addColumn<QTime>(name: "result" ); |
1180 | |
1181 | QTest::newRow( dataTag: "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QTime( 12, 34, 56 ); |
1182 | QTest::newRow( dataTag: "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ) ) << QTime( 12, 34, 56 ); |
1183 | QTest::newRow( dataTag: "qstring" ) << QVariant( QString( "12:34:56" ) ) << QTime( 12, 34, 56 ); |
1184 | QTest::newRow( dataTag: "qstring-with-ms" ) << QVariant( QString( "12:34:56.789" ) ) << QTime( 12, 34, 56, 789 ); |
1185 | } |
1186 | |
1187 | void tst_QVariant::toTime() |
1188 | { |
1189 | QFETCH( QVariant, value ); |
1190 | QFETCH( QTime, result ); |
1191 | QVERIFY( value.isValid() ); |
1192 | QVERIFY( value.canConvert( QVariant::Time ) ); |
1193 | QCOMPARE( value.toTime(), result ); |
1194 | } |
1195 | |
1196 | void tst_QVariant::toDateTime_data() |
1197 | { |
1198 | QTest::addColumn<QVariant>(name: "value" ); |
1199 | QTest::addColumn<QDateTime>(name: "result" ); |
1200 | |
1201 | QTest::newRow( dataTag: "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ) ) |
1202 | << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ); |
1203 | QTest::newRow( dataTag: "qdate" ) << QVariant( QDate( 2002, 10, 10 ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 0, 0, 0 ) ); |
1204 | QTest::newRow( dataTag: "qstring" ) << QVariant( QString( "2002-10-10T12:34:56" ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ); |
1205 | QTest::newRow( dataTag: "qstring-utc" ) << QVariant( QString( "2002-10-10T12:34:56Z" ) ) |
1206 | << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ), Qt::UTC ); |
1207 | QTest::newRow( dataTag: "qstring-with-ms" ) << QVariant( QString( "2002-10-10T12:34:56.789" ) ) |
1208 | << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56, 789 ) ); |
1209 | } |
1210 | |
1211 | void tst_QVariant::toDateTime() |
1212 | { |
1213 | QFETCH( QVariant, value ); |
1214 | QFETCH( QDateTime, result ); |
1215 | QVERIFY( value.isValid() ); |
1216 | QVERIFY( value.canConvert( QVariant::DateTime ) ); |
1217 | QCOMPARE( value.toDateTime(), result ); |
1218 | } |
1219 | |
1220 | void tst_QVariant::toLocale() |
1221 | { |
1222 | QVariant variant; |
1223 | QLocale loc = variant.toLocale(); |
1224 | variant = QLocale::system(); |
1225 | loc = variant.toLocale(); |
1226 | } |
1227 | |
1228 | void tst_QVariant::toRegExp() |
1229 | { |
1230 | QVariant variant; |
1231 | QRegExp rx = variant.toRegExp(); |
1232 | variant = QRegExp("foo" ); |
1233 | rx = variant.toRegExp(); |
1234 | } |
1235 | |
1236 | void tst_QVariant::toRegularExpression() |
1237 | { |
1238 | QVariant variant; |
1239 | QRegularExpression re = variant.toRegularExpression(); |
1240 | QCOMPARE(re, QRegularExpression()); |
1241 | |
1242 | variant = QRegularExpression("abc.*def" ); |
1243 | re = variant.toRegularExpression(); |
1244 | QCOMPARE(re, QRegularExpression("abc.*def" )); |
1245 | |
1246 | variant = QVariant::fromValue(value: QRegularExpression("[ab]\\w+" )); |
1247 | re = variant.value<QRegularExpression>(); |
1248 | QCOMPARE(re, QRegularExpression("[ab]\\w+" )); |
1249 | } |
1250 | |
1251 | struct CustomStreamableClass |
1252 | { |
1253 | int i; |
1254 | bool operator==(const CustomStreamableClass& other) const |
1255 | { |
1256 | return i == other.i; |
1257 | } |
1258 | }; |
1259 | Q_DECLARE_METATYPE(CustomStreamableClass); |
1260 | |
1261 | QDataStream &operator<<(QDataStream &out, const CustomStreamableClass &myObj) |
1262 | { |
1263 | return out << myObj.i; |
1264 | } |
1265 | |
1266 | QDataStream &operator>>(QDataStream &in, CustomStreamableClass &myObj) |
1267 | { |
1268 | return in >> myObj.i; |
1269 | } |
1270 | |
1271 | void tst_QVariant::writeToReadFromDataStream_data() |
1272 | { |
1273 | qRegisterMetaTypeStreamOperators<CustomStreamableClass>(); |
1274 | |
1275 | QTest::addColumn<QVariant>(name: "writeVariant" ); |
1276 | QTest::addColumn<bool>(name: "isNull" ); |
1277 | { |
1278 | QVariantList valuelist; |
1279 | valuelist << QVariant( 1 ) << QVariant( QString("Two" ) ) << QVariant( 3.45 ); |
1280 | QVariant var(valuelist); |
1281 | QTest::newRow( dataTag: "list_valid" ) << var << false; |
1282 | } |
1283 | |
1284 | QTest::newRow( dataTag: "invalid" ) << QVariant() << true; |
1285 | QTest::newRow( dataTag: "bitarray_invalid" ) << QVariant( QBitArray() ) << true; |
1286 | QBitArray bitarray( 3 ); |
1287 | bitarray[0] = 0; |
1288 | bitarray[1] = 1; |
1289 | bitarray[2] = 0; |
1290 | QTest::newRow( dataTag: "bitarray_valid" ) << QVariant( bitarray ) << false; |
1291 | QTest::newRow( dataTag: "bytearray_invalid" ) << QVariant( QByteArray() ) << true; |
1292 | QTest::newRow( dataTag: "int_invalid" ) << QVariant(QVariant::Int) << true; |
1293 | QByteArray bytearray(5, ' '); |
1294 | bytearray[0] = 'T'; |
1295 | bytearray[1] = 'e'; |
1296 | bytearray[2] = 's'; |
1297 | bytearray[3] = 't'; |
1298 | bytearray[4] = '\0'; |
1299 | QTest::newRow( dataTag: "bytearray_valid" ) << QVariant( bytearray ) << false; |
1300 | QTest::newRow( dataTag: "date_invalid" ) << QVariant( QDate() ) << true; |
1301 | QTest::newRow( dataTag: "date_valid" ) << QVariant( QDate( 2002, 07, 06 ) ) << false; |
1302 | QTest::newRow( dataTag: "datetime_invalid" ) << QVariant( QDateTime() ) << true; |
1303 | QTest::newRow( dataTag: "datetime_valid" ) << QVariant( QDateTime( QDate( 2002, 07, 06 ), QTime( 14, 0, 0 ) ) ) << false; |
1304 | QTest::newRow( dataTag: "double_valid" ) << QVariant( 123.456 ) << false; |
1305 | QTest::newRow( dataTag: "float_valid" ) << QVariant( 123.456f ) << false; |
1306 | QTest::newRow( dataTag: "int_valid" ) << QVariant( -123 ) << false; |
1307 | QVariantMap vMap; |
1308 | vMap.insert( akey: "int" , avalue: QVariant( 1 ) ); |
1309 | vMap.insert( akey: "string" , avalue: QVariant( QString("Two" ) ) ); |
1310 | vMap.insert( akey: "double" , avalue: QVariant( 3.45 ) ); |
1311 | vMap.insert( akey: "float" , avalue: QVariant( 3.45f ) ); |
1312 | QTest::newRow( dataTag: "map_valid" ) << QVariant( vMap ) << false; |
1313 | QTest::newRow( dataTag: "point_invalid" ) << QVariant::fromValue( value: QPoint() ) << true; |
1314 | QTest::newRow( dataTag: "point_valid" ) << QVariant::fromValue( value: QPoint( 10, 10 ) ) << false; |
1315 | QTest::newRow( dataTag: "rect_invalid" ) << QVariant( QRect() ) << true; |
1316 | QTest::newRow( dataTag: "rect_valid" ) << QVariant( QRect( 10, 10, 20, 20 ) ) << false; |
1317 | QTest::newRow( dataTag: "size_invalid" ) << QVariant( QSize( 0, 0 ) ) << true; |
1318 | QTest::newRow( dataTag: "size_valid" ) << QVariant( QSize( 10, 10 ) ) << false; |
1319 | QTest::newRow( dataTag: "string_invalid" ) << QVariant( QString() ) << true; |
1320 | QTest::newRow( dataTag: "string_valid" ) << QVariant( QString( "Test" ) ) << false; |
1321 | QStringList stringlist; |
1322 | stringlist << "One" << "Two" << "Three" ; |
1323 | QTest::newRow( dataTag: "stringlist_valid" ) << QVariant( stringlist ) << false; |
1324 | QTest::newRow( dataTag: "time_invalid" ) << QVariant( QTime() ) << true; |
1325 | QTest::newRow( dataTag: "time_valid" ) << QVariant( QTime( 14, 0, 0 ) ) << false; |
1326 | QTest::newRow( dataTag: "uint_valid" ) << QVariant( (uint)123 ) << false; |
1327 | QTest::newRow( dataTag: "qchar" ) << QVariant(QChar('a')) << false; |
1328 | QTest::newRow( dataTag: "qchar_null" ) << QVariant(QChar(0)) << true; |
1329 | QTest::newRow( dataTag: "regexp" ) << QVariant(QRegExp("foo" , Qt::CaseInsensitive)) << false; |
1330 | QTest::newRow( dataTag: "regexp_empty" ) << QVariant(QRegExp()) << false; |
1331 | QTest::newRow( dataTag: "regularexpression" ) << QVariant(QRegularExpression("abc.*def" )) << false; |
1332 | QTest::newRow( dataTag: "regularexpression_empty" ) << QVariant(QRegularExpression()) << false; |
1333 | |
1334 | // types known to QMetaType, but not part of QVariant::Type |
1335 | QTest::newRow(dataTag: "QMetaType::Long invalid" ) << QVariant(QMetaType::Long, (void *) 0) << false; |
1336 | long longInt = -1l; |
1337 | QTest::newRow(dataTag: "QMetaType::Long" ) << QVariant(QMetaType::Long, &longInt) << false; |
1338 | QTest::newRow(dataTag: "QMetaType::Short invalid" ) << QVariant(QMetaType::Short, (void *) 0) << false; |
1339 | short shortInt = 1; |
1340 | QTest::newRow(dataTag: "QMetaType::Short" ) << QVariant(QMetaType::Short, &shortInt) << false; |
1341 | QTest::newRow(dataTag: "QMetaType::Char invalid" ) << QVariant(QMetaType::Char, (void *) 0) << false; |
1342 | char ch = 'c'; |
1343 | QTest::newRow(dataTag: "QMetaType::Char" ) << QVariant(QMetaType::Char, &ch) << false; |
1344 | QTest::newRow(dataTag: "QMetaType::ULong invalid" ) << QVariant(QMetaType::ULong, (void *) 0) << false; |
1345 | ulong ulongInt = 1ul; |
1346 | QTest::newRow(dataTag: "QMetaType::ULong" ) << QVariant(QMetaType::ULong, &ulongInt) << false; |
1347 | QTest::newRow(dataTag: "QMetaType::UShort invalid" ) << QVariant(QMetaType::UShort, (void *) 0) << false; |
1348 | ushort ushortInt = 1u; |
1349 | QTest::newRow(dataTag: "QMetaType::UShort" ) << QVariant(QMetaType::UShort, &ushortInt) << false; |
1350 | QTest::newRow(dataTag: "QMetaType::UChar invalid" ) << QVariant(QMetaType::UChar, (void *) 0) << false; |
1351 | uchar uch = 0xf0; |
1352 | QTest::newRow(dataTag: "QMetaType::UChar" ) << QVariant(QMetaType::UChar, &uch) << false; |
1353 | QTest::newRow(dataTag: "QMetaType::Float invalid" ) << QVariant(QMetaType::Float, (void *) 0) << false; |
1354 | float f = 1.234f; |
1355 | QTest::newRow(dataTag: "QMetaType::Float" ) << QVariant(QMetaType::Float, &f) << false; |
1356 | CustomStreamableClass custom = {.i: 123}; |
1357 | QTest::newRow(dataTag: "Custom type" ) << QVariant::fromValue(value: custom) << false; |
1358 | } |
1359 | |
1360 | void tst_QVariant::writeToReadFromDataStream() |
1361 | { |
1362 | QFETCH( QVariant, writeVariant ); |
1363 | QFETCH( bool, isNull ); |
1364 | QByteArray data; |
1365 | |
1366 | QDataStream writeStream( &data, QIODevice::WriteOnly ); |
1367 | writeStream << writeVariant; |
1368 | |
1369 | QVariant readVariant; |
1370 | QDataStream readStream( &data, QIODevice::ReadOnly ); |
1371 | readStream >> readVariant; |
1372 | QVERIFY( readVariant.isNull() == isNull ); |
1373 | // Best way to confirm the readVariant contains the same data? |
1374 | // Since only a few won't match since the serial numbers are different |
1375 | // I won't bother adding another bool in the data test. |
1376 | const int writeType = writeVariant.userType(); |
1377 | if (writeType == qMetaTypeId<CustomStreamableClass>()) |
1378 | QCOMPARE(qvariant_cast<CustomStreamableClass>(readVariant), qvariant_cast<CustomStreamableClass>(writeVariant)); |
1379 | else if ( writeType != QVariant::Invalid && writeType != QVariant::Bitmap && writeType != QVariant::Pixmap |
1380 | && writeType != QVariant::Image) { |
1381 | switch (writeType) { |
1382 | default: |
1383 | QCOMPARE( readVariant, writeVariant ); |
1384 | break; |
1385 | |
1386 | // compare types know by QMetaType but not QVariant (QVariant::operator==() knows nothing about them) |
1387 | case QMetaType::Long: |
1388 | QCOMPARE(qvariant_cast<long>(readVariant), qvariant_cast<long>(writeVariant)); |
1389 | break; |
1390 | case QMetaType::ULong: |
1391 | QCOMPARE(qvariant_cast<ulong>(readVariant), qvariant_cast<ulong>(writeVariant)); |
1392 | break; |
1393 | case QMetaType::Short: |
1394 | QCOMPARE(qvariant_cast<short>(readVariant), qvariant_cast<short>(writeVariant)); |
1395 | break; |
1396 | case QMetaType::UShort: |
1397 | QCOMPARE(qvariant_cast<ushort>(readVariant), qvariant_cast<ushort>(writeVariant)); |
1398 | break; |
1399 | case QMetaType::Char: |
1400 | QCOMPARE(qvariant_cast<char>(readVariant), qvariant_cast<char>(writeVariant)); |
1401 | break; |
1402 | case QMetaType::UChar: |
1403 | QCOMPARE(qvariant_cast<uchar>(readVariant), qvariant_cast<uchar>(writeVariant)); |
1404 | break; |
1405 | case QMetaType::Float: |
1406 | { |
1407 | // the uninitialized float can be NaN (observed on Windows Mobile 5 ARMv4i) |
1408 | float readFloat = qvariant_cast<float>(v: readVariant); |
1409 | float writtenFloat = qvariant_cast<float>(v: writeVariant); |
1410 | QCOMPARE(qIsNaN(readFloat), qIsNaN(writtenFloat)); |
1411 | if (!qIsNaN(f: readFloat)) |
1412 | QCOMPARE(readFloat, writtenFloat); |
1413 | } |
1414 | break; |
1415 | } |
1416 | } |
1417 | } |
1418 | |
1419 | void tst_QVariant::writeToReadFromOldDataStream() |
1420 | { |
1421 | QVariant writeVariant = QString("hello" ); |
1422 | QByteArray data; |
1423 | |
1424 | QDataStream writeStream(&data, QIODevice::WriteOnly); |
1425 | writeStream.setVersion(QDataStream::Qt_2_1); |
1426 | writeStream << writeVariant; |
1427 | |
1428 | QVariant readVariant; |
1429 | QDataStream readStream(&data, QIODevice::ReadOnly); |
1430 | readStream.setVersion(QDataStream::Qt_2_1); |
1431 | readStream >> readVariant; |
1432 | |
1433 | QCOMPARE(writeVariant.userType(), readVariant.userType()); |
1434 | QCOMPARE(writeVariant, readVariant); |
1435 | } |
1436 | |
1437 | void tst_QVariant::checkDataStream() |
1438 | { |
1439 | const int typeId = QMetaType::LastCoreType + 1; |
1440 | QVERIFY(!QMetaType::isRegistered(typeId)); |
1441 | |
1442 | QByteArray errorMessage("Trying to construct an instance of an invalid type, type id: " ); |
1443 | errorMessage.append(a: QString::number(typeId, base: 10).toUtf8()); |
1444 | |
1445 | QTest::ignoreMessage(type: QtWarningMsg, message: errorMessage.constData()); |
1446 | QByteArray settingsHex("000000" ); |
1447 | settingsHex.append(a: QString::number(typeId, base: 16).toUtf8()); |
1448 | settingsHex.append(s: "ffffffffff" ); |
1449 | const QByteArray settings = QByteArray::fromHex(hexEncoded: settingsHex); |
1450 | QDataStream in(settings); |
1451 | QVariant v; |
1452 | in >> v; |
1453 | // the line below has been left out for now since the data stream |
1454 | // is not necessarily considered corrupt when an invalid QVariant is |
1455 | // constructed. However, it might be worth considering changing that behavior |
1456 | // in the future. |
1457 | // QCOMPARE(in.status(), QDataStream::ReadCorruptData); |
1458 | QCOMPARE(v.type(), QVariant::Invalid); |
1459 | } |
1460 | |
1461 | void tst_QVariant::operator_eq_eq_data() |
1462 | { |
1463 | QTest::addColumn<QVariant>(name: "left" ); |
1464 | QTest::addColumn<QVariant>(name: "right" ); |
1465 | QTest::addColumn<bool>(name: "equal" ); // left == right ? |
1466 | |
1467 | QVariant inv; |
1468 | QVariant i0( int(0) ); |
1469 | QVariant i1( int(1) ); |
1470 | // Invalid |
1471 | QTest::newRow( dataTag: "invinv" ) << inv << inv << true; |
1472 | // Int |
1473 | QTest::newRow( dataTag: "int1int1" ) << i1 << i1 << true; |
1474 | QTest::newRow( dataTag: "int1int0" ) << i1 << i0 << false; |
1475 | QTest::newRow( dataTag: "nullint" ) << i0 << QVariant(QVariant::Int) << true; |
1476 | |
1477 | // LongLong and ULongLong |
1478 | QVariant ll1( (qlonglong)1 ); |
1479 | QVariant lln2( (qlonglong)-2 ); |
1480 | QVariant ull1( (qulonglong)1 ); |
1481 | QVariant ull3( (qulonglong)3 ); |
1482 | QTest::newRow( dataTag: "ll1ll1" ) << ll1 << ll1 << true; |
1483 | QTest::newRow( dataTag: "ll1lln2" ) << ll1 << lln2 << false; |
1484 | QTest::newRow( dataTag: "ll1ull1" ) << ull1 << ull1 << true; |
1485 | QTest::newRow( dataTag: "ll1i1" ) << ull1 << i1 << true; |
1486 | QTest::newRow( dataTag: "ull1ull1" ) << ull1 << ull1 << true; |
1487 | QTest::newRow( dataTag: "ull1i1" ) << ull1 << ull1 << true; |
1488 | |
1489 | QVariant mInt(-42); |
1490 | QVariant mIntString(QByteArray("-42" )); |
1491 | QVariant mIntQString(QString("-42" )); |
1492 | |
1493 | QVariant mUInt(42u); |
1494 | QVariant mUIntString(QByteArray("42" )); |
1495 | QVariant mUIntQString(QString("42" )); |
1496 | |
1497 | QVariant mDouble(42.11); |
1498 | #ifdef QT_NO_DOUBLECONVERSION |
1499 | // Without libdouble-conversion we don't get the shortest possible representation. |
1500 | QVariant mDoubleString(QByteArray("42.109999999999999" )); |
1501 | QVariant mDoubleQString(QByteArray("42.109999999999999" )); |
1502 | #else |
1503 | // You cannot fool the double-to-string conversion into producing insignificant digits with |
1504 | // libdouble-conversion. You can, of course, add insignificant digits to the string and fool |
1505 | // the double-to-double comparison after converting the string to a double. |
1506 | QVariant mDoubleString(QByteArray("42.11" )); |
1507 | QVariant mDoubleQString(QString("42.11" )); |
1508 | #endif |
1509 | |
1510 | // Float-to-double conversion produces insignificant extra bits. |
1511 | QVariant mFloat(42.11f); |
1512 | #ifdef QT_NO_DOUBLECONVERSION |
1513 | // The trailing '2' is not significant, but snprintf doesn't know this. |
1514 | QVariant mFloatString(QByteArray("42.110000610351562" )); |
1515 | QVariant mFloatQString(QString("42.110000610351562" )); |
1516 | #else |
1517 | QVariant mFloatString(QByteArray("42.11000061035156" )); |
1518 | QVariant mFloatQString(QString("42.11000061035156" )); |
1519 | #endif |
1520 | |
1521 | QVariant mLongLong((qlonglong)-42); |
1522 | QVariant mLongLongString(QByteArray("-42" )); |
1523 | QVariant mLongLongQString(QString("-42" )); |
1524 | |
1525 | QVariant mULongLong((qulonglong)42); |
1526 | QVariant mULongLongString(QByteArray("42" )); |
1527 | QVariant mULongLongQString(QString("42" )); |
1528 | |
1529 | QVariant mBool(false); |
1530 | QVariant mBoolString(QByteArray("false" )); |
1531 | QVariant mBoolQString(QString("false" )); |
1532 | |
1533 | QTest::newRow( dataTag: "double_int" ) << QVariant(42.0) << QVariant(42) << true; |
1534 | QTest::newRow( dataTag: "float_int" ) << QVariant(42.f) << QVariant(42) << true; |
1535 | QTest::newRow( dataTag: "mInt_mIntString" ) << mInt << mIntString << true; |
1536 | QTest::newRow( dataTag: "mIntString_mInt" ) << mIntString << mInt << true; |
1537 | QTest::newRow( dataTag: "mInt_mIntQString" ) << mInt << mIntQString << true; |
1538 | QTest::newRow( dataTag: "mIntQString_mInt" ) << mIntQString << mInt << true; |
1539 | |
1540 | QTest::newRow( dataTag: "mUInt_mUIntString" ) << mUInt << mUIntString << true; |
1541 | QTest::newRow( dataTag: "mUIntString_mUInt" ) << mUIntString << mUInt << true; |
1542 | QTest::newRow( dataTag: "mUInt_mUIntQString" ) << mUInt << mUIntQString << true; |
1543 | QTest::newRow( dataTag: "mUIntQString_mUInt" ) << mUIntQString << mUInt << true; |
1544 | |
1545 | QTest::newRow( dataTag: "mDouble_mDoubleString" ) << mDouble << mDoubleString << true; |
1546 | QTest::newRow( dataTag: "mDoubleString_mDouble" ) << mDoubleString << mDouble << true; |
1547 | QTest::newRow( dataTag: "mDouble_mDoubleQString" ) << mDouble << mDoubleQString << true; |
1548 | QTest::newRow( dataTag: "mDoubleQString_mDouble" ) << mDoubleQString << mDouble << true; |
1549 | |
1550 | QTest::newRow( dataTag: "mFloat_mFloatString" ) << mFloat << mFloatString << true; |
1551 | QTest::newRow( dataTag: "mFloatString_mFloat" ) << mFloatString << mFloat << true; |
1552 | QTest::newRow( dataTag: "mFloat_mFloatQString" ) << mFloat << mFloatQString << true; |
1553 | QTest::newRow( dataTag: "mFloatQString_mFloat" ) << mFloatQString << mFloat << true; |
1554 | |
1555 | QTest::newRow( dataTag: "mLongLong_mLongLongString" ) << mLongLong << mLongLongString << true; |
1556 | QTest::newRow( dataTag: "mLongLongString_mLongLong" ) << mLongLongString << mLongLong << true; |
1557 | QTest::newRow( dataTag: "mLongLong_mLongLongQString" ) << mLongLong << mLongLongQString << true; |
1558 | QTest::newRow( dataTag: "mLongLongQString_mLongLong" ) << mLongLongQString << mLongLong << true; |
1559 | |
1560 | QTest::newRow( dataTag: "mULongLong_mULongLongString" ) << mULongLong << mULongLongString << true; |
1561 | QTest::newRow( dataTag: "mULongLongString_mULongLong" ) << mULongLongString << mULongLong << true; |
1562 | QTest::newRow( dataTag: "mULongLong_mULongLongQString" ) << mULongLong << mULongLongQString << true; |
1563 | QTest::newRow( dataTag: "mULongLongQString_mULongLong" ) << mULongLongQString << mULongLong << true; |
1564 | |
1565 | QTest::newRow( dataTag: "mBool_mBoolString" ) << mBool << mBoolString << true; |
1566 | QTest::newRow( dataTag: "mBoolString_mBool" ) << mBoolString << mBool << true; |
1567 | QTest::newRow( dataTag: "mBool_mBoolQString" ) << mBool << mBoolQString << true; |
1568 | QTest::newRow( dataTag: "mBoolQString_mBool" ) << mBoolQString << mBool << true; |
1569 | |
1570 | QTest::newRow(dataTag: "ba2qstring" ) << QVariant(QLatin1String("hallo" )) << QVariant(QString("hallo" )) << true; |
1571 | QTest::newRow(dataTag: "qstring2ba" ) << QVariant(QString("hallo" )) << QVariant(QLatin1String("hallo" )) << true; |
1572 | QTest::newRow(dataTag: "char_char" ) << QVariant(QChar('a')) << QVariant(QChar('a')) << true; |
1573 | QTest::newRow(dataTag: "char_char2" ) << QVariant(QChar('a')) << QVariant(QChar('b')) << false; |
1574 | |
1575 | QTest::newRow(dataTag: "invalidConversion" ) << QVariant(QString("bubu" )) << QVariant(0) << false; |
1576 | QTest::newRow(dataTag: "invalidConversionR" ) << QVariant(0) << QVariant(QString("bubu" )) << false; |
1577 | // ### many other combinations missing |
1578 | |
1579 | { |
1580 | QUuid uuid(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); |
1581 | QTest::newRow(dataTag: "uuidstring" ) << QVariant(uuid) << QVariant(uuid.toString()) << true; |
1582 | QTest::newRow(dataTag: "stringuuid" ) << QVariant(uuid.toString()) << QVariant(uuid) << true; |
1583 | QTest::newRow(dataTag: "uuidbytearray" ) << QVariant(uuid) << QVariant(uuid.toByteArray()) << true; |
1584 | QTest::newRow(dataTag: "bytearrayuuid" ) << QVariant(uuid.toByteArray()) << QVariant(uuid) << true; |
1585 | } |
1586 | |
1587 | { |
1588 | QMap<QString, QVariant> map1; |
1589 | map1.insert( akey: "X" , avalue: 1 ); |
1590 | |
1591 | QMap<QString, QVariant> map2; |
1592 | map2.insert( akey: "Y" , avalue: 1 ); |
1593 | |
1594 | QTest::newRow(dataTag: "TwoItemsInEqual" ) << QVariant(map1) << QVariant(map2) << false; |
1595 | |
1596 | } |
1597 | |
1598 | { |
1599 | QMap<QString, QVariant> map1; |
1600 | map1.insert( akey: "X" , avalue: 1 ); |
1601 | |
1602 | QMap<QString, QVariant> map2; |
1603 | map2.insert( akey: "X" , avalue: 1 ); |
1604 | |
1605 | QTest::newRow(dataTag: "TwoItemsEqual" ) << QVariant(map1) << QVariant(map2) << true; |
1606 | } |
1607 | |
1608 | { |
1609 | QMap<QString, QVariant> map1; |
1610 | map1.insert( akey: "X" , avalue: 1 ); |
1611 | |
1612 | QMap<QString, QVariant> map2; |
1613 | |
1614 | QTest::newRow(dataTag: "PopulatedEmptyMap" ) << QVariant(map1) << QVariant(map2) << false; |
1615 | } |
1616 | |
1617 | { |
1618 | QMap<QString, QVariant> map1; |
1619 | |
1620 | QMap<QString, QVariant> map2; |
1621 | map2.insert( akey: "X" , avalue: 1 ); |
1622 | |
1623 | QTest::newRow(dataTag: "EmptyPopulatedMap" ) << QVariant(map1) << QVariant(map2) << false; |
1624 | } |
1625 | |
1626 | { |
1627 | QMap<QString, QVariant> map1; |
1628 | map1.insert( akey: "X" , avalue: 1 ); |
1629 | map1.insert( akey: "Y" , avalue: 1 ); |
1630 | |
1631 | QMap<QString, QVariant> map2; |
1632 | map2.insert( akey: "X" , avalue: 1 ); |
1633 | |
1634 | QTest::newRow(dataTag: "FirstLarger" ) << QVariant(map1) << QVariant(map2) << false; |
1635 | } |
1636 | |
1637 | { |
1638 | QMap<QString, QVariant> map1; |
1639 | map1.insert( akey: "X" , avalue: 1 ); |
1640 | |
1641 | QMap<QString, QVariant> map2; |
1642 | map2.insert( akey: "X" , avalue: 1 ); |
1643 | map2.insert( akey: "Y" , avalue: 1 ); |
1644 | |
1645 | QTest::newRow(dataTag: "SecondLarger" ) << QVariant(map1) << QVariant(map2) << false; |
1646 | } |
1647 | |
1648 | // same thing with hash |
1649 | { |
1650 | QHash<QString, QVariant> hash1; |
1651 | hash1.insert( akey: "X" , avalue: 1 ); |
1652 | |
1653 | QHash<QString, QVariant> hash2; |
1654 | hash2.insert( akey: "Y" , avalue: 1 ); |
1655 | |
1656 | QTest::newRow(dataTag: "HashTwoItemsInEqual" ) << QVariant(hash1) << QVariant(hash2) << false; |
1657 | |
1658 | } |
1659 | |
1660 | { |
1661 | QHash<QString, QVariant> hash1; |
1662 | hash1.insert( akey: "X" , avalue: 1 ); |
1663 | |
1664 | QHash<QString, QVariant> hash2; |
1665 | hash2.insert( akey: "X" , avalue: 1 ); |
1666 | |
1667 | QTest::newRow(dataTag: "HashTwoItemsEqual" ) << QVariant(hash1) << QVariant(hash2) << true; |
1668 | } |
1669 | |
1670 | { |
1671 | QHash<QString, QVariant> hash1; |
1672 | hash1.insert( akey: "X" , avalue: 1 ); |
1673 | |
1674 | QHash<QString, QVariant> hash2; |
1675 | |
1676 | QTest::newRow(dataTag: "HashPopulatedEmptyHash" ) << QVariant(hash1) << QVariant(hash2) << false; |
1677 | } |
1678 | |
1679 | { |
1680 | QHash<QString, QVariant> hash1; |
1681 | |
1682 | QHash<QString, QVariant> hash2; |
1683 | hash2.insert( akey: "X" , avalue: 1 ); |
1684 | |
1685 | QTest::newRow(dataTag: "EmptyPopulatedHash" ) << QVariant(hash1) << QVariant(hash2) << false; |
1686 | } |
1687 | |
1688 | { |
1689 | QHash<QString, QVariant> hash1; |
1690 | hash1.insert( akey: "X" , avalue: 1 ); |
1691 | hash1.insert( akey: "Y" , avalue: 1 ); |
1692 | |
1693 | QHash<QString, QVariant> hash2; |
1694 | hash2.insert( akey: "X" , avalue: 1 ); |
1695 | |
1696 | QTest::newRow(dataTag: "HashFirstLarger" ) << QVariant(hash1) << QVariant(hash2) << false; |
1697 | } |
1698 | |
1699 | { |
1700 | QHash<QString, QVariant> hash1; |
1701 | hash1.insert( akey: "X" , avalue: 1 ); |
1702 | |
1703 | QHash<QString, QVariant> hash2; |
1704 | hash2.insert( akey: "X" , avalue: 1 ); |
1705 | hash2.insert( akey: "Y" , avalue: 1 ); |
1706 | |
1707 | QTest::newRow(dataTag: "HashSecondLarger" ) << QVariant(hash1) << QVariant(hash2) << false; |
1708 | } |
1709 | } |
1710 | |
1711 | void tst_QVariant::operator_eq_eq() |
1712 | { |
1713 | QFETCH( QVariant, left ); |
1714 | QFETCH( QVariant, right ); |
1715 | QFETCH( bool, equal ); |
1716 | QCOMPARE( left == right, equal ); |
1717 | } |
1718 | |
1719 | void tst_QVariant::operator_eq_eq_rhs() |
1720 | { |
1721 | QVariant v = 42; |
1722 | |
1723 | QVERIFY(v == 42); |
1724 | QVERIFY(42 == v); |
1725 | |
1726 | #if 0 |
1727 | /* This should _not_ compile */ |
1728 | QStringList list; |
1729 | QDateTime dt; |
1730 | |
1731 | QVERIFY(dt == list); |
1732 | #endif |
1733 | } |
1734 | |
1735 | void tst_QVariant::compareNumbers_data() const |
1736 | { |
1737 | typedef signed char schar; |
1738 | QTest::addColumn<QVariant>(name: "v1" ); |
1739 | QTest::addColumn<QVariant>(name: "v2" ); |
1740 | QTest::addColumn<int>(name: "expected" ); |
1741 | |
1742 | // sanity checking: same types |
1743 | QTest::newRow(dataTag: "bool1" ) << QVariant(false) << QVariant(false) << 0; |
1744 | QTest::newRow(dataTag: "bool2" ) << QVariant(true) << QVariant(true) << 0; |
1745 | QTest::newRow(dataTag: "bool3" ) << QVariant(false) << QVariant(true) << -1; |
1746 | QTest::newRow(dataTag: "bool4" ) << QVariant(true) << QVariant(false) << +1; |
1747 | |
1748 | QTest::newRow(dataTag: "char1" ) << QVariant::fromValue(value: char(0)) << QVariant::fromValue(value: char(0)) << 0; |
1749 | QTest::newRow(dataTag: "char2" ) << QVariant::fromValue(CHAR_MAX) << QVariant::fromValue(CHAR_MAX) << 0; |
1750 | QTest::newRow(dataTag: "char3" ) << QVariant::fromValue(CHAR_MIN) << QVariant::fromValue(CHAR_MIN) << 0; |
1751 | QTest::newRow(dataTag: "char4" ) << QVariant::fromValue(CHAR_MIN) << QVariant::fromValue(CHAR_MAX) << -1; |
1752 | QTest::newRow(dataTag: "char5" ) << QVariant::fromValue(CHAR_MAX) << QVariant::fromValue(CHAR_MIN) << +1; |
1753 | |
1754 | QTest::newRow(dataTag: "schar1" ) << QVariant::fromValue(value: schar(0)) << QVariant::fromValue(value: schar(0)) << 0; |
1755 | QTest::newRow(dataTag: "schar2" ) << QVariant::fromValue(SCHAR_MAX) << QVariant::fromValue(SCHAR_MAX) << 0; |
1756 | QTest::newRow(dataTag: "schar3" ) << QVariant::fromValue(SCHAR_MIN) << QVariant::fromValue(SCHAR_MIN) << 0; |
1757 | QTest::newRow(dataTag: "schar4" ) << QVariant::fromValue(SCHAR_MIN) << QVariant::fromValue(SCHAR_MAX) << -1; |
1758 | QTest::newRow(dataTag: "schar5" ) << QVariant::fromValue(SCHAR_MAX) << QVariant::fromValue(SCHAR_MIN) << +1; |
1759 | |
1760 | QTest::newRow(dataTag: "uchar1" ) << QVariant::fromValue(value: uchar(0)) << QVariant::fromValue(value: uchar(0)) << 0; |
1761 | QTest::newRow(dataTag: "uchar2" ) << QVariant::fromValue(UCHAR_MAX) << QVariant::fromValue(UCHAR_MAX) << 0; |
1762 | QTest::newRow(dataTag: "uchar3" ) << QVariant::fromValue(value: uchar(0)) << QVariant::fromValue(UCHAR_MAX) << -1; |
1763 | QTest::newRow(dataTag: "uchar4" ) << QVariant::fromValue(UCHAR_MAX) << QVariant::fromValue(value: uchar(0)) << +1; |
1764 | |
1765 | QTest::newRow(dataTag: "short1" ) << QVariant::fromValue(value: short(0)) << QVariant::fromValue(value: short(0)) << 0; |
1766 | QTest::newRow(dataTag: "short2" ) << QVariant::fromValue(SHRT_MAX) << QVariant::fromValue(SHRT_MAX) << 0; |
1767 | QTest::newRow(dataTag: "short3" ) << QVariant::fromValue(SHRT_MIN) << QVariant::fromValue(SHRT_MIN) << 0; |
1768 | QTest::newRow(dataTag: "short4" ) << QVariant::fromValue(SHRT_MIN) << QVariant::fromValue(SHRT_MAX) << -1; |
1769 | QTest::newRow(dataTag: "short5" ) << QVariant::fromValue(SHRT_MAX) << QVariant::fromValue(SHRT_MIN) << +1; |
1770 | |
1771 | QTest::newRow(dataTag: "ushort1" ) << QVariant::fromValue(value: ushort(0)) << QVariant::fromValue(value: ushort(0)) << 0; |
1772 | QTest::newRow(dataTag: "ushort2" ) << QVariant::fromValue(USHRT_MAX) << QVariant::fromValue(USHRT_MAX) << 0; |
1773 | QTest::newRow(dataTag: "ushort3" ) << QVariant::fromValue(value: ushort(0)) << QVariant::fromValue(USHRT_MAX) << -1; |
1774 | QTest::newRow(dataTag: "ushort4" ) << QVariant::fromValue(USHRT_MAX) << QVariant::fromValue(value: ushort(0)) << +1; |
1775 | |
1776 | QTest::newRow(dataTag: "int1" ) << QVariant::fromValue(value: int(0)) << QVariant::fromValue(value: int(0)) << 0; |
1777 | QTest::newRow(dataTag: "int2" ) << QVariant::fromValue(INT_MAX) << QVariant::fromValue(INT_MAX) << 0; |
1778 | QTest::newRow(dataTag: "int3" ) << QVariant::fromValue(INT_MIN) << QVariant::fromValue(INT_MIN) << 0; |
1779 | QTest::newRow(dataTag: "int4" ) << QVariant::fromValue(INT_MIN) << QVariant::fromValue(INT_MAX) << -1; |
1780 | QTest::newRow(dataTag: "int5" ) << QVariant::fromValue(INT_MAX) << QVariant::fromValue(INT_MIN) << +1; |
1781 | |
1782 | QTest::newRow(dataTag: "uint1" ) << QVariant::fromValue(value: uint(0)) << QVariant::fromValue(value: uint(0)) << 0; |
1783 | QTest::newRow(dataTag: "uint2" ) << QVariant::fromValue(UINT_MAX) << QVariant::fromValue(UINT_MAX) << 0; |
1784 | QTest::newRow(dataTag: "uint3" ) << QVariant::fromValue(value: uint(0)) << QVariant::fromValue(UINT_MAX) << -1; |
1785 | QTest::newRow(dataTag: "uint4" ) << QVariant::fromValue(UINT_MAX) << QVariant::fromValue(value: uint(0)) << +1; |
1786 | |
1787 | QTest::newRow(dataTag: "long1" ) << QVariant::fromValue(value: long(0)) << QVariant::fromValue(value: long(0)) << 0; |
1788 | QTest::newRow(dataTag: "long2" ) << QVariant::fromValue(LONG_MAX) << QVariant::fromValue(LONG_MAX) << 0; |
1789 | QTest::newRow(dataTag: "long3" ) << QVariant::fromValue(LONG_MIN) << QVariant::fromValue(LONG_MIN) << 0; |
1790 | QTest::newRow(dataTag: "long4" ) << QVariant::fromValue(LONG_MIN) << QVariant::fromValue(LONG_MAX) << -1; |
1791 | QTest::newRow(dataTag: "long5" ) << QVariant::fromValue(LONG_MAX) << QVariant::fromValue(LONG_MIN) << +1; |
1792 | |
1793 | QTest::newRow(dataTag: "ulong1" ) << QVariant::fromValue(value: ulong(0)) << QVariant::fromValue(value: ulong(0)) << 0; |
1794 | QTest::newRow(dataTag: "ulong2" ) << QVariant::fromValue(ULONG_MAX) << QVariant::fromValue(ULONG_MAX) << 0; |
1795 | QTest::newRow(dataTag: "ulong3" ) << QVariant::fromValue(value: ulong(0)) << QVariant::fromValue(ULONG_MAX) << -1; |
1796 | QTest::newRow(dataTag: "ulong4" ) << QVariant::fromValue(ULONG_MAX) << QVariant::fromValue(value: ulong(0)) << +1; |
1797 | |
1798 | QTest::newRow(dataTag: "llong1" ) << QVariant::fromValue(value: qlonglong(0)) << QVariant::fromValue(value: qlonglong(0)) << 0; |
1799 | QTest::newRow(dataTag: "llong2" ) << QVariant::fromValue(LLONG_MAX) << QVariant::fromValue(LLONG_MAX) << 0; |
1800 | QTest::newRow(dataTag: "llong3" ) << QVariant::fromValue(LLONG_MIN) << QVariant::fromValue(LLONG_MIN) << 0; |
1801 | QTest::newRow(dataTag: "llong4" ) << QVariant::fromValue(LLONG_MIN) << QVariant::fromValue(LLONG_MAX) << -1; |
1802 | QTest::newRow(dataTag: "llong5" ) << QVariant::fromValue(LLONG_MAX) << QVariant::fromValue(LLONG_MIN) << +1; |
1803 | |
1804 | QTest::newRow(dataTag: "ullong1" ) << QVariant::fromValue(value: qulonglong(0)) << QVariant::fromValue(value: qulonglong(0)) << 0; |
1805 | QTest::newRow(dataTag: "ullong2" ) << QVariant::fromValue(ULLONG_MAX) << QVariant::fromValue(ULLONG_MAX) << 0; |
1806 | QTest::newRow(dataTag: "ullong3" ) << QVariant::fromValue(value: qulonglong(0)) << QVariant::fromValue(ULLONG_MAX) << -1; |
1807 | QTest::newRow(dataTag: "ullong4" ) << QVariant::fromValue(ULLONG_MAX) << QVariant::fromValue(value: qulonglong(0)) << +1; |
1808 | |
1809 | QTest::newRow(dataTag: "float1" ) << QVariant::fromValue(value: 0.f) << QVariant::fromValue(value: 0.f) << 0; |
1810 | QTest::newRow(dataTag: "float2" ) << QVariant::fromValue(value: -1.f) << QVariant::fromValue(value: 0.f) << -1; |
1811 | QTest::newRow(dataTag: "float3" ) << QVariant::fromValue(value: 0.f) << QVariant::fromValue(value: -1.f) << +1; |
1812 | QTest::newRow(dataTag: "float4" ) << QVariant::fromValue(value: -float(qInf())) << QVariant::fromValue(value: 0.f) << -1; |
1813 | QTest::newRow(dataTag: "float5" ) << QVariant::fromValue(value: 0.f) << QVariant::fromValue(value: -float(qInf())) << +1; |
1814 | QTest::newRow(dataTag: "float6" ) << QVariant::fromValue(value: -float(qInf())) << QVariant::fromValue(value: -float(qInf())) << 0; |
1815 | QTest::newRow(dataTag: "float7" ) << QVariant::fromValue(value: float(qInf())) << QVariant::fromValue(value: float(qInf())) << 0; |
1816 | |
1817 | QTest::newRow(dataTag: "double1" ) << QVariant::fromValue(value: 0.) << QVariant::fromValue(value: 0.) << 0; |
1818 | QTest::newRow(dataTag: "double2" ) << QVariant::fromValue(value: -1.) << QVariant::fromValue(value: 0.) << -1; |
1819 | QTest::newRow(dataTag: "double3" ) << QVariant::fromValue(value: 0.) << QVariant::fromValue(value: -1.) << +1; |
1820 | QTest::newRow(dataTag: "double4" ) << QVariant::fromValue(value: -qInf()) << QVariant::fromValue(value: 0.) << -1; |
1821 | QTest::newRow(dataTag: "double5" ) << QVariant::fromValue(value: 0.) << QVariant::fromValue(value: -qInf()) << +1; |
1822 | QTest::newRow(dataTag: "double6" ) << QVariant::fromValue(value: -double(qInf())) << QVariant::fromValue(value: -qInf()) << 0; |
1823 | QTest::newRow(dataTag: "double7" ) << QVariant::fromValue(value: qInf()) << QVariant::fromValue(value: qInf()) << 0; |
1824 | QTest::newRow(dataTag: "double8" ) << QVariant::fromValue(value: -qInf()) << QVariant::fromValue(value: qInf()) << -1; |
1825 | QTest::newRow(dataTag: "double9" ) << QVariant::fromValue(value: qQNaN()) << QVariant::fromValue(value: 0.) << INT_MAX; |
1826 | QTest::newRow(dataTag: "double10" ) << QVariant::fromValue(value: 0.) << QVariant::fromValue(value: qQNaN()) << INT_MAX; |
1827 | QTest::newRow(dataTag: "double11" ) << QVariant::fromValue(value: qQNaN()) << QVariant::fromValue(value: qQNaN()) << INT_MAX; |
1828 | |
1829 | // mixed comparisons |
1830 | // fp + fp |
1831 | QTest::newRow(dataTag: "float+double1" ) << QVariant::fromValue(value: 0.f) << QVariant::fromValue(value: 0.) << 0; |
1832 | QTest::newRow(dataTag: "float+double2" ) << QVariant::fromValue(value: -1.f) << QVariant::fromValue(value: 0.) << -1; |
1833 | QTest::newRow(dataTag: "float+double3" ) << QVariant::fromValue(value: 0.f) << QVariant::fromValue(value: -1.) << +1; |
1834 | QTest::newRow(dataTag: "float+double4" ) << QVariant::fromValue(value: -float(qInf())) << QVariant::fromValue(value: 0.) << -1; |
1835 | QTest::newRow(dataTag: "float+double5" ) << QVariant::fromValue(value: 0.f) << QVariant::fromValue(value: -qInf()) << +1; |
1836 | QTest::newRow(dataTag: "float+double6" ) << QVariant::fromValue(value: -float(qInf())) << QVariant::fromValue(value: -qInf()) << 0; |
1837 | QTest::newRow(dataTag: "float+double7" ) << QVariant::fromValue(value: float(qInf())) << QVariant::fromValue(value: qInf()) << 0; |
1838 | QTest::newRow(dataTag: "float+double8" ) << QVariant::fromValue(value: -float(qInf())) << QVariant::fromValue(value: qInf()) << -1; |
1839 | QTest::newRow(dataTag: "float+double9" ) << QVariant::fromValue(value: qQNaN()) << QVariant::fromValue(value: 0.) << INT_MAX; |
1840 | QTest::newRow(dataTag: "float+double10" ) << QVariant::fromValue(value: 0.) << QVariant::fromValue(value: qQNaN()) << INT_MAX; |
1841 | QTest::newRow(dataTag: "float+double11" ) << QVariant::fromValue(value: qQNaN()) << QVariant::fromValue(value: qQNaN()) << INT_MAX; |
1842 | |
1843 | // fp + int |
1844 | QTest::newRow(dataTag: "float+int1" ) << QVariant::fromValue(value: 0.f) << QVariant::fromValue(value: 0) << 0; |
1845 | QTest::newRow(dataTag: "double+int1" ) << QVariant::fromValue(value: 0.) << QVariant::fromValue(value: 0) << 0; |
1846 | QTest::newRow(dataTag: "float+int2" ) << QVariant::fromValue(value: -1.f) << QVariant::fromValue(value: 0) << -1; |
1847 | QTest::newRow(dataTag: "double+int2" ) << QVariant::fromValue(value: -1.) << QVariant::fromValue(value: 0) << -1; |
1848 | QTest::newRow(dataTag: "float+int3" ) << QVariant::fromValue(value: 0.f) << QVariant::fromValue(value: -1) << +1; |
1849 | QTest::newRow(dataTag: "double+int3" ) << QVariant::fromValue(value: 0.) << QVariant::fromValue(value: -1) << +1; |
1850 | QTest::newRow(dataTag: "float+int4" ) << QVariant::fromValue(value: 1.5f) << QVariant::fromValue(value: 1) << +1; |
1851 | QTest::newRow(dataTag: "double+int4" ) << QVariant::fromValue(value: 1.5) << QVariant::fromValue(value: 1) << +1; |
1852 | QTest::newRow(dataTag: "double+int5" ) << QVariant::fromValue(value: qInf()) << QVariant::fromValue(value: 1) << +1; |
1853 | |
1854 | // fp + uint |
1855 | QTest::newRow(dataTag: "float+uint1" ) << QVariant::fromValue(value: 0.f) << QVariant::fromValue(value: 0U) << 0; |
1856 | QTest::newRow(dataTag: "double+uint1" ) << QVariant::fromValue(value: 0.) << QVariant::fromValue(value: 0U) << 0; |
1857 | QTest::newRow(dataTag: "float+uint2" ) << QVariant::fromValue(value: -1.f) << QVariant::fromValue(value: 0U) << -1; |
1858 | QTest::newRow(dataTag: "double+uint2" ) << QVariant::fromValue(value: -1.) << QVariant::fromValue(value: 0U) << -1; |
1859 | QTest::newRow(dataTag: "float+uint3" ) << QVariant::fromValue(value: 0.f) << QVariant::fromValue(value: 1U) << -1; |
1860 | QTest::newRow(dataTag: "double+uint3" ) << QVariant::fromValue(value: 0.) << QVariant::fromValue(value: 1U) << -1; |
1861 | QTest::newRow(dataTag: "float+uint4" ) << QVariant::fromValue(value: 1.5f) << QVariant::fromValue(value: 1U) << +1; |
1862 | QTest::newRow(dataTag: "double+uint4" ) << QVariant::fromValue(value: 1.5) << QVariant::fromValue(value: 1U) << +1; |
1863 | |
1864 | // lower ranked + int |
1865 | QTest::newRow(dataTag: "bool+int1" ) << QVariant::fromValue(value: false) << QVariant::fromValue(value: 0) << 0; |
1866 | QTest::newRow(dataTag: "bool+int2" ) << QVariant::fromValue(value: false) << QVariant::fromValue(value: 1) << -1; |
1867 | QTest::newRow(dataTag: "bool+int3" ) << QVariant::fromValue(value: true) << QVariant::fromValue(value: 0) << +1; |
1868 | QTest::newRow(dataTag: "bool+int4" ) << QVariant::fromValue(value: true) << QVariant::fromValue(value: 1) << 0; |
1869 | QTest::newRow(dataTag: "bool+int5" ) << QVariant::fromValue(value: true) << QVariant::fromValue(value: 2) << -1; |
1870 | |
1871 | QTest::newRow(dataTag: "char+int1" ) << QVariant::fromValue(value: char(0)) << QVariant::fromValue(value: 0) << 0; |
1872 | QTest::newRow(dataTag: "char+int2" ) << QVariant::fromValue(value: char(0)) << QVariant::fromValue(value: 1) << -1; |
1873 | QTest::newRow(dataTag: "char+int3" ) << QVariant::fromValue(value: char(1)) << QVariant::fromValue(value: 0) << +1; |
1874 | QTest::newRow(dataTag: "char+int4" ) << QVariant::fromValue(value: char(1)) << QVariant::fromValue(value: 1) << 0; |
1875 | if (std::numeric_limits<char>::is_signed) { |
1876 | QTest::newRow(dataTag: "char+int5" ) << QVariant::fromValue(value: char(-1)) << QVariant::fromValue(value: 0) << -1; |
1877 | QTest::newRow(dataTag: "char+int6" ) << QVariant::fromValue(value: char(-1)) << QVariant::fromValue(value: -1) << 0; |
1878 | } |
1879 | |
1880 | QTest::newRow(dataTag: "schar+int1" ) << QVariant::fromValue(value: schar(0)) << QVariant::fromValue(value: 0) << 0; |
1881 | QTest::newRow(dataTag: "schar+int2" ) << QVariant::fromValue(value: schar(0)) << QVariant::fromValue(value: 1) << -1; |
1882 | QTest::newRow(dataTag: "schar+int3" ) << QVariant::fromValue(value: schar(1)) << QVariant::fromValue(value: 0) << +1; |
1883 | QTest::newRow(dataTag: "schar+int4" ) << QVariant::fromValue(value: schar(1)) << QVariant::fromValue(value: 1) << 0; |
1884 | QTest::newRow(dataTag: "schar+int5" ) << QVariant::fromValue(value: schar(-1)) << QVariant::fromValue(value: 0) << -1; |
1885 | QTest::newRow(dataTag: "schar+int6" ) << QVariant::fromValue(value: schar(-1)) << QVariant::fromValue(value: -1) << 0; |
1886 | |
1887 | QTest::newRow(dataTag: "uchar+int1" ) << QVariant::fromValue(value: uchar(0)) << QVariant::fromValue(value: 0) << 0; |
1888 | QTest::newRow(dataTag: "uchar+int2" ) << QVariant::fromValue(value: uchar(0)) << QVariant::fromValue(value: 1) << -1; |
1889 | QTest::newRow(dataTag: "uchar+int3" ) << QVariant::fromValue(value: uchar(1)) << QVariant::fromValue(value: 0) << +1; |
1890 | QTest::newRow(dataTag: "uchar+int4" ) << QVariant::fromValue(value: uchar(1)) << QVariant::fromValue(value: 1) << 0; |
1891 | |
1892 | QTest::newRow(dataTag: "short+int1" ) << QVariant::fromValue(value: short(0)) << QVariant::fromValue(value: 0) << 0; |
1893 | QTest::newRow(dataTag: "short+int2" ) << QVariant::fromValue(value: short(0)) << QVariant::fromValue(value: 1) << -1; |
1894 | QTest::newRow(dataTag: "short+int3" ) << QVariant::fromValue(value: short(1)) << QVariant::fromValue(value: 0) << +1; |
1895 | QTest::newRow(dataTag: "short+int4" ) << QVariant::fromValue(value: short(1)) << QVariant::fromValue(value: 1) << 0; |
1896 | QTest::newRow(dataTag: "short+int5" ) << QVariant::fromValue(value: short(-1)) << QVariant::fromValue(value: 0) << -1; |
1897 | QTest::newRow(dataTag: "short+int6" ) << QVariant::fromValue(value: short(-1)) << QVariant::fromValue(value: -1) << 0; |
1898 | |
1899 | QTest::newRow(dataTag: "ushort+int1" ) << QVariant::fromValue(value: ushort(0)) << QVariant::fromValue(value: 0) << 0; |
1900 | QTest::newRow(dataTag: "ushort+int2" ) << QVariant::fromValue(value: ushort(0)) << QVariant::fromValue(value: 1) << -1; |
1901 | QTest::newRow(dataTag: "ushort+int3" ) << QVariant::fromValue(value: ushort(1)) << QVariant::fromValue(value: 0) << +1; |
1902 | QTest::newRow(dataTag: "ushort+int4" ) << QVariant::fromValue(value: ushort(1)) << QVariant::fromValue(value: 1) << 0; |
1903 | |
1904 | // lower ranked + uint (without sign change) |
1905 | QTest::newRow(dataTag: "bool+uint1" ) << QVariant::fromValue(value: false) << QVariant::fromValue(value: 0U) << 0; |
1906 | QTest::newRow(dataTag: "bool+uint2" ) << QVariant::fromValue(value: false) << QVariant::fromValue(value: 1U) << -1; |
1907 | QTest::newRow(dataTag: "bool+uint3" ) << QVariant::fromValue(value: true) << QVariant::fromValue(value: 0U) << +1; |
1908 | QTest::newRow(dataTag: "bool+uint4" ) << QVariant::fromValue(value: true) << QVariant::fromValue(value: 1U) << 0; |
1909 | QTest::newRow(dataTag: "bool+uint5" ) << QVariant::fromValue(value: true) << QVariant::fromValue(value: 2U) << -1; |
1910 | |
1911 | QTest::newRow(dataTag: "char+uint1" ) << QVariant::fromValue(value: char(0)) << QVariant::fromValue(value: 0U) << 0; |
1912 | QTest::newRow(dataTag: "char+uint2" ) << QVariant::fromValue(value: char(0)) << QVariant::fromValue(value: 1U) << -1; |
1913 | QTest::newRow(dataTag: "char+uint3" ) << QVariant::fromValue(value: char(1)) << QVariant::fromValue(value: 0U) << +1; |
1914 | QTest::newRow(dataTag: "char+uint4" ) << QVariant::fromValue(value: char(1)) << QVariant::fromValue(value: 1U) << 0; |
1915 | |
1916 | QTest::newRow(dataTag: "schar+uint1" ) << QVariant::fromValue(value: schar(0)) << QVariant::fromValue(value: 0U) << 0; |
1917 | QTest::newRow(dataTag: "schar+uint2" ) << QVariant::fromValue(value: schar(0)) << QVariant::fromValue(value: 1U) << -1; |
1918 | QTest::newRow(dataTag: "schar+uint3" ) << QVariant::fromValue(value: schar(1)) << QVariant::fromValue(value: 0U) << +1; |
1919 | QTest::newRow(dataTag: "schar+uint4" ) << QVariant::fromValue(value: schar(1)) << QVariant::fromValue(value: 1U) << 0; |
1920 | |
1921 | QTest::newRow(dataTag: "uchar+uint1" ) << QVariant::fromValue(value: uchar(0)) << QVariant::fromValue(value: 0U) << 0; |
1922 | QTest::newRow(dataTag: "uchar+uint2" ) << QVariant::fromValue(value: uchar(0)) << QVariant::fromValue(value: 1U) << -1; |
1923 | QTest::newRow(dataTag: "uchar+uint3" ) << QVariant::fromValue(value: uchar(1)) << QVariant::fromValue(value: 0U) << +1; |
1924 | QTest::newRow(dataTag: "uchar+uint4" ) << QVariant::fromValue(value: uchar(1)) << QVariant::fromValue(value: 1U) << 0; |
1925 | |
1926 | QTest::newRow(dataTag: "short+uint1" ) << QVariant::fromValue(value: short(0)) << QVariant::fromValue(value: 0U) << 0; |
1927 | QTest::newRow(dataTag: "short+uint2" ) << QVariant::fromValue(value: short(0)) << QVariant::fromValue(value: 1U) << -1; |
1928 | QTest::newRow(dataTag: "short+uint3" ) << QVariant::fromValue(value: short(1)) << QVariant::fromValue(value: 0U) << +1; |
1929 | QTest::newRow(dataTag: "short+uint4" ) << QVariant::fromValue(value: short(1)) << QVariant::fromValue(value: 1U) << 0; |
1930 | |
1931 | QTest::newRow(dataTag: "ushort+uint1" ) << QVariant::fromValue(value: ushort(0)) << QVariant::fromValue(value: 0U) << 0; |
1932 | QTest::newRow(dataTag: "ushort+uint2" ) << QVariant::fromValue(value: ushort(0)) << QVariant::fromValue(value: 1U) << -1; |
1933 | QTest::newRow(dataTag: "ushort+uint3" ) << QVariant::fromValue(value: ushort(1)) << QVariant::fromValue(value: 0U) << +1; |
1934 | QTest::newRow(dataTag: "ushort+uint4" ) << QVariant::fromValue(value: ushort(1)) << QVariant::fromValue(value: 1U) << 0; |
1935 | |
1936 | // int + qlonglong |
1937 | QTest::newRow(dataTag: "int+qlonglong1" ) << QVariant::fromValue(value: 0) << QVariant::fromValue(Q_INT64_C(0)) << 0; |
1938 | QTest::newRow(dataTag: "int+qlonglong2" ) << QVariant::fromValue(value: 1) << QVariant::fromValue(Q_INT64_C(0)) << +1; |
1939 | QTest::newRow(dataTag: "int+qlonglong3" ) << QVariant::fromValue(value: 0) << QVariant::fromValue(Q_INT64_C(1)) << -1; |
1940 | QTest::newRow(dataTag: "int+qlonglong4" ) << QVariant::fromValue(value: 1) << QVariant::fromValue(Q_INT64_C(1)) << 0; |
1941 | QTest::newRow(dataTag: "int+qlonglong5" ) << QVariant::fromValue(value: 0) << QVariant::fromValue(Q_INT64_C(-1)) << +1; |
1942 | QTest::newRow(dataTag: "int+qlonglong6" ) << QVariant::fromValue(value: -1) << QVariant::fromValue(Q_INT64_C(0)) << -1; |
1943 | QTest::newRow(dataTag: "int+qlonglong7" ) << QVariant::fromValue(value: -1) << QVariant::fromValue(Q_INT64_C(-1)) << 0; |
1944 | |
1945 | // uint + qulonglong |
1946 | QTest::newRow(dataTag: "uint+qulonglong1" ) << QVariant::fromValue(value: 0U) << QVariant::fromValue(Q_UINT64_C(0)) << 0; |
1947 | QTest::newRow(dataTag: "uint+qulonglong2" ) << QVariant::fromValue(value: 1U) << QVariant::fromValue(Q_UINT64_C(0)) << +1; |
1948 | QTest::newRow(dataTag: "uint+qulonglong3" ) << QVariant::fromValue(value: 0U) << QVariant::fromValue(Q_UINT64_C(1)) << -1; |
1949 | QTest::newRow(dataTag: "uint+qulonglong4" ) << QVariant::fromValue(value: 1U) << QVariant::fromValue(Q_UINT64_C(1)) << 0; |
1950 | |
1951 | // int + uint (without sign change) |
1952 | QTest::newRow(dataTag: "int+uint1" ) << QVariant::fromValue(value: 0) << QVariant::fromValue(value: 0U) << 0; |
1953 | QTest::newRow(dataTag: "int+uint2" ) << QVariant::fromValue(value: 1) << QVariant::fromValue(value: 0U) << +1; |
1954 | QTest::newRow(dataTag: "int+uint3" ) << QVariant::fromValue(value: 0) << QVariant::fromValue(value: 1U) << -1; |
1955 | QTest::newRow(dataTag: "int+uint4" ) << QVariant::fromValue(value: 1) << QVariant::fromValue(value: 1U) << 0; |
1956 | |
1957 | // uint + qlonglong |
1958 | QTest::newRow(dataTag: "uint+qlonglong1" ) << QVariant::fromValue(value: 0U) << QVariant::fromValue(Q_INT64_C(0)) << 0; |
1959 | QTest::newRow(dataTag: "uint+qlonglong2" ) << QVariant::fromValue(value: 1U) << QVariant::fromValue(Q_INT64_C(0)) << +1; |
1960 | QTest::newRow(dataTag: "uint+qlonglong3" ) << QVariant::fromValue(value: 0U) << QVariant::fromValue(Q_INT64_C(1)) << -1; |
1961 | QTest::newRow(dataTag: "uint+qlonglong4" ) << QVariant::fromValue(value: 1U) << QVariant::fromValue(Q_INT64_C(1)) << 0; |
1962 | QTest::newRow(dataTag: "uint+qlonglong5" ) << QVariant::fromValue(value: 0U) << QVariant::fromValue(Q_INT64_C(-1)) << +1; |
1963 | |
1964 | // boundary conditions |
1965 | QTest::newRow(dataTag: "charmax+intmax" ) << QVariant::fromValue(CHAR_MAX) << QVariant::fromValue(INT_MAX) << -1; |
1966 | QTest::newRow(dataTag: "charmax+uintmax" ) << QVariant::fromValue(CHAR_MAX) << QVariant::fromValue(UINT_MAX) << -1; |
1967 | QTest::newRow(dataTag: "scharmax+intmax" ) << QVariant::fromValue(SCHAR_MAX) << QVariant::fromValue(INT_MAX) << -1; |
1968 | QTest::newRow(dataTag: "scharmax+uintmax" ) << QVariant::fromValue(SCHAR_MAX) << QVariant::fromValue(UINT_MAX) << -1; |
1969 | QTest::newRow(dataTag: "ucharmax+intmax" ) << QVariant::fromValue(UCHAR_MAX) << QVariant::fromValue(INT_MAX) << -1; |
1970 | QTest::newRow(dataTag: "ucharmax+uintmax" ) << QVariant::fromValue(UCHAR_MAX) << QVariant::fromValue(UINT_MAX) << -1; |
1971 | QTest::newRow(dataTag: "shortmax+intmax" ) << QVariant::fromValue(SHRT_MAX) << QVariant::fromValue(INT_MAX) << -1; |
1972 | QTest::newRow(dataTag: "shortmax+uintmax" ) << QVariant::fromValue(SHRT_MAX) << QVariant::fromValue(UINT_MAX) << -1; |
1973 | QTest::newRow(dataTag: "ushortmax+intmax" ) << QVariant::fromValue(USHRT_MAX) << QVariant::fromValue(INT_MAX) << -1; |
1974 | QTest::newRow(dataTag: "ushortmax+uintmax" ) << QVariant::fromValue(USHRT_MAX) << QVariant::fromValue(UINT_MAX) << -1; |
1975 | |
1976 | QTest::newRow(dataTag: "intmin+qlonglongmin" ) << QVariant::fromValue(INT_MIN) << QVariant::fromValue(LLONG_MIN) << +1; |
1977 | QTest::newRow(dataTag: "intmax+uintmax" ) << QVariant::fromValue(INT_MAX) << QVariant::fromValue(UINT_MAX) << -1; |
1978 | QTest::newRow(dataTag: "intmax+qlonglongmax" ) << QVariant::fromValue(INT_MAX) << QVariant::fromValue(LLONG_MAX) << -1; |
1979 | QTest::newRow(dataTag: "uintmax+qlonglongmax" ) << QVariant::fromValue(UINT_MAX) << QVariant::fromValue(LLONG_MAX) << -1; |
1980 | QTest::newRow(dataTag: "intmax+qulonglongmax" ) << QVariant::fromValue(INT_MAX) << QVariant::fromValue(ULLONG_MAX) << -1; |
1981 | QTest::newRow(dataTag: "qlonglongmax+qulonglongmax" ) << QVariant::fromValue(LLONG_MAX) << QVariant::fromValue(ULLONG_MAX) << -1; |
1982 | QTest::newRow(dataTag: "uintmax+qlonglongmin" ) << QVariant::fromValue(UINT_MAX) << QVariant::fromValue(LLONG_MIN) << +1; |
1983 | |
1984 | // check for no sign-extension issues |
1985 | QTest::newRow(dataTag: "ushortmax+intzero" ) << QVariant::fromValue(USHRT_MAX) << QVariant::fromValue(value: 0) << +1; |
1986 | QTest::newRow(dataTag: "ushortmax+qlonglongzero" ) << QVariant::fromValue(USHRT_MAX) << QVariant::fromValue(Q_INT64_C(0)) << +1; |
1987 | QTest::newRow(dataTag: "uintmax+qlonglongzero" ) << QVariant::fromValue(UINT_MAX) << QVariant::fromValue(Q_INT64_C(0)) << +1; |
1988 | |
1989 | // sign changes |
1990 | // the tests below check that a signed negative number sign-changes to a non-zero unsigned number and that |
1991 | // signed -1 sign-changes to unsigned maximum (all bits set, ~0). This works on two's complement machines |
1992 | // (all that Qt supports), and would also work on one's complement. |
1993 | if (std::numeric_limits<char>::is_signed) { |
1994 | QTest::newRow(dataTag: "signchange-char+uint" ) << QVariant::fromValue(value: char(-1)) << QVariant::fromValue(value: 0U) << +1; |
1995 | QTest::newRow(dataTag: "signchange-char+uintmax" ) << QVariant::fromValue(value: char(-1)) << QVariant::fromValue(UINT_MAX) << 0; |
1996 | QTest::newRow(dataTag: "signchange-charmin+uint" ) << QVariant::fromValue(CHAR_MIN) << QVariant::fromValue(value: 0U) << +1; |
1997 | QTest::newRow(dataTag: "signchange-char+qulonglong" ) << QVariant::fromValue(value: char(-1)) << QVariant::fromValue(Q_UINT64_C(0)) << +1; |
1998 | QTest::newRow(dataTag: "signchange-char+qulonglongmax" ) << QVariant::fromValue(value: char(-1)) << QVariant::fromValue(ULLONG_MAX) << 0; |
1999 | QTest::newRow(dataTag: "signchange-charmin+qulonglong" ) << QVariant::fromValue(CHAR_MIN) << QVariant::fromValue(Q_UINT64_C(0)) << +1; |
2000 | } |
2001 | QTest::newRow(dataTag: "signchange-schar+uint" ) << QVariant::fromValue(value: schar(-1)) << QVariant::fromValue(value: 0U) << +1; |
2002 | QTest::newRow(dataTag: "signchange-schar+uintmax" ) << QVariant::fromValue(value: schar(-1)) << QVariant::fromValue(UINT_MAX) << 0; |
2003 | QTest::newRow(dataTag: "signchange-scharmin+uint" ) << QVariant::fromValue(SCHAR_MIN) << QVariant::fromValue(value: 0U) << +1; |
2004 | QTest::newRow(dataTag: "signchange-schar+qulonglong" ) << QVariant::fromValue(value: schar(-1)) << QVariant::fromValue(Q_UINT64_C(0)) << +1; |
2005 | QTest::newRow(dataTag: "signchange-schar+qulonglongmax" ) << QVariant::fromValue(value: schar(-1)) << QVariant::fromValue(ULLONG_MAX) << 0; |
2006 | QTest::newRow(dataTag: "signchange-scharmin+qulonglong" ) << QVariant::fromValue(SCHAR_MIN) << QVariant::fromValue(Q_UINT64_C(0)) << +1; |
2007 | QTest::newRow(dataTag: "signchange-short+uint" ) << QVariant::fromValue(value: short(-1)) << QVariant::fromValue(value: 0U) << +1; |
2008 | QTest::newRow(dataTag: "signchange-short+uintmax" ) << QVariant::fromValue(value: short(-1)) << QVariant::fromValue(UINT_MAX) << 0; |
2009 | QTest::newRow(dataTag: "signchange-shortmin+uint" ) << QVariant::fromValue(SHRT_MIN) << QVariant::fromValue(value: 0U) << +1; |
2010 | QTest::newRow(dataTag: "signchange-short+qulonglong" ) << QVariant::fromValue(value: short(-1)) << QVariant::fromValue(Q_UINT64_C(0)) << +1; |
2011 | QTest::newRow(dataTag: "signchange-short+qulonglongmax" ) << QVariant::fromValue(value: short(-1)) << QVariant::fromValue(ULLONG_MAX) << 0; |
2012 | QTest::newRow(dataTag: "signchange-shortmin+qulonglong" ) << QVariant::fromValue(SHRT_MIN) << QVariant::fromValue(Q_UINT64_C(0)) << +1; |
2013 | QTest::newRow(dataTag: "signchange-int+uint" ) << QVariant::fromValue(value: -1) << QVariant::fromValue(value: 0U) << +1; |
2014 | QTest::newRow(dataTag: "signchange-int+uintmax" ) << QVariant::fromValue(value: -1) << QVariant::fromValue(UINT_MAX) << 0; |
2015 | QTest::newRow(dataTag: "signchange-intmin+uint" ) << QVariant::fromValue(INT_MIN) << QVariant::fromValue(value: 0U) << +1; |
2016 | QTest::newRow(dataTag: "signchange-int+qulonglong" ) << QVariant::fromValue(value: -1) << QVariant::fromValue(Q_UINT64_C(0)) << +1; |
2017 | QTest::newRow(dataTag: "signchange-int+qulonglongmax" ) << QVariant::fromValue(value: -1) << QVariant::fromValue(ULLONG_MAX) << 0; |
2018 | QTest::newRow(dataTag: "signchange-intmin+qulonglong" ) << QVariant::fromValue(INT_MIN) << QVariant::fromValue(Q_UINT64_C(0)) << +1; |
2019 | // no qlonglong+uint, since that should promote to qlonglong and then the comparison is signed (tested above) |
2020 | QTest::newRow(dataTag: "signchange-qlonglong+qulonglong" ) << QVariant::fromValue(Q_INT64_C(-1)) << QVariant::fromValue(Q_UINT64_C(0)) << +1; |
2021 | QTest::newRow(dataTag: "signchange-qlonglong+qulonglongmax" ) << QVariant::fromValue(Q_INT64_C(-1)) << QVariant::fromValue(ULLONG_MAX) << 0; |
2022 | QTest::newRow(dataTag: "signchange-qlonglongmin+qulonglong" ) << QVariant::fromValue(LLONG_MIN) << QVariant::fromValue(Q_UINT64_C(0)) << +1; |
2023 | } |
2024 | |
2025 | void tst_QVariant::compareNumbers() const |
2026 | { |
2027 | QFETCH(QVariant, v1); |
2028 | QFETCH(QVariant, v2); |
2029 | QFETCH(int, expected); |
2030 | |
2031 | if (expected == -1) { |
2032 | QVERIFY(v1 < v2); |
2033 | QVERIFY(v1 <= v2); |
2034 | QVERIFY(!(v1 == v2)); |
2035 | QVERIFY(!(v1 > v2)); |
2036 | QVERIFY(!(v1 >= v2)); |
2037 | |
2038 | QVERIFY(!(v2 < v1)); |
2039 | QVERIFY(!(v2 <= v1)); |
2040 | QVERIFY(!(v2 == v1)); |
2041 | QVERIFY(v2 >= v1); |
2042 | QVERIFY(v2 > v1); |
2043 | } else if (expected == 0) { |
2044 | QVERIFY(!(v1 < v2)); |
2045 | QVERIFY(v1 <= v2); |
2046 | QCOMPARE(v1, v2); |
2047 | QVERIFY(!(v1 > v2)); |
2048 | QVERIFY(v1 >= v2); |
2049 | |
2050 | QVERIFY(!(v2 < v1)); |
2051 | QVERIFY(v2 <= v1); |
2052 | QCOMPARE(v2, v1); |
2053 | QVERIFY(v2 >= v1); |
2054 | QVERIFY(!(v2 > v1)); |
2055 | } else if (expected == +1) { |
2056 | QVERIFY(!(v1 < v2)); |
2057 | QVERIFY(!(v1 <= v2)); |
2058 | QVERIFY(!(v1 == v2)); |
2059 | QVERIFY(v1 > v2); |
2060 | QVERIFY(v1 >= v2); |
2061 | |
2062 | QVERIFY(v2 < v1); |
2063 | QVERIFY(v2 <= v1); |
2064 | QVERIFY(!(v2 == v1)); |
2065 | QVERIFY(!(v2 >= v1)); |
2066 | QVERIFY(!(v2 > v1)); |
2067 | } else { |
2068 | // unorderable (NaN) |
2069 | QVERIFY(!(v1 == v2)); |
2070 | } |
2071 | } |
2072 | |
2073 | void tst_QVariant::typeName_data() |
2074 | { |
2075 | QTest::addColumn<int>(name: "type" ); |
2076 | QTest::addColumn<QByteArray>(name: "res" ); |
2077 | QTest::newRow(dataTag: "0" ) << int(QVariant::Invalid) << QByteArray("" ); |
2078 | QTest::newRow(dataTag: "1" ) << int(QVariant::Map) << QByteArray("QVariantMap" ); |
2079 | QTest::newRow(dataTag: "2" ) << int(QVariant::List) << QByteArray("QVariantList" ); |
2080 | QTest::newRow(dataTag: "3" ) << int(QVariant::String) << QByteArray("QString" ); |
2081 | QTest::newRow(dataTag: "4" ) << int(QVariant::StringList) << QByteArray("QStringList" ); |
2082 | QTest::newRow(dataTag: "5" ) << int(QVariant::Font) << QByteArray("QFont" ); |
2083 | QTest::newRow(dataTag: "6" ) << int(QVariant::Pixmap) << QByteArray("QPixmap" ); |
2084 | QTest::newRow(dataTag: "7" ) << int(QVariant::Brush) << QByteArray("QBrush" ); |
2085 | QTest::newRow(dataTag: "8" ) << int(QVariant::Rect) << QByteArray("QRect" ); |
2086 | QTest::newRow(dataTag: "9" ) << int(QVariant::Size) << QByteArray("QSize" ); |
2087 | QTest::newRow(dataTag: "10" ) << int(QVariant::Color) << QByteArray("QColor" ); |
2088 | QTest::newRow(dataTag: "11" ) << int(QVariant::Palette) << QByteArray("QPalette" ); |
2089 | QTest::newRow(dataTag: "12" ) << int(QVariant::Point) << QByteArray("QPoint" ); |
2090 | QTest::newRow(dataTag: "13" ) << int(QVariant::Image) << QByteArray("QImage" ); |
2091 | QTest::newRow(dataTag: "14" ) << int(QVariant::Int) << QByteArray("int" ); |
2092 | QTest::newRow(dataTag: "15" ) << int(QVariant::UInt) << QByteArray("uint" ); |
2093 | QTest::newRow(dataTag: "16" ) << int(QVariant::Bool) << QByteArray("bool" ); |
2094 | QTest::newRow(dataTag: "17" ) << int(QVariant::Double) << QByteArray("double" ); |
2095 | QTest::newRow(dataTag: "18" ) << int(QMetaType::Float) << QByteArray("float" ); |
2096 | QTest::newRow(dataTag: "19" ) << int(QVariant::Polygon) << QByteArray("QPolygon" ); |
2097 | QTest::newRow(dataTag: "20" ) << int(QVariant::Region) << QByteArray("QRegion" ); |
2098 | QTest::newRow(dataTag: "21" ) << int(QVariant::Bitmap) << QByteArray("QBitmap" ); |
2099 | QTest::newRow(dataTag: "22" ) << int(QVariant::Cursor) << QByteArray("QCursor" ); |
2100 | QTest::newRow(dataTag: "23" ) << int(QVariant::SizePolicy) << QByteArray("QSizePolicy" ); |
2101 | QTest::newRow(dataTag: "24" ) << int(QVariant::Date) << QByteArray("QDate" ); |
2102 | QTest::newRow(dataTag: "25" ) << int(QVariant::Time) << QByteArray("QTime" ); |
2103 | QTest::newRow(dataTag: "26" ) << int(QVariant::DateTime) << QByteArray("QDateTime" ); |
2104 | QTest::newRow(dataTag: "27" ) << int(QVariant::ByteArray) << QByteArray("QByteArray" ); |
2105 | QTest::newRow(dataTag: "28" ) << int(QVariant::BitArray) << QByteArray("QBitArray" ); |
2106 | QTest::newRow(dataTag: "29" ) << int(QVariant::KeySequence) << QByteArray("QKeySequence" ); |
2107 | QTest::newRow(dataTag: "30" ) << int(QVariant::Pen) << QByteArray("QPen" ); |
2108 | QTest::newRow(dataTag: "31" ) << int(QVariant::LongLong) << QByteArray("qlonglong" ); |
2109 | QTest::newRow(dataTag: "32" ) << int(QVariant::ULongLong) << QByteArray("qulonglong" ); |
2110 | QTest::newRow(dataTag: "33" ) << int(QVariant::Char) << QByteArray("QChar" ); |
2111 | QTest::newRow(dataTag: "34" ) << int(QVariant::Url) << QByteArray("QUrl" ); |
2112 | QTest::newRow(dataTag: "35" ) << int(QVariant::TextLength) << QByteArray("QTextLength" ); |
2113 | QTest::newRow(dataTag: "36" ) << int(QVariant::TextFormat) << QByteArray("QTextFormat" ); |
2114 | QTest::newRow(dataTag: "37" ) << int(QVariant::Locale) << QByteArray("QLocale" ); |
2115 | QTest::newRow(dataTag: "38" ) << int(QVariant::LineF) << QByteArray("QLineF" ); |
2116 | QTest::newRow(dataTag: "39" ) << int(QVariant::RectF) << QByteArray("QRectF" ); |
2117 | QTest::newRow(dataTag: "40" ) << int(QVariant::PointF) << QByteArray("QPointF" ); |
2118 | QTest::newRow(dataTag: "41" ) << int(QVariant::RegExp) << QByteArray("QRegExp" ); |
2119 | QTest::newRow(dataTag: "43" ) << int(QVariant::Matrix) << QByteArray("QMatrix" ); |
2120 | QTest::newRow(dataTag: "44" ) << int(QVariant::Transform) << QByteArray("QTransform" ); |
2121 | QTest::newRow(dataTag: "45" ) << int(QVariant::Hash) << QByteArray("QVariantHash" ); |
2122 | QTest::newRow(dataTag: "46" ) << int(QVariant::Matrix4x4) << QByteArray("QMatrix4x4" ); |
2123 | QTest::newRow(dataTag: "47" ) << int(QVariant::Vector2D) << QByteArray("QVector2D" ); |
2124 | QTest::newRow(dataTag: "48" ) << int(QVariant::Vector3D) << QByteArray("QVector3D" ); |
2125 | QTest::newRow(dataTag: "49" ) << int(QVariant::Vector4D) << QByteArray("QVector4D" ); |
2126 | QTest::newRow(dataTag: "50" ) << int(QVariant::Quaternion) << QByteArray("QQuaternion" ); |
2127 | QTest::newRow(dataTag: "51" ) << int(QVariant::RegularExpression) << QByteArray("QRegularExpression" ); |
2128 | } |
2129 | |
2130 | void tst_QVariant::typeName() |
2131 | { |
2132 | QFETCH( int, type ); |
2133 | QFETCH( QByteArray, res ); |
2134 | QCOMPARE(QString::fromLatin1(QVariant::typeToName((QVariant::Type)type)), |
2135 | QString::fromLatin1(res.constData())); |
2136 | } |
2137 | |
2138 | // test nameToType as well |
2139 | void tst_QVariant::typeToName() |
2140 | { |
2141 | QVariant v; |
2142 | QCOMPARE( QVariant::typeToName( v.type() ), (const char*)0 ); // Invalid |
2143 | // assumes that QVariant::Type contains consecutive values |
2144 | |
2145 | int max = QVariant::LastGuiType; |
2146 | for ( int t = 1; t <= max; t++ ) { |
2147 | const char *n = QVariant::typeToName( typeId: (QVariant::Type)t ); |
2148 | if (n) |
2149 | QCOMPARE( int(QVariant::nameToType( n )), t ); |
2150 | |
2151 | } |
2152 | QCOMPARE(QVariant::typeToName(QVariant::Int), "int" ); |
2153 | // not documented but we return 0 if the type is out of range |
2154 | // by testing this we catch cases where QVariant is extended |
2155 | // but type_map is not updated accordingly |
2156 | QCOMPARE( QVariant::typeToName( QVariant::Type(max+1) ), (char*)0 ); |
2157 | // invalid type names |
2158 | QVERIFY( QVariant::nameToType( 0 ) == QVariant::Invalid ); |
2159 | QVERIFY( QVariant::nameToType( "" ) == QVariant::Invalid ); |
2160 | QVERIFY( QVariant::nameToType( "foo" ) == QVariant::Invalid ); |
2161 | |
2162 | QCOMPARE(QVariant::nameToType("UserType" ), QVariant::Invalid); |
2163 | |
2164 | // We don't support these old (Qt3) types anymore. |
2165 | QCOMPARE(QVariant::nameToType("QIconSet" ), QVariant::Invalid); |
2166 | QCOMPARE(QVariant::nameToType("Q3CString" ), QVariant::Invalid); |
2167 | QCOMPARE(QVariant::nameToType("Q_LLONG" ), QVariant::Invalid); |
2168 | QCOMPARE(QVariant::nameToType("Q_ULLONG" ), QVariant::Invalid); |
2169 | } |
2170 | |
2171 | void tst_QVariant::streamInvalidVariant() |
2172 | { |
2173 | int writeX = 1; |
2174 | int writeY = 2; |
2175 | int readX; |
2176 | int readY; |
2177 | QVariant writeVariant; |
2178 | QVariant readVariant; |
2179 | |
2180 | QVERIFY( writeVariant.type() == QVariant::Invalid ); |
2181 | |
2182 | QByteArray data; |
2183 | QDataStream writeStream( &data, QIODevice::WriteOnly ); |
2184 | writeStream << writeX << writeVariant << writeY; |
2185 | |
2186 | QDataStream readStream( &data, QIODevice::ReadOnly ); |
2187 | readStream >> readX >> readVariant >> readY; |
2188 | |
2189 | QVERIFY( readX == writeX ); |
2190 | // Two invalid QVariant's aren't necessarily the same, so == will |
2191 | // return false if one is invalid, so check the type() instead |
2192 | QVERIFY( readVariant.type() == QVariant::Invalid ); |
2193 | QVERIFY( readY == writeY ); |
2194 | } |
2195 | |
2196 | static int instanceCount = 0; |
2197 | |
2198 | struct MyType |
2199 | { |
2200 | MyType(int n = 0, const char *t=0): number(n), text(t) |
2201 | { |
2202 | ++instanceCount; |
2203 | } |
2204 | MyType(const MyType &other) |
2205 | : number(other.number), text(other.text) |
2206 | { |
2207 | ++instanceCount; |
2208 | } |
2209 | ~MyType() |
2210 | { |
2211 | --instanceCount; |
2212 | } |
2213 | int number; |
2214 | const char *text; |
2215 | }; |
2216 | |
2217 | Q_DECLARE_METATYPE(MyType) |
2218 | Q_DECLARE_METATYPE(MyType*) |
2219 | |
2220 | void tst_QVariant::userType() |
2221 | { |
2222 | { |
2223 | MyType data(1, "eins" ); |
2224 | MyType data2(2, "zwei" ); |
2225 | |
2226 | { |
2227 | QVariant userVar; |
2228 | userVar.setValue(data); |
2229 | |
2230 | QCOMPARE(userVar.type(), QVariant::UserType); |
2231 | QCOMPARE(userVar.userType(), qMetaTypeId<MyType>()); |
2232 | QCOMPARE(userVar.typeName(), "MyType" ); |
2233 | QVERIFY(!userVar.isNull()); |
2234 | QVERIFY(!userVar.canConvert(QVariant::String)); |
2235 | |
2236 | QVariant userVar2(userVar); |
2237 | QCOMPARE(userVar, userVar2); |
2238 | |
2239 | userVar2.setValue(data2); |
2240 | QVERIFY(userVar != userVar2); |
2241 | |
2242 | const MyType *varData = static_cast<const MyType *>(userVar.constData()); |
2243 | QVERIFY(varData); |
2244 | QCOMPARE(varData->number, data.number); |
2245 | QCOMPARE(varData->text, data.text); |
2246 | |
2247 | QVariant userVar3; |
2248 | userVar3.setValue(data2); |
2249 | |
2250 | userVar3 = userVar2; |
2251 | QCOMPARE(userVar2, userVar3); |
2252 | } |
2253 | // At this point all QVariants got destroyed but we have 2 MyType instances. |
2254 | QCOMPARE(instanceCount, 2); |
2255 | { |
2256 | QVariant userVar; |
2257 | userVar.setValue(&data); |
2258 | |
2259 | QCOMPARE(userVar.type(), QVariant::UserType); |
2260 | QCOMPARE(userVar.userType(), qMetaTypeId<MyType*>()); |
2261 | QCOMPARE(userVar.typeName(), "MyType*" ); |
2262 | QVERIFY(!userVar.isNull()); |
2263 | QVERIFY(!userVar.canConvert(QVariant::String)); |
2264 | |
2265 | QVariant userVar2(userVar); |
2266 | QCOMPARE(userVar, userVar2); |
2267 | |
2268 | userVar2.setValue(&data2); |
2269 | QVERIFY(userVar != userVar2); |
2270 | |
2271 | MyType * const*varData = reinterpret_cast<MyType *const *>(userVar.constData()); |
2272 | QVERIFY(varData); |
2273 | QCOMPARE(*varData, &data); |
2274 | |
2275 | QVariant userVar3; |
2276 | userVar3.setValue(&data2); |
2277 | |
2278 | /* This check is correct now. userVar2 contains a pointer to data2 and so |
2279 | * does userVar3. */ |
2280 | QCOMPARE(userVar2, userVar3); |
2281 | |
2282 | userVar3 = userVar2; |
2283 | QCOMPARE(userVar2, userVar3); |
2284 | } |
2285 | |
2286 | QCOMPARE(instanceCount, 2); |
2287 | QVariant myCarrier; |
2288 | myCarrier.setValue(data); |
2289 | QCOMPARE(instanceCount, 3); |
2290 | { |
2291 | QVariant second = myCarrier; |
2292 | QCOMPARE(instanceCount, 3); |
2293 | second.detach(); |
2294 | QCOMPARE(instanceCount, 4); |
2295 | } |
2296 | QCOMPARE(instanceCount, 3); |
2297 | |
2298 | MyType data3(0, "null" ); |
2299 | data3 = qvariant_cast<MyType>(v: myCarrier); |
2300 | QCOMPARE(data3.number, 1); |
2301 | QCOMPARE(data3.text, (const char *)"eins" ); |
2302 | #ifndef Q_CC_SUN |
2303 | QCOMPARE(instanceCount, 4); |
2304 | #endif |
2305 | |
2306 | } |
2307 | |
2308 | { |
2309 | const MyType data(3, "drei" ); |
2310 | QVariant myCarrier; |
2311 | |
2312 | myCarrier.setValue(data); |
2313 | QCOMPARE(myCarrier.typeName(), "MyType" ); |
2314 | |
2315 | const MyType data2 = qvariant_cast<MyType>(v: myCarrier); |
2316 | QCOMPARE(data2.number, 3); |
2317 | QCOMPARE(data2.text, (const char *)"drei" ); |
2318 | } |
2319 | |
2320 | { |
2321 | short s = 42; |
2322 | QVariant myCarrier; |
2323 | |
2324 | myCarrier.setValue(s); |
2325 | QCOMPARE((int)qvariant_cast<short>(myCarrier), 42); |
2326 | } |
2327 | |
2328 | { |
2329 | qlonglong ll = Q_INT64_C(42); |
2330 | QVariant myCarrier; |
2331 | |
2332 | myCarrier.setValue(ll); |
2333 | QCOMPARE(qvariant_cast<int>(myCarrier), 42); |
2334 | } |
2335 | |
2336 | // At this point all QVariants got destroyed and MyType objects too. |
2337 | QCOMPARE(instanceCount, 0); |
2338 | } |
2339 | |
2340 | struct MyTypePOD |
2341 | { |
2342 | int a; |
2343 | int b; |
2344 | }; |
2345 | Q_DECLARE_METATYPE(MyTypePOD) |
2346 | |
2347 | void tst_QVariant::podUserType() |
2348 | { |
2349 | MyTypePOD pod; |
2350 | pod.a = 10; |
2351 | pod.b = 20; |
2352 | |
2353 | QVariant pod_as_variant = QVariant::fromValue(value: pod); |
2354 | MyTypePOD pod2 = qvariant_cast<MyTypePOD>(v: pod_as_variant); |
2355 | |
2356 | QCOMPARE(pod.a, pod2.a); |
2357 | QCOMPARE(pod.b, pod2.b); |
2358 | |
2359 | pod_as_variant.setValue(pod); |
2360 | pod2 = qvariant_cast<MyTypePOD>(v: pod_as_variant); |
2361 | |
2362 | QCOMPARE(pod.a, pod2.a); |
2363 | QCOMPARE(pod.b, pod2.b); |
2364 | } |
2365 | |
2366 | void tst_QVariant::basicUserType() |
2367 | { |
2368 | QVariant v; |
2369 | { |
2370 | int i = 7; |
2371 | v = QVariant(QMetaType::Int, &i); |
2372 | } |
2373 | QCOMPARE(v.type(), QVariant::Int); |
2374 | QCOMPARE(v.toInt(), 7); |
2375 | |
2376 | { |
2377 | QString s("foo" ); |
2378 | v = QVariant(QMetaType::QString, &s); |
2379 | } |
2380 | QCOMPARE(v.type(), QVariant::String); |
2381 | QCOMPARE(v.toString(), QString("foo" )); |
2382 | |
2383 | { |
2384 | double d = 4.4; |
2385 | v = QVariant(QMetaType::Double, &d); |
2386 | } |
2387 | QCOMPARE(v.type(), QVariant::Double); |
2388 | QCOMPARE(v.toDouble(), 4.4); |
2389 | |
2390 | { |
2391 | float f = 4.5f; |
2392 | v = QVariant(QMetaType::Float, &f); |
2393 | } |
2394 | QCOMPARE(v.userType(), int(QMetaType::Float)); |
2395 | QCOMPARE(v.toDouble(), 4.5); |
2396 | |
2397 | { |
2398 | QByteArray ba("bar" ); |
2399 | v = QVariant(QMetaType::QByteArray, &ba); |
2400 | } |
2401 | QCOMPARE(v.type(), QVariant::ByteArray); |
2402 | QCOMPARE(v.toByteArray(), QByteArray("bar" )); |
2403 | } |
2404 | |
2405 | void tst_QVariant::data() |
2406 | { |
2407 | QVariant v; |
2408 | |
2409 | QVariant i = 1; |
2410 | QVariant d = 1.12; |
2411 | QVariant f = 1.12f; |
2412 | QVariant ll = (qlonglong)2; |
2413 | QVariant ull = (qulonglong)3; |
2414 | QVariant s(QString("hallo" )); |
2415 | QVariant r(QRect(1,2,3,4)); |
2416 | |
2417 | v = i; |
2418 | QVERIFY(v.data()); |
2419 | QCOMPARE(*static_cast<int *>(v.data()), i.toInt()); |
2420 | |
2421 | v = d; |
2422 | QVERIFY(v.data()); |
2423 | QCOMPARE(*static_cast<double *>(v.data()), d.toDouble()); |
2424 | |
2425 | v = f; |
2426 | QVERIFY(v.data()); |
2427 | QCOMPARE(*static_cast<float *>(v.data()), qvariant_cast<float>(v)); |
2428 | |
2429 | v = ll; |
2430 | QVERIFY(v.data()); |
2431 | QCOMPARE(*static_cast<qlonglong *>(v.data()), ll.toLongLong()); |
2432 | |
2433 | v = ull; |
2434 | QVERIFY(v.data()); |
2435 | QCOMPARE(*static_cast<qulonglong *>(v.data()), ull.toULongLong()); |
2436 | |
2437 | v = s; |
2438 | QVERIFY(v.data()); |
2439 | QCOMPARE(*static_cast<QString *>(v.data()), s.toString()); |
2440 | |
2441 | v = r; |
2442 | QVERIFY(v.data()); |
2443 | QCOMPARE(*static_cast<QRect *>(v.data()), r.toRect()); |
2444 | } |
2445 | |
2446 | void tst_QVariant::constData() |
2447 | { |
2448 | QVariant v; |
2449 | |
2450 | int i = 1; |
2451 | double d = 1.12; |
2452 | float f = 1.12f; |
2453 | qlonglong ll = 2; |
2454 | qulonglong ull = 3; |
2455 | QString s("hallo" ); |
2456 | QRect r(1,2,3,4); |
2457 | |
2458 | v = QVariant(i); |
2459 | QVERIFY(v.constData()); |
2460 | QCOMPARE(*static_cast<const int *>(v.constData()), i); |
2461 | |
2462 | v = QVariant(d); |
2463 | QVERIFY(v.constData()); |
2464 | QCOMPARE(*static_cast<const double *>(v.constData()), d); |
2465 | |
2466 | v = QVariant(f); |
2467 | QVERIFY(v.constData()); |
2468 | QCOMPARE(*static_cast<const float *>(v.constData()), f); |
2469 | |
2470 | v = QVariant(ll); |
2471 | QVERIFY(v.constData()); |
2472 | QCOMPARE(*static_cast<const qlonglong *>(v.constData()), ll); |
2473 | |
2474 | v = QVariant(ull); |
2475 | QVERIFY(v.constData()); |
2476 | QCOMPARE(*static_cast<const qulonglong *>(v.constData()), ull); |
2477 | |
2478 | v = QVariant(s); |
2479 | QVERIFY(v.constData()); |
2480 | QCOMPARE(*static_cast<const QString *>(v.constData()), s); |
2481 | |
2482 | v = QVariant(r); |
2483 | QVERIFY(v.constData()); |
2484 | QCOMPARE(*static_cast<const QRect *>(v.constData()), r); |
2485 | } |
2486 | |
2487 | struct Foo |
2488 | { |
2489 | Foo(): i(0) {} |
2490 | int i; |
2491 | }; |
2492 | |
2493 | Q_DECLARE_METATYPE(Foo) |
2494 | |
2495 | void tst_QVariant::variant_to() |
2496 | { |
2497 | QVariant v1(4.2); |
2498 | QVariant v2(5); |
2499 | |
2500 | QVariant v3; |
2501 | QVariant v4; |
2502 | |
2503 | QStringList sl; |
2504 | sl << QLatin1String("blah" ); |
2505 | |
2506 | v3.setValue(sl); |
2507 | |
2508 | Foo foo; |
2509 | foo.i = 42; |
2510 | |
2511 | v4.setValue(foo); |
2512 | |
2513 | QCOMPARE(qvariant_cast<double>(v1), 4.2); |
2514 | QCOMPARE(qvariant_cast<float>(v1), 4.2f); |
2515 | QCOMPARE(qvariant_cast<int>(v2), 5); |
2516 | QCOMPARE(qvariant_cast<QStringList>(v3), sl); |
2517 | QCOMPARE(qvariant_cast<QString>(v3), QString::fromLatin1("blah" )); |
2518 | |
2519 | QCOMPARE(qvariant_cast<Foo>(v4).i, 42); |
2520 | |
2521 | QVariant v5; |
2522 | QCOMPARE(qvariant_cast<Foo>(v5).i, 0); |
2523 | |
2524 | QCOMPARE(qvariant_cast<int>(v1), 4); |
2525 | |
2526 | QVariant n = QVariant::fromValue<short>(value: 42); |
2527 | QCOMPARE(qvariant_cast<int>(n), 42); |
2528 | QCOMPARE(qvariant_cast<uint>(n), 42u); |
2529 | QCOMPARE(qvariant_cast<double>(n), 42.0); |
2530 | QCOMPARE(qvariant_cast<float>(n), 42.f); |
2531 | QCOMPARE(qvariant_cast<short>(n), short(42)); |
2532 | QCOMPARE(qvariant_cast<ushort>(n), ushort(42)); |
2533 | |
2534 | n = QVariant::fromValue(value: 43l); |
2535 | QCOMPARE(qvariant_cast<int>(n), 43); |
2536 | QCOMPARE(qvariant_cast<uint>(n), 43u); |
2537 | QCOMPARE(qvariant_cast<double>(n), 43.0); |
2538 | QCOMPARE(qvariant_cast<float>(n), 43.f); |
2539 | QCOMPARE(qvariant_cast<long>(n), 43l); |
2540 | |
2541 | n = QLatin1String("44" ); |
2542 | QCOMPARE(qvariant_cast<int>(n), 44); |
2543 | QCOMPARE(qvariant_cast<ulong>(n), 44ul); |
2544 | QCOMPARE(qvariant_cast<float>(n), 44.0f); |
2545 | |
2546 | QCOMPARE(QVariant::fromValue(0.25f).toDouble(), 0.25); |
2547 | } |
2548 | |
2549 | struct Blah { int i; }; |
2550 | |
2551 | QDataStream& operator>>(QDataStream& s, Blah& c) |
2552 | { return (s >> c.i); } |
2553 | |
2554 | QDataStream& operator<<(QDataStream& s, const Blah& c) |
2555 | { return (s << c.i); } |
2556 | |
2557 | void tst_QVariant::saveLoadCustomTypes() |
2558 | { |
2559 | QByteArray data; |
2560 | |
2561 | Blah i = { .i: 42 }; |
2562 | int tp = qRegisterMetaType<Blah>(typeName: "Blah" ); |
2563 | QVariant v = QVariant(tp, &i); |
2564 | |
2565 | qRegisterMetaTypeStreamOperators<Blah>(typeName: "Blah" ); |
2566 | |
2567 | QCOMPARE(v.userType(), tp); |
2568 | QCOMPARE(v.type(), QVariant::UserType); |
2569 | { |
2570 | QDataStream stream(&data, QIODevice::WriteOnly); |
2571 | stream << v; |
2572 | } |
2573 | |
2574 | v = QVariant(); |
2575 | |
2576 | { |
2577 | QDataStream stream(data); |
2578 | stream >> v; |
2579 | } |
2580 | |
2581 | QCOMPARE(int(v.userType()), QMetaType::type("Blah" )); |
2582 | int value = *(int*)v.constData(); |
2583 | QCOMPARE(value, 42); |
2584 | } |
2585 | |
2586 | void tst_QVariant::url() |
2587 | { |
2588 | QString str("http://qt-project.org" ); |
2589 | QUrl url(str); |
2590 | |
2591 | QVariant v(url); //built with a QUrl |
2592 | |
2593 | QVariant v2 = v; |
2594 | |
2595 | QVariant v3(str); //built with a QString |
2596 | |
2597 | QCOMPARE(v2.toUrl(), url); |
2598 | QVERIFY(v3.canConvert<QUrl>()); |
2599 | QCOMPARE(v2.toUrl(), v3.toUrl()); |
2600 | |
2601 | QVERIFY(v2.canConvert<QString>()); |
2602 | QCOMPARE(v2.toString(), str); |
2603 | QCOMPARE(v3.toString(), str); |
2604 | } |
2605 | |
2606 | void tst_QVariant::variantMap() |
2607 | { |
2608 | QMap<QString, QVariant> map; |
2609 | map["test" ] = 42; |
2610 | |
2611 | QVariant v = map; |
2612 | QVariantMap map2 = qvariant_cast<QVariantMap>(v); |
2613 | QCOMPARE(map2.value("test" ).toInt(), 42); |
2614 | QCOMPARE(map2, map); |
2615 | |
2616 | map2 = v.toMap(); |
2617 | QCOMPARE(map2.value("test" ).toInt(), 42); |
2618 | QCOMPARE(map2, map); |
2619 | |
2620 | QVariant v2 = QVariant(QMetaType::type(typeName: "QVariantMap" ), &map); |
2621 | QCOMPARE(qvariant_cast<QVariantMap>(v2).value("test" ).toInt(), 42); |
2622 | |
2623 | QVariant v3 = QVariant(QMetaType::type(typeName: "QMap<QString, QVariant>" ), &map); |
2624 | QCOMPARE(qvariant_cast<QVariantMap>(v3).value("test" ).toInt(), 42); |
2625 | |
2626 | QCOMPARE(v, QVariant(v.toHash())); |
2627 | |
2628 | // multi-keys |
2629 | map.insertMulti(key: "test" , value: 47); |
2630 | v = map; |
2631 | map2 = qvariant_cast<QVariantMap>(v); |
2632 | QCOMPARE(map2, map); |
2633 | map2 = v.toMap(); |
2634 | QCOMPARE(map2, map); |
2635 | |
2636 | QCOMPARE(v, QVariant(v.toHash())); |
2637 | } |
2638 | |
2639 | void tst_QVariant::variantHash() |
2640 | { |
2641 | QHash<QString, QVariant> hash; |
2642 | hash["test" ] = 42; |
2643 | |
2644 | QVariant v = hash; |
2645 | QVariantHash hash2 = qvariant_cast<QVariantHash>(v); |
2646 | QCOMPARE(hash2.value("test" ).toInt(), 42); |
2647 | QCOMPARE(hash2, hash); |
2648 | |
2649 | hash2 = v.toHash(); |
2650 | QCOMPARE(hash2.value("test" ).toInt(), 42); |
2651 | QCOMPARE(hash2, hash); |
2652 | |
2653 | QVariant v2 = QVariant(QMetaType::type(typeName: "QVariantHash" ), &hash); |
2654 | QCOMPARE(qvariant_cast<QVariantHash>(v2).value("test" ).toInt(), 42); |
2655 | |
2656 | QVariant v3 = QVariant(QMetaType::type(typeName: "QHash<QString, QVariant>" ), &hash); |
2657 | QCOMPARE(qvariant_cast<QVariantHash>(v3).value("test" ).toInt(), 42); |
2658 | |
2659 | QCOMPARE(v, QVariant(v.toMap())); |
2660 | |
2661 | // multi-keys |
2662 | hash.insertMulti(key: "test" , value: 47); |
2663 | v = hash; |
2664 | hash2 = qvariant_cast<QVariantHash>(v); |
2665 | QCOMPARE(hash2, hash); |
2666 | hash2 = v.toHash(); |
2667 | QCOMPARE(hash2, hash); |
2668 | |
2669 | QCOMPARE(v, QVariant(v.toMap())); |
2670 | } |
2671 | |
2672 | class CustomQObject : public QObject { |
2673 | Q_OBJECT |
2674 | public: |
2675 | CustomQObject(QObject *parent = 0) : QObject(parent) {} |
2676 | }; |
2677 | Q_DECLARE_METATYPE(CustomQObject*) |
2678 | |
2679 | class CustomNonQObject { }; |
2680 | Q_DECLARE_METATYPE(CustomNonQObject) |
2681 | Q_DECLARE_METATYPE(CustomNonQObject*) |
2682 | |
2683 | void tst_QVariant::cleanupTestCase() |
2684 | { |
2685 | delete customNonQObjectPointer; |
2686 | qDeleteAll(c: objectPointerTestData); |
2687 | } |
2688 | |
2689 | void tst_QVariant::qvariant_cast_QObject_data() |
2690 | { |
2691 | QTest::addColumn<QVariant>(name: "data" ); |
2692 | QTest::addColumn<bool>(name: "success" ); |
2693 | QTest::addColumn<bool>(name: "isNull" ); |
2694 | QObject *obj = new QObject; |
2695 | obj->setObjectName(QString::fromLatin1(str: "Hello" )); |
2696 | QTest::newRow(dataTag: "from QObject" ) << QVariant(QMetaType::QObjectStar, &obj) << true << false; |
2697 | QTest::newRow(dataTag: "from QObject2" ) << QVariant::fromValue(value: obj) << true << false; |
2698 | QTest::newRow(dataTag: "from String" ) << QVariant(QLatin1String("1, 2, 3" )) << false << false; |
2699 | QTest::newRow(dataTag: "from int" ) << QVariant((int) 123) << false << false; |
2700 | CustomQObject *customObject = new CustomQObject(this); |
2701 | customObject->setObjectName(QString::fromLatin1(str: "Hello" )); |
2702 | QTest::newRow(dataTag: "from Derived QObject" ) << QVariant::fromValue(value: customObject) << true << false; |
2703 | QTest::newRow(dataTag: "from custom Object" ) << QVariant::fromValue(value: CustomNonQObject()) << false << false; |
2704 | |
2705 | // Deleted in cleanupTestCase. |
2706 | customNonQObjectPointer = new CustomNonQObject; |
2707 | QTest::newRow(dataTag: "from custom ObjectStar" ) << QVariant::fromValue(value: customNonQObjectPointer) << false << false; |
2708 | |
2709 | // Deleted in cleanupTestCase. |
2710 | objectPointerTestData.push_back(t: obj); |
2711 | objectPointerTestData.push_back(t: customObject); |
2712 | |
2713 | QTest::newRow(dataTag: "null QObject" ) << QVariant::fromValue<QObject*>(value: 0) << true << true; |
2714 | QTest::newRow(dataTag: "null derived QObject" ) << QVariant::fromValue<CustomQObject*>(value: 0) << true << true; |
2715 | QTest::newRow(dataTag: "null custom object" ) << QVariant::fromValue<CustomNonQObject*>(value: 0) << false << true; |
2716 | QTest::newRow(dataTag: "zero int" ) << QVariant::fromValue<int>(value: 0) << false << false; |
2717 | } |
2718 | |
2719 | void tst_QVariant::qvariant_cast_QObject() |
2720 | { |
2721 | QFETCH(QVariant, data); |
2722 | QFETCH(bool, success); |
2723 | QFETCH(bool, isNull); |
2724 | |
2725 | QObject *o = qvariant_cast<QObject *>(v: data); |
2726 | QCOMPARE(o != 0, success && !isNull); |
2727 | if (success) { |
2728 | if (!isNull) |
2729 | QCOMPARE(o->objectName(), QString::fromLatin1("Hello" )); |
2730 | QVERIFY(data.canConvert<QObject*>()); |
2731 | QVERIFY(data.canConvert(QMetaType::QObjectStar)); |
2732 | QVERIFY(data.canConvert(::qMetaTypeId<QObject*>())); |
2733 | QCOMPARE(data.value<QObject*>() == 0, isNull); |
2734 | QCOMPARE(data.isNull(), isNull); |
2735 | QVERIFY(data.convert(QMetaType::QObjectStar)); |
2736 | QCOMPARE(data.userType(), int(QMetaType::QObjectStar)); |
2737 | } else { |
2738 | QVERIFY(!data.canConvert<QObject*>()); |
2739 | QVERIFY(!data.canConvert(QMetaType::QObjectStar)); |
2740 | QVERIFY(!data.canConvert(::qMetaTypeId<QObject*>())); |
2741 | QCOMPARE(data.isNull(), isNull); |
2742 | QVERIFY(!data.value<QObject*>()); |
2743 | QVERIFY(!data.convert(QMetaType::QObjectStar)); |
2744 | QVERIFY(data.userType() != QMetaType::QObjectStar); |
2745 | } |
2746 | } |
2747 | |
2748 | class CustomQObjectDerived : public CustomQObject { |
2749 | Q_OBJECT |
2750 | public: |
2751 | CustomQObjectDerived(QObject *parent = 0) : CustomQObject(parent) {} |
2752 | }; |
2753 | Q_DECLARE_METATYPE(CustomQObjectDerived*) |
2754 | |
2755 | class CustomQObjectDerivedNoMetaType : public CustomQObject { |
2756 | Q_OBJECT |
2757 | public: |
2758 | CustomQObjectDerivedNoMetaType(QObject *parent = 0) : CustomQObject(parent) {} |
2759 | }; |
2760 | |
2761 | void tst_QVariant::qvariant_cast_QObject_derived() |
2762 | { |
2763 | { |
2764 | CustomQObjectDerivedNoMetaType *object = new CustomQObjectDerivedNoMetaType(this); |
2765 | QVariant data = QVariant::fromValue(value: object); |
2766 | QCOMPARE(data.userType(), qMetaTypeId<CustomQObjectDerivedNoMetaType*>()); |
2767 | QCOMPARE(data.value<QObject *>(), object); |
2768 | QCOMPARE(data.value<CustomQObjectDerivedNoMetaType *>(), object); |
2769 | QCOMPARE(data.value<CustomQObject *>(), object); |
2770 | } |
2771 | { |
2772 | CustomQObjectDerived *object = new CustomQObjectDerived(this); |
2773 | QVariant data = QVariant::fromValue(value: object); |
2774 | |
2775 | QCOMPARE(data.userType(), qMetaTypeId<CustomQObjectDerived*>()); |
2776 | |
2777 | QCOMPARE(data.value<QObject *>(), object); |
2778 | QCOMPARE(data.value<CustomQObjectDerived *>(), object); |
2779 | QCOMPARE(data.value<CustomQObject *>(), object); |
2780 | } |
2781 | { |
2782 | QObject *object = new CustomQObjectDerivedNoMetaType(this); |
2783 | QVariant data = QVariant::fromValue(value: object); |
2784 | QVERIFY(data.canConvert<CustomQObjectDerivedNoMetaType*>()); |
2785 | QVERIFY(data.convert(qMetaTypeId<CustomQObjectDerivedNoMetaType*>())); |
2786 | QCOMPARE(data.value<CustomQObjectDerivedNoMetaType*>(), object); |
2787 | QCOMPARE(data.isNull(), false); |
2788 | } |
2789 | } |
2790 | |
2791 | struct QObjectWrapper |
2792 | { |
2793 | explicit QObjectWrapper(QObject *o = 0) : obj(o) {} |
2794 | |
2795 | QObject* getObject() const { |
2796 | return obj; |
2797 | } |
2798 | private: |
2799 | QObject *obj; |
2800 | }; |
2801 | |
2802 | Q_DECLARE_METATYPE(QObjectWrapper) |
2803 | |
2804 | struct Converter |
2805 | { |
2806 | Converter() {} |
2807 | |
2808 | QObject* operator()(const QObjectWrapper &f) const |
2809 | { |
2810 | return f.getObject(); |
2811 | } |
2812 | }; |
2813 | |
2814 | namespace MyNS { |
2815 | |
2816 | template<typename T> |
2817 | class SmartPointer |
2818 | { |
2819 | T* pointer; |
2820 | public: |
2821 | typedef T element_type; |
2822 | explicit SmartPointer(T *t = 0) |
2823 | : pointer(t) |
2824 | { |
2825 | } |
2826 | |
2827 | T* operator->() const { return pointer; } |
2828 | }; |
2829 | |
2830 | template<typename T> |
2831 | struct SequentialContainer |
2832 | { |
2833 | typedef T value_type; |
2834 | typedef const T* const_iterator; |
2835 | T t; |
2836 | const_iterator begin() const { return &t; } |
2837 | const_iterator end() const { return &t + 1; } |
2838 | }; |
2839 | |
2840 | template<typename T, typename U> |
2841 | struct AssociativeContainer : public std::map<T, U> |
2842 | { |
2843 | }; |
2844 | |
2845 | } |
2846 | |
2847 | Q_DECLARE_SMART_POINTER_METATYPE(MyNS::SmartPointer) |
2848 | |
2849 | Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(MyNS::SequentialContainer) |
2850 | Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(MyNS::AssociativeContainer) |
2851 | |
2852 | // Test that explicit declaration does not degrade features. |
2853 | Q_DECLARE_METATYPE(MyNS::SmartPointer<int>) |
2854 | Q_DECLARE_METATYPE(MyNS::SmartPointer<QIODevice>) |
2855 | Q_DECLARE_METATYPE(QSharedPointer<QIODevice>) |
2856 | |
2857 | void tst_QVariant::qvariant_cast_QObject_wrapper() |
2858 | { |
2859 | QMetaType::registerConverter<QObjectWrapper, QObject*>(function: &QObjectWrapper::getObject); |
2860 | |
2861 | CustomQObjectDerived *object = new CustomQObjectDerived(this); |
2862 | QObjectWrapper wrapper(object); |
2863 | QVariant v = QVariant::fromValue(value: wrapper); |
2864 | QCOMPARE(v.value<QObject*>(), object); |
2865 | v.convert(targetTypeId: qMetaTypeId<QObject*>()); |
2866 | QCOMPARE(v.value<QObject*>(), object); |
2867 | |
2868 | MyNS::SequentialContainer<int> sc; |
2869 | sc.t = 47; |
2870 | MyNS::AssociativeContainer<int, short> ac; |
2871 | |
2872 | QVariant::fromValue(value: sc); |
2873 | QVariant::fromValue(value: ac); |
2874 | |
2875 | { |
2876 | QFile *f = new QFile(this); |
2877 | MyNS::SmartPointer<QFile> sp(f); |
2878 | QVariant spVar = QVariant::fromValue(value: sp); |
2879 | QVERIFY(spVar.canConvert<QObject*>()); |
2880 | QCOMPARE(f, spVar.value<QObject*>()); |
2881 | } |
2882 | { |
2883 | QFile *f = new QFile(this); |
2884 | QPointer<QFile> sp(f); |
2885 | QVariant spVar = QVariant::fromValue(value: sp); |
2886 | QVERIFY(spVar.canConvert<QObject*>()); |
2887 | QCOMPARE(f, spVar.value<QObject*>()); |
2888 | } |
2889 | #if QT_DEPRECATED_SINCE(5, 0) |
2890 | { |
2891 | QFile *f = new QFile(this); |
2892 | QT_WARNING_PUSH |
2893 | QT_WARNING_DISABLE_DEPRECATED |
2894 | QWeakPointer<QFile> sp(f); |
2895 | QT_WARNING_POP |
2896 | QVariant spVar = QVariant::fromValue(value: sp); |
2897 | QVERIFY(spVar.canConvert<QObject*>()); |
2898 | QCOMPARE(f, spVar.value<QObject*>()); |
2899 | } |
2900 | #endif |
2901 | { |
2902 | QFile *f = new QFile(this); |
2903 | QSharedPointer<QObject> sp(f); |
2904 | QWeakPointer<QObject> wp = sp; |
2905 | QVariant wpVar = QVariant::fromValue(value: wp); |
2906 | QVERIFY(wpVar.canConvert<QObject*>()); |
2907 | QCOMPARE(f, wpVar.value<QObject*>()); |
2908 | } |
2909 | { |
2910 | QFile *f = new QFile(this); |
2911 | QSharedPointer<QFile> sp(f); |
2912 | QWeakPointer<QFile> wp = sp.toWeakRef(); |
2913 | QVariant wpVar = QVariant::fromValue(value: wp); |
2914 | QVERIFY(wpVar.canConvert<QObject*>()); |
2915 | QCOMPARE(f, wpVar.value<QObject*>()); |
2916 | } |
2917 | { |
2918 | QFile *f = new QFile(this); |
2919 | QSharedPointer<QFile> sp(f); |
2920 | QVariant spVar = QVariant::fromValue(value: sp); |
2921 | QVERIFY(spVar.canConvert<QObject*>()); |
2922 | QCOMPARE(f, spVar.value<QObject*>()); |
2923 | } |
2924 | { |
2925 | QIODevice *f = new QFile(this); |
2926 | MyNS::SmartPointer<QIODevice> sp(f); |
2927 | QVariant spVar = QVariant::fromValue(value: sp); |
2928 | QVERIFY(spVar.canConvert<QObject*>()); |
2929 | QCOMPARE(f, spVar.value<QObject*>()); |
2930 | } |
2931 | { |
2932 | QIODevice *f = new QFile(this); |
2933 | QSharedPointer<QIODevice> sp(f); |
2934 | QVariant spVar = QVariant::fromValue(value: sp); |
2935 | QVERIFY(spVar.canConvert<QObject*>()); |
2936 | QCOMPARE(f, spVar.value<QObject*>()); |
2937 | } |
2938 | |
2939 | // Compile tests: |
2940 | qRegisterMetaType<MyNS::SmartPointer<int> >(); |
2941 | // Not declared as a metatype: |
2942 | qRegisterMetaType<MyNS::SmartPointer<double> >(typeName: "MyNS::SmartPointer<double>" ); |
2943 | } |
2944 | |
2945 | void tst_QVariant::qvariant_cast_QSharedPointerQObject() |
2946 | { |
2947 | // ensure no problems between this form and the auto-registering in QVariant::fromValue |
2948 | qRegisterMetaType<QSharedPointer<QObject> >(typeName: "QSharedPointer<QObject>" ); |
2949 | |
2950 | QObject *rawptr = new QObject; |
2951 | QSharedPointer<QObject> strong(rawptr); |
2952 | QWeakPointer<QObject> weak(strong); |
2953 | QPointer<QObject> qptr(rawptr); |
2954 | |
2955 | QVariant v = QVariant::fromValue(value: strong); |
2956 | QCOMPARE(v.value<QSharedPointer<QObject> >(), strong); |
2957 | |
2958 | // clear our QSP; the copy inside the variant should keep the object alive |
2959 | strong.clear(); |
2960 | |
2961 | // check that the object didn't get deleted |
2962 | QVERIFY(!weak.isNull()); |
2963 | QVERIFY(!qptr.isNull()); |
2964 | |
2965 | strong = qvariant_cast<QSharedPointer<QObject> >(v); |
2966 | QCOMPARE(strong.data(), rawptr); |
2967 | QVERIFY(strong == weak); |
2968 | |
2969 | // now really delete the object and verify |
2970 | strong.clear(); |
2971 | v.clear(); |
2972 | QVERIFY(weak.isNull()); |
2973 | QVERIFY(qptr.isNull()); |
2974 | |
2975 | // compile test: |
2976 | // QVariant::fromValue has already called this function |
2977 | qRegisterMetaType<QSharedPointer<QObject> >(); |
2978 | } |
2979 | |
2980 | void tst_QVariant::convertToQUint8() const |
2981 | { |
2982 | /* qint8. */ |
2983 | { |
2984 | const qint8 anInt = 32; |
2985 | |
2986 | /* QVariant(int) gets invoked here so the QVariant has nothing with qint8 to do. |
2987 | * It's of type QVariant::Int. */ |
2988 | const QVariant v0 = anInt; |
2989 | |
2990 | QVERIFY(v0.canConvert<qint8>()); |
2991 | QCOMPARE(int(qvariant_cast<qint8>(v0)), 32); |
2992 | QCOMPARE(int(v0.toInt()), 32); |
2993 | QCOMPARE(v0.toString(), QString("32" )); |
2994 | |
2995 | QCOMPARE(int(qvariant_cast<qlonglong>(v0)), 32); |
2996 | QCOMPARE(int(qvariant_cast<char>(v0)), 32); |
2997 | QCOMPARE(int(qvariant_cast<short>(v0)), 32); |
2998 | QCOMPARE(int(qvariant_cast<long>(v0)), 32); |
2999 | QCOMPARE(int(qvariant_cast<float>(v0)), 32); |
3000 | QCOMPARE(int(qvariant_cast<double>(v0)), 32); |
3001 | } |
3002 | |
3003 | /* quint8. */ |
3004 | { |
3005 | const quint8 anInt = 32; |
3006 | const QVariant v0 = anInt; |
3007 | |
3008 | QVERIFY(v0.canConvert<quint8>()); |
3009 | QCOMPARE(int(qvariant_cast<quint8>(v0)), 32); |
3010 | QCOMPARE(int(v0.toUInt()), 32); |
3011 | QCOMPARE(v0.toString(), QString("32" )); |
3012 | } |
3013 | |
3014 | /* qint16. */ |
3015 | { |
3016 | const qint16 anInt = 32; |
3017 | const QVariant v0 = anInt; |
3018 | |
3019 | QVERIFY(v0.canConvert<qint16>()); |
3020 | QCOMPARE(int(qvariant_cast<qint16>(v0)), 32); |
3021 | QCOMPARE(int(v0.toInt()), 32); |
3022 | QCOMPARE(v0.toString(), QString("32" )); |
3023 | } |
3024 | |
3025 | /* quint16. */ |
3026 | { |
3027 | const quint16 anInt = 32; |
3028 | const QVariant v0 = anInt; |
3029 | |
3030 | QVERIFY(v0.canConvert<quint16>()); |
3031 | QCOMPARE(int(qvariant_cast<quint16>(v0)), 32); |
3032 | QCOMPARE(int(v0.toUInt()), 32); |
3033 | QCOMPARE(v0.toString(), QString("32" )); |
3034 | } |
3035 | } |
3036 | |
3037 | void tst_QVariant::comparePointers() const |
3038 | { |
3039 | class MyClass |
3040 | { |
3041 | }; |
3042 | |
3043 | MyClass myClass; |
3044 | |
3045 | QVariant v = QVariant::fromValue<void *>(value: &myClass); |
3046 | QVariant v2 = QVariant::fromValue<void *>(value: &myClass); |
3047 | |
3048 | QCOMPARE(v, v2); |
3049 | } |
3050 | |
3051 | struct Data {}; |
3052 | Q_DECLARE_METATYPE(Data*) |
3053 | |
3054 | void tst_QVariant::voidStar() const |
3055 | { |
3056 | char c; |
3057 | void *p1 = &c; |
3058 | void *p2 = p1; |
3059 | |
3060 | QVariant v1, v2; |
3061 | v1 = QVariant::fromValue(value: p1); |
3062 | v2 = v1; |
3063 | QCOMPARE(v1, v2); |
3064 | |
3065 | v2 = QVariant::fromValue(value: p2); |
3066 | QCOMPARE(v1, v2); |
3067 | |
3068 | p2 = 0; |
3069 | v2 = QVariant::fromValue(value: p2); |
3070 | QVERIFY(v1 != v2); |
3071 | } |
3072 | |
3073 | void tst_QVariant::dataStar() const |
3074 | { |
3075 | qRegisterMetaType<Data*>(); |
3076 | Data *p1 = new Data; |
3077 | |
3078 | QVariant v1 = QVariant::fromValue(value: p1); |
3079 | QCOMPARE(v1.userType(), qMetaTypeId<Data*>()); |
3080 | QCOMPARE(qvariant_cast<Data*>(v1), p1); |
3081 | |
3082 | QVariant v2 = v1; |
3083 | QCOMPARE(v1, v2); |
3084 | |
3085 | v2 = QVariant::fromValue(value: p1); |
3086 | QCOMPARE(v1, v2); |
3087 | delete p1; |
3088 | } |
3089 | |
3090 | void tst_QVariant::canConvertQStringList() const |
3091 | { |
3092 | QFETCH(bool, canConvert); |
3093 | QFETCH(QStringList, input); |
3094 | QFETCH(QString, result); |
3095 | |
3096 | QVariant v(input); |
3097 | |
3098 | QCOMPARE(v.canConvert(QVariant::String), canConvert); |
3099 | QCOMPARE(v.toString(), result); |
3100 | } |
3101 | |
3102 | void tst_QVariant::canConvertQStringList_data() const |
3103 | { |
3104 | QTest::addColumn<bool>(name: "canConvert" ); |
3105 | QTest::addColumn<QStringList>(name: "input" ); |
3106 | QTest::addColumn<QString>(name: "result" ); |
3107 | |
3108 | QTest::newRow(dataTag: "An empty list" ) << false << QStringList() << QString(); |
3109 | QTest::newRow(dataTag: "A single item" ) << true << QStringList(QLatin1String("foo" )) << QString::fromLatin1(str: "foo" ); |
3110 | QTest::newRow(dataTag: "A single, but empty item" ) << true << QStringList(QString()) << QString(); |
3111 | |
3112 | QStringList l; |
3113 | l << "a" << "b" ; |
3114 | |
3115 | QTest::newRow(dataTag: "Two items" ) << false << l << QString(); |
3116 | |
3117 | l << "c" ; |
3118 | QTest::newRow(dataTag: "Three items" ) << false << l << QString(); |
3119 | } |
3120 | |
3121 | template<typename T> void convertMetaType() |
3122 | { |
3123 | QVERIFY(QVariant::fromValue<T>(10).isValid()); |
3124 | QVERIFY(QVariant::fromValue<T>(10).canConvert(QVariant::Int)); |
3125 | QCOMPARE(QVariant::fromValue<T>(10).toInt(), 10); |
3126 | QCOMPARE(QVariant::fromValue<T>(10), QVariant::fromValue<T>(10)); |
3127 | } |
3128 | |
3129 | #define CONVERT_META_TYPE(Type) \ |
3130 | convertMetaType<Type>(); \ |
3131 | if (QTest::currentTestFailed()) \ |
3132 | QFAIL("convertMetaType<" #Type "> failed"); |
3133 | |
3134 | void tst_QVariant::canConvertMetaTypeToInt() const |
3135 | { |
3136 | CONVERT_META_TYPE(long); |
3137 | CONVERT_META_TYPE(short); |
3138 | CONVERT_META_TYPE(short); |
3139 | CONVERT_META_TYPE(unsigned short); |
3140 | CONVERT_META_TYPE(ushort); |
3141 | CONVERT_META_TYPE(ulong); |
3142 | CONVERT_META_TYPE(unsigned long); |
3143 | CONVERT_META_TYPE(uchar); |
3144 | CONVERT_META_TYPE(unsigned char); |
3145 | CONVERT_META_TYPE(char); |
3146 | CONVERT_META_TYPE(uint); |
3147 | CONVERT_META_TYPE(unsigned int); |
3148 | } |
3149 | |
3150 | #undef CONVERT_META_TYPE |
3151 | |
3152 | /*! |
3153 | These calls should not produce any warnings. |
3154 | */ |
3155 | void tst_QVariant::variantToDateTimeWithoutWarnings() const |
3156 | { |
3157 | { |
3158 | const QVariant variant(QLatin1String("An invalid QDateTime string" )); |
3159 | const QDateTime dateTime(variant.toDateTime()); |
3160 | QVERIFY(!dateTime.isValid()); |
3161 | } |
3162 | |
3163 | { |
3164 | QVariant v1(QLatin1String("xyz" )); |
3165 | v1.convert(targetTypeId: QVariant::DateTime); |
3166 | |
3167 | QVariant v2(QLatin1String("xyz" )); |
3168 | QDateTime dt1(v2.toDateTime()); |
3169 | |
3170 | const QVariant v3(QLatin1String("xyz" )); |
3171 | const QDateTime dt2(v3.toDateTime()); |
3172 | } |
3173 | } |
3174 | |
3175 | void tst_QVariant::invalidDateTime() const |
3176 | { |
3177 | QVariant variant(QString::fromLatin1(str: "Invalid date time string" )); |
3178 | QVERIFY(!variant.toDateTime().isValid()); |
3179 | QVERIFY(!variant.convert(QVariant::DateTime)); |
3180 | } |
3181 | |
3182 | struct MyClass |
3183 | { |
3184 | MyClass() : myValue(0) {} |
3185 | int myValue; |
3186 | }; |
3187 | |
3188 | Q_DECLARE_METATYPE( MyClass ) |
3189 | |
3190 | void tst_QVariant::loadUnknownUserType() |
3191 | { |
3192 | qRegisterMetaType<MyClass>(typeName: "MyClass" ); |
3193 | QTest::ignoreMessage(type: QtWarningMsg, message: "QVariant::load: unable to load type " |
3194 | + QByteArray::number(qMetaTypeId<MyClass>()) +"." ); |
3195 | char data[] = {0, 0, QMetaType::User >> 8 , char(QMetaType::User), 0, 0, 0, 0, 8, 'M', 'y', 'C', 'l', 'a', 's', 's', 0}; |
3196 | |
3197 | QByteArray ba(data, sizeof(data)); |
3198 | QDataStream ds(&ba, QIODevice::ReadOnly); |
3199 | QVariant var; |
3200 | var.load(ds); |
3201 | QCOMPARE(ds.status(), QDataStream::ReadCorruptData); |
3202 | } |
3203 | |
3204 | void tst_QVariant::loadBrokenUserType() |
3205 | { |
3206 | QTest::ignoreMessage(type: QtWarningMsg, message: "Trying to construct an instance of an invalid type, type id: 127" ); |
3207 | char data[] = {0, 0, 0, 127, 0 }; |
3208 | |
3209 | QByteArray ba(data, sizeof(data)); |
3210 | QDataStream ds(&ba, QIODevice::ReadOnly); |
3211 | QVariant var; |
3212 | var.load(ds); |
3213 | QCOMPARE(ds.status(), QDataStream::Ok); |
3214 | } |
3215 | |
3216 | void tst_QVariant::invalidDate() const |
3217 | { |
3218 | QString foo("Hello" ); |
3219 | QVariant variant(foo); |
3220 | QVERIFY(!variant.convert(QVariant::Date)); |
3221 | |
3222 | variant = foo; |
3223 | QVERIFY(!variant.convert(QVariant::DateTime)); |
3224 | |
3225 | variant = foo; |
3226 | QVERIFY(!variant.convert(QVariant::Time)); |
3227 | |
3228 | variant = foo; |
3229 | QVERIFY(!variant.convert(QVariant::Int)); |
3230 | |
3231 | variant = foo; |
3232 | QVERIFY(!variant.convert(QVariant::Double)); |
3233 | |
3234 | variant = foo; |
3235 | QVERIFY(!variant.convert(QVariant::Type(QMetaType::Float))); |
3236 | } |
3237 | |
3238 | struct WontCompare |
3239 | { |
3240 | int x,y,z,q,w,e,r,t; |
3241 | }; |
3242 | Q_DECLARE_METATYPE(WontCompare); |
3243 | |
3244 | void tst_QVariant::compareCustomTypes() const |
3245 | { |
3246 | qRegisterMetaType<WontCompare>(typeName: "WontCompare" ); |
3247 | |
3248 | WontCompare f1; |
3249 | f1.x = 0; |
3250 | const QVariant variant1(QVariant::fromValue(value: f1)); |
3251 | |
3252 | WontCompare f2; |
3253 | f2.x = 0; |
3254 | const QVariant variant2(QVariant::fromValue(value: f2)); |
3255 | |
3256 | /* We compare pointers. */ |
3257 | QVERIFY(variant1 != variant2); |
3258 | QCOMPARE(variant1, variant1); |
3259 | QCOMPARE(variant2, variant2); |
3260 | } |
3261 | |
3262 | void tst_QVariant::timeToDateTime() const |
3263 | { |
3264 | const QVariant val(QTime::currentTime()); |
3265 | QVERIFY(!val.canConvert(QVariant::DateTime)); |
3266 | QVERIFY(!val.toDateTime().isValid()); |
3267 | } |
3268 | |
3269 | struct CustomComparable |
3270 | { |
3271 | CustomComparable(int value = 0) : myValue(value) {} |
3272 | int myValue; |
3273 | |
3274 | bool operator==(const CustomComparable &other) const |
3275 | { return other.myValue == myValue; } |
3276 | }; |
3277 | |
3278 | Q_DECLARE_METATYPE(CustomComparable) |
3279 | |
3280 | void tst_QVariant::copyingUserTypes() const |
3281 | { |
3282 | QVariant var; |
3283 | QVariant varCopy; |
3284 | const CustomComparable userType = CustomComparable(42); |
3285 | var.setValue(userType); |
3286 | varCopy = var; |
3287 | |
3288 | const CustomComparable copiedType = qvariant_cast<CustomComparable>(v: varCopy); |
3289 | QCOMPARE(copiedType, userType); |
3290 | QCOMPARE(copiedType.myValue, 42); |
3291 | } |
3292 | |
3293 | void tst_QVariant::convertBoolToByteArray() const |
3294 | { |
3295 | QFETCH(QByteArray, input); |
3296 | QFETCH(bool, canConvert); |
3297 | QFETCH(bool, value); |
3298 | |
3299 | const QVariant variant(input); |
3300 | |
3301 | QCOMPARE(variant.canConvert<bool>(), canConvert); |
3302 | |
3303 | if(canConvert) { |
3304 | /* Just call this function so we run the code path. */ |
3305 | QCOMPARE(variant.toBool(), value); |
3306 | } |
3307 | } |
3308 | |
3309 | void tst_QVariant::convertBoolToByteArray_data() const |
3310 | { |
3311 | QTest::addColumn<QByteArray>(name: "input" ); |
3312 | QTest::addColumn<bool>(name: "canConvert" ); |
3313 | QTest::addColumn<bool>(name: "value" ); |
3314 | |
3315 | QTest::newRow(dataTag: "false" ) |
3316 | << QByteArray("false" ) |
3317 | << true |
3318 | << false; |
3319 | |
3320 | QTest::newRow(dataTag: "FALSE" ) |
3321 | << QByteArray("FALSE" ) |
3322 | << true |
3323 | << false; |
3324 | |
3325 | QTest::newRow(dataTag: "falSE" ) |
3326 | << QByteArray("FALSE" ) |
3327 | << true |
3328 | << false; |
3329 | |
3330 | QTest::newRow(dataTag: "" ) |
3331 | << QByteArray("" ) |
3332 | << true |
3333 | << false; |
3334 | |
3335 | QTest::newRow(dataTag: "null QByteArray" ) |
3336 | << QByteArray() |
3337 | << true |
3338 | << false; |
3339 | |
3340 | QTest::newRow(dataTag: "any-content" ) |
3341 | << QByteArray("any-content" ) |
3342 | << true |
3343 | << true; |
3344 | |
3345 | QTest::newRow(dataTag: "true" ) |
3346 | << QByteArray("true" ) |
3347 | << true |
3348 | << true; |
3349 | |
3350 | QTest::newRow(dataTag: "TRUE" ) |
3351 | << QByteArray("TRUE" ) |
3352 | << true |
3353 | << true; |
3354 | |
3355 | QTest::newRow(dataTag: "trUE" ) |
3356 | << QByteArray("trUE" ) |
3357 | << true |
3358 | << true; |
3359 | } |
3360 | |
3361 | void tst_QVariant::convertByteArrayToBool() const |
3362 | { |
3363 | QFETCH(bool, input); |
3364 | QFETCH(QByteArray, output); |
3365 | |
3366 | const QVariant variant(input); |
3367 | QCOMPARE(variant.type(), QVariant::Bool); |
3368 | QCOMPARE(variant.toBool(), input); |
3369 | QVERIFY(variant.canConvert<bool>()); |
3370 | |
3371 | QCOMPARE(variant.toByteArray(), output); |
3372 | } |
3373 | |
3374 | void tst_QVariant::convertByteArrayToBool_data() const |
3375 | { |
3376 | QTest::addColumn<bool>(name: "input" ); |
3377 | QTest::addColumn<QByteArray>(name: "output" ); |
3378 | |
3379 | QTest::newRow(dataTag: "false" ) |
3380 | << false |
3381 | << QByteArray("false" ); |
3382 | |
3383 | QTest::newRow(dataTag: "true" ) |
3384 | << true |
3385 | << QByteArray("true" ); |
3386 | } |
3387 | |
3388 | void tst_QVariant::convertIterables() const |
3389 | { |
3390 | { |
3391 | QStringList list; |
3392 | list.append(t: "Hello" ); |
3393 | QCOMPARE(QVariant::fromValue(list).value<QVariantList>().count(), list.count()); |
3394 | } |
3395 | { |
3396 | QByteArrayList list; |
3397 | list.append(t: "Hello" ); |
3398 | QCOMPARE(QVariant::fromValue(list).value<QVariantList>().count(), list.count()); |
3399 | } |
3400 | { |
3401 | QVariantList list; |
3402 | list.append(t: "World" ); |
3403 | QCOMPARE(QVariant::fromValue(list).value<QVariantList>().count(), list.count()); |
3404 | } |
3405 | { |
3406 | QMap<QString, int> map; |
3407 | map.insert(akey: "3" , avalue: 4); |
3408 | QCOMPARE(QVariant::fromValue(map).value<QVariantHash>().count(), map.count()); |
3409 | QCOMPARE(QVariant::fromValue(map).value<QVariantMap>().count(), map.count()); |
3410 | |
3411 | map.insertMulti(key: "3" , value: 5); |
3412 | QCOMPARE(QVariant::fromValue(map).value<QVariantHash>().count(), map.count()); |
3413 | QCOMPARE(QVariant::fromValue(map).value<QVariantMap>().count(), map.count()); |
3414 | } |
3415 | { |
3416 | QVariantMap map; |
3417 | map.insert(akey: "3" , avalue: 4); |
3418 | QCOMPARE(QVariant::fromValue(map).value<QVariantHash>().count(), map.count()); |
3419 | QCOMPARE(QVariant::fromValue(map).value<QVariantMap>().count(), map.count()); |
3420 | |
3421 | map.insertMulti(key: "3" , value: 5); |
3422 | QCOMPARE(QVariant::fromValue(map).value<QVariantHash>().count(), map.count()); |
3423 | QCOMPARE(QVariant::fromValue(map).value<QVariantMap>().count(), map.count()); |
3424 | } |
3425 | { |
3426 | QHash<QString, int> hash; |
3427 | hash.insert(akey: "3" , avalue: 4); |
3428 | QCOMPARE(QVariant::fromValue(hash).value<QVariantHash>().count(), hash.count()); |
3429 | QCOMPARE(QVariant::fromValue(hash).value<QVariantMap>().count(), hash.count()); |
3430 | |
3431 | hash.insertMulti(key: "3" , value: 5); |
3432 | QCOMPARE(QVariant::fromValue(hash).value<QVariantHash>().count(), hash.count()); |
3433 | QCOMPARE(QVariant::fromValue(hash).value<QVariantMap>().count(), hash.count()); |
3434 | } |
3435 | { |
3436 | QVariantHash hash; |
3437 | hash.insert(akey: "3" , avalue: 4); |
3438 | QCOMPARE(QVariant::fromValue(hash).value<QVariantHash>().count(), hash.count()); |
3439 | QCOMPARE(QVariant::fromValue(hash).value<QVariantMap>().count(), hash.count()); |
3440 | |
3441 | hash.insertMulti(key: "3" , value: 5); |
3442 | QCOMPARE(QVariant::fromValue(hash).value<QVariantHash>().count(), hash.count()); |
3443 | QCOMPARE(QVariant::fromValue(hash).value<QVariantMap>().count(), hash.count()); |
3444 | } |
3445 | } |
3446 | |
3447 | /*! |
3448 | We verify that: |
3449 | 1. Converting the string "9.9" to int fails. This is the behavior of |
3450 | toLongLong() and hence also QVariant, since it uses it. |
3451 | 2. Converting the QVariant containing the double 9.9 to int works. |
3452 | |
3453 | Rationale: "9.9" is not a valid int. However, doubles are by definition not |
3454 | ints and therefore it makes more sense to perform conversion for those. |
3455 | */ |
3456 | void tst_QVariant::toIntFromQString() const |
3457 | { |
3458 | QVariant first("9.9" ); |
3459 | bool ok; |
3460 | QCOMPARE(first.toInt(&ok), 0); |
3461 | QVERIFY(!ok); |
3462 | |
3463 | QCOMPARE(QString("9.9" ).toLongLong(&ok), qlonglong(0)); |
3464 | QVERIFY(!ok); |
3465 | |
3466 | QVariant v(9.9); |
3467 | QCOMPARE(v.toInt(&ok), 10); |
3468 | QVERIFY(ok); |
3469 | } |
3470 | |
3471 | /*! |
3472 | We verify that: |
3473 | 1. Conversion from (64 bit) double to int works (no overflow). |
3474 | 2. Same conversion works for QVariant::convert. |
3475 | |
3476 | Rationale: if 2147483630 is set in float and then converted to int, |
3477 | there will be overflow and the result will be -2147483648. |
3478 | */ |
3479 | void tst_QVariant::toIntFromDouble() const |
3480 | { |
3481 | double d = 2147483630; // max int 2147483647 |
3482 | QCOMPARE((int)d, 2147483630); |
3483 | |
3484 | QVariant var(d); |
3485 | QVERIFY( var.canConvert( QVariant::Int ) ); |
3486 | |
3487 | bool ok; |
3488 | int result = var.toInt(ok: &ok); |
3489 | |
3490 | QVERIFY( ok == true ); |
3491 | QCOMPARE(result, 2147483630); |
3492 | } |
3493 | |
3494 | void tst_QVariant::fpStringRoundtrip_data() const |
3495 | { |
3496 | QTest::addColumn<QVariant>(name: "number" ); |
3497 | |
3498 | QTest::newRow(dataTag: "float" ) << QVariant(1 + FLT_EPSILON); |
3499 | QTest::newRow(dataTag: "double" ) << QVariant(1 + DBL_EPSILON); |
3500 | } |
3501 | |
3502 | void tst_QVariant::fpStringRoundtrip() const |
3503 | { |
3504 | QFETCH(QVariant, number); |
3505 | |
3506 | QVariant converted = number; |
3507 | QVERIFY(converted.convert(QVariant::String)); |
3508 | QVERIFY(converted.convert(number.type())); |
3509 | QCOMPARE(converted, number); |
3510 | |
3511 | converted = number; |
3512 | QVERIFY(converted.convert(QVariant::ByteArray)); |
3513 | QVERIFY(converted.convert(number.type())); |
3514 | QCOMPARE(converted, number); |
3515 | } |
3516 | |
3517 | void tst_QVariant::numericalConvert_data() |
3518 | { |
3519 | QTest::addColumn<QVariant>(name: "v" ); |
3520 | QTest::addColumn<bool>(name: "isInteger" ); |
3521 | QTest::newRow(dataTag: "float" ) << QVariant(float(5.3)) << false; |
3522 | QTest::newRow(dataTag: "double" ) << QVariant(double(5.3)) << false; |
3523 | QTest::newRow(dataTag: "qreal" ) << QVariant(qreal(5.3)) << false; |
3524 | QTest::newRow(dataTag: "int" ) << QVariant(int(5)) << true; |
3525 | QTest::newRow(dataTag: "uint" ) << QVariant(uint(5)) << true; |
3526 | QTest::newRow(dataTag: "short" ) << QVariant(short(5)) << true; |
3527 | QTest::newRow(dataTag: "longlong" ) << QVariant(quint64(5)) << true; |
3528 | QTest::newRow(dataTag: "long" ) << QVariant::fromValue(value: long(5)) << true; |
3529 | QTest::newRow(dataTag: "stringint" ) << QVariant(QString::fromLatin1(str: "5" )) << true; |
3530 | QTest::newRow(dataTag: "string" ) << QVariant(QString::fromLatin1(str: "5.30000019" )) << false; |
3531 | } |
3532 | |
3533 | void tst_QVariant::numericalConvert() |
3534 | { |
3535 | QFETCH(QVariant, v); |
3536 | QFETCH(bool, isInteger); |
3537 | double num = isInteger ? 5 : 5.3; |
3538 | |
3539 | QCOMPARE(v.toFloat() , float(num)); |
3540 | QCOMPARE(float(v.toReal()) , float(num)); |
3541 | QCOMPARE(float(v.toDouble()) , float(num)); |
3542 | if (isInteger) { |
3543 | QCOMPARE(v.toInt() , int(num)); |
3544 | QCOMPARE(v.toUInt() , uint(num)); |
3545 | QCOMPARE(v.toULongLong() , quint64(num)); |
3546 | QCOMPARE(v.value<ulong>() , ulong(num)); |
3547 | QCOMPARE(v.value<ushort>() , ushort(num)); |
3548 | } |
3549 | switch (v.userType()) |
3550 | { |
3551 | case QVariant::Double: |
3552 | QCOMPARE(v.toString() , QString::number(num, 'g', QLocale::FloatingPointShortest)); |
3553 | break; |
3554 | case QMetaType::Float: |
3555 | QCOMPARE(v.toString() , |
3556 | QString::number(float(num), 'g', QLocale::FloatingPointShortest)); |
3557 | break; |
3558 | } |
3559 | } |
3560 | |
3561 | |
3562 | template<class T> void playWithVariant(const T &orig, bool isNull, const QString &toString, double toDouble, bool toBool) |
3563 | { |
3564 | QVariant v = QVariant::fromValue(orig); |
3565 | QVERIFY(v.isValid()); |
3566 | QCOMPARE(v.isNull(), isNull); |
3567 | QCOMPARE(v.toString(), toString); |
3568 | QCOMPARE(v.toDouble(), toDouble); |
3569 | QCOMPARE(v.toBool(), toBool); |
3570 | QCOMPARE(qvariant_cast<T>(v), orig); |
3571 | |
3572 | { |
3573 | QVariant v2 = v; |
3574 | if (!(QTypeInfo<T>::isStatic && QTypeInfo<T>::isComplex)) { |
3575 | // Type is movable so standard comparison algorithm in QVariant should work |
3576 | // In a custom type QVariant is not aware of ==operator so it won't be called, |
3577 | // which may cause problems especially visible when using a not-movable type |
3578 | QCOMPARE(v2, v); |
3579 | } |
3580 | QVERIFY(v2.isValid()); |
3581 | QCOMPARE(v2.isNull(), isNull); |
3582 | QCOMPARE(v2.toString(), toString); |
3583 | QCOMPARE(v2.toDouble(), toDouble); |
3584 | QCOMPARE(v2.toBool(), toBool); |
3585 | QCOMPARE(qvariant_cast<T>(v2), orig); |
3586 | |
3587 | QVariant v3; |
3588 | v = QVariant(); |
3589 | QCOMPARE(v3, v); |
3590 | v = v2; |
3591 | if (!(QTypeInfo<T>::isStatic && QTypeInfo<T>::isComplex)) { |
3592 | // Type is movable so standard comparison algorithm in QVariant should work |
3593 | // In a custom type QVariant is not aware of ==operator so it won't be called, |
3594 | // which may cause problems especially visible when using a not-movable type |
3595 | QCOMPARE(v2, v); |
3596 | } |
3597 | QCOMPARE(qvariant_cast<T>(v2), qvariant_cast<T>(v)); |
3598 | QCOMPARE(v2.toString(), toString); |
3599 | v3 = QVariant::fromValue(orig); |
3600 | |
3601 | QVERIFY(v3.isValid()); |
3602 | QCOMPARE(v3.isNull(), isNull); |
3603 | QCOMPARE(v3.toString(), toString); |
3604 | QCOMPARE(v3.toDouble(), toDouble); |
3605 | QCOMPARE(v3.toBool(), toBool); |
3606 | QCOMPARE(qvariant_cast<T>(v3), qvariant_cast<T>(v)); |
3607 | } |
3608 | |
3609 | QVERIFY(v.isValid()); |
3610 | QCOMPARE(v.isNull(), isNull); |
3611 | QCOMPARE(v.toString(), toString); |
3612 | QCOMPARE(v.toDouble(), toDouble); |
3613 | QCOMPARE(v.toBool(), toBool); |
3614 | QCOMPARE(qvariant_cast<T>(v), orig); |
3615 | |
3616 | if (qMetaTypeId<T>() != qMetaTypeId<QVariant>()) { |
3617 | QCOMPARE(v.userType(), qMetaTypeId<T>()); |
3618 | QCOMPARE(QVariant::typeToName(QVariant::Type(v.userType())), QMetaType::typeName(qMetaTypeId<T>())); |
3619 | } |
3620 | } |
3621 | |
3622 | #define PLAY_WITH_VARIANT(Orig, IsNull, ToString, ToDouble, ToBool) \ |
3623 | playWithVariant(Orig, IsNull, ToString, ToDouble, ToBool);\ |
3624 | if (QTest::currentTestFailed())\ |
3625 | QFAIL("playWithVariant failed"); |
3626 | |
3627 | struct MyPrimitive |
3628 | { |
3629 | char x, y; |
3630 | bool operator==(const MyPrimitive &o) const |
3631 | { |
3632 | return x == o.x && y == o.y; |
3633 | } |
3634 | }; |
3635 | |
3636 | QT_BEGIN_NAMESPACE |
3637 | Q_DECLARE_TYPEINFO(MyPrimitive, Q_PRIMITIVE_TYPE); |
3638 | QT_END_NAMESPACE |
3639 | |
3640 | struct MyData |
3641 | { |
3642 | void *ptr; |
3643 | MyData() : ptr(this) {} |
3644 | ~MyData() |
3645 | { |
3646 | if (ptr != this) qWarning(msg: "%s: object has moved" , Q_FUNC_INFO); |
3647 | } |
3648 | MyData(const MyData& o) : ptr(this) |
3649 | { |
3650 | if (o.ptr != &o) qWarning(msg: "%s: other object has moved" , Q_FUNC_INFO); |
3651 | } |
3652 | MyData &operator=(const MyData &o) |
3653 | { |
3654 | if (ptr != this) qWarning(msg: "%s: object has moved" , Q_FUNC_INFO); |
3655 | if (o.ptr != &o) qWarning(msg: "%s: other object has moved" , Q_FUNC_INFO); |
3656 | return *this; |
3657 | } |
3658 | bool operator==(const MyData &o) const |
3659 | { |
3660 | if (ptr != this) qWarning(msg: "%s: object has moved" , Q_FUNC_INFO); |
3661 | if (o.ptr != &o) qWarning(msg: "%s: other object has moved" , Q_FUNC_INFO); |
3662 | return true; |
3663 | } |
3664 | }; |
3665 | |
3666 | struct MyMovable |
3667 | { |
3668 | static int count; |
3669 | int v; |
3670 | MyMovable() { v = count++; } |
3671 | ~MyMovable() { count--; } |
3672 | MyMovable(const MyMovable &o) : v(o.v) { count++; } |
3673 | |
3674 | bool operator==(const MyMovable &o) const |
3675 | { |
3676 | return v == o.v; |
3677 | } |
3678 | }; |
3679 | |
3680 | int MyMovable::count = 0; |
3681 | |
3682 | struct MyNotMovable |
3683 | { |
3684 | static int count; |
3685 | MyNotMovable *that; |
3686 | MyNotMovable() : that(this) { count++; } |
3687 | ~MyNotMovable() { QCOMPARE(that, this); count--; } |
3688 | MyNotMovable(const MyNotMovable &o) : that(this) { QCOMPARE(o.that, &o); count++; } |
3689 | MyNotMovable &operator=(const MyNotMovable &o) { |
3690 | bool ok = that == this && o.that == &o; |
3691 | if (!ok) qFatal(msg: "MyNotMovable has been moved" ); |
3692 | return *this; |
3693 | } |
3694 | |
3695 | //PLAY_WITH_VARIANT test that they are equal, but never that they are not equal |
3696 | // so it would be fine just to always return true |
3697 | bool operator==(const MyNotMovable &o) const |
3698 | { |
3699 | bool ok = that == this && o.that == &o; |
3700 | if (!ok) qFatal(msg: "MyNotMovable has been moved" ); |
3701 | return ok; |
3702 | } |
3703 | }; |
3704 | |
3705 | int MyNotMovable::count = 0; |
3706 | |
3707 | struct MyShared : QSharedData { |
3708 | MyMovable movable; |
3709 | }; |
3710 | |
3711 | QT_BEGIN_NAMESPACE |
3712 | Q_DECLARE_TYPEINFO(MyMovable, Q_MOVABLE_TYPE); |
3713 | QT_END_NAMESPACE |
3714 | |
3715 | Q_DECLARE_METATYPE(MyPrimitive) |
3716 | Q_DECLARE_METATYPE(MyData) |
3717 | Q_DECLARE_METATYPE(MyMovable) |
3718 | Q_DECLARE_METATYPE(MyNotMovable) |
3719 | Q_DECLARE_METATYPE(MyPrimitive *) |
3720 | Q_DECLARE_METATYPE(MyData *) |
3721 | Q_DECLARE_METATYPE(MyMovable *) |
3722 | Q_DECLARE_METATYPE(MyNotMovable *) |
3723 | Q_DECLARE_METATYPE(QSharedDataPointer<MyShared>) |
3724 | |
3725 | void tst_QVariant::setValue() |
3726 | { |
3727 | MyNotMovable t; //we just take a value so that we're sure that it will be shared |
3728 | QVariant v1 = QVariant::fromValue(value: t); |
3729 | QVERIFY( v1.isDetached() ); |
3730 | QVariant v2 = v1; |
3731 | QVERIFY( !v1.isDetached() ); |
3732 | QVERIFY( !v2.isDetached() ); |
3733 | |
3734 | v2.setValue(3); //set an integer value |
3735 | |
3736 | QVERIFY( v1.isDetached() ); |
3737 | QVERIFY( v2.isDetached() ); |
3738 | } |
3739 | |
3740 | void tst_QVariant::moreCustomTypes() |
3741 | { |
3742 | { |
3743 | QList<QSize> listSize; |
3744 | PLAY_WITH_VARIANT(listSize, false, QString(), 0, false); |
3745 | listSize << QSize(4,5) << QSize(89,23) << QSize(5,6); |
3746 | PLAY_WITH_VARIANT(listSize, false, QString(), 0, false); |
3747 | } |
3748 | |
3749 | { |
3750 | QString str; |
3751 | PLAY_WITH_VARIANT(str, true, QString(), 0, false); |
3752 | str = QString::fromLatin1(str: "123456789.123" ); |
3753 | PLAY_WITH_VARIANT(str, false, str, 123456789.123, true); |
3754 | } |
3755 | |
3756 | { |
3757 | QSize size; |
3758 | PLAY_WITH_VARIANT(size, false, QString(), 0, false); |
3759 | PLAY_WITH_VARIANT(QSize(45,78), false, QString(), 0, false); |
3760 | } |
3761 | |
3762 | { |
3763 | MyData d; |
3764 | PLAY_WITH_VARIANT(d, false, QString(), 0, false); |
3765 | PLAY_WITH_VARIANT(&d, false, QString(), 0, false); |
3766 | QList<MyData> l; |
3767 | PLAY_WITH_VARIANT(l, false, QString(), 0, false); |
3768 | l << MyData() << MyData(); |
3769 | PLAY_WITH_VARIANT(l, false, QString(), 0, false); |
3770 | } |
3771 | |
3772 | { |
3773 | MyPrimitive d = { .x: 4, .y: 5 }; |
3774 | PLAY_WITH_VARIANT(d, false, QString(), 0, false); |
3775 | PLAY_WITH_VARIANT(&d, false, QString(), 0, false); |
3776 | QList<MyPrimitive> l; |
3777 | PLAY_WITH_VARIANT(l, false, QString(), 0, false); |
3778 | l << d; |
3779 | PLAY_WITH_VARIANT(l, false, QString(), 0, false); |
3780 | } |
3781 | |
3782 | { |
3783 | MyMovable d; |
3784 | PLAY_WITH_VARIANT(d, false, QString(), 0, false); |
3785 | PLAY_WITH_VARIANT(&d, false, QString(), 0, false); |
3786 | QList<MyMovable> l; |
3787 | PLAY_WITH_VARIANT(l, false, QString(), 0, false); |
3788 | l << MyMovable() << d; |
3789 | PLAY_WITH_VARIANT(l, false, QString(), 0, false); |
3790 | } |
3791 | QCOMPARE(MyMovable::count, 0); |
3792 | |
3793 | QCOMPARE(MyNotMovable::count, 0); |
3794 | { |
3795 | MyNotMovable d; |
3796 | PLAY_WITH_VARIANT(d, false, QString(), 0, false); |
3797 | PLAY_WITH_VARIANT(&d, false, QString(), 0, false); |
3798 | QList<MyNotMovable> l; |
3799 | PLAY_WITH_VARIANT(l, false, QString(), 0, false); |
3800 | l << MyNotMovable() << d; |
3801 | PLAY_WITH_VARIANT(l, false, QString(), 0, false); |
3802 | } |
3803 | QCOMPARE(MyNotMovable::count, 0); |
3804 | |
3805 | { |
3806 | #ifdef QT_NO_DOUBLECONVERSION |
3807 | // snprintf cannot do "shortest" conversion and always adds noise. |
3808 | PLAY_WITH_VARIANT(12.12, false, "12.119999999999999" , 12.12, true); |
3809 | #else |
3810 | // Double can be printed exactly with libdouble-conversion |
3811 | PLAY_WITH_VARIANT(12.12, false, "12.12" , 12.12, true); |
3812 | #endif |
3813 | |
3814 | // Float is converted to double, adding insignificant bits |
3815 | PLAY_WITH_VARIANT(12.12f, false, "12.119999885559082" , 12.12f, true); |
3816 | |
3817 | PLAY_WITH_VARIANT('a', false, "a" , 'a', true); |
3818 | PLAY_WITH_VARIANT((unsigned char)('a'), false, "a" , 'a', true); |
3819 | PLAY_WITH_VARIANT( quint8(12), false, "\xc" , 12, true); |
3820 | PLAY_WITH_VARIANT( qint8(13), false, "\xd" , 13, true); |
3821 | PLAY_WITH_VARIANT(quint16(14), false, "14" , 14, true); |
3822 | PLAY_WITH_VARIANT( qint16(15), false, "15" , 15, true); |
3823 | PLAY_WITH_VARIANT(quint32(16), false, "16" , 16, true); |
3824 | PLAY_WITH_VARIANT( qint32(17), false, "17" , 17, true); |
3825 | PLAY_WITH_VARIANT(quint64(18), false, "18" , 18, true); |
3826 | PLAY_WITH_VARIANT( qint64(19), false, "19" , 19, true); |
3827 | PLAY_WITH_VARIANT( qint8(-12), false, QLatin1String("\xf4" ), -12, true); // qint8 is char, so it gets converted via QChar |
3828 | PLAY_WITH_VARIANT( qint16(-13), false, "-13" , -13, true); |
3829 | PLAY_WITH_VARIANT( qint32(-14), false, "-14" , -14, true); |
3830 | PLAY_WITH_VARIANT( qint64(-15), false, "-15" , -15, true); |
3831 | PLAY_WITH_VARIANT(quint64(0), false, "0" , 0, false); |
3832 | PLAY_WITH_VARIANT( true, false, "true" , 1, true); |
3833 | PLAY_WITH_VARIANT( false, false, "false" , 0, false); |
3834 | |
3835 | PLAY_WITH_VARIANT(QString("hello\n" ), false, "hello\n" , 0, true); |
3836 | } |
3837 | |
3838 | { |
3839 | int i = 5; |
3840 | PLAY_WITH_VARIANT((void *)(&i), false, QString(), 0, false); |
3841 | PLAY_WITH_VARIANT((void *)(0), true, QString(), 0, false); |
3842 | } |
3843 | |
3844 | { |
3845 | QVariant v1 = QVariant::fromValue(value: 5); |
3846 | QVariant v2 = QVariant::fromValue(value: 5.0); |
3847 | QVariant v3 = QVariant::fromValue(value: quint16(5)); |
3848 | QVariant v4 = 5; |
3849 | QVariant v5 = QVariant::fromValue(value: MyPrimitive()); |
3850 | QVariant v6 = QVariant::fromValue(value: MyMovable()); |
3851 | QVariant v7 = QVariant::fromValue(value: MyData()); |
3852 | PLAY_WITH_VARIANT(v1, false, "5" , 5, true); |
3853 | PLAY_WITH_VARIANT(v2, false, "5" , 5, true); |
3854 | PLAY_WITH_VARIANT(v3, false, "5" , 5, true); |
3855 | PLAY_WITH_VARIANT(v4, false, "5" , 5, true); |
3856 | |
3857 | PLAY_WITH_VARIANT(v5, false, QString(), 0, false); |
3858 | } |
3859 | |
3860 | QCOMPARE(MyMovable::count, 0); |
3861 | { |
3862 | QSharedDataPointer<MyShared> d(new MyShared); |
3863 | PLAY_WITH_VARIANT(d, false, QString(), 0, false); |
3864 | } |
3865 | QCOMPARE(MyMovable::count, 0); |
3866 | |
3867 | { |
3868 | QList<QList<int> > data; |
3869 | PLAY_WITH_VARIANT(data, false, QString(), 0, false); |
3870 | data << (QList<int>() << 42); |
3871 | PLAY_WITH_VARIANT(data, false, QString(), 0, false); |
3872 | } |
3873 | |
3874 | { |
3875 | QList<QVector<int> > data; |
3876 | PLAY_WITH_VARIANT(data, false, QString(), 0, false); |
3877 | data << (QVector<int>() << 42); |
3878 | PLAY_WITH_VARIANT(data, false, QString(), 0, false); |
3879 | } |
3880 | |
3881 | { |
3882 | QList<QSet<int> > data; |
3883 | PLAY_WITH_VARIANT(data, false, QString(), 0, false); |
3884 | data << (QSet<int>() << 42); |
3885 | PLAY_WITH_VARIANT(data, false, QString(), 0, false); |
3886 | } |
3887 | |
3888 | #if QT_DEPRECATED_SINCE(5, 15) |
3889 | QT_WARNING_PUSH |
3890 | QT_WARNING_DISABLE_DEPRECATED |
3891 | { |
3892 | QList<QLinkedList<int> > data; |
3893 | PLAY_WITH_VARIANT(data, false, QString(), 0, false); |
3894 | data << (QLinkedList<int>() << 42); |
3895 | PLAY_WITH_VARIANT(data, false, QString(), 0, false); |
3896 | } |
3897 | QT_WARNING_POP |
3898 | #endif |
3899 | } |
3900 | |
3901 | void tst_QVariant::movabilityTest() |
3902 | { |
3903 | // This test checks if QVariant is movable even if an internal data is not movable. |
3904 | QVERIFY(!MyNotMovable::count); |
3905 | { |
3906 | QVariant variant = QVariant::fromValue(value: MyNotMovable()); |
3907 | QVERIFY(MyNotMovable::count); |
3908 | |
3909 | // prepare destination memory space to which variant will be moved |
3910 | QVariant buffer[1]; |
3911 | QCOMPARE(buffer[0].type(), QVariant::Invalid); |
3912 | buffer[0].~QVariant(); |
3913 | |
3914 | memcpy(dest: buffer, src: &variant, n: sizeof(QVariant)); |
3915 | QCOMPARE(buffer[0].type(), QVariant::UserType); |
3916 | QCOMPARE(buffer[0].userType(), qMetaTypeId<MyNotMovable>()); |
3917 | MyNotMovable tmp(buffer[0].value<MyNotMovable>()); |
3918 | |
3919 | new (&variant) QVariant(); |
3920 | } |
3921 | QVERIFY(!MyNotMovable::count); |
3922 | } |
3923 | |
3924 | void tst_QVariant::variantInVariant() |
3925 | { |
3926 | QVariant var1 = 5; |
3927 | QCOMPARE(var1.type(), QVariant::Int); |
3928 | QVariant var2 = var1; |
3929 | QCOMPARE(var2, var1); |
3930 | QCOMPARE(var2.type(), QVariant::Int); |
3931 | QVariant var3 = QVariant::fromValue(value: var1); |
3932 | QCOMPARE(var3, var1); |
3933 | QCOMPARE(var3.type(), QVariant::Int); |
3934 | QVariant var4 = qvariant_cast<QVariant>(v: var1); |
3935 | QCOMPARE(var4, var1); |
3936 | QCOMPARE(var4.type(), QVariant::Int); |
3937 | QVariant var5; |
3938 | var5 = var1; |
3939 | QCOMPARE(var5, var1); |
3940 | QCOMPARE(var5.type(), QVariant::Int); |
3941 | QVariant var6; |
3942 | var6.setValue(var1); |
3943 | QCOMPARE(var6, var1); |
3944 | QCOMPARE(var6.type(), QVariant::Int); |
3945 | |
3946 | QCOMPARE(QVariant::fromValue(var1), QVariant::fromValue(var2)); |
3947 | QCOMPARE(qvariant_cast<QVariant>(var3), QVariant::fromValue(var4)); |
3948 | QCOMPARE(qvariant_cast<QVariant>(var5), qvariant_cast<QVariant>(var6)); |
3949 | |
3950 | QString str("hello" ); |
3951 | QVariant var8 = qvariant_cast<QVariant>(v: QVariant::fromValue(value: QVariant::fromValue(value: str))); |
3952 | QCOMPARE((int)var8.type(), (int)QVariant::String); |
3953 | QCOMPARE(qvariant_cast<QString>(QVariant(qvariant_cast<QVariant>(var8))), str); |
3954 | |
3955 | QVariant var9(qMetaTypeId<QVariant>(), &var1); |
3956 | QCOMPARE(var9.userType(), qMetaTypeId<QVariant>()); |
3957 | QCOMPARE(qvariant_cast<QVariant>(var9), var1); |
3958 | } |
3959 | |
3960 | struct Convertible { |
3961 | double d; |
3962 | operator int() const { return (int)d; } |
3963 | operator double() const { return d; } |
3964 | operator QString() const { return QString::number(d); } |
3965 | }; |
3966 | |
3967 | Q_DECLARE_METATYPE(Convertible); |
3968 | |
3969 | struct BigConvertible { |
3970 | double d; |
3971 | double dummy; |
3972 | double dummy2; |
3973 | operator int() const { return (int)d; } |
3974 | operator double() const { return d; } |
3975 | operator QString() const { return QString::number(d); } |
3976 | }; |
3977 | |
3978 | Q_DECLARE_METATYPE(BigConvertible); |
3979 | Q_STATIC_ASSERT(sizeof(BigConvertible) > sizeof(QVariant)); |
3980 | |
3981 | void tst_QVariant::userConversion() |
3982 | { |
3983 | { |
3984 | QVERIFY(!(QMetaType::hasRegisteredConverterFunction<int, Convertible>())); |
3985 | QVERIFY(!(QMetaType::hasRegisteredConverterFunction<double, Convertible>())); |
3986 | QVERIFY(!(QMetaType::hasRegisteredConverterFunction<QString, Convertible>())); |
3987 | |
3988 | Convertible c = { .d: 123 }; |
3989 | QVariant v = QVariant::fromValue(value: c); |
3990 | |
3991 | bool ok; |
3992 | v.toInt(ok: &ok); |
3993 | QVERIFY(!ok); |
3994 | |
3995 | v.toDouble(ok: &ok); |
3996 | QVERIFY(!ok); |
3997 | |
3998 | QString s = v.toString(); |
3999 | QVERIFY(s.isEmpty()); |
4000 | |
4001 | QMetaType::registerConverter<Convertible, int>(); |
4002 | QMetaType::registerConverter<Convertible, double>(); |
4003 | QMetaType::registerConverter<Convertible, QString>(); |
4004 | |
4005 | int i = v.toInt(ok: &ok); |
4006 | QVERIFY(ok); |
4007 | QCOMPARE(i, 123); |
4008 | |
4009 | double d = v.toDouble(ok: &ok); |
4010 | QVERIFY(ok); |
4011 | QCOMPARE(d, 123.); |
4012 | |
4013 | s = v.toString(); |
4014 | QCOMPARE(s, QString::fromLatin1("123" )); |
4015 | } |
4016 | |
4017 | { |
4018 | QVERIFY(!(QMetaType::hasRegisteredConverterFunction<int, BigConvertible>())); |
4019 | QVERIFY(!(QMetaType::hasRegisteredConverterFunction<double, BigConvertible>())); |
4020 | QVERIFY(!(QMetaType::hasRegisteredConverterFunction<QString, BigConvertible>())); |
4021 | |
4022 | BigConvertible c = { .d: 123, .dummy: 0, .dummy2: 0 }; |
4023 | QVariant v = QVariant::fromValue(value: c); |
4024 | |
4025 | bool ok; |
4026 | v.toInt(ok: &ok); |
4027 | QVERIFY(!ok); |
4028 | |
4029 | v.toDouble(ok: &ok); |
4030 | QVERIFY(!ok); |
4031 | |
4032 | QString s = v.toString(); |
4033 | QVERIFY(s.isEmpty()); |
4034 | |
4035 | QMetaType::registerConverter<BigConvertible, int>(); |
4036 | QMetaType::registerConverter<BigConvertible, double>(); |
4037 | QMetaType::registerConverter<BigConvertible, QString>(); |
4038 | |
4039 | int i = v.toInt(ok: &ok); |
4040 | QVERIFY(ok); |
4041 | QCOMPARE(i, 123); |
4042 | |
4043 | double d = v.toDouble(ok: &ok); |
4044 | QVERIFY(ok); |
4045 | QCOMPARE(d, 123.); |
4046 | |
4047 | s = v.toString(); |
4048 | QCOMPARE(s, QString::fromLatin1("123" )); |
4049 | } |
4050 | } |
4051 | |
4052 | void tst_QVariant::modelIndexConversion() |
4053 | { |
4054 | QVariant modelIndexVariant = QModelIndex(); |
4055 | QVERIFY(modelIndexVariant.canConvert(QMetaType::QPersistentModelIndex)); |
4056 | QVERIFY(modelIndexVariant.convert(QMetaType::QPersistentModelIndex)); |
4057 | QCOMPARE(modelIndexVariant.type(), QVariant::PersistentModelIndex); |
4058 | QVERIFY(modelIndexVariant.canConvert(QMetaType::QModelIndex)); |
4059 | QVERIFY(modelIndexVariant.convert(QMetaType::QModelIndex)); |
4060 | QCOMPARE(modelIndexVariant.type(), QVariant::ModelIndex); |
4061 | } |
4062 | |
4063 | class Forward; |
4064 | Q_DECLARE_OPAQUE_POINTER(Forward*) |
4065 | Q_DECLARE_METATYPE(Forward*) |
4066 | |
4067 | void tst_QVariant::forwardDeclare() |
4068 | { |
4069 | Forward *f = 0; |
4070 | QVariant v = QVariant::fromValue(value: f); |
4071 | QCOMPARE(qvariant_cast<Forward*>(v), f); |
4072 | } |
4073 | |
4074 | void tst_QVariant::loadQt5Stream_data() |
4075 | { |
4076 | dataStream_data(version: QDataStream::Qt_5_0); |
4077 | } |
4078 | |
4079 | void tst_QVariant::loadQt5Stream() |
4080 | { |
4081 | loadQVariantFromDataStream(version: QDataStream::Qt_5_0); |
4082 | } |
4083 | |
4084 | void tst_QVariant::saveQt5Stream_data() |
4085 | { |
4086 | dataStream_data(version: QDataStream::Qt_5_0); |
4087 | } |
4088 | |
4089 | void tst_QVariant::saveQt5Stream() |
4090 | { |
4091 | saveQVariantFromDataStream(version: QDataStream::Qt_5_0); |
4092 | } |
4093 | |
4094 | void tst_QVariant::loadQt4Stream_data() |
4095 | { |
4096 | dataStream_data(version: QDataStream::Qt_4_9); |
4097 | } |
4098 | |
4099 | void tst_QVariant::loadQt4Stream() |
4100 | { |
4101 | loadQVariantFromDataStream(version: QDataStream::Qt_4_9); |
4102 | } |
4103 | |
4104 | void tst_QVariant::saveQt4Stream_data() |
4105 | { |
4106 | dataStream_data(version: QDataStream::Qt_4_9); |
4107 | } |
4108 | |
4109 | void tst_QVariant::saveQt4Stream() |
4110 | { |
4111 | saveQVariantFromDataStream(version: QDataStream::Qt_4_9); |
4112 | } |
4113 | |
4114 | void tst_QVariant::dataStream_data(QDataStream::Version version) |
4115 | { |
4116 | QTest::addColumn<QString>(name: "fileName" ); |
4117 | |
4118 | QString path; |
4119 | switch (version) { |
4120 | case QDataStream::Qt_4_9: |
4121 | path = QString::fromLatin1(str: "qt4.9" ); |
4122 | break; |
4123 | case QDataStream::Qt_5_0: |
4124 | path = QString::fromLatin1(str: "qt5.0" ); |
4125 | break; |
4126 | default: |
4127 | Q_UNIMPLEMENTED(); |
4128 | } |
4129 | |
4130 | path = path.prepend(s: ":/stream/" ).append(s: "/" ); |
4131 | QDir dir(path); |
4132 | uint i = 0; |
4133 | foreach (const QFileInfo &fileInfo, dir.entryInfoList(QStringList() << "*.bin" )) { |
4134 | QTest::newRow(dataTag: (path + fileInfo.fileName()).toLatin1()) << fileInfo.filePath(); |
4135 | i += 1; |
4136 | } |
4137 | QVERIFY(i > 10); |
4138 | } |
4139 | |
4140 | void tst_QVariant::loadQVariantFromDataStream(QDataStream::Version version) |
4141 | { |
4142 | QFETCH(QString, fileName); |
4143 | |
4144 | QFile file(fileName); |
4145 | QVERIFY(file.open(QIODevice::ReadOnly)); |
4146 | |
4147 | QDataStream stream(&file); |
4148 | stream.setVersion(version); |
4149 | |
4150 | QString typeName; |
4151 | QVariant loadedVariant; |
4152 | stream >> typeName >> loadedVariant; |
4153 | |
4154 | const int id = QMetaType::type(typeName: typeName.toLatin1()); |
4155 | if (id == QMetaType::Void) { |
4156 | // Void type is not supported by QVariant |
4157 | return; |
4158 | } |
4159 | |
4160 | QVariant constructedVariant(static_cast<QVariant::Type>(id)); |
4161 | QCOMPARE(constructedVariant.userType(), id); |
4162 | QCOMPARE(QMetaType::typeName(loadedVariant.userType()), typeName.toLatin1().constData()); |
4163 | QCOMPARE(loadedVariant.userType(), constructedVariant.userType()); |
4164 | } |
4165 | |
4166 | void tst_QVariant::saveQVariantFromDataStream(QDataStream::Version version) |
4167 | { |
4168 | QFETCH(QString, fileName); |
4169 | |
4170 | QFile file(fileName); |
4171 | QVERIFY(file.open(QIODevice::ReadOnly)); |
4172 | QDataStream dataFileStream(&file); |
4173 | |
4174 | QString typeName; |
4175 | dataFileStream >> typeName; |
4176 | QByteArray data = file.readAll(); |
4177 | const int id = QMetaType::type(typeName: typeName.toLatin1()); |
4178 | if (id == QMetaType::Void) { |
4179 | // Void type is not supported by QVariant |
4180 | return; |
4181 | } |
4182 | |
4183 | QBuffer buffer; |
4184 | buffer.open(openMode: QIODevice::ReadWrite); |
4185 | QDataStream stream(&buffer); |
4186 | stream.setVersion(version); |
4187 | |
4188 | QVariant constructedVariant(static_cast<QVariant::Type>(id)); |
4189 | QCOMPARE(constructedVariant.userType(), id); |
4190 | stream << constructedVariant; |
4191 | |
4192 | // We are testing QVariant there is no point in testing full array. |
4193 | QCOMPARE(buffer.data().left(5), data.left(5)); |
4194 | |
4195 | buffer.seek(off: 0); |
4196 | QVariant recunstructedVariant; |
4197 | stream >> recunstructedVariant; |
4198 | QCOMPARE(recunstructedVariant.userType(), constructedVariant.userType()); |
4199 | } |
4200 | |
4201 | void tst_QVariant::debugStream_data() |
4202 | { |
4203 | QTest::addColumn<QVariant>(name: "variant" ); |
4204 | QTest::addColumn<int>(name: "typeId" ); |
4205 | for (int id = 0; id < QMetaType::LastCoreType + 1; ++id) { |
4206 | const char *tagName = QMetaType::typeName(type: id); |
4207 | if (!tagName) |
4208 | continue; |
4209 | if (id != QMetaType::Void) { |
4210 | QTest::newRow(dataTag: tagName) << QVariant(static_cast<QVariant::Type>(id)) << id; |
4211 | } |
4212 | } |
4213 | QTest::newRow(dataTag: "QBitArray(111)" ) << QVariant(QBitArray(3, true)) << qMetaTypeId<QBitArray>(); |
4214 | QTest::newRow(dataTag: "CustomStreamableClass" ) << QVariant(qMetaTypeId<CustomStreamableClass>(), 0) << qMetaTypeId<CustomStreamableClass>(); |
4215 | QTest::newRow(dataTag: "MyClass" ) << QVariant(qMetaTypeId<MyClass>(), 0) << qMetaTypeId<MyClass>(); |
4216 | QTest::newRow(dataTag: "InvalidVariant" ) << QVariant() << int(QMetaType::UnknownType); |
4217 | QTest::newRow(dataTag: "CustomQObject" ) << QVariant::fromValue(value: this) << qMetaTypeId<tst_QVariant*>(); |
4218 | } |
4219 | |
4220 | void tst_QVariant::debugStream() |
4221 | { |
4222 | QFETCH(QVariant, variant); |
4223 | QFETCH(int, typeId); |
4224 | |
4225 | MessageHandler msgHandler(typeId); |
4226 | qDebug() << variant; |
4227 | QVERIFY(msgHandler.testPassed()); |
4228 | } |
4229 | |
4230 | struct MessageHandlerType : public MessageHandler |
4231 | { |
4232 | MessageHandlerType(const int typeId) |
4233 | : MessageHandler(typeId, handler) |
4234 | {} |
4235 | static void handler(QtMsgType, const QMessageLogContext &, const QString &msg) |
4236 | { |
4237 | // Format itself is not important, but basic data as a type name should be included in the output |
4238 | ok = msg.startsWith(s: "QVariant::" ); |
4239 | QVERIFY2(ok, (QString::fromLatin1("Message is not started correctly: '" ) + msg + '\'').toLatin1().constData()); |
4240 | ok &= (currentId == QMetaType::UnknownType |
4241 | ? msg.contains(s: "Invalid" ) |
4242 | : msg.contains(s: QMetaType::typeName(type: currentId))); |
4243 | QVERIFY2(ok, (QString::fromLatin1("Message doesn't contain type name: '" ) + msg + '\'').toLatin1().constData()); |
4244 | } |
4245 | }; |
4246 | |
4247 | void tst_QVariant::debugStreamType_data() |
4248 | { |
4249 | debugStream_data(); |
4250 | } |
4251 | |
4252 | void tst_QVariant::debugStreamType() |
4253 | { |
4254 | QFETCH(QVariant, variant); |
4255 | QFETCH(int, typeId); |
4256 | |
4257 | MessageHandlerType msgHandler(typeId); |
4258 | qDebug() << QVariant::Type(typeId); |
4259 | QVERIFY(msgHandler.testPassed()); |
4260 | } |
4261 | |
4262 | void tst_QVariant::implicitConstruction() |
4263 | { |
4264 | // This is a compile-time test |
4265 | QVariant v; |
4266 | |
4267 | #define FOR_EACH_CORE_CLASS(F) \ |
4268 | F(Char) \ |
4269 | F(String) \ |
4270 | F(StringList) \ |
4271 | F(ByteArray) \ |
4272 | F(BitArray) \ |
4273 | F(Date) \ |
4274 | F(Time) \ |
4275 | F(DateTime) \ |
4276 | F(Url) \ |
4277 | F(Locale) \ |
4278 | F(Rect) \ |
4279 | F(RectF) \ |
4280 | F(Size) \ |
4281 | F(SizeF) \ |
4282 | F(Line) \ |
4283 | F(LineF) \ |
4284 | F(Point) \ |
4285 | F(PointF) \ |
4286 | F(RegExp) \ |
4287 | F(EasingCurve) \ |
4288 | F(Uuid) \ |
4289 | F(ModelIndex) \ |
4290 | F(PersistentModelIndex) \ |
4291 | F(RegularExpression) \ |
4292 | F(JsonValue) \ |
4293 | F(JsonObject) \ |
4294 | F(JsonArray) \ |
4295 | F(JsonDocument) \ |
4296 | |
4297 | #define CONSTRUCT(TYPE) \ |
4298 | { \ |
4299 | Q##TYPE t; \ |
4300 | v = t; \ |
4301 | t = v.to##TYPE(); \ |
4302 | QVERIFY(true); \ |
4303 | } |
4304 | |
4305 | FOR_EACH_CORE_CLASS(CONSTRUCT) |
4306 | |
4307 | #undef CONSTRUCT |
4308 | #undef FOR_EACH_CORE_CLASS |
4309 | } |
4310 | |
4311 | void tst_QVariant::saveInvalid_data() |
4312 | { |
4313 | QTest::addColumn<unsigned>(name: "version" ); |
4314 | for (unsigned version = QDataStream::Qt_5_0; version > QDataStream::Qt_1_0; --version) |
4315 | QTest::newRow(dataTag: QString::number(version).toUtf8()) << version; |
4316 | } |
4317 | |
4318 | void tst_QVariant::saveInvalid() |
4319 | { |
4320 | QFETCH(unsigned, version); |
4321 | |
4322 | QByteArray data; |
4323 | QDataStream stream(&data, QIODevice::WriteOnly); |
4324 | stream.setVersion(version); |
4325 | stream << QVariant(); |
4326 | QCOMPARE(stream.status(), QDataStream::Ok); |
4327 | QVERIFY(data.size() >= 4); |
4328 | QCOMPARE(int(data.constData()[0]), 0); |
4329 | QCOMPARE(int(data.constData()[1]), 0); |
4330 | QCOMPARE(int(data.constData()[2]), 0); |
4331 | QCOMPARE(int(data.constData()[3]), 0); |
4332 | } |
4333 | |
4334 | void tst_QVariant::saveNewBuiltinWithOldStream() |
4335 | { |
4336 | QByteArray data; |
4337 | QDataStream stream(&data, QIODevice::WriteOnly); |
4338 | stream.setVersion(QDataStream::Qt_3_1); |
4339 | stream << QVariant::fromValue<QJsonValue>(value: 123); // QJsonValue class was introduced in Qt5 |
4340 | QCOMPARE(stream.status(), QDataStream::Ok); |
4341 | QVERIFY(data.size() >= 4); |
4342 | QCOMPARE(int(data.constData()[0]), 0); |
4343 | QCOMPARE(int(data.constData()[1]), 0); |
4344 | QCOMPARE(int(data.constData()[2]), 0); |
4345 | QCOMPARE(int(data.constData()[3]), 0); |
4346 | } |
4347 | |
4348 | template<typename Container, typename Value_Type = typename Container::value_type> |
4349 | struct ContainerAPI |
4350 | { |
4351 | static void insert(Container &container, typename Container::value_type value) |
4352 | { |
4353 | container.push_back(value); |
4354 | } |
4355 | |
4356 | static bool compare(const QVariant &variant, typename Container::value_type value) |
4357 | { |
4358 | return variant.value<typename Container::value_type>() == value; |
4359 | } |
4360 | static bool compare(QVariant variant, const QVariant &value) |
4361 | { |
4362 | return variant == value; |
4363 | } |
4364 | }; |
4365 | |
4366 | template<typename Container> |
4367 | struct ContainerAPI<Container, QVariant> |
4368 | { |
4369 | static void insert(Container &container, int value) |
4370 | { |
4371 | container.push_back(QVariant::fromValue(value)); |
4372 | } |
4373 | |
4374 | static bool compare(QVariant variant, const QVariant &value) |
4375 | { |
4376 | return variant == value; |
4377 | } |
4378 | }; |
4379 | |
4380 | template<typename Container> |
4381 | struct ContainerAPI<Container, QString> |
4382 | { |
4383 | static void insert(Container &container, int value) |
4384 | { |
4385 | container.push_back(QString::number(value)); |
4386 | } |
4387 | |
4388 | static bool compare(const QVariant &variant, QString value) |
4389 | { |
4390 | return variant.value<QString>() == value; |
4391 | } |
4392 | static bool compare(QVariant variant, const QVariant &value) |
4393 | { |
4394 | return variant == value; |
4395 | } |
4396 | }; |
4397 | |
4398 | template<typename Container> |
4399 | struct ContainerAPI<Container, QByteArray> |
4400 | { |
4401 | static void insert(Container &container, int value) |
4402 | { |
4403 | container.push_back(QByteArray::number(value)); |
4404 | } |
4405 | |
4406 | static bool compare(const QVariant &variant, QByteArray value) |
4407 | { |
4408 | return variant.value<QByteArray>() == value; |
4409 | } |
4410 | static bool compare(QVariant variant, const QVariant &value) |
4411 | { |
4412 | return variant == value; |
4413 | } |
4414 | }; |
4415 | |
4416 | #ifdef __has_include |
4417 | # if __has_include(<forward_list>) |
4418 | # define TEST_FORWARD_LIST |
4419 | # include <forward_list> |
4420 | |
4421 | Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::forward_list) |
4422 | |
4423 | // Test that explicit declaration does not degrade features. |
4424 | Q_DECLARE_METATYPE(std::forward_list<int>) |
4425 | |
4426 | template<typename Value_Type> |
4427 | struct ContainerAPI<std::forward_list<Value_Type> > |
4428 | { |
4429 | static void insert(std::forward_list<Value_Type> &container, Value_Type value) |
4430 | { |
4431 | container.push_front(value); |
4432 | } |
4433 | static bool compare(const QVariant &variant, Value_Type value) |
4434 | { |
4435 | return variant.value<Value_Type>() == value; |
4436 | } |
4437 | static bool compare(QVariant variant, const QVariant &value) |
4438 | { |
4439 | return variant == value; |
4440 | } |
4441 | }; |
4442 | |
4443 | template<> |
4444 | struct ContainerAPI<std::forward_list<QVariant> > |
4445 | { |
4446 | static void insert(std::forward_list<QVariant> &container, int value) |
4447 | { |
4448 | container.push_front(val: QVariant::fromValue(value)); |
4449 | } |
4450 | |
4451 | static bool compare(QVariant variant, const QVariant &value) |
4452 | { |
4453 | return variant == value; |
4454 | } |
4455 | }; |
4456 | |
4457 | template<> |
4458 | struct ContainerAPI<std::forward_list<QString> > |
4459 | { |
4460 | static void insert(std::forward_list<QString> &container, int value) |
4461 | { |
4462 | container.push_front(val: QString::number(value)); |
4463 | } |
4464 | static bool compare(const QVariant &variant, QString value) |
4465 | { |
4466 | return variant.value<QString>() == value; |
4467 | } |
4468 | static bool compare(QVariant variant, const QVariant &value) |
4469 | { |
4470 | return variant == value; |
4471 | } |
4472 | }; |
4473 | # endif // __has_include(<forward_list>) |
4474 | #endif // __has_include |
4475 | |
4476 | template<typename Container> |
4477 | struct KeyGetter |
4478 | { |
4479 | static const typename Container::key_type & get(const typename Container::const_iterator &it) |
4480 | { |
4481 | return it.key(); |
4482 | } |
4483 | static const typename Container::mapped_type & value(const typename Container::const_iterator &it) |
4484 | { |
4485 | return it.value(); |
4486 | } |
4487 | }; |
4488 | |
4489 | template<typename T, typename U> |
4490 | struct KeyGetter<std::map<T, U> > |
4491 | { |
4492 | static const T & get(const typename std::map<T, U>::const_iterator &it) |
4493 | { |
4494 | return it->first; |
4495 | } |
4496 | static const U & value(const typename std::map<T, U>::const_iterator &it) |
4497 | { |
4498 | return it->second; |
4499 | } |
4500 | }; |
4501 | |
4502 | |
4503 | // We have no built-in defines to check the stdlib features. |
4504 | // #define TEST_UNORDERED_MAP |
4505 | |
4506 | #ifdef TEST_UNORDERED_MAP |
4507 | #include <unordered_map> |
4508 | typedef std::unordered_map<int, bool> StdUnorderedMap_int_bool; |
4509 | |
4510 | Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::unordered_map) |
4511 | |
4512 | Q_DECLARE_METATYPE(StdUnorderedMap_int_bool) |
4513 | |
4514 | template<typename T, typename U> |
4515 | struct KeyGetter<std::unordered_map<T, U> > |
4516 | { |
4517 | static const T & get(const typename std::unordered_map<T, U>::const_iterator &it) |
4518 | { |
4519 | return it->first; |
4520 | } |
4521 | static const U & value(const typename std::unordered_map<T, U>::const_iterator &it) |
4522 | { |
4523 | return it->second; |
4524 | } |
4525 | }; |
4526 | #endif |
4527 | |
4528 | void tst_QVariant::iterateContainerElements() |
4529 | { |
4530 | #ifdef Q_COMPILER_RANGE_FOR |
4531 | |
4532 | #define TEST_RANGE_FOR(CONTAINER) \ |
4533 | numSeen = 0; \ |
4534 | containerIter = intList.begin(); \ |
4535 | for (QVariant v : listIter) { \ |
4536 | QVERIFY(ContainerAPI<CONTAINER >::compare(v, *containerIter)); \ |
4537 | QVERIFY(ContainerAPI<CONTAINER >::compare(v, varList.at(numSeen))); \ |
4538 | ++containerIter; \ |
4539 | ++numSeen; \ |
4540 | } \ |
4541 | QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); |
4542 | |
4543 | #else |
4544 | |
4545 | #define TEST_RANGE_FOR(CONTAINER) |
4546 | |
4547 | #endif |
4548 | |
4549 | #define TEST_SEQUENTIAL_ITERATION_ON_FULL_NAME(CONTAINER) \ |
4550 | { \ |
4551 | int numSeen = 0; \ |
4552 | CONTAINER intList; \ |
4553 | ContainerAPI<CONTAINER >::insert(intList, 1); \ |
4554 | ContainerAPI<CONTAINER >::insert(intList, 2); \ |
4555 | ContainerAPI<CONTAINER >::insert(intList, 3); \ |
4556 | \ |
4557 | QVariant listVariant = QVariant::fromValue(intList); \ |
4558 | QVERIFY(listVariant.canConvert<QVariantList>()); \ |
4559 | QVariantList varList = listVariant.value<QVariantList>(); \ |
4560 | QCOMPARE(varList.size(), (int)std::distance(intList.begin(), intList.end())); \ |
4561 | QSequentialIterable listIter = listVariant.value<QSequentialIterable>(); \ |
4562 | QCOMPARE(varList.size(), listIter.size()); \ |
4563 | \ |
4564 | CONTAINER::iterator containerIter = intList.begin(); \ |
4565 | const CONTAINER::iterator containerEnd = intList.end(); \ |
4566 | for (int i = 0; i < listIter.size(); ++i, ++containerIter, ++numSeen) \ |
4567 | { \ |
4568 | QVERIFY(ContainerAPI<CONTAINER >::compare(listIter.at(i), *containerIter)); \ |
4569 | QVERIFY(ContainerAPI<CONTAINER >::compare(listIter.at(i), varList.at(i))); \ |
4570 | } \ |
4571 | QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); \ |
4572 | QCOMPARE(containerIter, containerEnd); \ |
4573 | \ |
4574 | containerIter = intList.begin(); \ |
4575 | numSeen = 0; \ |
4576 | Q_FOREACH (const QVariant &v, listIter) { \ |
4577 | QVERIFY(ContainerAPI<CONTAINER >::compare(v, *containerIter)); \ |
4578 | QVERIFY(ContainerAPI<CONTAINER >::compare(v, varList.at(numSeen))); \ |
4579 | ++containerIter; \ |
4580 | ++numSeen; \ |
4581 | } \ |
4582 | QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); \ |
4583 | TEST_RANGE_FOR(CONTAINER) \ |
4584 | } |
4585 | |
4586 | #define TEST_SEQUENTIAL_ITERATION(CONTAINER, VALUE_TYPE) \ |
4587 | TEST_SEQUENTIAL_ITERATION_ON_FULL_NAME(CONTAINER<VALUE_TYPE > ) |
4588 | |
4589 | |
4590 | TEST_SEQUENTIAL_ITERATION(QVector, int) |
4591 | TEST_SEQUENTIAL_ITERATION(QVector, QVariant) |
4592 | TEST_SEQUENTIAL_ITERATION(QVector, QString) |
4593 | TEST_SEQUENTIAL_ITERATION(QQueue, int) |
4594 | TEST_SEQUENTIAL_ITERATION(QQueue, QVariant) |
4595 | TEST_SEQUENTIAL_ITERATION(QQueue, QString) |
4596 | TEST_SEQUENTIAL_ITERATION(QList, int) |
4597 | TEST_SEQUENTIAL_ITERATION(QList, QVariant) |
4598 | TEST_SEQUENTIAL_ITERATION(QList, QString) |
4599 | TEST_SEQUENTIAL_ITERATION(QList, QByteArray) |
4600 | TEST_SEQUENTIAL_ITERATION(QStack, int) |
4601 | TEST_SEQUENTIAL_ITERATION(QStack, QVariant) |
4602 | TEST_SEQUENTIAL_ITERATION(QStack, QString) |
4603 | TEST_SEQUENTIAL_ITERATION(std::vector, int) |
4604 | TEST_SEQUENTIAL_ITERATION(std::vector, QVariant) |
4605 | TEST_SEQUENTIAL_ITERATION(std::vector, QString) |
4606 | TEST_SEQUENTIAL_ITERATION(std::list, int) |
4607 | TEST_SEQUENTIAL_ITERATION(std::list, QVariant) |
4608 | TEST_SEQUENTIAL_ITERATION(std::list, QString) |
4609 | TEST_SEQUENTIAL_ITERATION_ON_FULL_NAME(QStringList) |
4610 | TEST_SEQUENTIAL_ITERATION_ON_FULL_NAME(QByteArrayList) |
4611 | |
4612 | #ifdef TEST_FORWARD_LIST |
4613 | TEST_SEQUENTIAL_ITERATION(std::forward_list, int) |
4614 | TEST_SEQUENTIAL_ITERATION(std::forward_list, QVariant) |
4615 | TEST_SEQUENTIAL_ITERATION(std::forward_list, QString) |
4616 | #endif |
4617 | |
4618 | { |
4619 | QVariantList ints; |
4620 | ints << 1 << 2 << 3; |
4621 | QVariant var = QVariant::fromValue(value: ints); |
4622 | QSequentialIterable iter = var.value<QSequentialIterable>(); |
4623 | QSequentialIterable::const_iterator it = iter.begin(); |
4624 | QSequentialIterable::const_iterator end = iter.end(); |
4625 | QCOMPARE(ints.at(1), *(it + 1)); |
4626 | int i = 0; |
4627 | for ( ; it != end; ++it, ++i) { |
4628 | QCOMPARE(ints.at(i), *it); |
4629 | } |
4630 | |
4631 | it = iter.begin(); |
4632 | |
4633 | QVariantList intsCopy; |
4634 | intsCopy << *(it++); |
4635 | intsCopy << *(it++); |
4636 | intsCopy << *(it++); |
4637 | QCOMPARE(ints, intsCopy); |
4638 | } |
4639 | |
4640 | #define TEST_ASSOCIATIVE_ITERATION(CONTAINER, KEY_TYPE, MAPPED_TYPE) \ |
4641 | { \ |
4642 | int numSeen = 0; \ |
4643 | CONTAINER<KEY_TYPE, MAPPED_TYPE> mapping; \ |
4644 | mapping[5] = true; \ |
4645 | mapping[15] = false; \ |
4646 | \ |
4647 | QVariant mappingVariant = QVariant::fromValue(mapping); \ |
4648 | QVariantMap varMap = mappingVariant.value<QVariantMap>(); \ |
4649 | QVariantMap varHash = mappingVariant.value<QVariantMap>(); \ |
4650 | QAssociativeIterable mappingIter = mappingVariant.value<QAssociativeIterable>(); \ |
4651 | \ |
4652 | CONTAINER<KEY_TYPE, MAPPED_TYPE>::const_iterator containerIter = mapping.begin(); \ |
4653 | const CONTAINER<KEY_TYPE, MAPPED_TYPE>::const_iterator containerEnd = mapping.end(); \ |
4654 | for ( ; containerIter != containerEnd; ++containerIter, ++numSeen) \ |
4655 | { \ |
4656 | MAPPED_TYPE expected = KeyGetter<CONTAINER<KEY_TYPE, MAPPED_TYPE> >::value(containerIter); \ |
4657 | KEY_TYPE key = KeyGetter<CONTAINER<KEY_TYPE, MAPPED_TYPE> >::get(containerIter); \ |
4658 | MAPPED_TYPE actual = mappingIter.value(key).value<MAPPED_TYPE >(); \ |
4659 | QCOMPARE(varMap.value(QString::number(key)).value<MAPPED_TYPE>(), expected); \ |
4660 | QCOMPARE(varHash.value(QString::number(key)).value<MAPPED_TYPE>(), expected); \ |
4661 | QCOMPARE(actual, expected); \ |
4662 | const QAssociativeIterable::const_iterator it = mappingIter.find(key); \ |
4663 | QVERIFY(it != mappingIter.end()); \ |
4664 | QCOMPARE(it.value().value<MAPPED_TYPE>(), expected); \ |
4665 | } \ |
4666 | QCOMPARE(numSeen, (int)std::distance(mapping.begin(), mapping.end())); \ |
4667 | QCOMPARE(containerIter, containerEnd); \ |
4668 | QVERIFY(mappingIter.find(10) == mappingIter.end()); \ |
4669 | } |
4670 | |
4671 | TEST_ASSOCIATIVE_ITERATION(QHash, int, bool) |
4672 | TEST_ASSOCIATIVE_ITERATION(QMap, int, bool) |
4673 | TEST_ASSOCIATIVE_ITERATION(std::map, int, bool) |
4674 | #ifdef TEST_UNORDERED_MAP |
4675 | TEST_ASSOCIATIVE_ITERATION(std::unordered_map, int, bool) |
4676 | #endif |
4677 | |
4678 | { |
4679 | QMap<int, QString> mapping; |
4680 | mapping.insert(akey: 1, avalue: "one" ); |
4681 | mapping.insert(akey: 2, avalue: "two" ); |
4682 | mapping.insert(akey: 3, avalue: "three" ); |
4683 | QVariant var = QVariant::fromValue(value: mapping); |
4684 | QAssociativeIterable iter = var.value<QAssociativeIterable>(); |
4685 | QAssociativeIterable::const_iterator it = iter.begin(); |
4686 | QAssociativeIterable::const_iterator end = iter.end(); |
4687 | QCOMPARE(*(mapping.begin() + 1), (*(it + 1)).toString()); |
4688 | int i = 0; |
4689 | for ( ; it != end; ++it, ++i) { |
4690 | QCOMPARE(*(mapping.begin() + i), (*it).toString()); |
4691 | } |
4692 | |
4693 | QVariantList nums; |
4694 | nums << "one" << "two" << "three" ; |
4695 | |
4696 | it = iter.begin(); |
4697 | |
4698 | QVariantList numsCopy; |
4699 | numsCopy << *(it++); |
4700 | numsCopy << *(it++); |
4701 | numsCopy << *(it++); |
4702 | QCOMPARE(nums, numsCopy); |
4703 | } |
4704 | } |
4705 | |
4706 | void tst_QVariant::pairElements() |
4707 | { |
4708 | typedef QPair<QVariant, QVariant> QVariantPair; |
4709 | |
4710 | #define TEST_PAIR_ELEMENT_ACCESS(PAIR, T1, T2, VALUE1, VALUE2) \ |
4711 | { \ |
4712 | PAIR<T1, T2> p(VALUE1, VALUE2); \ |
4713 | QVariant v = QVariant::fromValue(p); \ |
4714 | \ |
4715 | QVERIFY(v.canConvert<QVariantPair>()); \ |
4716 | QVariantPair pi = v.value<QVariantPair>(); \ |
4717 | QCOMPARE(pi.first, QVariant::fromValue(VALUE1)); \ |
4718 | QCOMPARE(pi.second, QVariant::fromValue(VALUE2)); \ |
4719 | } |
4720 | |
4721 | TEST_PAIR_ELEMENT_ACCESS(QPair, int, int, 4, 5) |
4722 | TEST_PAIR_ELEMENT_ACCESS(std::pair, int, int, 4, 5) |
4723 | TEST_PAIR_ELEMENT_ACCESS(QPair, QString, QString, QStringLiteral("one" ), QStringLiteral("two" )) |
4724 | TEST_PAIR_ELEMENT_ACCESS(std::pair, QString, QString, QStringLiteral("one" ), QStringLiteral("two" )) |
4725 | TEST_PAIR_ELEMENT_ACCESS(QPair, QVariant, QVariant, 4, 5) |
4726 | TEST_PAIR_ELEMENT_ACCESS(std::pair, QVariant, QVariant, 4, 5) |
4727 | TEST_PAIR_ELEMENT_ACCESS(QPair, QVariant, int, 41, 15) |
4728 | TEST_PAIR_ELEMENT_ACCESS(std::pair, QVariant, int, 34, 65) |
4729 | TEST_PAIR_ELEMENT_ACCESS(QPair, int, QVariant, 24, 25) |
4730 | TEST_PAIR_ELEMENT_ACCESS(std::pair, int, QVariant, 44, 15) |
4731 | } |
4732 | |
4733 | enum EnumTest_Enum0 { EnumTest_Enum0_value = 42, EnumTest_Enum0_negValue = -8 }; |
4734 | Q_DECLARE_METATYPE(EnumTest_Enum0) |
4735 | enum EnumTest_Enum1 : qint64 { EnumTest_Enum1_value = 42, EnumTest_Enum1_bigValue = (Q_INT64_C(1) << 33) + 50 }; |
4736 | Q_DECLARE_METATYPE(EnumTest_Enum1) |
4737 | |
4738 | enum EnumTest_Enum3 : qint64 { EnumTest_Enum3_value = -47, EnumTest_Enum3_bigValue = (Q_INT64_C(1) << 56) + 5 }; |
4739 | Q_DECLARE_METATYPE(EnumTest_Enum3) |
4740 | enum EnumTest_Enum4 : quint64 { EnumTest_Enum4_value = 47, EnumTest_Enum4_bigValue = (Q_INT64_C(1) << 52) + 45 }; |
4741 | Q_DECLARE_METATYPE(EnumTest_Enum4) |
4742 | enum EnumTest_Enum5 : uint { EnumTest_Enum5_value = 47 }; |
4743 | Q_DECLARE_METATYPE(EnumTest_Enum5) |
4744 | enum EnumTest_Enum6 : uchar { EnumTest_Enum6_value = 47 }; |
4745 | Q_DECLARE_METATYPE(EnumTest_Enum6) |
4746 | enum class EnumTest_Enum7 { EnumTest_Enum7_value = 47, ensureSignedEnum7 = -1 }; |
4747 | Q_DECLARE_METATYPE(EnumTest_Enum7) |
4748 | enum EnumTest_Enum8 : short { EnumTest_Enum8_value = 47 }; |
4749 | Q_DECLARE_METATYPE(EnumTest_Enum8) |
4750 | |
4751 | template<typename Enum> void testVariant(Enum value, bool *ok) |
4752 | { |
4753 | *ok = false; |
4754 | QVariant var = QVariant::fromValue(value); |
4755 | |
4756 | QCOMPARE(var.userType(), qMetaTypeId<Enum>()); |
4757 | |
4758 | QVERIFY(var.canConvert<Enum>()); |
4759 | QVERIFY(var.canConvert<int>()); |
4760 | QVERIFY(var.canConvert<unsigned int>()); |
4761 | QVERIFY(var.canConvert<short>()); |
4762 | QVERIFY(var.canConvert<unsigned short>()); |
4763 | QVERIFY(var.canConvert<qint64>()); |
4764 | QVERIFY(var.canConvert<quint64>()); |
4765 | |
4766 | |
4767 | QCOMPARE(var.value<Enum>(), value); |
4768 | QCOMPARE(var.value<int>(), static_cast<int>(value)); |
4769 | QCOMPARE(var.value<uint>(), static_cast<uint>(value)); |
4770 | QCOMPARE(var.value<short>(), static_cast<short>(value)); |
4771 | QCOMPARE(var.value<unsigned short>(), static_cast<unsigned short>(value)); |
4772 | QCOMPARE(var.value<qint64>(), static_cast<qint64>(value)); |
4773 | if (sizeof(value) < 8 && static_cast<qint64>(value) < 0) { |
4774 | QEXPECT_FAIL("" , "The metatype system don't store the sign of enums" , Continue); |
4775 | // The value is stored internaly with 32 bit. When asked to convert it to 64 bit unsigned, |
4776 | // we consider that the value was unsigned, so we don't extent the bit signs |
4777 | } |
4778 | QCOMPARE(var.value<quint64>(), static_cast<quint64>(value)); |
4779 | |
4780 | QVariant var2 = var; |
4781 | QVERIFY(var2.convert(QMetaType::Int)); |
4782 | QCOMPARE(var2.value<int>(), static_cast<int>(value)); |
4783 | |
4784 | if ((static_cast<qint64>(value) <= INT_MAX) && (static_cast<qint64>(value) >= INT_MIN)) { |
4785 | int intValue = static_cast<int>(value); |
4786 | QVariant intVar = intValue; |
4787 | QVERIFY(intVar.canConvert<Enum>()); |
4788 | QCOMPARE(intVar.value<Enum>(), value); |
4789 | } |
4790 | qint64 longValue = static_cast<qint64>(value); |
4791 | QVERIFY(QVariant(longValue).canConvert<Enum>()); |
4792 | QCOMPARE(QVariant(longValue).value<Enum>(), value); |
4793 | |
4794 | *ok = true; |
4795 | } |
4796 | |
4797 | void tst_QVariant::enums() |
4798 | { |
4799 | bool ok = false; |
4800 | testVariant(value: EnumTest_Enum0_value, ok: &ok); |
4801 | QVERIFY(ok); |
4802 | testVariant(value: EnumTest_Enum0_negValue, ok: &ok); |
4803 | QVERIFY(ok); |
4804 | testVariant(value: EnumTest_Enum1_value, ok: &ok); |
4805 | QVERIFY(ok); |
4806 | testVariant(value: EnumTest_Enum1_bigValue, ok: &ok); |
4807 | QVERIFY(ok); |
4808 | testVariant(value: EnumTest_Enum3::EnumTest_Enum3_value, ok: &ok); |
4809 | QVERIFY(ok); |
4810 | testVariant(value: EnumTest_Enum3::EnumTest_Enum3_bigValue, ok: &ok); |
4811 | QVERIFY(ok); |
4812 | testVariant(value: EnumTest_Enum4::EnumTest_Enum4_value, ok: &ok); |
4813 | QVERIFY(ok); |
4814 | testVariant(value: EnumTest_Enum4::EnumTest_Enum4_bigValue, ok: &ok); |
4815 | QVERIFY(ok); |
4816 | testVariant(value: EnumTest_Enum5::EnumTest_Enum5_value, ok: &ok); |
4817 | QVERIFY(ok); |
4818 | testVariant(value: EnumTest_Enum6::EnumTest_Enum6_value, ok: &ok); |
4819 | QVERIFY(ok); |
4820 | testVariant(value: EnumTest_Enum7::EnumTest_Enum7_value, ok: &ok); |
4821 | QVERIFY(ok); |
4822 | testVariant(value: EnumTest_Enum8::EnumTest_Enum8_value, ok: &ok); |
4823 | QVERIFY(ok); |
4824 | testVariant(value: EnumTest_Enum3::EnumTest_Enum3_value, ok: &ok); |
4825 | QVERIFY(ok); |
4826 | } |
4827 | |
4828 | template<typename Enum> void testVariantMeta(Enum value, bool *ok, const char *string) |
4829 | { |
4830 | testVariant<Enum>(value, ok); |
4831 | QVERIFY(ok); |
4832 | *ok = false; |
4833 | |
4834 | QVariant var = QVariant::fromValue(value); |
4835 | QVERIFY(var.canConvert<QString>()); |
4836 | QVERIFY(var.canConvert<QByteArray>()); |
4837 | |
4838 | QCOMPARE(var.value<QString>(), QString::fromLatin1(string)); |
4839 | QCOMPARE(var.value<QByteArray>(), QByteArray(string)); |
4840 | |
4841 | QVariant strVar = QString::fromLatin1(str: string); |
4842 | QVERIFY(strVar.canConvert<Enum>()); |
4843 | if ((static_cast<qint64>(value) > INT_MAX) || (static_cast<qint64>(value) < INT_MIN)) { |
4844 | QEXPECT_FAIL("" , "QMetaEnum api uses 'int' as return type QTBUG-27451" , Abort); |
4845 | *ok = true; |
4846 | } |
4847 | QCOMPARE(strVar.value<Enum>(), value); |
4848 | strVar = QByteArray(string); |
4849 | QVERIFY(strVar.canConvert<Enum>()); |
4850 | QCOMPARE(strVar.value<Enum>(), value); |
4851 | *ok = true; |
4852 | } |
4853 | |
4854 | void tst_QVariant::metaEnums() |
4855 | { |
4856 | bool ok = false; |
4857 | #define METAENUMS_TEST(Value) \ |
4858 | testVariantMeta(Value, &ok, #Value); QVERIFY(ok) |
4859 | |
4860 | METAENUMS_TEST(MetaEnumTest_Enum0_value); |
4861 | METAENUMS_TEST(MetaEnumTest_Enum1_value); |
4862 | METAENUMS_TEST(MetaEnumTest_Enum1_bigValue); |
4863 | METAENUMS_TEST(MetaEnumTest_Enum3_value); |
4864 | METAENUMS_TEST(MetaEnumTest_Enum3_bigValue); |
4865 | METAENUMS_TEST(MetaEnumTest_Enum3_bigNegValue); |
4866 | METAENUMS_TEST(MetaEnumTest_Enum4_value); |
4867 | METAENUMS_TEST(MetaEnumTest_Enum4_bigValue); |
4868 | METAENUMS_TEST(MetaEnumTest_Enum5_value); |
4869 | METAENUMS_TEST(MetaEnumTest_Enum6_value); |
4870 | METAENUMS_TEST(MetaEnumTest_Enum8_value); |
4871 | } |
4872 | |
4873 | void tst_QVariant::compareSanity_data() |
4874 | { |
4875 | QTest::addColumn<QVariant>(name: "value1" ); |
4876 | QTest::addColumn<QVariant>(name: "value2" ); |
4877 | |
4878 | QTest::newRow( dataTag: "int <>/== QUrl" ) << QVariant( 97 ) << QVariant(QUrl("a" )); |
4879 | QTest::newRow( dataTag: "int <>/== QChar" ) << QVariant( 97 ) << QVariant(QChar('a')); |
4880 | QTest::newRow( dataTag: "int <>/== QString" ) << QVariant( 97 ) << QVariant(QString("a" )); |
4881 | QTest::newRow( dataTag: "QUrl <>/== QChar" ) << QVariant(QUrl("a" )) << QVariant(QChar('a')); |
4882 | QTest::newRow( dataTag: "QUrl <>/== QString" ) << QVariant(QUrl("a" )) << QVariant(QString("a" )); |
4883 | QTest::newRow( dataTag: "QChar <>/== QString" ) << QVariant(QChar('a')) << QVariant(QString("a" )); |
4884 | } |
4885 | |
4886 | void tst_QVariant::compareSanity() |
4887 | { |
4888 | QFETCH(QVariant, value1); |
4889 | QFETCH(QVariant, value2); |
4890 | |
4891 | if (value1 == value2) { |
4892 | QVERIFY(!(value1 < value2) && !(value1 > value2)); |
4893 | } else { |
4894 | QVERIFY(value1 != value2); |
4895 | QVERIFY((value1 < value2) || (value1 > value2)); |
4896 | } |
4897 | } |
4898 | |
4899 | static void richComparison(const QVariant& less, const QVariant& more) |
4900 | { |
4901 | QVERIFY(less.type() == more.type()); |
4902 | |
4903 | QVERIFY(less < more); |
4904 | QVERIFY(!(more < less)); |
4905 | |
4906 | QVERIFY(more > less); |
4907 | QVERIFY(!(less > more)); |
4908 | |
4909 | QVERIFY(less <= more); |
4910 | QVERIFY(!(more <= less)); |
4911 | QVERIFY(less <= less); |
4912 | |
4913 | QVERIFY(more >= less); |
4914 | QVERIFY(!(less >= more)); |
4915 | QVERIFY(more >= more); |
4916 | } |
4917 | |
4918 | void tst_QVariant::compareRich() |
4919 | { |
4920 | richComparison(less: QUuid("{49d8ad2a-2ee8-4c3d-949f-1b5a3765ddf0}" ), |
4921 | more: QUuid("{f6d56824-16e9-4543-a375-add2877c2d05}" )); |
4922 | richComparison(less: QByteArray::fromRawData("a" , size: 1), |
4923 | more: QByteArray::fromRawData("b" , size: 1)); |
4924 | richComparison(QStringLiteral("a" ), QStringLiteral("b" )); |
4925 | richComparison(less: QLatin1String("a" ), more: QLatin1String("b" )); |
4926 | richComparison(less: QChar('a'), more: QChar('b')); |
4927 | richComparison(less: QDate(2016, 7, 23), more: QDate(2016, 7, 24)); |
4928 | richComparison(less: QTime(0, 0), more: QTime(0, 1)); |
4929 | richComparison(less: QDateTime(QDate(2016, 7, 23), QTime(0, 0)), |
4930 | more: QDateTime(QDate(2016, 7, 23), QTime(0, 1))); |
4931 | |
4932 | richComparison(less: QStringList(), more: QStringList() << QStringLiteral("a" )); |
4933 | richComparison(less: QStringList(), more: QStringList() << QStringLiteral("a" ) |
4934 | << QStringLiteral("b" )); |
4935 | richComparison(less: QStringList() << QStringLiteral("a" ), |
4936 | more: QStringList() << QStringLiteral("b" )); |
4937 | richComparison(less: QStringList() << QStringLiteral("a" ), |
4938 | more: QStringList() << QStringLiteral("b" ) |
4939 | << QStringLiteral("c" )); |
4940 | richComparison(less: QStringList() << QStringLiteral("a" ) |
4941 | << QStringLiteral("c" ), |
4942 | more: QStringList() << QStringLiteral("b" )); |
4943 | richComparison(less: QStringList() << QStringLiteral("a" ) |
4944 | << QStringLiteral("c" ), |
4945 | more: QStringList() << QStringLiteral("b" ) |
4946 | << QStringLiteral("d" )); |
4947 | richComparison(less: QStringList() << QStringLiteral("a" ) |
4948 | << QStringLiteral("c" ), |
4949 | more: QStringList() << QStringLiteral("a" ) |
4950 | << QStringLiteral("d" )); |
4951 | } |
4952 | |
4953 | void tst_QVariant::nullConvert() |
4954 | { |
4955 | // Test quirks with QVariants different types of null states. |
4956 | |
4957 | // null variant with no initialized value |
4958 | QVariant nullVar(QVariant::String); |
4959 | QVERIFY(nullVar.isValid()); |
4960 | QVERIFY(nullVar.isNull()); |
4961 | // We can not convert a variant with no value |
4962 | QVERIFY(!nullVar.convert(QVariant::Url)); |
4963 | QCOMPARE(nullVar.type(), QVariant::Url); |
4964 | QVERIFY(nullVar.isNull()); |
4965 | |
4966 | // variant initialized with null value |
4967 | QVariant nullStr = QVariant::fromValue(value: QString()); |
4968 | QVERIFY(nullStr.isValid()); |
4969 | QVERIFY(nullStr.isNull()); |
4970 | // We can convert an initialized null value however |
4971 | QVERIFY(nullStr.convert(QVariant::Url)); |
4972 | QCOMPARE(nullStr.type(), QVariant::Url); |
4973 | QVERIFY(nullStr.isValid()); |
4974 | // QUrl does not have an isNull method |
4975 | QVERIFY(!nullStr.isNull()); |
4976 | // The URL is not valid however |
4977 | QVERIFY(!nullStr.toUrl().isValid()); |
4978 | } |
4979 | |
4980 | void tst_QVariant::accessSequentialContainerKey() |
4981 | { |
4982 | QString nameResult; |
4983 | |
4984 | { |
4985 | QMap<QString, QObject*> mapping; |
4986 | QString name = QString::fromLatin1(str: "Seven" ); |
4987 | mapping.insert(akey: name, avalue: nullptr); |
4988 | |
4989 | QVariant variant = QVariant::fromValue(value: mapping); |
4990 | |
4991 | QAssociativeIterable iterable = variant.value<QAssociativeIterable>(); |
4992 | QAssociativeIterable::const_iterator iit = iterable.begin(); |
4993 | const QAssociativeIterable::const_iterator end = iterable.end(); |
4994 | for ( ; iit != end; ++iit) { |
4995 | nameResult += iit.key().toString(); |
4996 | } |
4997 | } // Destroy mapping |
4998 | // Regression test for QTBUG-52246 - no memory corruption/double deletion |
4999 | // of the string key. |
5000 | |
5001 | QCOMPARE(nameResult, QStringLiteral("Seven" )); |
5002 | } |
5003 | |
5004 | void tst_QVariant::shouldDeleteVariantDataWorksForSequential() |
5005 | { |
5006 | QCOMPARE(instanceCount, 0); |
5007 | { |
5008 | QtMetaTypePrivate::QSequentialIterableImpl iterator {}; |
5009 | iterator._iteratorCapabilities = QtMetaTypePrivate::RandomAccessCapability | |
5010 | QtMetaTypePrivate::BiDirectionalCapability | |
5011 | QtMetaTypePrivate::ForwardCapability; |
5012 | iterator._metaType_flags = QVariantConstructionFlags::ShouldDeleteVariantData; |
5013 | |
5014 | iterator._size = [](const void *) {return 1;}; |
5015 | iterator._metaType_id = qMetaTypeId<MyType>(); |
5016 | iterator._moveToBegin = [](const void *, void **) {}; |
5017 | iterator._moveToEnd = [](const void *, void **) {}; |
5018 | iterator._advance = [](void **, int) {}; |
5019 | iterator._destroyIter = [](void **){}; |
5020 | iterator._equalIter = [](void * const *, void * const *){return true; /*all iterators are nullptr*/}; |
5021 | iterator._destroyIter = [](void **){}; |
5022 | iterator._at = [](const void *, int ) -> void const * { |
5023 | MyType mytype {1, "eins" }; |
5024 | return QMetaType::create(type: qMetaTypeId<MyType>(), copy: &mytype); |
5025 | }; |
5026 | iterator._get = [](void * const *, int, uint) -> QtMetaTypePrivate::VariantData { |
5027 | MyType mytype {2, "zwei" }; |
5028 | return {qMetaTypeId<MyType>(), QMetaType::create(type: qMetaTypeId<MyType>(), copy: &mytype), QVariantConstructionFlags::ShouldDeleteVariantData}; |
5029 | }; |
5030 | QSequentialIterable iterable {iterator}; |
5031 | QVariant value1 = iterable.at(idx: 0); |
5032 | QVERIFY(value1.canConvert<MyType>()); |
5033 | QCOMPARE(value1.value<MyType>().number, 1); |
5034 | QVariant value2 = *iterable.begin(); |
5035 | QVERIFY(value2.canConvert<MyType>()); |
5036 | QCOMPARE(value2.value<MyType>().number, 2); |
5037 | } |
5038 | QCOMPARE(instanceCount, 0); |
5039 | } |
5040 | |
5041 | void tst_QVariant::shouldDeleteVariantDataWorksForAssociative() |
5042 | { |
5043 | QCOMPARE(instanceCount, 0); |
5044 | { |
5045 | QtMetaTypePrivate::QAssociativeIterableImpl iterator {}; |
5046 | iterator._metaType_flags_key = QVariantConstructionFlags::ShouldDeleteVariantData; |
5047 | iterator._metaType_flags_value = QVariantConstructionFlags::ShouldDeleteVariantData; |
5048 | |
5049 | iterator._size = [](const void *) {return 1;}; |
5050 | iterator._metaType_id_value = qMetaTypeId<MyType>(); |
5051 | iterator._metaType_id_key = qMetaTypeId<MyType>(); |
5052 | iterator._begin = [](const void *, void **) {}; |
5053 | iterator._end = [](const void *, void **) {}; |
5054 | iterator._advance = [](void **, int) {}; |
5055 | iterator._destroyIter = [](void **){}; |
5056 | iterator._equalIter = [](void * const *, void * const *){return true; /*all iterators are nullptr*/}; |
5057 | iterator._destroyIter = [](void **){}; |
5058 | iterator._find = [](const void *, const void *, void **iterator ) -> void { |
5059 | (*iterator) = reinterpret_cast<void *>(quintptr(42)); |
5060 | }; |
5061 | iterator._getKey = [](void * const *iterator, int, uint) -> QtMetaTypePrivate::VariantData { |
5062 | MyType mytype {1, "key" }; |
5063 | if (reinterpret_cast<quintptr>(*iterator) == 42) { |
5064 | mytype.number = 42; |
5065 | mytype.text = "find_key" ; |
5066 | } |
5067 | return {qMetaTypeId<MyType>(), QMetaType::create(type: qMetaTypeId<MyType>(), copy: &mytype), QVariantConstructionFlags::ShouldDeleteVariantData}; |
5068 | }; |
5069 | iterator._getValue = [](void * const *iterator, int, uint) -> QtMetaTypePrivate::VariantData { |
5070 | MyType mytype {2, "value" }; |
5071 | if (reinterpret_cast<quintptr>(*iterator) == 42) { |
5072 | mytype.number = 42; |
5073 | mytype.text = "find_value" ; |
5074 | } |
5075 | return {qMetaTypeId<MyType>(), QMetaType::create(type: qMetaTypeId<MyType>(), copy: &mytype), QVariantConstructionFlags::ShouldDeleteVariantData}; |
5076 | }; |
5077 | QAssociativeIterable iterable {iterator}; |
5078 | auto it = iterable.begin(); |
5079 | QVariant value1 = it.key(); |
5080 | QVERIFY(value1.canConvert<MyType>()); |
5081 | QCOMPARE(value1.value<MyType>().number, 1); |
5082 | QCOMPARE(value1.value<MyType>().text, "key" ); |
5083 | QVariant value2 = it.value(); |
5084 | QVERIFY(value2.canConvert<MyType>()); |
5085 | QCOMPARE(value2.value<MyType>().number, 2); |
5086 | auto findIt = iterable.find(key: QVariant::fromValue(value: MyType {})); |
5087 | value1 = findIt.key(); |
5088 | QCOMPARE(value1.value<MyType>().number, 42); |
5089 | QCOMPARE(value1.value<MyType>().text, "find_key" ); |
5090 | value2 = findIt.value(); |
5091 | QCOMPARE(value2.value<MyType>().number, 42); |
5092 | QCOMPARE(value2.value<MyType>().text, "find_value" ); |
5093 | } |
5094 | QCOMPARE(instanceCount, 0); |
5095 | } |
5096 | |
5097 | void tst_QVariant::fromStdVariant() |
5098 | { |
5099 | #if __has_include(<variant>) && __cplusplus >= 201703L |
5100 | { |
5101 | typedef std::variant<int, bool> intorbool_t; |
5102 | intorbool_t stdvar = 5; |
5103 | QVariant qvar = QVariant::fromStdVariant(value: stdvar); |
5104 | QVERIFY(!qvar.isNull()); |
5105 | QCOMPARE(qvar.type(), QVariant::Int); |
5106 | QCOMPARE(qvar.value<int>(), std::get<int>(stdvar)); |
5107 | stdvar = true; |
5108 | qvar = QVariant::fromStdVariant(value: stdvar); |
5109 | QVERIFY(!qvar.isNull()); |
5110 | QCOMPARE(qvar.type(), QVariant::Bool); |
5111 | QCOMPARE(qvar.value<bool>(), std::get<bool>(stdvar)); |
5112 | } |
5113 | { |
5114 | std::variant<std::monostate, int> stdvar; |
5115 | QVariant qvar = QVariant::fromStdVariant(value: stdvar); |
5116 | QVERIFY(!qvar.isValid()); |
5117 | stdvar = -4; |
5118 | qvar = QVariant::fromStdVariant(value: stdvar); |
5119 | QVERIFY(!qvar.isNull()); |
5120 | QCOMPARE(qvar.type(), QVariant::Int); |
5121 | QCOMPARE(qvar.value<int>(), std::get<int>(stdvar)); |
5122 | } |
5123 | { |
5124 | std::variant<int, bool, QChar> stdvar = QChar::fromLatin1(c: ' '); |
5125 | QVariant qvar = QVariant::fromStdVariant(value: stdvar); |
5126 | QVERIFY(!qvar.isNull()); |
5127 | QCOMPARE(qvar.type(), QVariant::Char); |
5128 | QCOMPARE(qvar.value<QChar>(), std::get<QChar>(stdvar)); |
5129 | } |
5130 | #endif |
5131 | } |
5132 | |
5133 | void tst_QVariant::qt4UuidDataStream() |
5134 | { |
5135 | qRegisterMetaTypeStreamOperators<QUuid>(); |
5136 | |
5137 | QByteArray data; |
5138 | QDataStream stream(&data, QIODevice::WriteOnly); |
5139 | stream.setVersion(QDataStream::Qt_4_8); |
5140 | QUuid source(0x12345678,0x1234,0x1234,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89); |
5141 | stream << QVariant::fromValue(value: source); |
5142 | const QByteArray qt4Data = QByteArray::fromHex(hexEncoded: "0000007f000000000651557569640012345678123412341223344556677889" ); |
5143 | QCOMPARE(data, qt4Data); |
5144 | |
5145 | QDataStream input(&data, QIODevice::ReadOnly); |
5146 | input.setVersion(QDataStream::Qt_4_8); |
5147 | QVariant result; |
5148 | input >> result; |
5149 | QCOMPARE(result.value<QUuid>(), source); |
5150 | } |
5151 | |
5152 | void tst_QVariant::sequentialIterableEndianessSanityCheck() |
5153 | { |
5154 | namespace QMTP = QtMetaTypePrivate; |
5155 | uint oldIteratorCaps = QMTP::ForwardCapability | QMTP::BiDirectionalCapability | QMTP::RandomAccessCapability; |
5156 | QMTP::QSequentialIterableImpl seqImpl {}; |
5157 | QCOMPARE(seqImpl.revision(), 1u); |
5158 | memcpy(dest: &seqImpl._iteratorCapabilities, src: &oldIteratorCaps, n: sizeof(oldIteratorCaps)); |
5159 | QCOMPARE(seqImpl.revision(), 0u); |
5160 | } |
5161 | |
5162 | void tst_QVariant::sequentialIterableAppend() |
5163 | { |
5164 | { |
5165 | QVector<int> container {1, 2}; |
5166 | auto variant = QVariant::fromValue(value: container); |
5167 | QVERIFY(variant.canConvert<QtMetaTypePrivate::QSequentialIterableImpl>()); |
5168 | auto asIterable = variant.value<QtMetaTypePrivate::QSequentialIterableImpl>(); |
5169 | const int i = 3, j = 4; |
5170 | asIterable.append(newElement: &i); |
5171 | asIterable.append(newElement: &j); |
5172 | QCOMPARE(variant.value<QVector<int>>(), QVector<int> ({1, 2, 3, 4})); |
5173 | } |
5174 | { |
5175 | QSet<QByteArray> container { QByteArray{"hello" }, QByteArray{"world" } }; |
5176 | auto variant = QVariant::fromValue(value: std::move(container)); |
5177 | QVERIFY(variant.canConvert<QtMetaTypePrivate::QSequentialIterableImpl>()); |
5178 | auto asIterable = variant.value<QtMetaTypePrivate::QSequentialIterableImpl>(); |
5179 | QByteArray qba1 {"goodbye" }; |
5180 | QByteArray qba2 { "moon" }; |
5181 | asIterable.append( newElement: &qba1 ); |
5182 | asIterable.append( newElement: &qba2); |
5183 | QSet<QByteArray> reference { "hello" , "world" , "goodbye" , "moon" }; |
5184 | QCOMPARE(variant.value<QSet<QByteArray>>(), reference); |
5185 | } |
5186 | } |
5187 | |
5188 | void tst_QVariant::preferDirectConversionOverInterfaces() |
5189 | { |
5190 | using namespace QtMetaTypePrivate; |
5191 | bool calledCorrectConverter = false; |
5192 | QMetaType::registerConverter<MyType, QSequentialIterableImpl>(function: [](const MyType &) { |
5193 | return QSequentialIterableImpl {}; |
5194 | }); |
5195 | QMetaType::registerConverter<MyType, QVariantList>(function: [&calledCorrectConverter](const MyType &) { |
5196 | calledCorrectConverter = true; |
5197 | return QVariantList {}; |
5198 | }); |
5199 | QMetaType::registerConverter<MyType, QAssociativeIterableImpl>(function: [](const MyType &) { |
5200 | return QAssociativeIterableImpl {}; |
5201 | }); |
5202 | QMetaType::registerConverter<MyType, QVariantHash>(function: [&calledCorrectConverter](const MyType &) { |
5203 | calledCorrectConverter = true; |
5204 | return QVariantHash {}; |
5205 | }); |
5206 | QMetaType::registerConverter<MyType, QVariantMap>(function: [&calledCorrectConverter](const MyType &) { |
5207 | calledCorrectConverter = true; |
5208 | return QVariantMap {}; |
5209 | }); |
5210 | auto holder = QVariant::fromValue(value: MyType {}); |
5211 | |
5212 | QVERIFY(holder.canConvert<QSequentialIterableImpl>()); |
5213 | QVERIFY(holder.canConvert<QVariantList>()); |
5214 | QVERIFY(holder.canConvert<QAssociativeIterableImpl>()); |
5215 | QVERIFY(holder.canConvert<QVariantHash>()); |
5216 | QVERIFY(holder.canConvert<QVariantMap>()); |
5217 | |
5218 | holder.value<QVariantList>(); |
5219 | QVERIFY(calledCorrectConverter); |
5220 | calledCorrectConverter = false; |
5221 | |
5222 | holder.value<QVariantHash>(); |
5223 | QVERIFY(calledCorrectConverter); |
5224 | calledCorrectConverter = false; |
5225 | |
5226 | holder.value<QVariantMap>(); |
5227 | QVERIFY(calledCorrectConverter); |
5228 | } |
5229 | |
5230 | QTEST_MAIN(tst_QVariant) |
5231 | #include "tst_qvariant.moc" |
5232 | |