#include <QtQml/qqmlproperty.h>
#include <QtQml/private/qqmlproperty_p.h>
#include <private/qqmlbinding_p.h>
+#include <private/qqmlboundsignal_p.h>
#include <QtWidgets/QLineEdit>
#include <QtCore/qfileinfo.h>
#include <QtCore/qdir.h>
void aliasPropertyBindings();
void noContext();
void assignEmptyVariantMap();
+ void warnOnInvalidBinding();
+ void registeredCompositeTypeProperty();
void copy();
private:
{
QQmlProperty prop;
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QVERIFY(prop.method().signature() == 0);
+ QVERIFY(!prop.method().isValid());
QCOMPARE(prop.type(), QQmlProperty::Invalid);
QCOMPARE(prop.isProperty(), false);
QCOMPARE(prop.isWritable(), false);
QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0);
QVERIFY(binding == 0);
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression == 0);
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1);
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
delete obj;
}
+// 1 = equal, 0 = unknown, -1 = not equal.
+static int compareVariantAndListReference(const QVariant &v, QQmlListReference &r)
+{
+ if (QLatin1String(v.typeName()) != QLatin1String("QQmlListReference"))
+ return -1;
+
+ QQmlListReference lhs = v.value<QQmlListReference>();
+ if (lhs.isValid() != r.isValid())
+ return -1;
+
+ if (lhs.canCount() != r.canCount())
+ return -1;
+
+ if (!lhs.canCount()) {
+ if (lhs.canAt() != r.canAt())
+ return -1; // not equal.
+ return 0; // not sure if they're equal or not, and no way to tell.
+ }
+
+ // if we get here, we must be able to count.
+ if (lhs.count() != r.count())
+ return -1;
+
+ if (lhs.canAt() != r.canAt())
+ return -1;
+
+ if (!lhs.canAt())
+ return 0; // can count, but can't check element equality.
+
+ for (int i = 0; i < lhs.count(); ++i) {
+ if (lhs.at(i) != r.at(i)) {
+ return -1; // different elements :. not equal.
+ }
+ }
+
+ return 1; // equal.
+}
+
+void tst_qqmlproperty::registeredCompositeTypeProperty()
+{
+ // Composite type properties
+ {
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("registeredCompositeTypeProperty.qml"));
+ QObject *obj = component.create();
+ QVERIFY(obj);
+
+ // create property accessors and check types.
+ QQmlProperty p1(obj, "first");
+ QQmlProperty p2(obj, "second");
+ QQmlProperty p3(obj, "third");
+ QQmlProperty p1e(obj, "first", &engine);
+ QQmlProperty p2e(obj, "second", &engine);
+ QQmlProperty p3e(obj, "third", &engine);
+ QVERIFY(p1.propertyType() == p2.propertyType());
+ QVERIFY(p1.propertyType() != p3.propertyType());
+
+ // check that the values are retrievable from CPP
+ QVariant first = obj->property("first");
+ QVariant second = obj->property("second");
+ QVariant third = obj->property("third");
+ QVERIFY(first.isValid());
+ QVERIFY(second.isValid());
+ QVERIFY(third.isValid());
+ // ensure that conversion from qobject-derived-ptr to qobject-ptr works.
+ QVERIFY(first.value<QObject*>());
+ QVERIFY(second.value<QObject*>());
+ QVERIFY(third.value<QObject*>());
+
+ // check that the values retrieved via QQmlProperty match those retrieved via QMetaProperty::read().
+ QCOMPARE(p1.read().value<QObject*>(), first.value<QObject*>());
+ QCOMPARE(p2.read().value<QObject*>(), second.value<QObject*>());
+ QCOMPARE(p3.read().value<QObject*>(), third.value<QObject*>());
+ QCOMPARE(p1e.read().value<QObject*>(), first.value<QObject*>());
+ QCOMPARE(p2e.read().value<QObject*>(), second.value<QObject*>());
+ QCOMPARE(p3e.read().value<QObject*>(), third.value<QObject*>());
+
+ delete obj;
+ }
+
+ // List-of-composite-type type properties
+ {
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("registeredCompositeTypeProperty.qml"));
+ QObject *obj = component.create();
+ QVERIFY(obj);
+
+ // create list property accessors and check types
+ QQmlProperty lp1e(obj, "fclist", &engine);
+ QQmlProperty lp2e(obj, "sclistOne", &engine);
+ QQmlProperty lp3e(obj, "sclistTwo", &engine);
+ QVERIFY(lp1e.propertyType() != lp2e.propertyType());
+ QVERIFY(lp2e.propertyType() == lp3e.propertyType());
+
+ // check that the list values are retrievable from CPP
+ QVariant firstList = obj->property("fclist");
+ QVariant secondList = obj->property("sclistOne");
+ QVariant thirdList = obj->property("sclistTwo");
+ QVERIFY(firstList.isValid());
+ QVERIFY(secondList.isValid());
+ QVERIFY(thirdList.isValid());
+
+ // check that the value returned by QQmlProperty::read() is equivalent to the list reference.
+ QQmlListReference r1(obj, "fclist", &engine);
+ QQmlListReference r2(obj, "sclistOne", &engine);
+ QQmlListReference r3(obj, "sclistTwo", &engine);
+ QCOMPARE(compareVariantAndListReference(lp1e.read(), r1), 1);
+ QCOMPARE(compareVariantAndListReference(lp2e.read(), r2), 1);
+ QCOMPARE(compareVariantAndListReference(lp3e.read(), r3), 1);
+
+ delete obj;
+ }
+}
+
class PropertyObject : public QObject
{
Q_OBJECT
{
QQmlProperty prop(&object);
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QVERIFY(prop.method().signature() == 0);
+ QVERIFY(!prop.method().isValid());
QCOMPARE(prop.type(), QQmlProperty::Invalid);
QCOMPARE(prop.isProperty(), false);
QCOMPARE(prop.isWritable(), false);
QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0);
QVERIFY(binding == 0);
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression == 0);
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1);
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
{
QQmlProperty prop(&dobject);
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
- binding.data()->setTarget(prop);
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
+ static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QVERIFY(prop.method().signature() == 0);
+ QVERIFY(!prop.method().isValid());
QCOMPARE(prop.type(), QQmlProperty::Property);
QCOMPARE(prop.isProperty(), true);
QCOMPARE(prop.isWritable(), false);
QVERIFY(binding != 0);
QVERIFY(QQmlPropertyPrivate::binding(prop) == binding.data());
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression == 0);
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
{
QQmlProperty prop(&object, QString("defaultProperty"));
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QVERIFY(prop.method().signature() == 0);
+ QVERIFY(!prop.method().isValid());
QCOMPARE(prop.type(), QQmlProperty::Invalid);
QCOMPARE(prop.isProperty(), false);
QCOMPARE(prop.isWritable(), false);
QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0);
QVERIFY(binding == 0);
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression == 0);
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1);
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
{
QQmlProperty prop(&dobject, QString("defaultProperty"));
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
- binding.data()->setTarget(prop);
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
+ static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QVERIFY(prop.method().signature() == 0);
+ QVERIFY(!prop.method().isValid());
QCOMPARE(prop.type(), QQmlProperty::Property);
QCOMPARE(prop.isProperty(), true);
QCOMPARE(prop.isWritable(), false);
QVERIFY(binding != 0);
QVERIFY(QQmlPropertyPrivate::binding(prop) == binding.data());
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression == 0);
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
{
QQmlProperty prop(&dobject, QString("onClicked"));
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
- binding.data()->setTarget(prop);
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
+ static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QCOMPARE(QString(prop.method().signature()), QString("clicked()"));
+ QCOMPARE(QString(prop.method().methodSignature()), QString("clicked()"));
QCOMPARE(prop.type(), QQmlProperty::SignalProperty);
QCOMPARE(prop.isProperty(), false);
QCOMPARE(prop.isWritable(), false);
QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0);
QVERIFY(binding == 0);
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression != 0);
- QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == expression.data());
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(!sigExprWatcher.wasDeleted());
+ QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == sigExpr);
QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
{
QQmlProperty prop(&dobject, QString("onPropertyWithNotifyChanged"));
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
- binding.data()->setTarget(prop);
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
+ static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QCOMPARE(QString(prop.method().signature()), QString("oddlyNamedNotifySignal()"));
+ QCOMPARE(QString(prop.method().methodSignature()), QString("oddlyNamedNotifySignal()"));
QCOMPARE(prop.type(), QQmlProperty::SignalProperty);
QCOMPARE(prop.isProperty(), false);
QCOMPARE(prop.isWritable(), false);
QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0);
QVERIFY(binding == 0);
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression != 0);
- QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == expression.data());
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(!sigExprWatcher.wasDeleted());
+ QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == sigExpr);
QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
{
QQmlProperty prop(&object, engine.rootContext());
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QVERIFY(prop.method().signature() == 0);
+ QVERIFY(!prop.method().isValid());
QCOMPARE(prop.type(), QQmlProperty::Invalid);
QCOMPARE(prop.isProperty(), false);
QCOMPARE(prop.isWritable(), false);
QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0);
QVERIFY(binding == 0);
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression == 0);
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1);
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
{
QQmlProperty prop(&dobject, engine.rootContext());
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
- binding.data()->setTarget(prop);
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
+ static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QVERIFY(prop.method().signature() == 0);
+ QVERIFY(!prop.method().isValid());
QCOMPARE(prop.type(), QQmlProperty::Property);
QCOMPARE(prop.isProperty(), true);
QCOMPARE(prop.isWritable(), false);
QVERIFY(binding != 0);
QVERIFY(QQmlPropertyPrivate::binding(prop) == binding.data());
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression == 0);
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
{
QQmlProperty prop(&object, QString("defaultProperty"), engine.rootContext());
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QVERIFY(prop.method().signature() == 0);
+ QVERIFY(!prop.method().isValid());
QCOMPARE(prop.type(), QQmlProperty::Invalid);
QCOMPARE(prop.isProperty(), false);
QCOMPARE(prop.isWritable(), false);
QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0);
QVERIFY(binding == 0);
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression == 0);
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), -1);
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
{
QQmlProperty prop(&dobject, QString("defaultProperty"), engine.rootContext());
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
- binding.data()->setTarget(prop);
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
+ static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QVERIFY(prop.method().signature() == 0);
+ QVERIFY(!prop.method().isValid());
QCOMPARE(prop.type(), QQmlProperty::Property);
QCOMPARE(prop.isProperty(), true);
QCOMPARE(prop.isWritable(), false);
QVERIFY(binding != 0);
QVERIFY(QQmlPropertyPrivate::binding(prop) == binding.data());
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression == 0);
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(sigExprWatcher.wasDeleted());
QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
{
QQmlProperty prop(&dobject, QString("onClicked"), engine.rootContext());
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
- binding.data()->setTarget(prop);
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
+ static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QCOMPARE(QString(prop.method().signature()), QString("clicked()"));
+ QCOMPARE(QString(prop.method().methodSignature()), QString("clicked()"));
QCOMPARE(prop.type(), QQmlProperty::SignalProperty);
QCOMPARE(prop.isProperty(), false);
QCOMPARE(prop.isWritable(), false);
QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0);
QVERIFY(binding == 0);
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression != 0);
- QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == expression.data());
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(!sigExprWatcher.wasDeleted());
+ QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == sigExpr);
QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
{
QQmlProperty prop(&dobject, QString("onPropertyWithNotifyChanged"), engine.rootContext());
- QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()));
- binding.data()->setTarget(prop);
+ QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())));
+ static_cast<QQmlBinding *>(binding.data())->setTarget(prop);
QVERIFY(binding != 0);
- QWeakPointer<QQmlExpression> expression(new QQmlExpression());
- QVERIFY(expression != 0);
+ QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1);
+ QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr);
+ QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted());
QObject *obj = new QObject;
QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
QCOMPARE(prop.connectNotifySignal(obj, -1), false);
- QCOMPARE(QString(prop.method().signature()), QString("oddlyNamedNotifySignal()"));
+ QCOMPARE(QString(prop.method().methodSignature()), QString("oddlyNamedNotifySignal()"));
QCOMPARE(prop.type(), QQmlProperty::SignalProperty);
QCOMPARE(prop.isProperty(), false);
QCOMPARE(prop.isWritable(), false);
QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0);
QVERIFY(binding == 0);
QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0);
- QVERIFY(QQmlPropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
- QVERIFY(expression != 0);
- QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == expression.data());
+ QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0);
+ QVERIFY(!sigExprWatcher.wasDeleted());
+ QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == sigExpr);
QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()"));
QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1);
QQmlProperty p(&o, "onClicked");
QCOMPARE(p.read(), QVariant());
- QVERIFY(0 == QQmlPropertyPrivate::setSignalExpression(p, new QQmlExpression()));
+ QVERIFY(0 == QQmlPropertyPrivate::takeSignalExpression(p, new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1)));
QVERIFY(0 != QQmlPropertyPrivate::signalExpression(p));
QCOMPARE(p.read(), QVariant());
QQmlProperty p(&o, "onPropertyWithNotifyChanged");
QCOMPARE(p.read(), QVariant());
- QVERIFY(0 == QQmlPropertyPrivate::setSignalExpression(p, new QQmlExpression()));
+ QVERIFY(0 == QQmlPropertyPrivate::takeSignalExpression(p, new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1)));
QVERIFY(0 != QQmlPropertyPrivate::signalExpression(p));
QCOMPARE(p.read(), QVariant());
QQmlProperty p(&o, "onClicked");
QCOMPARE(p.write(QVariant("console.log(1921)")), false);
- QVERIFY(0 == QQmlPropertyPrivate::setSignalExpression(p, new QQmlExpression()));
+ QVERIFY(0 == QQmlPropertyPrivate::takeSignalExpression(p, new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1)));
QVERIFY(0 != QQmlPropertyPrivate::signalExpression(p));
QCOMPARE(p.write(QVariant("console.log(1921)")), false);
QQmlProperty p(&o, "onPropertyWithNotifyChanged");
QCOMPARE(p.write(QVariant("console.log(1921)")), false);
- QVERIFY(0 == QQmlPropertyPrivate::setSignalExpression(p, new QQmlExpression()));
+ QVERIFY(0 == QQmlPropertyPrivate::takeSignalExpression(p, new QQmlBoundSignalExpression(QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), false, QString(), -1, -1)));
QVERIFY(0 != QQmlPropertyPrivate::signalExpression(p));
QCOMPARE(p.write(QVariant("console.log(1921)")), false);
<< QByteArray("http://www.example.com/main%20file.qml");
QTest::newRow("preencodedName")
- << QByteArray("http://www.example.com/resources%7cmain%20file.qml")
+ << QByteArray("http://www.example.com/resources%7Cmain%20file.qml")
<< QString("http")
<< QString("/resources|main file.qml")
- << QByteArray("http://www.example.com/resources%7cmain%20file.qml");
+ << QByteArray("http://www.example.com/resources%7Cmain%20file.qml");
QTest::newRow("encodableQuery")
<< QByteArray("http://www.example.com/main.qml?type=text/qml&comment=now working?")
<< QByteArray("http://www.example.com/main.qml?type=text/qml&comment=now%20working?");
QTest::newRow("preencodedQuery")
- << QByteArray("http://www.example.com/main.qml?type=text%2fqml&comment=now working%3f")
+ << QByteArray("http://www.example.com/main.qml?type=text%2Fqml&comment=now working%3F")
<< QString("http")
<< QString("/main.qml")
- << QByteArray("http://www.example.com/main.qml?type=text%2fqml&comment=now%20working%3f");
+ << QByteArray("http://www.example.com/main.qml?type=text%2Fqml&comment=now%20working%3F");
QTest::newRow("encodableFragment")
<< QByteArray("http://www.example.com/main.qml?type=text/qml#start+30000|volume+50%")
<< QString("/main.qml")
<< QByteArray("http://www.example.com/main.qml?type=text/qml#start+30000%7Cvolume+50%25");
- QTest::newRow("preencodedFragment")
- << QByteArray("http://www.example.com/main.qml?type=text/qml#start+30000%7cvolume%2b50%")
+ QTest::newRow("improperlyEncodedFragment")
+ << QByteArray("http://www.example.com/main.qml?type=text/qml#start+30000%7Cvolume%2B50%")
<< QString("http")
<< QString("/main.qml")
- << QByteArray("http://www.example.com/main.qml?type=text/qml#start+30000%7cvolume%2b50%25");
+ << QByteArray("http://www.example.com/main.qml?type=text/qml#start+30000%257Cvolume%252B50%25");
}
void tst_qqmlproperty::urlHandling()
QCOMPARE(byteArrayResult.scheme(), scheme);
QCOMPARE(byteArrayResult.path(), path);
+ QCOMPARE(byteArrayResult.toString(QUrl::FullyEncoded), QString::fromUtf8(encoded));
QCOMPARE(byteArrayResult.toEncoded(), encoded);
}
QCOMPARE(stringResult.scheme(), scheme);
QCOMPARE(stringResult.path(), path);
+ QCOMPARE(stringResult.toString(QUrl::FullyEncoded), QString::fromUtf8(encoded));
QCOMPARE(stringResult.toEncoded(), encoded);
}
}
delete engine;
engine = 0;
- QSKIP("QTBUG-24734: test accesses deleted QML engine from QQmlProperty::propertyTypeName()");
-
QCOMPARE(p.propertyTypeName(), "int");
QCOMPARE(p.read(), QVariant(10));
p.write(QVariant(20));
delete obj;
}
+void tst_qqmlproperty::warnOnInvalidBinding()
+{
+ QUrl testUrl(testFileUrl("invalidBinding.qml"));
+ QString expectedWarning;
+
+ // V4 error message for property-to-property binding
+ expectedWarning = testUrl.toString() + QString::fromLatin1(":6:36: Unable to assign QQuickText to QQuickRectangle");
+ QTest::ignoreMessage(QtWarningMsg, expectedWarning.toLatin1().constData());
+
+ // V8 error message for function-to-property binding
+ expectedWarning = testUrl.toString() + QString::fromLatin1(":7:36: Unable to assign QQuickText to QQuickRectangle");
+ QTest::ignoreMessage(QtWarningMsg, expectedWarning.toLatin1().constData());
+
+ // V8 error message for invalid binding to anchor
+ expectedWarning = testUrl.toString() + QString::fromLatin1(":14: Unable to assign QQuickItem_QML_7 to QQuickAnchorLine");
+ QTest::ignoreMessage(QtWarningMsg, expectedWarning.toLatin1().constData());
+
+ QQmlComponent component(&engine, testUrl);
+ QObject *obj = component.create();
+ QVERIFY(obj);
+ delete obj;
+}
+
void tst_qqmlproperty::initTestCase()
{
QQmlDataTest::initTestCase();