summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-09-09 12:18:55 +0200
committerLars Knoll <lars.knoll@digia.com>2014-09-10 21:10:57 +0200
commit6316a681f3f3dde46d5ab5c915f31a2098b463bb (patch)
treecb94be60559848ae8388b6cadf84c82d37af1bf4 /tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
parentdf25927a6827c0abce6d35440359a835d23226f7 (diff)
Fix user defined conversions to numeric types
The old code was completely broken. It did dereference val for user types, but val does in this case only contain garbage. Instead use the pointer to the correct data. Change-Id: I20ccf0bfa3dd3774c787d08c51cc8dd7b1ec9a1a Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>
Diffstat (limited to 'tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp')
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp93
1 files changed, 93 insertions, 0 deletions
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index f78f993645..c7d862c20e 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -224,6 +224,7 @@ private slots:
void moreCustomTypes();
void movabilityTest();
void variantInVariant();
+ void userConversion();
void forwardDeclare();
void debugStream_data();
@@ -3312,6 +3313,98 @@ void tst_QVariant::variantInVariant()
QCOMPARE(qvariant_cast<QVariant>(var9), var1);
}
+struct Convertible {
+ double d;
+ operator int() const { return (int)d; }
+ operator double() const { return d; }
+ operator QString() const { return QString::number(d); }
+};
+
+Q_DECLARE_METATYPE(Convertible);
+
+struct BigConvertible {
+ double d;
+ double dummy;
+ double dummy2;
+ operator int() const { return (int)d; }
+ operator double() const { return d; }
+ operator QString() const { return QString::number(d); }
+};
+
+Q_DECLARE_METATYPE(BigConvertible);
+Q_STATIC_ASSERT(sizeof(BigConvertible) > sizeof(QVariant));
+
+void tst_QVariant::userConversion()
+{
+ {
+ QVERIFY(!(QMetaType::hasRegisteredConverterFunction<int, Convertible>()));
+ QVERIFY(!(QMetaType::hasRegisteredConverterFunction<double, Convertible>()));
+ QVERIFY(!(QMetaType::hasRegisteredConverterFunction<QString, Convertible>()));
+
+ Convertible c = { 123 };
+ QVariant v = qVariantFromValue(c);
+
+ bool ok;
+ v.toInt(&ok);
+ QVERIFY(!ok);
+
+ v.toDouble(&ok);
+ QVERIFY(!ok);
+
+ QString s = v.toString();
+ QVERIFY(s.isEmpty());
+
+ QMetaType::registerConverter<Convertible, int>();
+ QMetaType::registerConverter<Convertible, double>();
+ QMetaType::registerConverter<Convertible, QString>();
+
+ int i = v.toInt(&ok);
+ QVERIFY(ok);
+ QCOMPARE(i, 123);
+
+ double d = v.toDouble(&ok);
+ QVERIFY(ok);
+ QCOMPARE(d, 123.);
+
+ s = v.toString();
+ QCOMPARE(s, QString::fromLatin1("123"));
+ }
+
+ {
+ QVERIFY(!(QMetaType::hasRegisteredConverterFunction<int, BigConvertible>()));
+ QVERIFY(!(QMetaType::hasRegisteredConverterFunction<double, BigConvertible>()));
+ QVERIFY(!(QMetaType::hasRegisteredConverterFunction<QString, BigConvertible>()));
+
+ BigConvertible c = { 123, 0, 0 };
+ QVariant v = qVariantFromValue(c);
+
+ bool ok;
+ v.toInt(&ok);
+ QVERIFY(!ok);
+
+ v.toDouble(&ok);
+ QVERIFY(!ok);
+
+ QString s = v.toString();
+ QVERIFY(s.isEmpty());
+
+ QMetaType::registerConverter<BigConvertible, int>();
+ QMetaType::registerConverter<BigConvertible, double>();
+ QMetaType::registerConverter<BigConvertible, QString>();
+
+ int i = v.toInt(&ok);
+ QVERIFY(ok);
+ QCOMPARE(i, 123);
+
+ double d = v.toDouble(&ok);
+ QVERIFY(ok);
+ QCOMPARE(d, 123.);
+
+ s = v.toString();
+ QCOMPARE(s, QString::fromLatin1("123"));
+ }
+}
+
class Forward;
Q_DECLARE_OPAQUE_POINTER(Forward*)
Q_DECLARE_METATYPE(Forward*)