5e0fce3f815155dac7942b1e60a7beb38b2605fe
[profile/ivi/qtbase.git] / tests / auto / corelib / kernel / qvariant / tst_qvariant.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtTest/QtTest>
43
44 #include <qvariant.h>
45 #include <qbitarray.h>
46 #include <qdatetime.h>
47 #include <qmap.h>
48 #include <qiodevice.h>
49 #include <qurl.h>
50 #include <qlocale.h>
51 #include <qkeysequence.h>
52 #include <qbitmap.h>
53 #include <qcursor.h>
54 #include <qimage.h>
55 #include <qicon.h>
56 #include <qmatrix.h>
57 #include <qmatrix4x4.h>
58 #include <qpen.h>
59 #include <qpolygon.h>
60 #include <qpalette.h>
61 #include <qtransform.h>
62 #include <qvector2d.h>
63 #include <qvector3d.h>
64 #include <qvector4d.h>
65 #include <qquaternion.h>
66 #include <qdebug.h>
67
68 #include <limits.h>
69
70 #include <QLinkedList>
71 #include <QRegularExpression>
72 #include <QDir>
73 #include <QBuffer>
74 #include <QFont>
75 #include "qnumeric.h"
76
77 #include "tst_qvariant_common.h"
78
79 class CustomNonQObject;
80
81 class tst_QVariant : public QObject
82 {
83     Q_OBJECT
84
85 public:
86     tst_QVariant(QObject *parent = 0)
87       : QObject(parent), customNonQObjectPointer(0)
88     {
89
90     }
91
92 private slots:
93     void cleanupTestCase();
94
95     void constructor();
96     void copy_constructor();
97     void constructor_invalid_data();
98     void constructor_invalid();
99     void isNull();
100     void swap();
101
102     void canConvert_data();
103     void canConvert();
104
105     void toSize_data();
106     void toSize();
107
108     void toSizeF_data();
109     void toSizeF();
110
111     void toPoint_data();
112     void toPoint();
113
114     void toRect_data();
115     void toRect();
116
117     void toChar_data();
118     void toChar();
119
120     void toLine_data();
121     void toLine();
122
123     void toLineF_data();
124     void toLineF();
125
126     void toInt_data();
127     void toInt();
128
129     void toUInt_data();
130     void toUInt();
131
132     void toBool_data();
133     void toBool();
134
135     void toLongLong_data();
136     void toLongLong();
137
138     void toULongLong_data();
139     void toULongLong();
140
141     void toByteArray_data();
142     void toByteArray();
143
144     void toString_data();
145     void toString();
146
147     void toDate_data();
148     void toDate();
149
150     void toTime_data();
151     void toTime();
152
153     void toDateTime_data();
154     void toDateTime();
155
156     void toDouble_data();
157     void toDouble();
158
159     void toPointF_data();
160     void toPointF();
161
162     void toFont_data();
163     void toFont();
164
165     void toKeySequence_data();
166     void toKeySequence();
167
168     void toRectF_data();
169     void toRectF();
170
171     void toColor_data();
172     void toColor();
173
174     void toPixmap_data();
175     void toPixmap();
176
177     void toImage_data();
178     void toImage();
179
180     void toBrush_data();
181     void toBrush();
182
183     void qvariant_cast_QObject_data();
184     void qvariant_cast_QObject();
185     void qvariant_cast_QObject_derived();
186
187     void toLocale();
188
189     void toRegExp();
190     void toRegularExpression();
191
192     void matrix();
193
194     void transform();
195
196     void matrix4x4();
197     void vector2D();
198     void vector3D();
199     void vector4D();
200     void quaternion();
201
202     void url();
203
204     void userType();
205     void basicUserType();
206
207     void variant_to();
208
209     void writeToReadFromDataStream_data();
210     void writeToReadFromDataStream();
211     void writeToReadFromOldDataStream();
212     void checkDataStream();
213
214     void operator_eq_eq_data();
215     void operator_eq_eq();
216
217     void operator_eq_eq_rhs();
218
219     void typeName_data();
220     void typeName();
221     void typeToName();
222
223     void streamInvalidVariant();
224
225     void podUserType();
226
227     void data();
228     void constData();
229
230     void saveLoadCustomTypes();
231
232     void variantMap();
233     void variantHash();
234
235     void convertToQUint8() const;
236     void invalidQColor() const;
237     void comparePointers() const;
238     void voidStar() const;
239     void dataStar() const;
240     void canConvertQStringList() const;
241     void canConvertQStringList_data() const;
242     void canConvertMetaTypeToInt() const;
243     void variantToDateTimeWithoutWarnings() const;
244     void invalidDateTime() const;
245
246     void loadUnknownUserType();
247     void loadBrokenUserType();
248
249     void invalidDate() const;
250     void compareCustomTypes() const;
251     void timeToDateTime() const;
252     void copyingUserTypes() const;
253     void convertBoolToByteArray() const;
254     void convertBoolToByteArray_data() const;
255     void convertByteArrayToBool() const;
256     void convertByteArrayToBool_data() const;
257     void toIntFromQString() const;
258     void toIntFromDouble() const;
259     void setValue();
260
261     void numericalConvert();
262     void moreCustomTypes();
263     void movabilityTest();
264     void variantInVariant();
265
266     void colorInteger();
267
268     void forwardDeclare();
269     void debugStream_data();
270     void debugStream();
271     void debugStreamType_data();
272     void debugStreamType();
273
274     void loadQt4Stream_data();
275     void loadQt4Stream();
276     void saveQt4Stream_data();
277     void saveQt4Stream();
278     void loadQt5Stream_data();
279     void loadQt5Stream();
280     void saveQt5Stream_data();
281     void saveQt5Stream();
282
283     void guiVariantAtExit();
284 private:
285     void dataStream_data(QDataStream::Version version);
286     void loadQVariantFromDataStream(QDataStream::Version version);
287     void saveQVariantFromDataStream(QDataStream::Version version);
288
289     CustomNonQObject *customNonQObjectPointer;
290     QVector<QObject*> objectPointerTestData;
291 };
292
293 const qlonglong intMax1 = (qlonglong)INT_MAX + 1;
294 const qulonglong uintMax1 = (qulonglong)UINT_MAX + 1;
295
296 void tst_QVariant::constructor()
297 {
298     QVariant variant;
299     QVERIFY( !variant.isValid() );
300     QVERIFY( variant.isNull() );
301
302     QVariant var2(variant);
303     QVERIFY( !var2.isValid() );
304     QVERIFY( variant.isNull() );
305
306     QVariant varll(intMax1);
307     QVariant varll2(varll);
308     QCOMPARE(varll2, varll);
309
310     QVariant var3(QVariant::String);
311     QCOMPARE(var3.typeName(), "QString");
312     QVERIFY(var3.isNull());
313     QVERIFY(var3.isValid());
314
315     QVariant var4(QVariant::Invalid);
316     QCOMPARE(var4.type(), QVariant::Invalid);
317     QVERIFY(var4.isNull());
318     QVERIFY(!var4.isValid());
319
320     QVariant var5(QLatin1String("hallo"));
321     QCOMPARE(var5.type(), QVariant::String);
322     QCOMPARE(var5.typeName(), "QString");
323
324     QVariant var6(qlonglong(0));
325     QCOMPARE(var6.type(), QVariant::LongLong);
326     QCOMPARE(var6.typeName(), "qlonglong");
327
328     QVariant var7 = 5;
329     QVERIFY(var7.isValid());
330     QVERIFY(!var7.isNull());
331     QVariant var8;
332     var8.setValue<int>(5);
333     QVERIFY(var8.isValid());
334     QVERIFY(!var8.isNull());
335 }
336
337 void tst_QVariant::constructor_invalid_data()
338 {
339     QTest::addColumn<uint>("typeId");
340
341     QTest::newRow("-1") << uint(-1);
342     QTest::newRow("-122234567") << uint(-122234567);
343     QTest::newRow("0xfffffffff") << uint(0xfffffffff);
344     QTest::newRow("LastCoreType + 1") << uint(QMetaType::LastCoreType + 1);
345     QVERIFY(!QMetaType::isRegistered(QMetaType::LastCoreType + 1));
346 }
347
348 void tst_QVariant::constructor_invalid()
349 {
350
351     QFETCH(uint, typeId);
352     {
353         MessageHandlerInvalidType msg;
354         QVariant variant(static_cast<QVariant::Type>(typeId));
355         QVERIFY(!variant.isValid());
356         QVERIFY(variant.userType() == QMetaType::UnknownType);
357         QVERIFY(msg.ok);
358     }
359     {
360         MessageHandlerInvalidType msg;
361         QVariant variant(typeId, /* copy */ 0);
362         QVERIFY(!variant.isValid());
363         QVERIFY(variant.userType() == QMetaType::UnknownType);
364         QVERIFY(msg.ok);
365     }
366 }
367
368 void tst_QVariant::copy_constructor()
369 {
370     QVariant var7(QVariant::Int);
371     QVariant var8(var7);
372     QCOMPARE(var8.type(), QVariant::Int);
373     QVERIFY(var8.isNull());
374 }
375
376 void tst_QVariant::isNull()
377 {
378     QVariant var;
379     QVERIFY( var.isNull() );
380
381     QString str1;
382     QVariant var1( str1 );
383     QVERIFY( var1.isNull() );
384
385     QVariant var2( QString::null );
386     QVERIFY( var2.isNull() );
387
388     QVariant var3( QString( "blah" ) );
389     QVERIFY( !var3.isNull() );
390
391     QVariant var4( 0 );
392     QVERIFY( !var4.isNull() );
393
394     QVariant var5 = QString();
395     QVERIFY( var5.isNull() );
396
397     QVariant var6( QString( "blah" ) );
398     QVERIFY( !var6.isNull() );
399     var6 = QVariant();
400     QVERIFY( var6.isNull() );
401     var6.convert( QVariant::String );
402     QVERIFY( var6.isNull() );
403     QVariant varLL( (qlonglong)0 );
404     QVERIFY( !varLL.isNull() );
405     QVariant var7(QString::null);
406     QVERIFY(var7.isNull());
407 }
408
409 void tst_QVariant::swap()
410 {
411     QVariant v1 = 1, v2 = 2.0;
412     v1.swap(v2);
413     QCOMPARE(v1.type(),QVariant::Double);
414     QCOMPARE(v1.toDouble(),2.0);
415     QCOMPARE(v2.type(),QVariant::Int);
416     QCOMPARE(v2.toInt(),1);
417 }
418
419 void tst_QVariant::canConvert_data()
420 {
421     TST_QVARIANT_CANCONVERT_DATATABLE_HEADERS
422
423
424 #ifdef Y
425 #undef Y
426 #endif
427 #ifdef N
428 #undef N
429 #endif
430 #define Y true
431 #define N false
432     //            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
433
434
435     QVariant var(QBitArray(0));
436     QTest::newRow("BitArray")
437         << 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;
438     var = QVariant::fromValue(QBitmap());
439     QTest::newRow("Bitmap")
440         << var << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N;
441     var = QVariant::fromValue(QBrush());
442     QTest::newRow("Brush")
443         << var << N << N << N << Y << N << Y << 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;
444     var = QVariant(QByteArray());
445     QTest::newRow("ByteArray")
446         << 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;
447     var = QVariant::fromValue(QColor());
448     QTest::newRow("Color")
449         << var << N << N << N << Y << Y << Y << 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;
450 #ifndef QT_NO_CURSOR
451     var = QVariant::fromValue(QCursor());
452     QTest::newRow("Cursor")
453         << var << N << N << N << N << N << N << 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;
454 #endif
455     var = QVariant(QDate());
456     QTest::newRow("Date")
457         << 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;
458     var = QVariant(QDateTime());
459     QTest::newRow("DateTime")
460         << 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;
461     var = QVariant((double)0.1);
462     QTest::newRow("Double")
463         << 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;
464     var = QVariant(0.1f);
465     QTest::newRow("Float")
466         << 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;
467     var = QVariant::fromValue(QFont());
468     QTest::newRow("Font")
469         << var << 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 << Y << N << N << N << N;
470     var = QVariant::fromValue(QIcon());
471     QTest::newRow("Icon")
472         << 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 << N << N << N << N << N;
473     var = QVariant::fromValue(QImage());
474     QTest::newRow("Image")
475         << var << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N;
476     var = QVariant((int)1);
477     QTest::newRow("Int")
478         << 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;
479     var = QVariant();
480     QTest::newRow("Invalid")
481         << 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;
482     var = QVariant::fromValue(QKeySequence());
483     QTest::newRow("KeySequence")
484         << var << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << Y << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N;
485     var = QVariant(QList<QVariant>());
486     QTest::newRow("List")
487         << 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;
488     var = QVariant((qlonglong)1);
489     QTest::newRow("LongLong")
490         << 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;
491     var = QVariant(QMap<QString,QVariant>());
492     QTest::newRow("Map")
493         << 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;
494     var = QVariant::fromValue(QPalette());
495     QTest::newRow("Palette")
496         << var << 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 << N << N << N;
497     var = QVariant::fromValue(QPen());
498     QTest::newRow("Pen")
499         << var << 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 << N << N;
500     var = QVariant::fromValue(QPixmap());
501     QTest::newRow("Pixmap")
502         << var << N << Y << N << Y << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N;
503     var = QVariant::fromValue(QPolygon());
504     QTest::newRow("PointArray")
505         << 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 << N << N << N << N << N;
506     var = QVariant(QPoint());
507     QTest::newRow("Point")
508         << 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;
509     var = QVariant(QRect());
510     QTest::newRow("Rect")
511         << 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;
512     var = QVariant::fromValue(QRegion());
513     QTest::newRow("Region")
514         << var << 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 << N;
515     var = QVariant(QSize());
516     QTest::newRow("Size")
517         << 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;
518     var = QVariant(QString());
519     QTest::newRow("String")
520         << 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;
521    var = QVariant(QStringList("entry"));
522     QTest::newRow("StringList")
523         << 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;
524     var = QVariant(QTime());
525     QTest::newRow("Time")
526         << 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;
527     var = QVariant((uint)1);
528     QTest::newRow("UInt")
529         << 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;
530     var = QVariant((int)1);
531     QTest::newRow("Int")
532         << 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;
533     var = QVariant((qulonglong)1);
534     QTest::newRow("ULongLong")
535         << 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;
536     var = QVariant::fromValue('a');
537     QTest::newRow("Char")
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<signed char>(-1);
540     QTest::newRow("SChar")
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
543 #undef N
544 #undef Y
545 }
546
547 void tst_QVariant::canConvert()
548 {
549     TST_QVARIANT_CANCONVERT_FETCH_DATA
550
551     TST_QVARIANT_CANCONVERT_COMPARE_DATA
552
553     // Invalid type ids
554     QCOMPARE(val.canConvert(-1), false);
555     QCOMPARE(val.canConvert(-23), false);
556     QCOMPARE(val.canConvert(-23876), false);
557     QCOMPARE(val.canConvert(23876), false);
558 }
559
560 void tst_QVariant::toInt_data()
561 {
562     QTest::addColumn<QVariant>("value");
563     QTest::addColumn<int>("result");
564     QTest::addColumn<bool>("valueOK");
565
566     QTest::newRow( "invalid" ) << QVariant()  << 0 << false;
567     QTest::newRow( "int" ) << QVariant( 123 ) << 123 << true;
568     QTest::newRow( "char" ) << QVariant::fromValue('a') << int('a') << true;
569     signed char signedChar = -13;
570     QTest::newRow( "signed char" ) << QVariant::fromValue(signedChar) << -13 << true;
571     QTest::newRow( "double" ) << QVariant( 3.1415927 ) << 3 << true;
572     QTest::newRow( "float" ) << QVariant( 3.1415927f ) << 3 << true;
573     QTest::newRow( "uint" ) << QVariant( 123u ) << 123 << true;
574     QTest::newRow( "int-string" ) << QVariant( QString("123") ) << 123 << true;
575     QTest::newRow( "string" ) << QVariant( QString("Unicode String") ) << 0 << false;
576     QTest::newRow( "longlong0" ) << QVariant( (qlonglong)34 ) << 34 << true;
577     QTest::newRow( "longlong1" ) << QVariant( intMax1 ) << (int)INT_MIN << true;
578     QTest::newRow( "ulonglong0" ) << QVariant( (qulonglong)34 ) << 34 << true;
579     QTest::newRow( "ulonglong1" ) << QVariant( uintMax1 ) << 0 << true;
580     QTest::newRow( "signedint" ) << QVariant( -123 ) << -123 << true;
581     QTest::newRow( "signeddouble" ) << QVariant( -3.1415927 ) << -3 << true;
582     QTest::newRow( "signedfloat" ) << QVariant( -3.1415927f ) << -3 << true;
583     QTest::newRow( "signedint-string" ) << QVariant( QString("-123") ) << -123 << true;
584     QTest::newRow( "signedlonglong0" ) << QVariant( (qlonglong)-34 ) << -34 << true;
585     QTest::newRow( "QChar" ) << QVariant(QChar('a')) << int('a') << true;
586     QTest::newRow( "keysequence" ) << QVariant::fromValue( QKeySequence( Qt::Key_A ) ) << 65 << true;
587     QByteArray bytearray(4, ' ');
588     bytearray[0] = 'T';
589     bytearray[1] = 'e';
590     bytearray[2] = 's';
591     bytearray[3] = 't';
592     QTest::newRow( "QByteArray1" ) << QVariant( bytearray ) << 0 << false;
593     bytearray[0] = '4';
594     bytearray[1] = '5';
595     bytearray[2] = '0';
596     bytearray[3] = '0';
597     QTest::newRow( "QByteArray2" ) << QVariant( bytearray ) << 4500 << true;
598 }
599
600 void tst_QVariant::toInt()
601 {
602     QFETCH( QVariant, value );
603     QFETCH( int, result );
604     QFETCH( bool, valueOK );
605     QVERIFY( value.isValid() == value.canConvert( QVariant::Int ) );
606     bool ok;
607     int i = value.toInt( &ok );
608     QCOMPARE( i, result );
609     QVERIFY( ok == valueOK );
610 }
611
612 void tst_QVariant::toUInt_data()
613 {
614     QTest::addColumn<QVariant>("value");
615     QTest::addColumn<uint>("result");
616     QTest::addColumn<bool>("valueOK");
617
618     QTest::newRow( "int" ) << QVariant( 123 ) << (uint)123 << true;
619     QTest::newRow( "char" ) << QVariant::fromValue('a') << uint('a') << true;
620     signed char signedChar = 12;
621     QTest::newRow( "signed char" ) << QVariant::fromValue(signedChar) << uint(12) << true;
622     QTest::newRow( "double" ) << QVariant( 3.1415927 ) << (uint)3 << true;
623     QTest::newRow( "float" ) << QVariant( 3.1415927f ) << (uint)3 << true;
624     QTest::newRow( "uint" ) << QVariant( 123u ) << (uint)123 << true;
625     QTest::newRow( "int-string" ) << QVariant( QString("123") ) << (uint)123 << true;
626     QTest::newRow( "string" ) << QVariant( QString("Unicode String") ) << (uint)0 << false;
627     QTest::newRow( "string2" ) << QVariant( QString("4") ) << (uint)4 << true;
628     QTest::newRow( "longlong0" ) << QVariant( (qlonglong)34 ) << (uint)34 << true;
629     QTest::newRow( "longlong1" ) << QVariant( intMax1 ) << (uint)INT_MIN << true;
630     QTest::newRow( "ulonglong0" ) << QVariant( (qulonglong)34 ) << (uint)34 << true;
631     QTest::newRow( "ulonglong1" ) << QVariant( uintMax1 ) << (uint)0 << true;
632     QTest::newRow( "negativeint" ) << QVariant( -123 ) << (uint)-123 << true;
633     QTest::newRow( "negativedouble" ) << QVariant( -3.1415927 ) << (uint)-3 << true;
634     QTest::newRow( "negativefloat" ) << QVariant( -3.1415927f ) << (uint)-3 << true;
635     QTest::newRow( "negativeint-string" ) << QVariant( QString("-123") ) << (uint)0 << false;
636     QTest::newRow( "negativelonglong0" ) << QVariant( (qlonglong)-34 ) << (uint)-34 << true;
637     QTest::newRow( "QChar" ) << QVariant(QChar('a')) << uint('a') << true;
638     QByteArray bytearray(4, ' ');
639     bytearray[0] = '4';
640     bytearray[1] = '3';
641     bytearray[2] = '2';
642     bytearray[3] = '1';
643     QTest::newRow( "QByteArray" ) << QVariant( bytearray ) << (uint)4321 << true;
644 }
645
646 void tst_QVariant::toUInt()
647 {
648     QFETCH( QVariant, value );
649     QFETCH( uint, result );
650     QFETCH( bool, valueOK );
651     QVERIFY( value.isValid() );
652     QVERIFY( value.canConvert( QVariant::UInt ) );
653
654     bool ok;
655     uint i = value.toUInt( &ok );
656     QVERIFY( ok == valueOK );
657     QCOMPARE( i, result );
658 }
659
660
661 void tst_QVariant::toSize_data()
662 {
663     QTest::addColumn<QVariant>("value");
664     QTest::addColumn<QSize>("result");
665     QTest::newRow( "qsizef4" ) << QVariant( QSizeF(4, 2) ) << QSize(4, 2);
666     QTest::newRow( "qsizef1" ) << QVariant( QSizeF(0, 0) ) << QSize(0, 0);
667     QTest::newRow( "qsizef2" ) << QVariant( QSizeF(-5, -1) ) << QSize(-5, -1);
668     QTest::newRow( "qsizef3" ) << QVariant( QSizeF() ) << QSize();
669 }
670
671 void tst_QVariant::toSize()
672 {
673     QFETCH( QVariant, value );
674     QFETCH( QSize, result );
675     QVERIFY( value.isValid() );
676     QVERIFY( value.canConvert( QVariant::Size ) );
677
678     QSize i = value.toSize();
679     QCOMPARE( i, result );
680 }
681
682 void tst_QVariant::toSizeF_data()
683 {
684     QTest::addColumn<QVariant>("value");
685     QTest::addColumn<QSizeF>("result");
686     QTest::newRow( "qsize1" ) << QVariant( QSize(0, 0) ) << QSizeF(0, 0);
687     QTest::newRow( "qsize2" ) << QVariant( QSize(-5, -1) ) << QSizeF(-5, -1);
688      QTest::newRow( "qsize3" ) << QVariant( QSize() ) << QSizeF();
689     QTest::newRow( "qsize4" ) << QVariant(QSize(4,2)) << QSizeF(4,2);
690 }
691
692 void tst_QVariant::toSizeF()
693 {
694     QFETCH( QVariant, value );
695     QFETCH( QSizeF, result );
696     QVERIFY( value.isValid() );
697     QVERIFY( value.canConvert( QVariant::SizeF ) );
698
699     QSizeF i = value.toSizeF();
700     QCOMPARE( i, result );
701 }
702
703 void tst_QVariant::toLine_data()
704 {
705     QTest::addColumn<QVariant>("value");
706     QTest::addColumn<QLine>("result");
707     QTest::newRow( "linef1" ) << QVariant( QLineF(1, 2, 3, 4) ) << QLine(1, 2, 3, 4);
708     QTest::newRow( "linef2" ) << QVariant( QLineF(-1, -2, -3, -4) ) << QLine(-1, -2, -3, -4);
709     QTest::newRow( "linef3" ) << QVariant( QLineF(0, 0, 0, 0) ) << QLine(0, 0, 0, 0);
710     QTest::newRow( "linef4" ) << QVariant( QLineF() ) << QLine();
711 }
712
713 void tst_QVariant::toLine()
714 {
715     QFETCH( QVariant, value );
716     QFETCH( QLine, result );
717     QVERIFY( value.isValid() );
718     QVERIFY( value.canConvert( QVariant::Line ) );
719
720     QLine i = value.toLine();
721     QCOMPARE( i, result );
722 }
723
724 void tst_QVariant::toLineF_data()
725 {
726     QTest::addColumn<QVariant>("value");
727     QTest::addColumn<QLineF>("result");
728     QTest::newRow( "line1" ) << QVariant( QLine(-1, -2, -3, -4) ) << QLineF(-1, -2, -3, -4);
729     QTest::newRow( "line2" ) << QVariant( QLine(0, 0, 0, 0) ) << QLineF(0, 0, 0, 0);
730     QTest::newRow( "line3" ) << QVariant( QLine() ) << QLineF();
731     QTest::newRow( "line4" ) << QVariant( QLine(1, 2, 3, 4) ) << QLineF(1, 2, 3, 4);
732 }
733
734 void tst_QVariant::toLineF()
735 {
736     QFETCH( QVariant, value );
737     QFETCH( QLineF, result );
738     QVERIFY( value.isValid() );
739     QVERIFY( value.canConvert( QVariant::LineF ) );
740
741     QLineF i = value.toLineF();
742     QCOMPARE( i, result );
743 }
744
745 void tst_QVariant::toPoint_data()
746 {
747     QTest::addColumn<QVariant>("value");
748     QTest::addColumn<QPoint>("result");
749     QTest::newRow( "pointf1" ) << QVariant( QPointF(4, 2) ) << QPoint(4, 2);
750     QTest::newRow( "pointf2" ) << QVariant( QPointF(0, 0) ) << QPoint(0, 0);
751     QTest::newRow( "pointf3" ) << QVariant( QPointF(-4, -2) ) << QPoint(-4, -2);
752     QTest::newRow( "pointf4" ) << QVariant( QPointF() ) << QPoint();
753     QTest::newRow( "pointf5" ) << QVariant( QPointF(-4.2f, -2.3f) ) << QPoint(-4, -2);
754 }
755
756 void tst_QVariant::toPoint()
757 {
758     QFETCH( QVariant, value );
759     QFETCH( QPoint, result );
760     QVERIFY( value.isValid() );
761     QVERIFY( value.canConvert( QVariant::Point ) );
762     QPoint i = value.toPoint();
763     QCOMPARE( i, result );
764 }
765
766 void tst_QVariant::toRect_data()
767 {
768     QTest::addColumn<QVariant>("value");
769     QTest::addColumn<QRect>("result");
770     QTest::newRow( "rectf1" ) << QVariant(QRectF(1, 2, 3, 4)) << QRect(1, 2, 3, 4);
771     QTest::newRow( "rectf2" ) << QVariant(QRectF(0, 0, 0, 0)) << QRect(0, 0, 0, 0);
772     QTest::newRow( "rectf3" ) << QVariant(QRectF(-1, -2, -3, -4)) << QRect(-1, -2, -3, -4);
773     QTest::newRow( "rectf4" ) << QVariant(QRectF(-1.3f, 0, 3.9f, -4.0)) << QRect(-1, 0, 4, -4);
774     QTest::newRow( "rectf5" ) << QVariant(QRectF()) << QRect();
775 }
776
777 void tst_QVariant::toRect()
778 {
779     QFETCH( QVariant, value );
780     QFETCH( QRect, result );
781     QVERIFY( value.isValid() );
782     QVERIFY( value.canConvert( QVariant::Rect ) );
783     QRect i = value.toRect();
784     QCOMPARE( i, result );
785 }
786
787 void tst_QVariant::toChar_data()
788 {
789     QTest::addColumn<QVariant>("value");
790     QTest::addColumn<QChar>("result");
791     QTest::newRow( "longlong" ) << QVariant(qlonglong('6')) << QChar('6');
792     QTest::newRow( "ulonglong" ) << QVariant(qulonglong('7')) << QChar('7');
793 }
794
795 void tst_QVariant::toChar()
796 {
797     QFETCH( QVariant, value );
798     QFETCH( QChar, result );
799     QVERIFY( value.isValid() );
800     QVERIFY( value.canConvert( QVariant::Char ) );
801
802     QChar i = value.toChar();
803     QCOMPARE( i, result );
804 }
805
806 void tst_QVariant::toBool_data()
807 {
808     QTest::addColumn<QVariant>("value");
809     QTest::addColumn<bool>("result");
810
811     QTest::newRow( "int0" ) << QVariant( 0 ) << false;
812     QTest::newRow( "int1" ) << QVariant( 123 ) << true;
813     QTest::newRow( "uint0" ) << QVariant( 0u ) << false;
814     QTest::newRow( "uint1" ) << QVariant( 123u ) << true;
815     QTest::newRow( "double0" ) << QVariant( 0.0 ) << false;
816     QTest::newRow( "float0" ) << QVariant( 0.0f ) << false;
817     QTest::newRow( "double1" ) << QVariant( 3.1415927 ) << true;
818     QTest::newRow( "float1" ) << QVariant( 3.1415927f ) << true;
819     QTest::newRow( "string0" ) << QVariant( QString("3") ) << true;
820     QTest::newRow( "string1" ) << QVariant( QString("true") ) << true;
821     QTest::newRow( "string2" ) << QVariant( QString("0") ) << false;
822     QTest::newRow( "string3" ) << QVariant( QString("fAlSe") ) << false;
823     QTest::newRow( "longlong0" ) << QVariant( (qlonglong)0 ) << false;
824     QTest::newRow( "longlong1" ) << QVariant( (qlonglong)1 ) << true;
825     QTest::newRow( "ulonglong0" ) << QVariant( (qulonglong)0 ) << false;
826     QTest::newRow( "ulonglong1" ) << QVariant( (qulonglong)1 ) << true;
827     QTest::newRow( "QChar" ) << QVariant(QChar('a')) << true;
828     QTest::newRow( "Null_QChar" ) << QVariant(QChar(0)) << false;
829 }
830
831 void tst_QVariant::toBool()
832 {
833     QFETCH( QVariant, value );
834     QFETCH( bool, result );
835     QVERIFY( value.isValid() );
836     QVERIFY( value.canConvert( QVariant::Bool ) );
837
838     bool i = value.toBool();
839     QCOMPARE( i, result );
840 }
841
842 void tst_QVariant::toPointF_data()
843 {
844     QTest::addColumn<QVariant>("value");
845     QTest::addColumn<QPointF>("result");
846
847     QTest::newRow( "QPoint" ) << QVariant( QPointF( 19, 84) ) << QPointF( 19, 84 );
848 }
849
850 void tst_QVariant::toPointF()
851 {
852     QFETCH( QVariant, value );
853     QFETCH( QPointF, result );
854     QVERIFY( value.isValid() );
855     QVERIFY( value.canConvert( QVariant::PointF ) );
856     QPointF d = value.toPointF();
857     QCOMPARE( d, result );
858 }
859
860 void tst_QVariant::toRectF_data()
861 {
862     QTest::addColumn<QVariant>("value");
863     QTest::addColumn<QRectF>("result");
864
865     QRect r( 1, 9, 8, 4 );
866     QRectF rf( 1.0, 9.0, 8.0, 4.0 );
867     QTest::newRow( "QRect" ) << QVariant( r ) << rf;
868 }
869
870 void tst_QVariant::toRectF()
871 {
872     QFETCH( QVariant, value );
873     QFETCH( QRectF, result );
874     QVERIFY( value.isValid() );
875     QVERIFY( value.canConvert( QVariant::RectF ) );
876     QRectF d = value.toRectF();
877     QCOMPARE( d, result );
878 }
879
880 void tst_QVariant::toColor_data()
881 {
882     QTest::addColumn<QVariant>("value");
883     QTest::addColumn<QColor>("result");
884
885     QColor c("red");
886     QTest::newRow( "string" ) << QVariant( QString( "red" ) ) << c;
887     QTest::newRow( "solid brush" ) << QVariant( QBrush(c) ) << c;
888 }
889
890 void tst_QVariant::toColor()
891 {
892     QFETCH( QVariant, value );
893     QFETCH( QColor, result );
894     QVERIFY( value.isValid() );
895     QVERIFY( value.canConvert( QVariant::Color ) );
896     QColor d = qvariant_cast<QColor>(value);
897     QCOMPARE( d, result );
898 }
899
900 void tst_QVariant::toPixmap_data()
901 {
902     QTest::addColumn<QVariant>("value");
903     QTest::addColumn<QPixmap>("result");
904
905     QPixmap pm(30, 30);
906     pm.fill(Qt::red);
907     QTest::newRow( "image" ) << QVariant( pm ) << pm;
908
909     QBitmap bm(30, 30);
910     bm.fill(Qt::color1);
911     QTest::newRow( "bitmap" ) << QVariant( bm ) << QPixmap(bm);
912 }
913
914 void tst_QVariant::toPixmap()
915 {
916     QFETCH( QVariant, value );
917     QFETCH( QPixmap, result );
918     QVERIFY( value.isValid() );
919     QVERIFY( value.canConvert( QVariant::Pixmap ) );
920     QPixmap d = qvariant_cast<QPixmap>(value);
921     QCOMPARE( d, result );
922 }
923
924 void tst_QVariant::toImage_data()
925 {
926     QTest::addColumn<QVariant>("value");
927     QTest::addColumn<QImage>("result");
928
929     QImage im(30, 30, QImage::Format_ARGB32);
930     im.fill(0x7fff0000);
931     QTest::newRow( "image" ) << QVariant( im ) << im;
932 }
933
934 void tst_QVariant::toImage()
935 {
936     QFETCH( QVariant, value );
937     QFETCH( QImage, result );
938     QVERIFY( value.isValid() );
939     QVERIFY( value.canConvert( QVariant::Image ) );
940     QImage d = qvariant_cast<QImage>(value);
941     QCOMPARE( d, result );
942 }
943
944 void tst_QVariant::toBrush_data()
945 {
946     QTest::addColumn<QVariant>("value");
947     QTest::addColumn<QBrush>("result");
948
949     QColor c(Qt::red);
950     QTest::newRow( "color" ) << QVariant( c ) << QBrush(c);
951     QPixmap pm(30, 30);
952     pm.fill(c);
953     QTest::newRow( "pixmap" ) << QVariant( pm ) << QBrush(pm);
954 }
955
956 void tst_QVariant::toBrush()
957 {
958     QFETCH( QVariant, value );
959     QFETCH( QBrush, result );
960     QVERIFY( value.isValid() );
961     QVERIFY( value.canConvert( QVariant::Brush ) );
962     QBrush d = qvariant_cast<QBrush>(value);
963     QCOMPARE( d, result );
964 }
965
966 void tst_QVariant::toFont_data()
967 {
968     QTest::addColumn<QVariant>("value");
969     QTest::addColumn<QFont>("result");
970
971     QFont f("times",12,-1,false);
972     QTest::newRow( "string" ) << QVariant( QString( "times,12,-1,5,50,0,0,0,0,0" ) ) << f;
973 }
974
975 void tst_QVariant::toFont()
976 {
977     QFETCH( QVariant, value );
978     QFETCH( QFont, result );
979     QVERIFY( value.isValid() );
980     QVERIFY( value.canConvert( QVariant::Font ) );
981     QFont d = qvariant_cast<QFont>(value);
982     QCOMPARE( d, result );
983 }
984
985 void tst_QVariant::toKeySequence_data()
986 {
987     QTest::addColumn<QVariant>("value");
988     QTest::addColumn<QKeySequence>("result");
989
990
991     QTest::newRow( "int" ) << QVariant( 67108929 ) << QKeySequence( Qt::CTRL + Qt::Key_A );
992
993
994     QTest::newRow( "qstring" )
995         << QVariant( QString( "Ctrl+A" ) )
996         << QKeySequence( Qt::CTRL + Qt::Key_A );
997 }
998
999 void tst_QVariant::toKeySequence()
1000 {
1001     QFETCH( QVariant, value );
1002     QFETCH( QKeySequence, result );
1003     QVERIFY( value.isValid() );
1004     QVERIFY( value.canConvert( QVariant::KeySequence ) );
1005     QKeySequence d = qvariant_cast<QKeySequence>(value);
1006     QCOMPARE( d, result );
1007 }
1008
1009 void tst_QVariant::toDouble_data()
1010 {
1011     QTest::addColumn<QVariant>("value");
1012     QTest::addColumn<double>("result");
1013     QTest::addColumn<bool>("valueOK");
1014
1015     QByteArray bytearray(4, ' ');
1016     bytearray[0] = '3';
1017     bytearray[1] = '2';
1018     bytearray[2] = '.';
1019     bytearray[3] = '1';
1020     QTest::newRow( "bytearray" ) << QVariant( bytearray ) << 32.1 << true;
1021 }
1022
1023 void tst_QVariant::toDouble()
1024 {
1025     QFETCH( QVariant, value );
1026     QFETCH( double, result );
1027     QFETCH( bool, valueOK );
1028     QVERIFY( value.isValid() );
1029     QVERIFY( value.canConvert( QVariant::Double ) );
1030     bool ok;
1031     double d = value.toDouble( &ok );
1032     QCOMPARE( d, result );
1033     QVERIFY( ok == valueOK );
1034 }
1035
1036 void tst_QVariant::toLongLong_data()
1037 {
1038     QTest::addColumn<QVariant>("value");
1039     QTest::addColumn<qlonglong>("result");
1040     QTest::addColumn<bool>("valueOK");
1041
1042     QTest::newRow( "int0" ) << QVariant( 123 ) << (qlonglong)123 << true;
1043     QTest::newRow( "double" ) << QVariant( 3.1415927 ) << (qlonglong)3 << true;
1044     QTest::newRow( "float" ) << QVariant( 3.1415927f ) << (qlonglong)3 << true;
1045     QTest::newRow( "uint" ) << QVariant( 123u ) << (qlonglong)123 << true;
1046     QTest::newRow( "int-string" ) << QVariant( QString("123") )
1047                                << (qlonglong)123 << true;
1048     QTest::newRow( "string" ) << QVariant( QString("Unicode fun") ) << (qlonglong)0
1049                            << false;
1050     QTest::newRow( "longlong" ) << QVariant( intMax1 ) << intMax1 << true;
1051     QTest::newRow( "ulonglong" ) << QVariant( uintMax1 ) << (qlonglong)uintMax1 << true;
1052     QTest::newRow( "QChar" ) << QVariant(QChar('a')) << qlonglong('a') << true;
1053     QByteArray bytearray(4, ' ');
1054     bytearray[0] = '3';
1055     bytearray[1] = '2';
1056     bytearray[2] = '0';
1057     bytearray[3] = '0';
1058     QTest::newRow( "QByteArray" ) << QVariant( bytearray ) << (qlonglong) 3200 << true;
1059 }
1060
1061 void tst_QVariant::toLongLong()
1062 {
1063     QFETCH( QVariant, value );
1064     QFETCH( qlonglong, result );
1065     QFETCH( bool, valueOK );
1066     QVERIFY( value.isValid() );
1067     QVERIFY( value.canConvert( QVariant::LongLong ) );
1068     bool ok;
1069     qlonglong ll = value.toLongLong( &ok );
1070     QCOMPARE( ll, result );
1071     QVERIFY( ok == valueOK );
1072 }
1073
1074 void tst_QVariant::toULongLong_data()
1075 {
1076     QTest::addColumn<QVariant>("value");
1077     QTest::addColumn<qulonglong>("result");
1078     QTest::addColumn<bool>("valueOK");
1079
1080     QTest::newRow( "int0" ) << QVariant( 123 ) << (qulonglong)123 << true;
1081     QTest::newRow( "double" ) << QVariant( 3.1415927 ) << (qulonglong)3 << true;
1082     QTest::newRow( "float" ) << QVariant( 3.1415927f ) << (qulonglong)3 << true;
1083     QTest::newRow( "uint" ) << QVariant( 123u ) << (qulonglong)123 << true;
1084     QTest::newRow( "int-string" ) << QVariant( QString("123") )
1085                                << (qulonglong)123 << true;
1086     QTest::newRow( "string" ) << QVariant( QString("Unicode fun") ) << (qulonglong)0
1087                            << false;
1088     QTest::newRow( "ulonglong-string" ) << QVariant( QString("18446744073709551615") )
1089                                      << Q_UINT64_C(18446744073709551615)
1090                                      << true;
1091     QTest::newRow( "bytaa-string" ) << QVariant( QString("18446744073709551615") )
1092                                      << Q_UINT64_C(18446744073709551615)
1093                                      << true;
1094     QTest::newRow( "longlong" ) << QVariant( intMax1 ) << (qulonglong)intMax1 << true;
1095     QTest::newRow( "ulonglong" ) << QVariant( uintMax1 ) << uintMax1 << true;
1096     QTest::newRow( "QChar" ) << QVariant(QChar('a')) << qulonglong('a') << true;
1097     QByteArray bytearray(4, ' ');
1098     bytearray[0] = '3';
1099     bytearray[1] = '2';
1100     bytearray[2] = '0';
1101     bytearray[3] = '1';
1102     QTest::newRow( "QByteArray" ) << QVariant( bytearray ) << (qulonglong) 3201 << true;
1103 }
1104
1105 void tst_QVariant::toULongLong()
1106 {
1107     QFETCH( QVariant, value );
1108     QFETCH( qulonglong, result );
1109     QFETCH( bool, valueOK );
1110     QVERIFY( value.isValid() );
1111     QVERIFY( value.canConvert( QVariant::ULongLong ) );
1112     bool ok;
1113     qulonglong ll = value.toULongLong( &ok );
1114     QCOMPARE( ll, result );
1115     QVERIFY( ok == valueOK );
1116 }
1117
1118 void tst_QVariant::toByteArray_data()
1119 {
1120     QTest::addColumn<QVariant>("value");
1121     QTest::addColumn<QByteArray>("result");
1122
1123     QByteArray ba(5, ' ');
1124     ba[0] = 'T';
1125     ba[1] = 'e';
1126     ba[2] = 's';
1127     ba[3] = 't';
1128     ba[4] = '\0';
1129
1130     QByteArray variantBa = ba;
1131
1132     QTest::newRow( "qbytearray" ) << QVariant( variantBa ) << ba;
1133     QTest::newRow( "int" ) << QVariant( -123 ) << QByteArray( "-123" );
1134     QTest::newRow( "uint" ) << QVariant( (uint)123 ) << QByteArray( "123" );
1135     QTest::newRow( "double" ) << QVariant( 123.456 ) << QByteArray( "123.456" );
1136     QTest::newRow( "float" ) << QVariant( 123.456f ) << QByteArray( "123.456" );
1137     QTest::newRow( "longlong" ) << QVariant( (qlonglong)34 ) << QByteArray( "34" );
1138     QTest::newRow( "ulonglong" ) << QVariant( (qulonglong)34 ) << QByteArray( "34" );
1139 }
1140
1141 void tst_QVariant::toByteArray()
1142 {
1143     QFETCH( QVariant, value );
1144     QFETCH( QByteArray, result );
1145     QVERIFY( value.isValid() );
1146     QVERIFY( value.canConvert( QVariant::ByteArray ) );
1147     QByteArray ba = value.toByteArray();
1148     QCOMPARE( ba, result );
1149 }
1150
1151 void tst_QVariant::toString_data()
1152 {
1153     QTest::addColumn<QVariant>("value");
1154     QTest::addColumn<QString>("result");
1155
1156     QTest::newRow( "qstring" ) << QVariant( QString( "Test" ) ) << QString( "Test" );
1157     QTest::newRow( "charstar" ) << QVariant(QLatin1String("Test")) << QString("Test");
1158     QTest::newRow( "qbytearray") << QVariant( QByteArray( "Test\0" ) ) << QString( "Test" );
1159     QTest::newRow( "int" ) << QVariant( -123 ) << QString( "-123" );
1160     QTest::newRow( "uint" ) << QVariant( (uint)123 ) << QString( "123" );
1161     QTest::newRow( "double" ) << QVariant( 123.456 ) << QString( "123.456" );
1162     QTest::newRow( "float" ) << QVariant( 123.456f ) << QString( "123.456" );
1163     QTest::newRow( "bool" ) << QVariant( true ) << QString( "true" );
1164     QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 1, 1 ) ) << QString( "2002-01-01" );
1165     QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56" );
1166     QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56 ) ) ) << QString( "2002-01-01T12:34:56" );
1167     QTest::newRow( "qkeysequence" ) << QVariant::fromValue( QKeySequence( Qt::CTRL + Qt::Key_A ) )
1168 #ifndef Q_OS_MAC
1169         << QString( "Ctrl+A" );
1170 #else
1171         << QString(QChar(0x2318)) + "A";
1172 #endif
1173
1174     QFont font( "times", 12 );
1175     QTest::newRow( "qfont" ) << QVariant::fromValue( font ) << QString("times,12,-1,5,50,0,0,0,0,0");
1176     QTest::newRow( "qcolor" ) << QVariant::fromValue( QColor( 10, 10, 10 ) ) << QString( "#0a0a0a" );
1177     QTest::newRow( "llong" ) << QVariant( (qlonglong)Q_INT64_C(123456789012) ) <<
1178         QString( "123456789012" );
1179 }
1180
1181 void tst_QVariant::toString()
1182 {
1183     QFETCH( QVariant, value );
1184     QFETCH( QString, result );
1185     QVERIFY( value.isValid() );
1186     QVERIFY( value.canConvert( QVariant::String ) );
1187     QString str = value.toString();
1188     QCOMPARE( str, result );
1189 }
1190
1191 void tst_QVariant::toDate_data()
1192 {
1193     QTest::addColumn<QVariant>("value");
1194     QTest::addColumn<QDate>("result");
1195
1196     QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 10, 10 ) ) << QDate( 2002, 10, 10 );
1197     QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ) ) << QDate( 2002, 10, 10 );
1198     QTest::newRow( "qstring" ) << QVariant( QString( "2002-10-10" ) ) << QDate( 2002, 10, 10 );
1199 }
1200
1201 void tst_QVariant::toDate()
1202 {
1203     QFETCH( QVariant, value );
1204     QFETCH( QDate, result );
1205     QVERIFY( value.isValid() );
1206     QVERIFY( value.canConvert( QVariant::Date ) );
1207     QCOMPARE( value.toDate(), result );
1208 }
1209
1210 void tst_QVariant::toTime_data()
1211 {
1212     QTest::addColumn<QVariant>("value");
1213     QTest::addColumn<QTime>("result");
1214
1215     QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QTime( 12, 34, 56 );
1216     QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ) ) << QTime( 12, 34, 56 );
1217     QTest::newRow( "qstring" ) << QVariant( QString( "12:34:56" ) ) << QTime( 12, 34, 56 );
1218 }
1219
1220 void tst_QVariant::toTime()
1221 {
1222     QFETCH( QVariant, value );
1223     QFETCH( QTime, result );
1224     QVERIFY( value.isValid() );
1225     QVERIFY( value.canConvert( QVariant::Time ) );
1226     QCOMPARE( value.toTime(), result );
1227 }
1228
1229 void tst_QVariant::toDateTime_data()
1230 {
1231     QTest::addColumn<QVariant>("value");
1232     QTest::addColumn<QDateTime>("result");
1233
1234     QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ) )
1235         << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) );
1236     QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 10, 10 ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 0, 0, 0 ) );
1237     QTest::newRow( "qstring" ) << QVariant( QString( "2002-10-10T12:34:56" ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) );
1238 }
1239
1240 void tst_QVariant::toDateTime()
1241 {
1242     QFETCH( QVariant, value );
1243     QFETCH( QDateTime, result );
1244     QVERIFY( value.isValid() );
1245     QVERIFY( value.canConvert( QVariant::DateTime ) );
1246     QCOMPARE( value.toDateTime(), result );
1247 }
1248
1249 void tst_QVariant::toLocale()
1250 {
1251     QVariant variant;
1252     QLocale loc = variant.toLocale();
1253     variant = QLocale::system();
1254     loc = variant.toLocale();
1255 }
1256
1257 void tst_QVariant::toRegExp()
1258 {
1259     QVariant variant;
1260     QRegExp rx = variant.toRegExp();
1261     variant = QRegExp("foo");
1262     rx = variant.toRegExp();
1263 }
1264
1265 void tst_QVariant::toRegularExpression()
1266 {
1267     QVariant variant;
1268     QRegularExpression re = variant.toRegularExpression();
1269     QCOMPARE(re, QRegularExpression());
1270
1271     variant = QRegularExpression("abc.*def");
1272     re = variant.toRegularExpression();
1273     QCOMPARE(re, QRegularExpression("abc.*def"));
1274
1275     variant = QVariant::fromValue(QRegularExpression("[ab]\\w+"));
1276     re = variant.value<QRegularExpression>();
1277     QCOMPARE(re, QRegularExpression("[ab]\\w+"));
1278 }
1279
1280 void tst_QVariant::matrix()
1281 {
1282     QVariant variant;
1283     QMatrix matrix = qvariant_cast<QMatrix>(variant);
1284     QVERIFY(matrix.isIdentity());
1285     variant.setValue(QMatrix().rotate(90));
1286     QCOMPARE(QMatrix().rotate(90), qvariant_cast<QMatrix>(variant));
1287
1288     void *mmatrix = QMetaType::create(QVariant::Matrix, 0);
1289     QVERIFY(mmatrix);
1290     QMetaType::destroy(QVariant::Matrix, mmatrix);
1291 }
1292
1293 void tst_QVariant::matrix4x4()
1294 {
1295     QVariant variant;
1296     QMatrix4x4 matrix = qvariant_cast<QMatrix4x4>(variant);
1297     QVERIFY(matrix.isIdentity());
1298     QMatrix4x4 m;
1299     m.scale(2.0f);
1300     variant.setValue(m);
1301     QCOMPARE(m, qvariant_cast<QMatrix4x4>(variant));
1302
1303     void *mmatrix = QMetaType::create(QVariant::Matrix4x4, 0);
1304     QVERIFY(mmatrix);
1305     QMetaType::destroy(QVariant::Matrix4x4, mmatrix);
1306 }
1307
1308 void tst_QVariant::transform()
1309 {
1310     QVariant variant;
1311     QTransform matrix = qvariant_cast<QTransform>(variant);
1312     QVERIFY(matrix.isIdentity());
1313     variant.setValue(QTransform().rotate(90));
1314     QCOMPARE(QTransform().rotate(90), qvariant_cast<QTransform>(variant));
1315
1316     void *mmatrix = QMetaType::create(QVariant::Transform, 0);
1317     QVERIFY(mmatrix);
1318     QMetaType::destroy(QVariant::Transform, mmatrix);
1319 }
1320
1321
1322 void tst_QVariant::vector2D()
1323 {
1324     QVariant variant;
1325     QVector2D vector = qvariant_cast<QVector2D>(variant);
1326     QVERIFY(vector.isNull());
1327     variant.setValue(QVector2D(0.1, 0.2));
1328     QCOMPARE(QVector2D(0.1, 0.2), qvariant_cast<QVector2D>(variant));
1329
1330     void *pvector = QMetaType::create(QVariant::Vector2D, 0);
1331     QVERIFY(pvector);
1332     QMetaType::destroy(QVariant::Vector2D, pvector);
1333 }
1334
1335 void tst_QVariant::vector3D()
1336 {
1337     QVariant variant;
1338     QVector3D vector = qvariant_cast<QVector3D>(variant);
1339     QVERIFY(vector.isNull());
1340     variant.setValue(QVector3D(0.1, 0.2, 0.3));
1341     QCOMPARE(QVector3D(0.1, 0.2, 0.3), qvariant_cast<QVector3D>(variant));
1342
1343     void *pvector = QMetaType::create(QVariant::Vector3D, 0);
1344     QVERIFY(pvector);
1345     QMetaType::destroy(QVariant::Vector3D, pvector);
1346 }
1347
1348 void tst_QVariant::vector4D()
1349 {
1350     QVariant variant;
1351     QVector4D vector = qvariant_cast<QVector4D>(variant);
1352     QVERIFY(vector.isNull());
1353     variant.setValue(QVector4D(0.1, 0.2, 0.3, 0.4));
1354     QCOMPARE(QVector4D(0.1, 0.2, 0.3, 0.4), qvariant_cast<QVector4D>(variant));
1355
1356     void *pvector = QMetaType::create(QVariant::Vector4D, 0);
1357     QVERIFY(pvector);
1358     QMetaType::destroy(QVariant::Vector4D, pvector);
1359 }
1360
1361 void tst_QVariant::quaternion()
1362 {
1363     QVariant variant;
1364     QQuaternion quaternion = qvariant_cast<QQuaternion>(variant);
1365     QVERIFY(quaternion.isIdentity());
1366     variant.setValue(QQuaternion(0.1, 0.2, 0.3, 0.4));
1367     QCOMPARE(QQuaternion(0.1, 0.2, 0.3, 0.4), qvariant_cast<QQuaternion>(variant));
1368
1369     void *pquaternion = QMetaType::create(QVariant::Quaternion, 0);
1370     QVERIFY(pquaternion);
1371     QMetaType::destroy(QVariant::Quaternion, pquaternion);
1372 }
1373
1374 struct CustomStreamableClass
1375 {
1376     int i;
1377     bool operator==(const CustomStreamableClass& other) const
1378     {
1379         return i == other.i;
1380     }
1381 };
1382 Q_DECLARE_METATYPE(CustomStreamableClass);
1383
1384 QDataStream &operator<<(QDataStream &out, const CustomStreamableClass &myObj)
1385 {
1386     return out << myObj.i;
1387 }
1388
1389 QDataStream &operator>>(QDataStream &in, CustomStreamableClass &myObj)
1390 {
1391     return in >> myObj.i;
1392 }
1393
1394 void tst_QVariant::writeToReadFromDataStream_data()
1395 {
1396     qRegisterMetaTypeStreamOperators<CustomStreamableClass>();
1397
1398     QTest::addColumn<QVariant>("writeVariant");
1399     QTest::addColumn<bool>("isNull");
1400     {
1401         typedef QList<QVariant> variantsList;
1402         variantsList valuelist;
1403         valuelist << QVariant( 1 ) << QVariant( QString("Two") ) << QVariant( 3.45 );
1404         QVariant var(valuelist);
1405         QTest::newRow( "list_valid" ) << var << false;
1406     }
1407
1408     QTest::newRow( "invalid" ) << QVariant() << true;
1409     QTest::newRow( "bitarray_invalid" ) << QVariant( QBitArray() ) << true;
1410     QBitArray bitarray( 3 );
1411     bitarray[0] = 0;
1412     bitarray[1] = 1;
1413     bitarray[2] = 0;
1414     QTest::newRow( "bitarray_valid" ) << QVariant( bitarray ) << false;
1415     QTest::newRow( "bytearray_invalid" ) << QVariant( QByteArray() ) << true;
1416     QTest::newRow( "int_invalid") << QVariant(QVariant::Int) << true;
1417     QByteArray bytearray(5, ' ');
1418     bytearray[0] = 'T';
1419     bytearray[1] = 'e';
1420     bytearray[2] = 's';
1421     bytearray[3] = 't';
1422     bytearray[4] = '\0';
1423     QTest::newRow( "bytearray_valid" ) << QVariant( bytearray ) << false;
1424     QTest::newRow( "bitmap_invalid" ) << QVariant::fromValue( QBitmap() ) << true;
1425     QBitmap bitmap( 10, 10 );
1426     bitmap.fill( Qt::red );
1427     QTest::newRow( "bitmap_valid" ) << QVariant::fromValue( bitmap ) << false;
1428     QTest::newRow( "brush_valid" ) << QVariant::fromValue( QBrush( Qt::red ) ) << false;
1429     QTest::newRow( "color_valid" ) << QVariant::fromValue( QColor( Qt::red ) ) << false;
1430 #ifndef QT_NO_CURSOR
1431     QTest::newRow( "cursor_valid" ) << QVariant::fromValue( QCursor( Qt::PointingHandCursor ) ) << false;
1432 #endif
1433     QTest::newRow( "date_invalid" ) << QVariant( QDate() ) << true;
1434     QTest::newRow( "date_valid" ) << QVariant( QDate( 2002, 07, 06 ) ) << false;
1435     QTest::newRow( "datetime_invalid" ) << QVariant( QDateTime() ) << true;
1436     QTest::newRow( "datetime_valid" ) << QVariant( QDateTime( QDate( 2002, 07, 06 ), QTime( 14, 0, 0 ) ) ) << false;
1437     QTest::newRow( "double_valid" ) << QVariant( 123.456 ) << false;
1438     QTest::newRow( "float_valid" ) << QVariant( 123.456f ) << false;
1439     QTest::newRow( "font_valid" ) << QVariant::fromValue( QFont( "times", 12 ) ) << false;
1440     QTest::newRow( "pixmap_invalid" ) << QVariant::fromValue( QPixmap() ) << true;
1441     QPixmap pixmap( 10, 10 );
1442     pixmap.fill( Qt::red );
1443     QTest::newRow( "pixmap_valid" ) << QVariant::fromValue( pixmap ) << false;
1444 //    QTest::newRow( "iconset_valid" ) << QVariant( QIcon( pixmap ) ) << false;
1445     QTest::newRow( "image_invalid" ) << QVariant::fromValue( QImage() ) << true;
1446     QTest::newRow( "keysequence_valid" ) << QVariant::fromValue( QKeySequence( Qt::CTRL + Qt::Key_A ) ) << false;
1447     QTest::newRow( "int_valid" ) << QVariant( -123 ) << false;
1448     typedef QMap<QString, QVariant> variantsMap;
1449     variantsMap vMap;
1450     vMap.insert( "int", QVariant( 1 ) );
1451     vMap.insert( "string", QVariant( QString("Two") ) );
1452     vMap.insert( "double", QVariant( 3.45 ) );
1453     vMap.insert( "float", QVariant( 3.45f ) );
1454     QTest::newRow( "map_valid" ) << QVariant( vMap ) << false;
1455     QTest::newRow( "palette_valid" ) << QVariant::fromValue(QPalette(QColor("turquoise"))) << false;
1456     QTest::newRow( "pen_valid" ) << QVariant::fromValue( QPen( Qt::red ) ) << false;
1457     QTest::newRow( "pointarray_invalid" ) << QVariant::fromValue( QPolygon() ) << true;
1458     QTest::newRow( "pointarray_valid" ) << QVariant::fromValue( QPolygon( QRect( 10, 10, 20, 20 ) ) ) << false;
1459     QTest::newRow( "region_invalid" ) << QVariant::fromValue( QRegion() ) << true;
1460     QTest::newRow( "region_valid" ) << QVariant::fromValue( QRegion( 10, 10, 20, 20 ) ) << false;
1461     QTest::newRow( "point_invalid" ) << QVariant::fromValue( QPoint() ) << true;
1462     QTest::newRow( "point_valid" ) << QVariant::fromValue( QPoint( 10, 10 ) ) << false;
1463     QTest::newRow( "rect_invalid" ) << QVariant( QRect() ) << true;
1464     QTest::newRow( "rect_valid" ) << QVariant( QRect( 10, 10, 20, 20 ) ) << false;
1465     QTest::newRow( "size_invalid" ) << QVariant( QSize( 0, 0 ) ) << true;
1466     QTest::newRow( "size_valid" ) << QVariant( QSize( 10, 10 ) ) << false;
1467     QTest::newRow( "string_invalid" ) << QVariant( QString() ) << true;
1468     QTest::newRow( "string_valid" ) << QVariant( QString( "Test" ) ) << false;
1469     QStringList stringlist;
1470     stringlist << "One" << "Two" << "Three";
1471     QTest::newRow( "stringlist_valid" ) << QVariant( stringlist ) << false;
1472     QTest::newRow( "time_invalid" ) << QVariant( QTime() ) << true;
1473     QTest::newRow( "time_valid" ) << QVariant( QTime( 14, 0, 0 ) ) << false;
1474     QTest::newRow( "uint_valid" ) << QVariant( (uint)123 ) << false;
1475     QTest::newRow( "qchar" ) << QVariant(QChar('a')) << false;
1476     QTest::newRow( "qchar_null" ) << QVariant(QChar(0)) << true;
1477     QTest::newRow( "regexp" ) << QVariant(QRegExp("foo", Qt::CaseInsensitive)) << false;
1478     QTest::newRow( "regexp_empty" ) << QVariant(QRegExp()) << false;
1479     QTest::newRow( "regularexpression" ) << QVariant(QRegularExpression("abc.*def")) << false;
1480     QTest::newRow( "regularexpression_empty" ) << QVariant(QRegularExpression()) << false;
1481
1482     // types known to QMetaType, but not part of QVariant::Type
1483     QTest::newRow("QMetaType::Long invalid") << QVariant(QMetaType::Long, (void *) 0) << false;
1484     long longInt = -1l;
1485     QTest::newRow("QMetaType::Long") << QVariant(QMetaType::Long, &longInt) << false;
1486     QTest::newRow("QMetaType::Short invalid") << QVariant(QMetaType::Short, (void *) 0) << false;
1487     short shortInt = 1;
1488     QTest::newRow("QMetaType::Short") << QVariant(QMetaType::Short, &shortInt) << false;
1489     QTest::newRow("QMetaType::Char invalid") << QVariant(QMetaType::Char, (void *) 0) << false;
1490     char ch = 'c';
1491     QTest::newRow("QMetaType::Char") << QVariant(QMetaType::Char, &ch) << false;
1492     QTest::newRow("QMetaType::ULong invalid") << QVariant(QMetaType::ULong, (void *) 0) << false;
1493     ulong ulongInt = 1ul;
1494     QTest::newRow("QMetaType::ULong") << QVariant(QMetaType::ULong, &ulongInt) << false;
1495     QTest::newRow("QMetaType::UShort invalid") << QVariant(QMetaType::UShort, (void *) 0) << false;
1496     ushort ushortInt = 1u;
1497     QTest::newRow("QMetaType::UShort") << QVariant(QMetaType::UShort, &ushortInt) << false;
1498     QTest::newRow("QMetaType::UChar invalid") << QVariant(QMetaType::UChar, (void *) 0) << false;
1499     uchar uch = 0xf0;
1500     QTest::newRow("QMetaType::UChar") << QVariant(QMetaType::UChar, &uch) << false;
1501     QTest::newRow("QMetaType::Float invalid") << QVariant(QMetaType::Float, (void *) 0) << false;
1502     float f = 1.234f;
1503     QTest::newRow("QMetaType::Float") << QVariant(QMetaType::Float, &f) << false;
1504     CustomStreamableClass custom = {123};
1505     QTest::newRow("Custom type") << QVariant::fromValue(custom) << false;
1506 }
1507
1508 void tst_QVariant::writeToReadFromDataStream()
1509 {
1510     QFETCH( QVariant, writeVariant );
1511     QFETCH( bool, isNull );
1512     QByteArray data;
1513
1514     QDataStream writeStream( &data, QIODevice::WriteOnly );
1515     writeStream << writeVariant;
1516
1517     QVariant readVariant;
1518     QDataStream readStream( &data, QIODevice::ReadOnly );
1519     readStream >> readVariant;
1520     QVERIFY( readVariant.isNull() == isNull );
1521     // Best way to confirm the readVariant contains the same data?
1522     // Since only a few won't match since the serial numbers are different
1523     // I won't bother adding another bool in the data test.
1524     const int writeType = writeVariant.userType();
1525     if (writeType == qMetaTypeId<CustomStreamableClass>())
1526         QCOMPARE(qvariant_cast<CustomStreamableClass>(readVariant), qvariant_cast<CustomStreamableClass>(writeVariant));
1527     else if ( writeType != QVariant::Invalid && writeType != QVariant::Bitmap && writeType != QVariant::Pixmap
1528         && writeType != QVariant::Image) {
1529         switch (writeType) {
1530         default:
1531             QCOMPARE( readVariant, writeVariant );
1532             break;
1533
1534         // compare types know by QMetaType but not QVariant (QVariant::operator==() knows nothing about them)
1535         case QMetaType::Long:
1536             QCOMPARE(qvariant_cast<long>(readVariant), qvariant_cast<long>(writeVariant));
1537             break;
1538         case QMetaType::ULong:
1539             QCOMPARE(qvariant_cast<ulong>(readVariant), qvariant_cast<ulong>(writeVariant));
1540             break;
1541         case QMetaType::Short:
1542             QCOMPARE(qvariant_cast<short>(readVariant), qvariant_cast<short>(writeVariant));
1543             break;
1544         case QMetaType::UShort:
1545             QCOMPARE(qvariant_cast<ushort>(readVariant), qvariant_cast<ushort>(writeVariant));
1546             break;
1547         case QMetaType::Char:
1548             QCOMPARE(qvariant_cast<char>(readVariant), qvariant_cast<char>(writeVariant));
1549             break;
1550         case QMetaType::UChar:
1551             QCOMPARE(qvariant_cast<uchar>(readVariant), qvariant_cast<uchar>(writeVariant));
1552             break;
1553         case QMetaType::Float:
1554             {
1555                 // the uninitialized float can be NaN (observed on Windows Mobile 5 ARMv4i)
1556                 float readFloat = qvariant_cast<float>(readVariant);
1557                 float writtenFloat = qvariant_cast<float>(writeVariant);
1558                 QVERIFY(qIsNaN(readFloat) == qIsNaN(writtenFloat));
1559                 if (!qIsNaN(readFloat))
1560                     QVERIFY(readFloat == writtenFloat);
1561             }
1562             break;
1563         }
1564     }
1565 }
1566
1567 void tst_QVariant::writeToReadFromOldDataStream()
1568 {
1569     QVariant writeVariant = QString("hello");
1570     QByteArray data;
1571
1572     QDataStream writeStream(&data, QIODevice::WriteOnly);
1573     writeStream.setVersion(QDataStream::Qt_2_1);
1574     writeStream << writeVariant;
1575
1576     QVariant readVariant;
1577     QDataStream readStream(&data, QIODevice::ReadOnly);
1578     readStream.setVersion(QDataStream::Qt_2_1);
1579     readStream >> readVariant;
1580
1581     QCOMPARE(writeVariant.userType(), readVariant.userType());
1582     QCOMPARE(writeVariant, readVariant);
1583 }
1584
1585 void tst_QVariant::checkDataStream()
1586 {
1587     const int typeId = QMetaType::LastCoreType + 1;
1588     QVERIFY(!QMetaType::isRegistered(typeId));
1589
1590     QByteArray errorMessage("Trying to construct an instance of an invalid type, type id: ");
1591     errorMessage.append(QString::number(typeId, 10));
1592
1593     QTest::ignoreMessage(QtWarningMsg, errorMessage.constData());
1594     QByteArray settingsHex("000000");
1595     settingsHex.append(QString::number(typeId, 16));
1596     settingsHex.append("ffffffffff");
1597     const QByteArray settings = QByteArray::fromHex(settingsHex);
1598     QDataStream in(settings);
1599     QVariant v;
1600     in >> v;
1601     // the line below has been left out for now since the data stream
1602     // is not necessarily considered corrupt when an invalid QVariant is
1603     // constructed. However, it might be worth considering changing that behavior
1604     // in the future.
1605 //    QCOMPARE(in.status(), QDataStream::ReadCorruptData);
1606     QCOMPARE(v.type(), QVariant::Invalid);
1607 }
1608
1609 void tst_QVariant::operator_eq_eq_data()
1610 {
1611     QTest::addColumn<QVariant>("left");
1612     QTest::addColumn<QVariant>("right");
1613     QTest::addColumn<bool>("equal"); // left == right ?
1614
1615     QVariant inv;
1616     QVariant i0( int(0) );
1617     QVariant i1( int(1) );
1618     // Invalid
1619     QTest::newRow( "invinv" ) << inv << inv << true;
1620     // Int
1621     QTest::newRow( "int1int1" ) << i1 << i1 << true;
1622     QTest::newRow( "int1int0" ) << i1 << i0 << false;
1623     QTest::newRow( "nullint" ) << i0 << QVariant(QVariant::Int) << false;
1624
1625     // LongLong and ULongLong
1626     QVariant ll1( (qlonglong)1 );
1627     QVariant lln2( (qlonglong)-2 );
1628     QVariant ull1( (qulonglong)1 );
1629     QVariant ull3( (qulonglong)3 );
1630     QTest::newRow( "ll1ll1" ) << ll1 << ll1 << true;
1631     QTest::newRow( "ll1lln2" ) << ll1 << lln2 << false;
1632     QTest::newRow( "ll1ull1" ) << ull1 << ull1 << true;
1633     QTest::newRow( "ll1i1" ) << ull1 << i1 << true;
1634     QTest::newRow( "ull1ull1" ) << ull1 << ull1 << true;
1635     QTest::newRow( "ull1i1" ) << ull1 << ull1 << true;
1636
1637     QVariant mInt(-42);
1638     QVariant mIntString(QByteArray("-42"));
1639     QVariant mIntQString(QString("-42"));
1640
1641     QVariant mUInt(42u);
1642     QVariant mUIntString(QByteArray("42"));
1643     QVariant mUIntQString(QString("42"));
1644
1645     QVariant mDouble(42.11);
1646     QVariant mDoubleString(QByteArray("42.11"));
1647     QVariant mDoubleQString(QString("42.11"));
1648
1649     QVariant mFloat(42.11f);
1650     QVariant mFloatString(QByteArray("42.11"));
1651     QVariant mFloatQString(QString("42.11"));
1652
1653     QVariant mLongLong((qlonglong)-42);
1654     QVariant mLongLongString(QByteArray("-42"));
1655     QVariant mLongLongQString(QString("-42"));
1656
1657     QVariant mULongLong((qulonglong)42);
1658     QVariant mULongLongString(QByteArray("42"));
1659     QVariant mULongLongQString(QString("42"));
1660
1661     QVariant mBool(false);
1662     QVariant mBoolString(QByteArray("false"));
1663     QVariant mBoolQString(QString("false"));
1664
1665     QTest::newRow( "double_int" ) << QVariant(42.0) << QVariant(42) << true;
1666     QTest::newRow( "float_int" ) << QVariant(42.f) << QVariant(42) << true;
1667     QTest::newRow( "mInt_mIntString" ) << mInt << mIntString << true;
1668     QTest::newRow( "mIntString_mInt" ) << mIntString << mInt << true;
1669     QTest::newRow( "mInt_mIntQString" ) << mInt << mIntQString << true;
1670     QTest::newRow( "mIntQString_mInt" ) << mIntQString << mInt << true;
1671
1672     QTest::newRow( "mUInt_mUIntString" ) << mUInt << mUIntString << true;
1673     QTest::newRow( "mUIntString_mUInt" ) << mUIntString << mUInt << true;
1674     QTest::newRow( "mUInt_mUIntQString" ) << mUInt << mUIntQString << true;
1675     QTest::newRow( "mUIntQString_mUInt" ) << mUIntQString << mUInt << true;
1676
1677     QTest::newRow( "mDouble_mDoubleString" ) << mDouble << mDoubleString << true;
1678     QTest::newRow( "mDoubleString_mDouble" ) << mDoubleString << mDouble << true;
1679     QTest::newRow( "mDouble_mDoubleQString" ) << mDouble << mDoubleQString << true;
1680     QTest::newRow( "mDoubleQString_mDouble" ) << mDoubleQString << mDouble << true;
1681
1682     QTest::newRow( "mFloat_mFloatString" ) << mFloat << mFloatString << true;
1683     QTest::newRow( "mFloatString_mFloat" ) << mFloatString << mFloat << true;
1684     QTest::newRow( "mFloat_mFloatQString" ) << mFloat << mFloatQString << true;
1685     QTest::newRow( "mFloatQString_mFloat" ) << mFloatQString << mFloat << true;
1686
1687     QTest::newRow( "mLongLong_mLongLongString" ) << mLongLong << mLongLongString << true;
1688     QTest::newRow( "mLongLongString_mLongLong" ) << mLongLongString << mLongLong << true;
1689     QTest::newRow( "mLongLong_mLongLongQString" ) << mLongLong << mLongLongQString << true;
1690     QTest::newRow( "mLongLongQString_mLongLong" ) << mLongLongQString << mLongLong << true;
1691
1692     QTest::newRow( "mULongLong_mULongLongString" ) << mULongLong << mULongLongString << true;
1693     QTest::newRow( "mULongLongString_mULongLong" ) << mULongLongString << mULongLong << true;
1694     QTest::newRow( "mULongLong_mULongLongQString" ) << mULongLong << mULongLongQString << true;
1695     QTest::newRow( "mULongLongQString_mULongLong" ) << mULongLongQString << mULongLong << true;
1696
1697     QTest::newRow( "mBool_mBoolString" ) << mBool << mBoolString << true;
1698     QTest::newRow( "mBoolString_mBool" ) << mBoolString << mBool << true;
1699     QTest::newRow( "mBool_mBoolQString" ) << mBool << mBoolQString << true;
1700     QTest::newRow( "mBoolQString_mBool" ) << mBoolQString << mBool << true;
1701
1702     QTest::newRow("ba2qstring") << QVariant(QLatin1String("hallo")) << QVariant(QString("hallo")) << true;
1703     QTest::newRow("qstring2ba") << QVariant(QString("hallo")) << QVariant(QLatin1String("hallo")) << true;
1704     QTest::newRow("char_char") << QVariant(QChar('a')) << QVariant(QChar('a')) << true;
1705     QTest::newRow("char_char2") << QVariant(QChar('a')) << QVariant(QChar('b')) << false;
1706
1707     QTest::newRow("invalidConversion") << QVariant(QString("bubu")) << QVariant(0) << false;
1708     QTest::newRow("invalidConversionR") << QVariant(0) << QVariant(QString("bubu")) << false;
1709     // ### many other combinations missing
1710
1711     {
1712         QMap<QString, QVariant> map1;
1713         map1.insert( "X", 1 );
1714
1715         QMap<QString, QVariant> map2;
1716         map2.insert( "Y", 1 );
1717
1718         QTest::newRow("TwoItemsInEqual") << QVariant(map1) << QVariant(map2) << false;
1719
1720     }
1721
1722     {
1723         QMap<QString, QVariant> map1;
1724         map1.insert( "X", 1 );
1725
1726         QMap<QString, QVariant> map2;
1727         map2.insert( "X", 1 );
1728
1729         QTest::newRow("TwoItemsEqual") << QVariant(map1) << QVariant(map2) << true;
1730     }
1731
1732     {
1733         QMap<QString, QVariant> map1;
1734         map1.insert( "X", 1 );
1735
1736         QMap<QString, QVariant> map2;
1737
1738         QTest::newRow("PopulatedEmptyMap") << QVariant(map1) << QVariant(map2) << false;
1739     }
1740
1741     {
1742         QMap<QString, QVariant> map1;
1743
1744         QMap<QString, QVariant> map2;
1745         map2.insert( "X", 1 );
1746
1747         QTest::newRow("EmptyPopulatedMap") << QVariant(map1) << QVariant(map2) << false;
1748     }
1749
1750     {
1751         QMap<QString, QVariant> map1;
1752         map1.insert( "X", 1 );
1753         map1.insert( "Y", 1 );
1754
1755         QMap<QString, QVariant> map2;
1756         map2.insert( "X", 1 );
1757
1758         QTest::newRow("FirstLarger") << QVariant(map1) << QVariant(map2) << false;
1759     }
1760
1761     {
1762         QMap<QString, QVariant> map1;
1763         map1.insert( "X", 1 );
1764
1765         QMap<QString, QVariant> map2;
1766         map2.insert( "X", 1 );
1767         map2.insert( "Y", 1 );
1768
1769         QTest::newRow("SecondLarger") << QVariant(map1) << QVariant(map2) << false;
1770     }
1771
1772     // same thing with hash
1773     {
1774         QHash<QString, QVariant> hash1;
1775         hash1.insert( "X", 1 );
1776
1777         QHash<QString, QVariant> hash2;
1778         hash2.insert( "Y", 1 );
1779
1780         QTest::newRow("HashTwoItemsInEqual") << QVariant(hash1) << QVariant(hash2) << false;
1781
1782     }
1783
1784     {
1785         QHash<QString, QVariant> hash1;
1786         hash1.insert( "X", 1 );
1787
1788         QHash<QString, QVariant> hash2;
1789         hash2.insert( "X", 1 );
1790
1791         QTest::newRow("HashTwoItemsEqual") << QVariant(hash1) << QVariant(hash2) << true;
1792     }
1793
1794     {
1795         QHash<QString, QVariant> hash1;
1796         hash1.insert( "X", 1 );
1797
1798         QHash<QString, QVariant> hash2;
1799
1800         QTest::newRow("HashPopulatedEmptyHash") << QVariant(hash1) << QVariant(hash2) << false;
1801     }
1802
1803     {
1804         QHash<QString, QVariant> hash1;
1805
1806         QHash<QString, QVariant> hash2;
1807         hash2.insert( "X", 1 );
1808
1809         QTest::newRow("EmptyPopulatedHash") << QVariant(hash1) << QVariant(hash2) << false;
1810     }
1811
1812     {
1813         QHash<QString, QVariant> hash1;
1814         hash1.insert( "X", 1 );
1815         hash1.insert( "Y", 1 );
1816
1817         QHash<QString, QVariant> hash2;
1818         hash2.insert( "X", 1 );
1819
1820         QTest::newRow("HashFirstLarger") << QVariant(hash1) << QVariant(hash2) << false;
1821     }
1822
1823     {
1824         QHash<QString, QVariant> hash1;
1825         hash1.insert( "X", 1 );
1826
1827         QHash<QString, QVariant> hash2;
1828         hash2.insert( "X", 1 );
1829         hash2.insert( "Y", 1 );
1830
1831         QTest::newRow("HashSecondLarger") << QVariant(hash1) << QVariant(hash2) << false;
1832     }
1833 }
1834
1835 void tst_QVariant::operator_eq_eq()
1836 {
1837     QFETCH( QVariant, left );
1838     QFETCH( QVariant, right );
1839     QFETCH( bool, equal );
1840     QEXPECT_FAIL("nullint", "See QTBUG-22933", Continue);
1841     QCOMPARE( left == right, equal );
1842 }
1843
1844 void tst_QVariant::operator_eq_eq_rhs()
1845 {
1846     QVariant v = 42;
1847
1848     QVERIFY(v == 42);
1849     QVERIFY(42 == v);
1850
1851 #if 0
1852     /* This should _not_ compile */
1853     QStringList list;
1854     QDateTime dt;
1855
1856     QVERIFY(dt == list);
1857 #endif
1858 }
1859
1860 void tst_QVariant::typeName_data()
1861 {
1862     QTest::addColumn<int>("type");
1863     QTest::addColumn<QByteArray>("res");
1864     QTest::newRow("0") << int(QVariant::Invalid) << QByteArray("");
1865     QTest::newRow("1") << int(QVariant::Map) << QByteArray("QVariantMap");
1866     QTest::newRow("2") << int(QVariant::List) << QByteArray("QVariantList");
1867     QTest::newRow("3") << int(QVariant::String) << QByteArray("QString");
1868     QTest::newRow("4") << int(QVariant::StringList) << QByteArray("QStringList");
1869     QTest::newRow("5") << int(QVariant::Font) << QByteArray("QFont");
1870     QTest::newRow("6") << int(QVariant::Pixmap) << QByteArray("QPixmap");
1871     QTest::newRow("7") << int(QVariant::Brush) << QByteArray("QBrush");
1872     QTest::newRow("8") << int(QVariant::Rect) << QByteArray("QRect");
1873     QTest::newRow("9") << int(QVariant::Size) << QByteArray("QSize");
1874     QTest::newRow("10") << int(QVariant::Color) << QByteArray("QColor");
1875     QTest::newRow("11") << int(QVariant::Palette) << QByteArray("QPalette");
1876     QTest::newRow("12") << int(QVariant::Point) << QByteArray("QPoint");
1877     QTest::newRow("13") << int(QVariant::Image) << QByteArray("QImage");
1878     QTest::newRow("14") << int(QVariant::Int) << QByteArray("int");
1879     QTest::newRow("15") << int(QVariant::UInt) << QByteArray("uint");
1880     QTest::newRow("16") << int(QVariant::Bool) << QByteArray("bool");
1881     QTest::newRow("17") << int(QVariant::Double) << QByteArray("double");
1882     QTest::newRow("18") << int(QMetaType::Float) << QByteArray("float");
1883     QTest::newRow("19") << int(QVariant::Polygon) << QByteArray("QPolygon");
1884     QTest::newRow("20") << int(QVariant::Region) << QByteArray("QRegion");
1885     QTest::newRow("21") << int(QVariant::Bitmap) << QByteArray("QBitmap");
1886     QTest::newRow("22") << int(QVariant::Cursor) << QByteArray("QCursor");
1887     QTest::newRow("23") << int(QVariant::SizePolicy) << QByteArray("QSizePolicy");
1888     QTest::newRow("24") << int(QVariant::Date) << QByteArray("QDate");
1889     QTest::newRow("25") << int(QVariant::Time) << QByteArray("QTime");
1890     QTest::newRow("26") << int(QVariant::DateTime) << QByteArray("QDateTime");
1891     QTest::newRow("27") << int(QVariant::ByteArray) << QByteArray("QByteArray");
1892     QTest::newRow("28") << int(QVariant::BitArray) << QByteArray("QBitArray");
1893     QTest::newRow("29") << int(QVariant::KeySequence) << QByteArray("QKeySequence");
1894     QTest::newRow("30") << int(QVariant::Pen) << QByteArray("QPen");
1895     QTest::newRow("31") << int(QVariant::LongLong) << QByteArray("qlonglong");
1896     QTest::newRow("32") << int(QVariant::ULongLong) << QByteArray("qulonglong");
1897     QTest::newRow("33") << int(QVariant::Char) << QByteArray("QChar");
1898     QTest::newRow("34") << int(QVariant::Url) << QByteArray("QUrl");
1899     QTest::newRow("35") << int(QVariant::TextLength) << QByteArray("QTextLength");
1900     QTest::newRow("36") << int(QVariant::TextFormat) << QByteArray("QTextFormat");
1901     QTest::newRow("37") << int(QVariant::Locale) << QByteArray("QLocale");
1902     QTest::newRow("38") << int(QVariant::LineF) << QByteArray("QLineF");
1903     QTest::newRow("39") << int(QVariant::RectF) << QByteArray("QRectF");
1904     QTest::newRow("40") << int(QVariant::PointF) << QByteArray("QPointF");
1905     QTest::newRow("41") << int(QVariant::RegExp) << QByteArray("QRegExp");
1906     QTest::newRow("43") << int(QVariant::Matrix) << QByteArray("QMatrix");
1907     QTest::newRow("44") << int(QVariant::Transform) << QByteArray("QTransform");
1908     QTest::newRow("45") << int(QVariant::Hash) << QByteArray("QVariantHash");
1909     QTest::newRow("46") << int(QVariant::Matrix4x4) << QByteArray("QMatrix4x4");
1910     QTest::newRow("47") << int(QVariant::Vector2D) << QByteArray("QVector2D");
1911     QTest::newRow("48") << int(QVariant::Vector3D) << QByteArray("QVector3D");
1912     QTest::newRow("49") << int(QVariant::Vector4D) << QByteArray("QVector4D");
1913     QTest::newRow("50") << int(QVariant::Quaternion) << QByteArray("QQuaternion");
1914     QTest::newRow("51") << int(QVariant::RegularExpression) << QByteArray("QRegularExpression");
1915 }
1916
1917 void tst_QVariant::typeName()
1918 {
1919     QFETCH( int, type );
1920     QFETCH( QByteArray, res );
1921     QCOMPARE(QString::fromLatin1(QVariant::typeToName((QVariant::Type)type)),
1922             QString::fromLatin1(res.constData()));
1923 }
1924
1925 // test nameToType as well
1926 void tst_QVariant::typeToName()
1927 {
1928     QVariant v;
1929     QCOMPARE( QVariant::typeToName( v.type() ), (const char*)0 ); // Invalid
1930     // assumes that QVariant::Type contains consecutive values
1931
1932     int max = QVariant::LastGuiType;
1933     for ( int t = 1; t <= max; t++ ) {
1934         const char *n = QVariant::typeToName( (QVariant::Type)t );
1935         if (n)
1936             QCOMPARE( int(QVariant::nameToType( n )), t );
1937
1938     }
1939     QCOMPARE(QVariant::typeToName(QVariant::Int), "int");
1940     // not documented but we return 0 if the type is out of range
1941     // by testing this we catch cases where QVariant is extended
1942     // but type_map is not updated accordingly
1943     QCOMPARE( QVariant::typeToName( QVariant::Type(max+1) ), (char*)0 );
1944     // invalid type names
1945     QVERIFY( QVariant::nameToType( 0 ) == QVariant::Invalid );
1946     QVERIFY( QVariant::nameToType( "" ) == QVariant::Invalid );
1947     QVERIFY( QVariant::nameToType( "foo" ) == QVariant::Invalid );
1948
1949     QCOMPARE(QVariant::nameToType("UserType"), QVariant::Invalid);
1950
1951     // We don't support these old (Qt3) types anymore.
1952     QCOMPARE(QVariant::nameToType("QIconSet"), QVariant::Invalid);
1953     QCOMPARE(QVariant::nameToType("Q3CString"), QVariant::Invalid);
1954     QCOMPARE(QVariant::nameToType("Q_LLONG"), QVariant::Invalid);
1955     QCOMPARE(QVariant::nameToType("Q_ULLONG"), QVariant::Invalid);
1956 }
1957
1958 void tst_QVariant::streamInvalidVariant()
1959 {
1960     int writeX = 1;
1961     int writeY = 2;
1962     int readX;
1963     int readY;
1964     QVariant writeVariant;
1965     QVariant readVariant;
1966
1967     QVERIFY( writeVariant.type() == QVariant::Invalid );
1968
1969     QByteArray data;
1970     QDataStream writeStream( &data, QIODevice::WriteOnly );
1971     writeStream << writeX << writeVariant << writeY;
1972
1973     QDataStream readStream( &data, QIODevice::ReadOnly );
1974     readStream >> readX >> readVariant >> readY;
1975
1976     QVERIFY( readX == writeX );
1977     // Two invalid QVariant's aren't necessarily the same, so == will
1978     // return false if one is invalid, so check the type() instead
1979     QVERIFY( readVariant.type() == QVariant::Invalid );
1980     QVERIFY( readY == writeY );
1981 }
1982
1983 static int instanceCount = 0;
1984
1985 struct MyType
1986 {
1987     MyType(int n = 0, const char *t=0): number(n), text(t)
1988     {
1989         ++instanceCount;
1990     }
1991     MyType(const MyType &other)
1992         : number(other.number), text(other.text)
1993     {
1994         ++instanceCount;
1995     }
1996     ~MyType()
1997     {
1998         --instanceCount;
1999     }
2000     int number;
2001     const char *text;
2002 };
2003
2004 Q_DECLARE_METATYPE(MyType)
2005 Q_DECLARE_METATYPE(MyType*)
2006
2007 void tst_QVariant::userType()
2008 {
2009     {
2010         MyType data(1, "eins");
2011         MyType data2(2, "zwei");
2012
2013         {
2014             QVariant userVar;
2015             userVar.setValue(data);
2016
2017             QCOMPARE(userVar.type(), QVariant::UserType);
2018             QCOMPARE(userVar.userType(), qMetaTypeId<MyType>());
2019             QCOMPARE(userVar.typeName(), "MyType");
2020             QVERIFY(!userVar.isNull());
2021             QVERIFY(!userVar.canConvert(QVariant::String));
2022
2023             QVariant userVar2(userVar);
2024             QVERIFY(userVar == userVar2);
2025
2026             userVar2.setValue(data2);
2027             QVERIFY(userVar != userVar2);
2028
2029             const MyType *varData = static_cast<const MyType *>(userVar.constData());
2030             QVERIFY(varData);
2031             QCOMPARE(varData->number, data.number);
2032             QCOMPARE(varData->text, data.text);
2033
2034             QVariant userVar3;
2035             userVar3.setValue(data2);
2036
2037             userVar3 = userVar2;
2038             QVERIFY(userVar2 == userVar3);
2039         }
2040         // At this point all QVariants got destroyed but we have 2 MyType instances.
2041         QCOMPARE(instanceCount, 2);
2042         {
2043             QVariant userVar;
2044             userVar.setValue(&data);
2045
2046             QCOMPARE(userVar.type(), QVariant::UserType);
2047             QCOMPARE(userVar.userType(), qMetaTypeId<MyType*>());
2048             QCOMPARE(userVar.typeName(), "MyType*");
2049             QVERIFY(!userVar.isNull());
2050             QVERIFY(!userVar.canConvert(QVariant::String));
2051
2052             QVariant userVar2(userVar);
2053             QVERIFY(userVar == userVar2);
2054
2055             userVar2.setValue(&data2);
2056             QVERIFY(userVar != userVar2);
2057
2058             MyType * const*varData = reinterpret_cast<MyType *const *>(userVar.constData());
2059             QVERIFY(varData);
2060             QCOMPARE(*varData, &data);
2061
2062             QVariant userVar3;
2063             userVar3.setValue(&data2);
2064
2065             /* This check is correct now. userVar2 contains a pointer to data2 and so
2066              * does userVar3. */
2067             QVERIFY(userVar2 == userVar3);
2068
2069             userVar3 = userVar2;
2070             QVERIFY(userVar2 == userVar3);
2071         }
2072
2073         QCOMPARE(instanceCount, 2);
2074         QVariant myCarrier;
2075         myCarrier.setValue(data);
2076         QCOMPARE(instanceCount, 3);
2077         {
2078             QVariant second = myCarrier;
2079             QCOMPARE(instanceCount, 3);
2080             second.detach();
2081             QCOMPARE(instanceCount, 4);
2082         }
2083         QCOMPARE(instanceCount, 3);
2084
2085         MyType data3(0, "null");
2086         data3 = qvariant_cast<MyType>(myCarrier);
2087         QCOMPARE(data3.number, 1);
2088         QCOMPARE(data3.text, (const char *)"eins");
2089 #ifndef Q_CC_SUN
2090         QCOMPARE(instanceCount, 4);
2091 #endif
2092
2093     }
2094
2095     {
2096         const MyType data(3, "drei");
2097         QVariant myCarrier;
2098
2099         myCarrier.setValue(data);
2100         QCOMPARE(myCarrier.typeName(), "MyType");
2101
2102         const MyType data2 = qvariant_cast<MyType>(myCarrier);
2103         QCOMPARE(data2.number, 3);
2104         QCOMPARE(data2.text, (const char *)"drei");
2105     }
2106
2107     {
2108         short s = 42;
2109         QVariant myCarrier;
2110
2111         myCarrier.setValue(s);
2112         QCOMPARE((int)qvariant_cast<short>(myCarrier), 42);
2113     }
2114
2115     {
2116         qlonglong ll = Q_INT64_C(42);
2117         QVariant myCarrier;
2118
2119         myCarrier.setValue(ll);
2120         QCOMPARE(qvariant_cast<int>(myCarrier), 42);
2121     }
2122
2123     // At this point all QVariants got destroyed and MyType objects too.
2124     QCOMPARE(instanceCount, 0);
2125 }
2126
2127 struct MyTypePOD
2128 {
2129     int a;
2130     int b;
2131 };
2132 Q_DECLARE_METATYPE(MyTypePOD)
2133
2134 void tst_QVariant::podUserType()
2135 {
2136     MyTypePOD pod;
2137     pod.a = 10;
2138     pod.b = 20;
2139
2140     QVariant pod_as_variant = QVariant::fromValue(pod);
2141     MyTypePOD pod2 = qvariant_cast<MyTypePOD>(pod_as_variant);
2142
2143     QCOMPARE(pod.a, pod2.a);
2144     QCOMPARE(pod.b, pod2.b);
2145
2146     pod_as_variant.setValue(pod);
2147     pod2 = qvariant_cast<MyTypePOD>(pod_as_variant);
2148
2149     QCOMPARE(pod.a, pod2.a);
2150     QCOMPARE(pod.b, pod2.b);
2151 }
2152
2153 void tst_QVariant::basicUserType()
2154 {
2155     QVariant v;
2156     {
2157         int i = 7;
2158         v = QVariant(QMetaType::Int, &i);
2159     }
2160     QCOMPARE(v.type(), QVariant::Int);
2161     QCOMPARE(v.toInt(), 7);
2162
2163     {
2164         QString s("foo");
2165         v = QVariant(QMetaType::QString, &s);
2166     }
2167     QCOMPARE(v.type(), QVariant::String);
2168     QCOMPARE(v.toString(), QString("foo"));
2169
2170     {
2171         double d = 4.4;
2172         v = QVariant(QMetaType::Double, &d);
2173     }
2174     QCOMPARE(v.type(), QVariant::Double);
2175     QCOMPARE(v.toDouble(), 4.4);
2176
2177     {
2178         float f = 4.5f;
2179         v = QVariant(QMetaType::Float, &f);
2180     }
2181     QCOMPARE(v.userType(), int(QMetaType::Float));
2182     QCOMPARE(v.toDouble(), 4.5);
2183
2184     {
2185         QByteArray ba("bar");
2186         v = QVariant(QMetaType::QByteArray, &ba);
2187     }
2188     QCOMPARE(v.type(), QVariant::ByteArray);
2189     QCOMPARE(v.toByteArray(), QByteArray("bar"));
2190 }
2191
2192 void tst_QVariant::data()
2193 {
2194     QVariant v;
2195
2196     QVariant i = 1;
2197     QVariant d = 1.12;
2198     QVariant f = 1.12f;
2199     QVariant ll = (qlonglong)2;
2200     QVariant ull = (qulonglong)3;
2201     QVariant s(QString("hallo"));
2202     QVariant r(QRect(1,2,3,4));
2203
2204     v = i;
2205     QVERIFY(v.data());
2206     QCOMPARE(*static_cast<int *>(v.data()), i.toInt());
2207
2208     v = d;
2209     QVERIFY(v.data());
2210     QCOMPARE(*static_cast<double *>(v.data()), d.toDouble());
2211
2212     v = f;
2213     QVERIFY(v.data());
2214     QCOMPARE(*static_cast<float *>(v.data()), qvariant_cast<float>(v));
2215
2216     v = ll;
2217     QVERIFY(v.data());
2218     QCOMPARE(*static_cast<qlonglong *>(v.data()), ll.toLongLong());
2219
2220     v = ull;
2221     QVERIFY(v.data());
2222     QCOMPARE(*static_cast<qulonglong *>(v.data()), ull.toULongLong());
2223
2224     v = s;
2225     QVERIFY(v.data());
2226     QCOMPARE(*static_cast<QString *>(v.data()), s.toString());
2227
2228     v = r;
2229     QVERIFY(v.data());
2230     QCOMPARE(*static_cast<QRect *>(v.data()), r.toRect());
2231 }
2232
2233 void tst_QVariant::constData()
2234 {
2235     QVariant v;
2236
2237     int i = 1;
2238     double d = 1.12;
2239     float f = 1.12f;
2240     qlonglong ll = 2;
2241     qulonglong ull = 3;
2242     QString s("hallo");
2243     QRect r(1,2,3,4);
2244
2245     v = QVariant(i);
2246     QVERIFY(v.constData());
2247     QCOMPARE(*static_cast<const int *>(v.constData()), i);
2248
2249     v = QVariant(d);
2250     QVERIFY(v.constData());
2251     QCOMPARE(*static_cast<const double *>(v.constData()), d);
2252
2253     v = QVariant(f);
2254     QVERIFY(v.constData());
2255     QCOMPARE(*static_cast<const float *>(v.constData()), f);
2256
2257     v = QVariant(ll);
2258     QVERIFY(v.constData());
2259     QCOMPARE(*static_cast<const qlonglong *>(v.constData()), ll);
2260
2261     v = QVariant(ull);
2262     QVERIFY(v.constData());
2263     QCOMPARE(*static_cast<const qulonglong *>(v.constData()), ull);
2264
2265     v = QVariant(s);
2266     QVERIFY(v.constData());
2267     QCOMPARE(*static_cast<const QString *>(v.constData()), s);
2268
2269     v = QVariant(r);
2270     QVERIFY(v.constData());
2271     QCOMPARE(*static_cast<const QRect *>(v.constData()), r);
2272 }
2273
2274 struct Foo
2275 {
2276     Foo(): i(0) {}
2277     int i;
2278 };
2279
2280 Q_DECLARE_METATYPE(Foo)
2281
2282 void tst_QVariant::variant_to()
2283 {
2284     QVariant v1(4.2);
2285     QVariant v2(5);
2286
2287     QVariant v3;
2288     QVariant v4;
2289
2290     QStringList sl;
2291     sl << QLatin1String("blah");
2292
2293     v3.setValue(sl);
2294
2295     Foo foo;
2296     foo.i = 42;
2297
2298     v4.setValue(foo);
2299
2300     QCOMPARE(qvariant_cast<double>(v1), 4.2);
2301     QCOMPARE(qvariant_cast<float>(v1), 4.2f);
2302     QCOMPARE(qvariant_cast<int>(v2), 5);
2303     QCOMPARE(qvariant_cast<QStringList>(v3), sl);
2304     QCOMPARE(qvariant_cast<QString>(v3), QString::fromLatin1("blah"));
2305
2306     QCOMPARE(qvariant_cast<Foo>(v4).i, 42);
2307
2308     QVariant v5;
2309     QCOMPARE(qvariant_cast<Foo>(v5).i, 0);
2310
2311     QCOMPARE(qvariant_cast<int>(v1), 4);
2312
2313     QVariant n = QVariant::fromValue<short>(42);
2314     QCOMPARE(qvariant_cast<int>(n), 42);
2315     QCOMPARE(qvariant_cast<uint>(n), 42u);
2316     QCOMPARE(qvariant_cast<double>(n), 42.0);
2317     QCOMPARE(qvariant_cast<float>(n), 42.f);
2318     QCOMPARE(qvariant_cast<short>(n), short(42));
2319     QCOMPARE(qvariant_cast<ushort>(n), ushort(42));
2320
2321     n = QVariant::fromValue(43l);
2322     QCOMPARE(qvariant_cast<int>(n), 43);
2323     QCOMPARE(qvariant_cast<uint>(n), 43u);
2324     QCOMPARE(qvariant_cast<double>(n), 43.0);
2325     QCOMPARE(qvariant_cast<float>(n), 43.f);
2326     QCOMPARE(qvariant_cast<long>(n), 43l);
2327
2328     n = QLatin1String("44");
2329     QCOMPARE(qvariant_cast<int>(n), 44);
2330     QCOMPARE(qvariant_cast<ulong>(n), 44ul);
2331     QCOMPARE(qvariant_cast<float>(n), 44.0f);
2332
2333     QCOMPARE(QVariant::fromValue(0.25f).toDouble(), 0.25);
2334 }
2335
2336 struct Blah { int i; };
2337
2338 QDataStream& operator>>(QDataStream& s, Blah& c)
2339 { return (s >> c.i); }
2340
2341 QDataStream& operator<<(QDataStream& s, const Blah& c)
2342 { return (s << c.i); }
2343
2344 void tst_QVariant::saveLoadCustomTypes()
2345 {
2346     QByteArray data;
2347
2348     Blah i = { 42 };
2349     int tp = qRegisterMetaType<Blah>("Blah");
2350     QVariant v = QVariant(tp, &i);
2351
2352     qRegisterMetaTypeStreamOperators<Blah>("Blah");
2353
2354     QCOMPARE(v.userType(), tp);
2355     QVERIFY(v.type() == QVariant::UserType);
2356     {
2357         QDataStream stream(&data, QIODevice::WriteOnly);
2358         stream << v;
2359     }
2360
2361     v = QVariant();
2362
2363     {
2364         QDataStream stream(data);
2365         stream >> v;
2366     }
2367
2368     QCOMPARE(int(v.userType()), QMetaType::type("Blah"));
2369     int value = *(int*)v.constData();
2370     QCOMPARE(value, 42);
2371 }
2372
2373 void tst_QVariant::url()
2374 {
2375     QString str("http://qt.nokia.com");
2376     QUrl url(str);
2377
2378     QVariant v(url); //built with a QUrl
2379
2380     QVariant v2 = v;
2381
2382     QVariant v3(str); //built with a QString
2383
2384     QCOMPARE(v2.toUrl(), url);
2385     QVERIFY(v3.canConvert<QUrl>());
2386     QCOMPARE(v2.toUrl(), v3.toUrl());
2387
2388     QVERIFY(v2.canConvert<QString>());
2389     QCOMPARE(v2.toString(), str);
2390     QCOMPARE(v3.toString(), str);
2391 }
2392
2393 void tst_QVariant::variantMap()
2394 {
2395     QMap<QString, QVariant> map;
2396     map["test"] = 42;
2397
2398     QVariant v = map;
2399     QVariantMap map2 = qvariant_cast<QVariantMap>(v);
2400
2401     QCOMPARE(map2.value("test").toInt(), 42);
2402
2403     QVariant v2 = QVariant(QMetaType::type("QVariantMap"), &map);
2404     QCOMPARE(qvariant_cast<QVariantMap>(v2).value("test").toInt(), 42);
2405
2406     QVariant v3 = QVariant(QMetaType::type("QMap<QString, QVariant>"), &map);
2407     QCOMPARE(qvariant_cast<QVariantMap>(v3).value("test").toInt(), 42);
2408 }
2409
2410 void tst_QVariant::variantHash()
2411 {
2412     QHash<QString, QVariant> hash;
2413     hash["test"] = 42;
2414
2415     QVariant v = hash;
2416     QVariantHash hash2 = qvariant_cast<QVariantHash>(v);
2417
2418     QCOMPARE(hash2.value("test").toInt(), 42);
2419
2420     QVariant v2 = QVariant(QMetaType::type("QVariantHash"), &hash);
2421     QCOMPARE(qvariant_cast<QVariantHash>(v2).value("test").toInt(), 42);
2422
2423     QVariant v3 = QVariant(QMetaType::type("QHash<QString, QVariant>"), &hash);
2424     QCOMPARE(qvariant_cast<QVariantHash>(v3).value("test").toInt(), 42);
2425 }
2426
2427 void tst_QVariant::invalidQColor() const
2428 {
2429     QVariant va("An invalid QColor::name() value.");
2430     QVERIFY(va.canConvert(QVariant::Color));
2431
2432     QVERIFY(!va.convert(QVariant::Color));
2433
2434     QVERIFY(!qvariant_cast<QColor>(va).isValid());
2435 }
2436
2437 class CustomQObject : public QObject {
2438     Q_OBJECT
2439 public:
2440     CustomQObject(QObject *parent = 0) : QObject(parent) {}
2441 };
2442 Q_DECLARE_METATYPE(CustomQObject*)
2443
2444 class CustomNonQObject { };
2445 Q_DECLARE_METATYPE(CustomNonQObject)
2446 Q_DECLARE_METATYPE(CustomNonQObject*)
2447
2448 void tst_QVariant::cleanupTestCase()
2449 {
2450     delete customNonQObjectPointer;
2451     qDeleteAll(objectPointerTestData);
2452 }
2453
2454 void tst_QVariant::qvariant_cast_QObject_data()
2455 {
2456     QTest::addColumn<QVariant>("data");
2457     QTest::addColumn<bool>("success");
2458     QObject *obj = new QObject;
2459     obj->setObjectName(QString::fromLatin1("Hello"));
2460     QTest::newRow("from QObject") << QVariant(QMetaType::QObjectStar, &obj) << true;
2461     QTest::newRow("from QObject2") << QVariant::fromValue(obj) << true;
2462     QTest::newRow("from String") << QVariant(QLatin1String("1, 2, 3")) << false;
2463     QTest::newRow("from int") << QVariant((int) 123) << false;
2464     CustomQObject *customObject = new CustomQObject(this);
2465     customObject->setObjectName(QString::fromLatin1("Hello"));
2466     QTest::newRow("from Derived QObject") << QVariant::fromValue(customObject) << true;
2467     QTest::newRow("from custom Object") << QVariant::fromValue(CustomNonQObject()) << false;
2468
2469     // Deleted in cleanupTestCase.
2470     customNonQObjectPointer = new CustomNonQObject;
2471     QTest::newRow("from custom ObjectStar") << QVariant::fromValue(customNonQObjectPointer) << false;
2472
2473     // Deleted in cleanupTestCase.
2474     objectPointerTestData.push_back(obj);
2475     objectPointerTestData.push_back(customObject);
2476 }
2477
2478 void tst_QVariant::qvariant_cast_QObject()
2479 {
2480     QFETCH(QVariant, data);
2481     QFETCH(bool, success);
2482
2483     QObject *o = qvariant_cast<QObject *>(data);
2484     QCOMPARE(o != 0, success);
2485     if (success) {
2486         QCOMPARE(o->objectName(), QString::fromLatin1("Hello"));
2487         QVERIFY(data.canConvert<QObject*>());
2488         QVERIFY(data.canConvert(QMetaType::QObjectStar));
2489         QVERIFY(data.canConvert(::qMetaTypeId<QObject*>()));
2490         QVERIFY(data.value<QObject*>());
2491         QVERIFY(data.convert(QMetaType::QObjectStar));
2492         QCOMPARE(data.userType(), int(QMetaType::QObjectStar));
2493     } else {
2494         QVERIFY(!data.canConvert<QObject*>());
2495         QVERIFY(!data.canConvert(QMetaType::QObjectStar));
2496         QVERIFY(!data.canConvert(::qMetaTypeId<QObject*>()));
2497         QVERIFY(!data.value<QObject*>());
2498         QVERIFY(!data.convert(QMetaType::QObjectStar));
2499         QVERIFY(data.userType() != QMetaType::QObjectStar);
2500     }
2501 }
2502
2503 class CustomQObjectDerived : public CustomQObject {
2504     Q_OBJECT
2505 public:
2506     CustomQObjectDerived(QObject *parent = 0) : CustomQObject(parent) {}
2507 };
2508 Q_DECLARE_METATYPE(CustomQObjectDerived*)
2509
2510 class CustomQObjectDerivedNoMetaType : public CustomQObject {
2511     Q_OBJECT
2512 public:
2513     CustomQObjectDerivedNoMetaType(QObject *parent = 0) : CustomQObject(parent) {}
2514 };
2515
2516 void tst_QVariant::qvariant_cast_QObject_derived()
2517 {
2518     {
2519         CustomQObjectDerivedNoMetaType *object = new CustomQObjectDerivedNoMetaType(this);
2520         QVariant data = QVariant::fromValue(object);
2521         QVERIFY(data.userType() == qMetaTypeId<CustomQObjectDerivedNoMetaType*>());
2522         QCOMPARE(data.value<QObject *>(), object);
2523         QCOMPARE(data.value<CustomQObjectDerivedNoMetaType *>(), object);
2524         QCOMPARE(data.value<CustomQObject *>(), object);
2525     }
2526     {
2527         CustomQObjectDerived *object = new CustomQObjectDerived(this);
2528         QVariant data = QVariant::fromValue(object);
2529
2530         QVERIFY(data.userType() == qMetaTypeId<CustomQObjectDerived*>());
2531
2532         QCOMPARE(data.value<QObject *>(), object);
2533         QCOMPARE(data.value<CustomQObjectDerived *>(), object);
2534         QCOMPARE(data.value<CustomQObject *>(), object);
2535     }
2536 }
2537
2538 void tst_QVariant::convertToQUint8() const
2539 {
2540     /* qint8. */
2541     {
2542         const qint8 anInt = 32;
2543
2544         /* QVariant(int) gets invoked here so the QVariant has nothing with qint8 to do.
2545          * It's of type QVariant::Int. */
2546         const QVariant v0 = anInt;
2547
2548         QVERIFY(v0.canConvert<qint8>());
2549         QCOMPARE(int(qvariant_cast<qint8>(v0)), 32);
2550         QCOMPARE(int(v0.toInt()), 32);
2551         QCOMPARE(v0.toString(), QString("32"));
2552
2553         QCOMPARE(int(qvariant_cast<qlonglong>(v0)), 32);
2554         QCOMPARE(int(qvariant_cast<char>(v0)),      32);
2555         QCOMPARE(int(qvariant_cast<short>(v0)),     32);
2556         QCOMPARE(int(qvariant_cast<long>(v0)),      32);
2557         QCOMPARE(int(qvariant_cast<float>(v0)),     32);
2558         QCOMPARE(int(qvariant_cast<double>(v0)),    32);
2559     }
2560
2561     /* quint8. */
2562     {
2563         const quint8 anInt = 32;
2564         const QVariant v0 = anInt;
2565
2566         QVERIFY(v0.canConvert<quint8>());
2567         QCOMPARE(int(qvariant_cast<quint8>(v0)), 32);
2568         QCOMPARE(int(v0.toUInt()), 32);
2569         QCOMPARE(v0.toString(), QString("32"));
2570     }
2571
2572     /* qint16. */
2573     {
2574         const qint16 anInt = 32;
2575         const QVariant v0 = anInt;
2576
2577         QVERIFY(v0.canConvert<qint16>());
2578         QCOMPARE(int(qvariant_cast<qint16>(v0)), 32);
2579         QCOMPARE(int(v0.toInt()), 32);
2580         QCOMPARE(v0.toString(), QString("32"));
2581     }
2582
2583     /* quint16. */
2584     {
2585         const quint16 anInt = 32;
2586         const QVariant v0 = anInt;
2587
2588         QVERIFY(v0.canConvert<quint16>());
2589         QCOMPARE(int(qvariant_cast<quint16>(v0)), 32);
2590         QCOMPARE(int(v0.toUInt()), 32);
2591         QCOMPARE(v0.toString(), QString("32"));
2592     }
2593 }
2594
2595 void tst_QVariant::comparePointers() const
2596 {
2597     class MyClass
2598     {
2599     };
2600
2601     MyClass myClass;
2602
2603     QVariant v  = QVariant::fromValue<void *>(&myClass);
2604     QVariant v2 = QVariant::fromValue<void *>(&myClass);
2605
2606     QCOMPARE(v, v2);
2607 }
2608
2609 struct Data {};
2610 Q_DECLARE_METATYPE(Data*)
2611
2612 void tst_QVariant::voidStar() const
2613 {
2614     char c;
2615     void *p1 = &c;
2616     void *p2 = p1;
2617
2618     QVariant v1, v2;
2619     v1 = QVariant::fromValue(p1);
2620     v2 = v1;
2621     QVERIFY(v1 == v2);
2622
2623     v2 = QVariant::fromValue(p2);
2624     QVERIFY(v1 == v2);
2625
2626     p2 = 0;
2627     v2 = QVariant::fromValue(p2);
2628     QVERIFY(v1 != v2);
2629 }
2630
2631 void tst_QVariant::dataStar() const
2632 {
2633     qRegisterMetaType<Data*>();
2634     Data *p1 = new Data;
2635
2636     QVariant v1 = QVariant::fromValue(p1);
2637     QCOMPARE(v1.userType(), qMetaTypeId<Data*>());
2638     QCOMPARE(qvariant_cast<Data*>(v1), p1);
2639
2640     QVariant v2 = v1;
2641     QVERIFY(v1 == v2);
2642
2643     v2 = QVariant::fromValue(p1);
2644     QVERIFY(v1 == v2);
2645     delete p1;
2646 }
2647
2648 void tst_QVariant::canConvertQStringList() const
2649 {
2650     QFETCH(bool, canConvert);
2651     QFETCH(QStringList, input);
2652     QFETCH(QString, result);
2653
2654     QVariant v(input);
2655
2656     QCOMPARE(v.canConvert(QVariant::String), canConvert);
2657     QCOMPARE(v.toString(), result);
2658 }
2659
2660 void tst_QVariant::canConvertQStringList_data() const
2661 {
2662     QTest::addColumn<bool>("canConvert");
2663     QTest::addColumn<QStringList>("input");
2664     QTest::addColumn<QString>("result");
2665
2666     QTest::newRow("An empty list") << false << QStringList() << QString();
2667     QTest::newRow("A single item") << true << QStringList(QLatin1String("foo")) << QString::fromLatin1("foo");
2668     QTest::newRow("A single, but empty item") << true << QStringList(QString()) << QString();
2669
2670     QStringList l;
2671     l << "a" << "b";
2672
2673     QTest::newRow("Two items") << false << l << QString();
2674
2675     l << "c";
2676     QTest::newRow("Three items") << false << l << QString();
2677 }
2678
2679 template<typename T> void convertMetaType()
2680 {
2681     QVERIFY(QVariant::fromValue<T>(10).isValid());
2682     QVERIFY(QVariant::fromValue<T>(10).canConvert(QVariant::Int));
2683     QCOMPARE(QVariant::fromValue<T>(10).toInt(), 10);
2684     QCOMPARE(QVariant::fromValue<T>(10), QVariant::fromValue<T>(10));
2685 }
2686
2687 #define CONVERT_META_TYPE(Type) \
2688     convertMetaType<Type>(); \
2689     if (QTest::currentTestFailed()) \
2690         QFAIL("convertMetaType<" #Type "> failed");
2691
2692 void tst_QVariant::canConvertMetaTypeToInt() const
2693 {
2694     CONVERT_META_TYPE(long);
2695     CONVERT_META_TYPE(short);
2696     CONVERT_META_TYPE(short);
2697     CONVERT_META_TYPE(unsigned short);
2698     CONVERT_META_TYPE(ushort);
2699     CONVERT_META_TYPE(ulong);
2700     CONVERT_META_TYPE(unsigned long);
2701     CONVERT_META_TYPE(uchar);
2702     CONVERT_META_TYPE(unsigned char);
2703     CONVERT_META_TYPE(char);
2704     CONVERT_META_TYPE(uint);
2705     CONVERT_META_TYPE(unsigned int);
2706 }
2707
2708 #undef CONVERT_META_TYPE
2709
2710 /*!
2711  These calls should not produce any warnings.
2712  */
2713 void tst_QVariant::variantToDateTimeWithoutWarnings() const
2714 {
2715     {
2716         const QVariant variant(QLatin1String("An invalid QDateTime string"));
2717         const QDateTime dateTime(variant.toDateTime());
2718         QVERIFY(!dateTime.isValid());
2719     }
2720
2721     {
2722         QVariant v1(QLatin1String("xyz"));
2723         v1.convert(QVariant::DateTime);
2724
2725         QVariant v2(QLatin1String("xyz"));
2726         QDateTime dt1(v2.toDateTime());
2727
2728         const QVariant v3(QLatin1String("xyz"));
2729         const QDateTime dt2(v3.toDateTime());
2730     }
2731 }
2732
2733 void tst_QVariant::invalidDateTime() const
2734 {
2735     QVariant variant(QString::fromLatin1("Invalid date time string"));
2736     QVERIFY(!variant.toDateTime().isValid());
2737     QVERIFY(!variant.convert(QVariant::DateTime));
2738 }
2739
2740 struct MyClass
2741 {
2742     MyClass() : myValue(0) {}
2743     int myValue;
2744 };
2745
2746 Q_DECLARE_METATYPE( MyClass )
2747
2748 void tst_QVariant::loadUnknownUserType()
2749 {
2750     qRegisterMetaType<MyClass>("MyClass");
2751     QTest::ignoreMessage(QtWarningMsg, "QVariant::load: unable to load type "
2752                          + QByteArray::number(qMetaTypeId<MyClass>()) +".");
2753     char data[] = {0, 0, QMetaType::User >> 8 , char(QMetaType::User), 0, 0, 0, 0, 8, 'M', 'y', 'C', 'l', 'a', 's', 's', 0};
2754
2755     QByteArray ba(data, sizeof(data));
2756     QDataStream ds(&ba, QIODevice::ReadOnly);
2757     QVariant var;
2758     var.load(ds);
2759     QCOMPARE(ds.status(), QDataStream::ReadCorruptData);
2760 }
2761
2762 void tst_QVariant::loadBrokenUserType()
2763 {
2764     QTest::ignoreMessage(QtWarningMsg, "Trying to construct an instance of an invalid type, type id: 127");
2765     char data[] = {0, 0, 0, 127, 0 };
2766
2767     QByteArray ba(data, sizeof(data));
2768     QDataStream ds(&ba, QIODevice::ReadOnly);
2769     QVariant var;
2770     var.load(ds);
2771     QCOMPARE(ds.status(), QDataStream::Ok);
2772 }
2773
2774 void tst_QVariant::invalidDate() const
2775 {
2776     QString foo("Hello");
2777     QVariant variant(foo);
2778     QVERIFY(!variant.convert(QVariant::Date));
2779
2780     variant = foo;
2781     QVERIFY(!variant.convert(QVariant::DateTime));
2782
2783     variant = foo;
2784     QVERIFY(!variant.convert(QVariant::Time));
2785
2786     variant = foo;
2787     QVERIFY(!variant.convert(QVariant::Int));
2788
2789     variant = foo;
2790     QVERIFY(!variant.convert(QVariant::Double));
2791
2792     variant = foo;
2793     QVERIFY(!variant.convert(QVariant::Type(QMetaType::Float)));
2794 }
2795
2796 struct WontCompare
2797 {
2798     int x,y,z,q,w,e,r,t;
2799 };
2800 Q_DECLARE_METATYPE(WontCompare);
2801
2802 void tst_QVariant::compareCustomTypes() const
2803 {
2804     qRegisterMetaType<WontCompare>("WontCompare");
2805
2806     WontCompare f1;
2807     f1.x = 0;
2808     const QVariant variant1(QVariant::fromValue(f1));
2809
2810     WontCompare f2;
2811     f2.x = 0;
2812     const QVariant variant2(QVariant::fromValue(f2));
2813
2814     /* We compare pointers. */
2815     QVERIFY(variant1 != variant2);
2816     QVERIFY(variant1 == variant1);
2817     QVERIFY(variant2 == variant2);
2818 }
2819
2820 void tst_QVariant::timeToDateTime() const
2821 {
2822     const QVariant val(QTime::currentTime());
2823     QVERIFY(!val.canConvert(QVariant::DateTime));
2824     QVERIFY(!val.toDateTime().isValid());
2825 }
2826
2827 struct CustomComparable
2828 {
2829     CustomComparable(int value = 0) : myValue(value) {}
2830     int myValue;
2831
2832     bool operator==(const CustomComparable &other) const
2833     { return other.myValue == myValue; }
2834 };
2835
2836 Q_DECLARE_METATYPE(CustomComparable)
2837
2838 void tst_QVariant::copyingUserTypes() const
2839 {
2840     QVariant var;
2841     QVariant varCopy;
2842     const CustomComparable userType = CustomComparable(42);
2843     var.setValue(userType);
2844     varCopy = var;
2845
2846     const CustomComparable copiedType = qvariant_cast<CustomComparable>(varCopy);
2847     QCOMPARE(copiedType, userType);
2848     QCOMPARE(copiedType.myValue, 42);
2849 }
2850
2851 void tst_QVariant::convertBoolToByteArray() const
2852 {
2853     QFETCH(QByteArray, input);
2854     QFETCH(bool, canConvert);
2855     QFETCH(bool, value);
2856
2857     const QVariant variant(input);
2858
2859     QCOMPARE(variant.canConvert<bool>(), canConvert);
2860
2861     if(canConvert) {
2862         /* Just call this function so we run the code path. */
2863         QCOMPARE(variant.toBool(), value);
2864     }
2865 }
2866
2867 void tst_QVariant::convertBoolToByteArray_data() const
2868 {
2869     QTest::addColumn<QByteArray>("input");
2870     QTest::addColumn<bool>("canConvert");
2871     QTest::addColumn<bool>("value");
2872
2873     QTest::newRow("false")
2874         << QByteArray("false")
2875         << true
2876         << false;
2877
2878     QTest::newRow("FALSE")
2879         << QByteArray("FALSE")
2880         << true
2881         << false;
2882
2883     QTest::newRow("falSE")
2884         << QByteArray("FALSE")
2885         << true
2886         << false;
2887
2888     QTest::newRow("")
2889         << QByteArray("")
2890         << true
2891         << false;
2892
2893     QTest::newRow("null QByteArray")
2894         << QByteArray()
2895         << true
2896         << false;
2897
2898     QTest::newRow("any-content")
2899         << QByteArray("any-content")
2900         << true
2901         << true;
2902
2903     QTest::newRow("true")
2904         << QByteArray("true")
2905         << true
2906         << true;
2907
2908     QTest::newRow("TRUE")
2909         << QByteArray("TRUE")
2910         << true
2911         << true;
2912
2913     QTest::newRow("trUE")
2914         << QByteArray("trUE")
2915         << true
2916         << true;
2917 }
2918
2919 void tst_QVariant::convertByteArrayToBool() const
2920 {
2921     QFETCH(bool, input);
2922     QFETCH(QByteArray, output);
2923
2924     const QVariant variant(input);
2925     QCOMPARE(variant.type(), QVariant::Bool);
2926     QCOMPARE(variant.toBool(), input);
2927     QVERIFY(variant.canConvert<bool>());
2928
2929     QCOMPARE(variant.toByteArray(), output);
2930 }
2931
2932 void tst_QVariant::convertByteArrayToBool_data() const
2933 {
2934     QTest::addColumn<bool>("input");
2935     QTest::addColumn<QByteArray>("output");
2936
2937     QTest::newRow("false")
2938         << false
2939         << QByteArray("false");
2940
2941     QTest::newRow("true")
2942         << true
2943         << QByteArray("true");
2944 }
2945
2946 /*!
2947   We verify that:
2948     1. Converting the string "9.9" to int fails. This is the behavior of
2949        toLongLong() and hence also QVariant, since it uses it.
2950     2. Converting the QVariant containing the double 9.9 to int works.
2951
2952   Rationale: "9.9" is not a valid int. However, doubles are by definition not
2953   ints and therefore it makes more sense to perform conversion for those.
2954 */
2955 void tst_QVariant::toIntFromQString() const
2956 {
2957     QVariant first("9.9");
2958     bool ok;
2959     QCOMPARE(first.toInt(&ok), 0);
2960     QVERIFY(!ok);
2961
2962     QCOMPARE(QString("9.9").toLongLong(&ok), qlonglong(0));
2963     QVERIFY(!ok);
2964
2965     QVariant v(9.9);
2966     QCOMPARE(v.toInt(&ok), 10);
2967     QVERIFY(ok);
2968 }
2969
2970 /*!
2971   We verify that:
2972     1. Conversion from (64 bit) double to int works (no overflow).
2973     2. Same conversion works for QVariant::convert.
2974
2975   Rationale: if 2147483630 is set in float and then converted to int,
2976   there will be overflow and the result will be -2147483648.
2977 */
2978 void tst_QVariant::toIntFromDouble() const
2979 {
2980     double d = 2147483630;  // max int 2147483647
2981     QVERIFY((int)d == 2147483630);
2982
2983     QVariant var(d);
2984     QVERIFY( var.canConvert( QVariant::Int ) );
2985
2986     bool ok;
2987     int result = var.toInt(&ok);
2988
2989     QVERIFY( ok == true );
2990     QCOMPARE(result, 2147483630);
2991 }
2992
2993 void tst_QVariant::setValue()
2994 {
2995     QTransform t; //we just take a value so that we're sure that it will be shared
2996     QVariant v1 = t;
2997     QVERIFY( v1.isDetached() );
2998     QVariant v2 = v1;
2999     QVERIFY( !v1.isDetached() );
3000     QVERIFY( !v2.isDetached() );
3001
3002     v2.setValue(3); //set an integer value
3003
3004     QVERIFY( v1.isDetached() );
3005     QVERIFY( v2.isDetached() );
3006 }
3007
3008 void tst_QVariant::numericalConvert()
3009 {
3010 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__)
3011     QSKIP("Known to fail due to a GCC bug on at least Ubuntu 10.04 32-bit - check QTBUG-8959");
3012 #endif
3013     QVariant vfloat(float(5.3));
3014     QVariant vdouble(double(5.3));
3015     QVariant vreal(qreal(5.3));
3016     QVariant vint(int(5));
3017     QVariant vuint(uint(5));
3018     QVariant vshort(short(5));
3019     QVariant vlonglong(quint64(5));
3020     QVariant vstringint(QString::fromLatin1("5"));
3021     QVariant vstring(QString::fromLatin1("5.3"));
3022
3023     QVector<QVariant *> vect;
3024     vect << &vfloat << &vdouble << &vreal << &vint << &vuint << &vshort<< &vlonglong << &vstringint << &vstring;
3025
3026     for(int i = 0; i < vect.size(); i++) {
3027         double num = 5.3;
3028         if (i >= 3 && i <= 7)
3029             num = 5;
3030         QVariant *v = vect.at(i);
3031         QCOMPARE(v->toFloat() , float(num));
3032         QCOMPARE(float(v->toReal()) , float(num));
3033         QCOMPARE(float(v->toDouble()) , float(num));
3034         if(i != 8) {
3035             QCOMPARE(v->toInt() , int(num));
3036             QCOMPARE(v->toUInt() , uint(num));
3037             QCOMPARE(v->toULongLong() , quint64(num));
3038         }
3039         QCOMPARE(v->toString() , QString::number(num));
3040     }
3041 }
3042
3043
3044 template<class T> void playWithVariant(const T &orig, bool isNull, const QString &toString, double toDouble, bool toBool)
3045 {
3046     QVariant v = QVariant::fromValue(orig);
3047     QVERIFY(v.isValid());
3048     QCOMPARE(v.isNull(), isNull);
3049     QCOMPARE(v.toString(), toString);
3050     QCOMPARE(v.toDouble(), toDouble);
3051     QCOMPARE(v.toBool(), toBool);
3052     QCOMPARE(qvariant_cast<T>(v), orig);
3053
3054     {
3055         QVariant v2 = v;
3056         if (!(QTypeInfo<T>::isStatic && QTypeInfo<T>::isComplex)) {
3057             // Type is movable so standard comparison algorithm in QVariant should work
3058             // In a custom type QVariant is not aware of ==operator so it won't be called,
3059             // which may cause problems especially visible when using a not-movable type
3060             QCOMPARE(v2, v);
3061         }
3062         QVERIFY(v2.isValid());
3063         QCOMPARE(v2.isNull(), isNull);
3064         QCOMPARE(v2.toString(), toString);
3065         QCOMPARE(v2.toDouble(), toDouble);
3066         QCOMPARE(v2.toBool(), toBool);
3067         QCOMPARE(qvariant_cast<T>(v2), orig);
3068
3069         QVariant v3;
3070         v = QVariant();
3071         QCOMPARE(v3, v);
3072         v = v2;
3073         if (!(QTypeInfo<T>::isStatic && QTypeInfo<T>::isComplex)) {
3074             // Type is movable so standard comparison algorithm in QVariant should work
3075             // In a custom type QVariant is not aware of ==operator so it won't be called,
3076             // which may cause problems especially visible when using a not-movable type
3077             QCOMPARE(v2, v);
3078         }
3079         QCOMPARE(qvariant_cast<T>(v2), qvariant_cast<T>(v));
3080         QCOMPARE(v2.toString(), toString);
3081         v3 = QVariant::fromValue(orig);
3082
3083         QVERIFY(v3.isValid());
3084         QCOMPARE(v3.isNull(), isNull);
3085         QCOMPARE(v3.toString(), toString);
3086         QCOMPARE(v3.toDouble(), toDouble);
3087         QCOMPARE(v3.toBool(), toBool);
3088         QCOMPARE(qvariant_cast<T>(v3), qvariant_cast<T>(v));
3089     }
3090
3091     QVERIFY(v.isValid());
3092     QCOMPARE(v.isNull(), isNull);
3093     QCOMPARE(v.toString(), toString);
3094     QCOMPARE(v.toDouble(), toDouble);
3095     QCOMPARE(v.toBool(), toBool);
3096     QCOMPARE(qvariant_cast<T>(v), orig);
3097
3098     if (qMetaTypeId<T>() != qMetaTypeId<QVariant>()) {
3099         QCOMPARE(v.userType(), qMetaTypeId<T>());
3100         QCOMPARE(QVariant::typeToName(QVariant::Type(v.userType())), QMetaType::typeName(qMetaTypeId<T>()));
3101     }
3102 }
3103
3104 #define PLAY_WITH_VARIANT(Orig, IsNull, ToString, ToDouble, ToBool) \
3105     playWithVariant(Orig, IsNull, ToString, ToDouble, ToBool);\
3106     if (QTest::currentTestFailed())\
3107         QFAIL("playWithVariant failed");
3108
3109 struct MyPrimitive
3110 {
3111     char x, y;
3112     bool operator==(const MyPrimitive &o) const
3113     {
3114         return x == o.x && y == o.y;
3115     }
3116 };
3117
3118 QT_BEGIN_NAMESPACE
3119 Q_DECLARE_TYPEINFO(MyPrimitive, Q_PRIMITIVE_TYPE);
3120 QT_END_NAMESPACE
3121
3122 struct MyData
3123 {
3124     void *ptr;
3125     MyData() : ptr(this) {}
3126     ~MyData()
3127     {
3128         if (ptr != this) qWarning("%s: object has moved", Q_FUNC_INFO);
3129     }
3130     MyData(const MyData& o) : ptr(this)
3131     {
3132         if (o.ptr != &o) qWarning("%s: other object has moved", Q_FUNC_INFO);
3133     }
3134     MyData &operator=(const MyData &o)
3135     {
3136         if (ptr != this) qWarning("%s: object has moved", Q_FUNC_INFO);
3137         if (o.ptr != &o) qWarning("%s: other object has moved", Q_FUNC_INFO);
3138         return *this;
3139     }
3140     bool operator==(const MyData &o) const
3141     {
3142         if (ptr != this) qWarning("%s: object has moved", Q_FUNC_INFO);
3143         if (o.ptr != &o) qWarning("%s: other object has moved", Q_FUNC_INFO);
3144         return true;
3145     }
3146 };
3147
3148 struct MyMovable
3149 {
3150     static int count;
3151     int v;
3152     MyMovable() { v = count++; }
3153     ~MyMovable() { count--; }
3154     MyMovable(const MyMovable &o) : v(o.v) { count++; }
3155
3156     bool operator==(const MyMovable &o) const
3157     {
3158         return v == o.v;
3159     }
3160 };
3161
3162 int MyMovable::count  = 0;
3163
3164 struct MyNotMovable
3165 {
3166     static int count;
3167     MyNotMovable *that;
3168     MyNotMovable() : that(this) { count++; }
3169     ~MyNotMovable() { QCOMPARE(that, this);  count--; }
3170     MyNotMovable(const MyNotMovable &o) : that(this) { QCOMPARE(o.that, &o); count++; }
3171     MyNotMovable &operator=(const MyNotMovable &o) {
3172         bool ok = that == this && o.that == &o;
3173         if (!ok) qFatal("MyNotMovable has been moved");
3174         return *this;
3175     }
3176
3177     //PLAY_WITH_VARIANT test that they are equal, but never that they are not equal
3178     // so it would be fine just to always return true
3179     bool operator==(const MyNotMovable &o) const
3180     {
3181         bool ok = that == this && o.that == &o;
3182         if (!ok) qFatal("MyNotMovable has been moved");
3183         return ok;
3184     }
3185 };
3186
3187 int MyNotMovable::count  = 0;
3188
3189 struct MyShared : QSharedData {
3190     MyMovable movable;
3191 };
3192
3193 QT_BEGIN_NAMESPACE
3194 Q_DECLARE_TYPEINFO(MyMovable, Q_MOVABLE_TYPE);
3195 QT_END_NAMESPACE
3196
3197 Q_DECLARE_METATYPE(QList<QSize>)
3198 Q_DECLARE_METATYPE(MyPrimitive)
3199 Q_DECLARE_METATYPE(MyData)
3200 Q_DECLARE_METATYPE(MyMovable)
3201 Q_DECLARE_METATYPE(MyNotMovable)
3202 Q_DECLARE_METATYPE(QList<MyPrimitive>)
3203 Q_DECLARE_METATYPE(QList<MyData>)
3204 Q_DECLARE_METATYPE(QList<MyMovable>)
3205 Q_DECLARE_METATYPE(QList<MyNotMovable>)
3206 Q_DECLARE_METATYPE(MyPrimitive *)
3207 Q_DECLARE_METATYPE(MyData *)
3208 Q_DECLARE_METATYPE(MyMovable *)
3209 Q_DECLARE_METATYPE(MyNotMovable *)
3210 Q_DECLARE_METATYPE(QSharedDataPointer<MyShared>)
3211
3212
3213 void tst_QVariant::moreCustomTypes()
3214 {
3215     {
3216         QList<QSize> listSize;
3217         PLAY_WITH_VARIANT(listSize, false, QString(), 0, false);
3218         listSize << QSize(4,5) << QSize(89,23) << QSize(5,6);
3219         PLAY_WITH_VARIANT(listSize, false, QString(), 0, false);
3220     }
3221
3222     {
3223         QString str;
3224         PLAY_WITH_VARIANT(str, true, QString(), 0, false);
3225         str = QString::fromLatin1("123456789.123");
3226         PLAY_WITH_VARIANT(str, false, str, 123456789.123, true);
3227     }
3228
3229     {
3230         QSize size;
3231         PLAY_WITH_VARIANT(size, false, QString(), 0, false);
3232         PLAY_WITH_VARIANT(QSize(45,78), false, QString(), 0, false);
3233     }
3234
3235     {
3236         MyData d;
3237         PLAY_WITH_VARIANT(d, false, QString(), 0, false);
3238         PLAY_WITH_VARIANT(&d, false, QString(), 0, false);
3239         QList<MyData> l;
3240         PLAY_WITH_VARIANT(l, false, QString(), 0, false);
3241         l << MyData() << MyData();
3242         PLAY_WITH_VARIANT(l, false, QString(), 0, false);
3243     }
3244
3245     {
3246         MyPrimitive d = { 4, 5 };
3247         PLAY_WITH_VARIANT(d, false, QString(), 0, false);
3248         PLAY_WITH_VARIANT(&d, false, QString(), 0, false);
3249         QList<MyPrimitive> l;
3250         PLAY_WITH_VARIANT(l, false, QString(), 0, false);
3251         l << d;
3252         PLAY_WITH_VARIANT(l, false, QString(), 0, false);
3253     }
3254
3255     {
3256         MyMovable d;
3257         PLAY_WITH_VARIANT(d, false, QString(), 0, false);
3258         PLAY_WITH_VARIANT(&d, false, QString(), 0, false);
3259         QList<MyMovable> l;
3260         PLAY_WITH_VARIANT(l, false, QString(), 0, false);
3261         l << MyMovable() << d;
3262         PLAY_WITH_VARIANT(l, false, QString(), 0, false);
3263     }
3264     QCOMPARE(MyMovable::count, 0);
3265
3266     QCOMPARE(MyNotMovable::count, 0);
3267     {
3268         MyNotMovable d;
3269         PLAY_WITH_VARIANT(d, false, QString(), 0, false);
3270         PLAY_WITH_VARIANT(&d, false, QString(), 0, false);
3271         QList<MyNotMovable> l;
3272         PLAY_WITH_VARIANT(l, false, QString(), 0, false);
3273         l << MyNotMovable() << d;
3274         PLAY_WITH_VARIANT(l, false, QString(), 0, false);
3275     }
3276     QCOMPARE(MyNotMovable::count, 0);
3277
3278     {
3279         PLAY_WITH_VARIANT(12.12, false, "12.12", 12.12, true);
3280         PLAY_WITH_VARIANT(12.12f, false, "12.12", 12.12f, true);
3281         PLAY_WITH_VARIANT('a', false, "a", 'a', true);
3282         PLAY_WITH_VARIANT((unsigned char)('a'), false, "a", 'a', true);
3283         PLAY_WITH_VARIANT( quint8(12), false, "\xc", 12, true);
3284         PLAY_WITH_VARIANT(  qint8(13), false, "\xd", 13, true);
3285         PLAY_WITH_VARIANT(quint16(14), false, "14", 14, true);
3286         PLAY_WITH_VARIANT( qint16(15), false, "15", 15, true);
3287         PLAY_WITH_VARIANT(quint32(16), false, "16", 16, true);
3288         PLAY_WITH_VARIANT( qint32(17), false, "17", 17, true);
3289         PLAY_WITH_VARIANT(quint64(18), false, "18", 18, true);
3290         PLAY_WITH_VARIANT( qint64(19), false, "19", 19, true);
3291         PLAY_WITH_VARIANT(  qint8(-12), false, QLatin1String("\xf4"), -12, true); // qint8 is char, so it gets converted via QChar
3292         PLAY_WITH_VARIANT( qint16(-13), false, "-13", -13, true);
3293         PLAY_WITH_VARIANT( qint32(-14), false, "-14", -14, true);
3294         PLAY_WITH_VARIANT( qint64(-15), false, "-15", -15, true);
3295         PLAY_WITH_VARIANT(quint64(0), false, "0", 0, false);
3296         PLAY_WITH_VARIANT( true, false, "true", 1, true);
3297         PLAY_WITH_VARIANT( false, false, "false", 0, false);
3298
3299         PLAY_WITH_VARIANT(QString("hello\n"), false, "hello\n", 0, true);
3300     }
3301
3302     {
3303         int i = 5;
3304         PLAY_WITH_VARIANT((void *)(&i), false, QString(), 0, false);
3305         PLAY_WITH_VARIANT((void *)(0), false, QString(), 0, false);
3306     }
3307
3308     {
3309         QVariant v1 = QVariant::fromValue(5);
3310         QVariant v2 = QVariant::fromValue(5.0);
3311         QVariant v3 = QVariant::fromValue(quint16(5));
3312         QVariant v4 = 5;
3313         QVariant v5 = QVariant::fromValue(MyPrimitive());
3314         QVariant v6 = QVariant::fromValue(MyMovable());
3315         QVariant v7 = QVariant::fromValue(MyData());
3316         PLAY_WITH_VARIANT(v1, false, "5", 5, true);
3317         PLAY_WITH_VARIANT(v2, false, "5", 5, true);
3318         PLAY_WITH_VARIANT(v3, false, "5", 5, true);
3319         PLAY_WITH_VARIANT(v4, false, "5", 5, true);
3320
3321         PLAY_WITH_VARIANT(v5, false, QString(), 0, false);
3322     }
3323
3324     QCOMPARE(MyMovable::count, 0);
3325     {
3326         QSharedDataPointer<MyShared> d(new MyShared);
3327         PLAY_WITH_VARIANT(d, false, QString(), 0, false);
3328     }
3329     QCOMPARE(MyMovable::count, 0);
3330
3331     {
3332         QList<QList<int> > data;
3333         PLAY_WITH_VARIANT(data, false, QString(), 0, false);
3334         data << (QList<int>() << 42);
3335         PLAY_WITH_VARIANT(data, false, QString(), 0, false);
3336     }
3337
3338     {
3339         QList<QVector<int> > data;
3340         PLAY_WITH_VARIANT(data, false, QString(), 0, false);
3341         data << (QVector<int>() << 42);
3342         PLAY_WITH_VARIANT(data, false, QString(), 0, false);
3343     }
3344
3345     {
3346         QList<QSet<int> > data;
3347         PLAY_WITH_VARIANT(data, false, QString(), 0, false);
3348         data << (QSet<int>() << 42);
3349         PLAY_WITH_VARIANT(data, false, QString(), 0, false);
3350     }
3351
3352     {
3353         QList<QLinkedList<int> > data;
3354         PLAY_WITH_VARIANT(data, false, QString(), 0, false);
3355         data << (QLinkedList<int>() << 42);
3356         PLAY_WITH_VARIANT(data, false, QString(), 0, false);
3357     }
3358 }
3359
3360 void tst_QVariant::movabilityTest()
3361 {
3362     // This test checks if QVariant is movable even if an internal data is not movable.
3363     QVERIFY(!MyNotMovable::count);
3364     {
3365         QVariant variant = QVariant::fromValue(MyNotMovable());
3366         QVERIFY(MyNotMovable::count);
3367
3368         // prepare destination memory space to which variant will be moved
3369         QVariant buffer[1];
3370         QCOMPARE(buffer[0].type(), QVariant::Invalid);
3371         buffer[0].~QVariant();
3372
3373         memcpy(buffer, &variant, sizeof(QVariant));
3374         QCOMPARE(buffer[0].type(), QVariant::UserType);
3375         QCOMPARE(buffer[0].userType(), qMetaTypeId<MyNotMovable>());
3376         MyNotMovable tmp(buffer[0].value<MyNotMovable>());
3377
3378         new (&variant) QVariant();
3379     }
3380     QVERIFY(!MyNotMovable::count);
3381 }
3382
3383 void tst_QVariant::variantInVariant()
3384 {
3385     QVariant var1 = 5;
3386     QCOMPARE(var1.type(), QVariant::Int);
3387     QVariant var2 = var1;
3388     QCOMPARE(var2, var1);
3389     QCOMPARE(var2.type(), QVariant::Int);
3390     QVariant var3 = QVariant::fromValue(var1);
3391     QCOMPARE(var3, var1);
3392     QCOMPARE(var3.type(), QVariant::Int);
3393     QVariant var4 = qvariant_cast<QVariant>(var1);
3394     QCOMPARE(var4, var1);
3395     QCOMPARE(var4.type(), QVariant::Int);
3396     QVariant var5;
3397     var5 = var1;
3398     QCOMPARE(var5, var1);
3399     QCOMPARE(var5.type(), QVariant::Int);
3400     QVariant var6;
3401     var6.setValue(var1);
3402     QCOMPARE(var6, var1);
3403     QCOMPARE(var6.type(), QVariant::Int);
3404
3405     QCOMPARE(QVariant::fromValue(var1), QVariant::fromValue(var2));
3406     QCOMPARE(qvariant_cast<QVariant>(var3), QVariant::fromValue(var4));
3407     QCOMPARE(qvariant_cast<QVariant>(var5), qvariant_cast<QVariant>(var6));
3408
3409     QString str("hello");
3410     QVariant var8 = qvariant_cast<QVariant>(QVariant::fromValue(QVariant::fromValue(str)));
3411     QCOMPARE((int)var8.type(), (int)QVariant::String);
3412     QCOMPARE(qvariant_cast<QString>(QVariant(qvariant_cast<QVariant>(var8))), str);
3413
3414     QVariant var9(qMetaTypeId<QVariant>(), &var1);
3415     QCOMPARE(var9.userType(), qMetaTypeId<QVariant>());
3416     QCOMPARE(qvariant_cast<QVariant>(var9), var1);
3417 }
3418
3419 void tst_QVariant::colorInteger()
3420 {
3421     QVariant v = QColor(Qt::red);
3422     QCOMPARE(v.type(), QVariant::Color);
3423     QCOMPARE(v.value<QColor>(), QColor(Qt::red));
3424
3425     v.setValue(1000);
3426     QCOMPARE(v.type(), QVariant::Int);
3427     QCOMPARE(v.toInt(), 1000);
3428
3429     v.setValue(QColor(Qt::yellow));
3430     QCOMPARE(v.type(), QVariant::Color);
3431     QCOMPARE(v.value<QColor>(), QColor(Qt::yellow));
3432 }
3433
3434 class Forward;
3435 Q_DECLARE_OPAQUE_POINTER(Forward*)
3436 Q_DECLARE_METATYPE(Forward*)
3437
3438 void tst_QVariant::forwardDeclare()
3439 {
3440     Forward *f = 0;
3441     QVariant v = QVariant::fromValue(f);
3442     QCOMPARE(qvariant_cast<Forward*>(v), f);
3443 }
3444
3445 void tst_QVariant::loadQt5Stream_data()
3446 {
3447     dataStream_data(QDataStream::Qt_5_0);
3448 }
3449
3450 void tst_QVariant::loadQt5Stream()
3451 {
3452     loadQVariantFromDataStream(QDataStream::Qt_5_0);
3453 }
3454
3455 void tst_QVariant::saveQt5Stream_data()
3456 {
3457     dataStream_data(QDataStream::Qt_5_0);
3458 }
3459
3460 void tst_QVariant::saveQt5Stream()
3461 {
3462     saveQVariantFromDataStream(QDataStream::Qt_5_0);
3463 }
3464
3465 void tst_QVariant::loadQt4Stream_data()
3466 {
3467     dataStream_data(QDataStream::Qt_4_9);
3468 }
3469
3470 void tst_QVariant::loadQt4Stream()
3471 {
3472     loadQVariantFromDataStream(QDataStream::Qt_4_9);
3473 }
3474
3475 void tst_QVariant::saveQt4Stream_data()
3476 {
3477     dataStream_data(QDataStream::Qt_4_9);
3478 }
3479
3480 void tst_QVariant::saveQt4Stream()
3481 {
3482     saveQVariantFromDataStream(QDataStream::Qt_4_9);
3483 }
3484
3485 void tst_QVariant::dataStream_data(QDataStream::Version version)
3486 {
3487     QTest::addColumn<QString>("fileName");
3488
3489     QString path;
3490     switch (version) {
3491     case QDataStream::Qt_4_9:
3492         path = QString::fromLatin1("qt4.9");
3493         break;
3494     case QDataStream::Qt_5_0:
3495         path = QString::fromLatin1("qt5.0");
3496         break;
3497     default:
3498         Q_UNIMPLEMENTED();
3499     }
3500
3501     path = path.prepend(":/stream/").append("/");
3502     QDir dir(path);
3503     uint i = 0;
3504     foreach (const QFileInfo &fileInfo, dir.entryInfoList(QStringList() << "*.bin")) {
3505         QTest::newRow((path + fileInfo.fileName()).toLatin1()) << fileInfo.filePath();
3506         i += 1;
3507     }
3508     QVERIFY(i > 10);
3509 }
3510
3511 void tst_QVariant::loadQVariantFromDataStream(QDataStream::Version version)
3512 {
3513     QFETCH(QString, fileName);
3514
3515     QFile file(fileName);
3516     QVERIFY(file.open(QIODevice::ReadOnly));
3517
3518     QDataStream stream(&file);
3519     stream.setVersion(version);
3520
3521     QString typeName;
3522     QVariant loadedVariant;
3523     stream >> typeName >> loadedVariant;
3524
3525     const int id = QMetaType::type(typeName.toLatin1());
3526     if (id == QMetaType::Void) {
3527         // Void type is not supported by QVariant
3528         return;
3529     }
3530
3531     QVariant constructedVariant(static_cast<QVariant::Type>(id));
3532     QCOMPARE(constructedVariant.userType(), id);
3533     QCOMPARE(QMetaType::typeName(loadedVariant.userType()), typeName.toLatin1().constData());
3534     QCOMPARE(loadedVariant.userType(), constructedVariant.userType());
3535 }
3536
3537 void tst_QVariant::saveQVariantFromDataStream(QDataStream::Version version)
3538 {
3539     QFETCH(QString, fileName);
3540
3541     QFile file(fileName);
3542     QVERIFY(file.open(QIODevice::ReadOnly));
3543     QDataStream dataFileStream(&file);
3544
3545     QString typeName;
3546     dataFileStream >> typeName;
3547     QByteArray data = file.readAll();
3548     const int id = QMetaType::type(typeName.toLatin1());
3549     if (id == QMetaType::Void) {
3550         // Void type is not supported by QVariant
3551         return;
3552     }
3553
3554     QBuffer buffer;
3555     buffer.open(QIODevice::ReadWrite);
3556     QDataStream stream(&buffer);
3557     stream.setVersion(version);
3558
3559     QVariant constructedVariant(static_cast<QVariant::Type>(id));
3560     QCOMPARE(constructedVariant.userType(), id);
3561     stream << constructedVariant;
3562
3563     // We are testing QVariant there is no point in testing full array.
3564     QCOMPARE(buffer.data().left(5), data.left(5));
3565
3566     buffer.seek(0);
3567     QVariant recunstructedVariant;
3568     stream >> recunstructedVariant;
3569     QCOMPARE(recunstructedVariant.userType(), constructedVariant.userType());
3570 }
3571
3572 void tst_QVariant::debugStream_data()
3573 {
3574     QTest::addColumn<QVariant>("variant");
3575     QTest::addColumn<int>("typeId");
3576     for (int id = 0; id < QMetaType::LastGuiType + 1; ++id) {
3577         const char *tagName = QMetaType::typeName(id);
3578         if (!tagName)
3579             continue;
3580         if (id != QMetaType::Void) {
3581             QTest::newRow(tagName) << QVariant(static_cast<QVariant::Type>(id)) << id;
3582         }
3583     }
3584     QTest::newRow("QBitArray(111)") << QVariant(QBitArray(3, true)) << qMetaTypeId<QBitArray>();
3585     QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId<CustomStreamableClass>(), 0) << qMetaTypeId<CustomStreamableClass>();
3586     QTest::newRow("MyClass") << QVariant(qMetaTypeId<MyClass>(), 0) << qMetaTypeId<MyClass>();
3587     QTest::newRow("InvalidVariant") << QVariant() << int(QMetaType::UnknownType);
3588     QTest::newRow("CustomQObject") << QVariant::fromValue(this) << qMetaTypeId<tst_QVariant*>();
3589 }
3590
3591 void tst_QVariant::debugStream()
3592 {
3593     QFETCH(QVariant, variant);
3594     QFETCH(int, typeId);
3595
3596     MessageHandler msgHandler(typeId);
3597     qDebug() << variant;
3598     QVERIFY(msgHandler.testPassed());
3599 }
3600
3601 struct MessageHandlerType : public MessageHandler
3602 {
3603     MessageHandlerType(const int typeId)
3604         : MessageHandler(typeId, handler)
3605     {}
3606     static void handler(QtMsgType, const char *txt)
3607     {
3608         QString msg = QString::fromLatin1(txt);
3609         // Format itself is not important, but basic data as a type name should be included in the output
3610         ok = msg.startsWith("QVariant::");
3611         QVERIFY2(ok, (QString::fromLatin1("Message is not started correctly: '") + msg + '\'').toLatin1().constData());
3612         ok &= (currentId == QMetaType::UnknownType
3613                 ? msg.contains("Invalid")
3614                 : msg.contains(QMetaType::typeName(currentId)));
3615         QVERIFY2(ok, (QString::fromLatin1("Message doesn't contain type name: '") + msg + '\'').toLatin1().constData());
3616     }
3617 };
3618
3619 void tst_QVariant::debugStreamType_data()
3620 {
3621     debugStream_data();
3622 }
3623
3624 void tst_QVariant::debugStreamType()
3625 {
3626     QFETCH(QVariant, variant);
3627     QFETCH(int, typeId);
3628
3629     MessageHandlerType msgHandler(typeId);
3630     qDebug() << QVariant::Type(typeId);
3631     QVERIFY(msgHandler.testPassed());
3632 }
3633
3634 void tst_QVariant::guiVariantAtExit()
3635 {
3636     // crash test, it should not crash at QGuiApplication exit
3637     static QVariant cursor = QCursor();
3638     static QVariant point = QPoint();
3639     static QVariant icon = QIcon();
3640     static QVariant image = QImage();
3641     static QVariant palette = QPalette();
3642     Q_UNUSED(cursor);
3643     Q_UNUSED(point);
3644     Q_UNUSED(icon);
3645     Q_UNUSED(image);
3646     Q_UNUSED(palette);
3647     QVERIFY(true);
3648 }
3649
3650 QTEST_MAIN(tst_QVariant)
3651 #include "tst_qvariant.moc"