}
writeValueProperty(object, engine, core, QVariant::fromValue(v8engine->scriptValueFromInternal(result)), context, flags);
} else if (isUndefined) {
- expression->delayedError()->error.setDescription(QLatin1String("Unable to assign [undefined] to ") + QLatin1String(QMetaType::typeName(type)));
+ QString errorStr = QLatin1String("Unable to assign [undefined] to ");
+ if (!QMetaType::typeName(type))
+ errorStr += QLatin1String("[unknown property type]");
+ else
+ errorStr += QLatin1String(QMetaType::typeName(type));
+ expression->delayedError()->error.setDescription(errorStr);
return false;
} else if (result->IsFunction()) {
if (!result->ToObject()->GetHiddenValue(v8engine->bindingFlagKey()).IsEmpty())
if (value->ToObject()->GetHiddenValue(engine->bindingFlagKey()).IsEmpty()) {
if (!property->isVarProperty() && property->propType != qMetaTypeId<QJSValue>()) {
// assigning a JS function to a non var or QJSValue property or is not allowed.
- QString error = QLatin1String("Cannot assign JavaScript function to ") +
- QLatin1String(QMetaType::typeName(property->propType));
+ QString error = QLatin1String("Cannot assign JavaScript function to ");
+ if (!QMetaType::typeName(property->propType))
+ error += QLatin1String("[unknown property type]");
+ else
+ error += QLatin1String(QMetaType::typeName(property->propType));
v8::ThrowException(v8::Exception::Error(engine->toString(error)));
return;
}
} else if (!newBinding && property->propType == qMetaTypeId<QJSValue>()) {
PROPERTY_STORE(QJSValue, engine->scriptValueFromInternal(value));
} else if (value->IsUndefined()) {
- QString error = QLatin1String("Cannot assign [undefined] to ") +
- QLatin1String(QMetaType::typeName(property->propType));
+ QString error = QLatin1String("Cannot assign [undefined] to ");
+ if (!QMetaType::typeName(property->propType))
+ error += QLatin1String("[unknown property type]");
+ else
+ error += QLatin1String(QMetaType::typeName(property->propType));
v8::ThrowException(v8::Exception::Error(engine->toString(error)));
} else if (value->IsFunction()) {
// this is handled by the binding creation above
MyQmlObject {
property int a: MyQmlObject.EnumValue10
property int b: Namespace.MyQmlObject.EnumValue10
+ property int c: child.enumProperty
+
+ // test binding codepath
+ property MyUnregisteredEnumTypeObject child: MyUnregisteredEnumTypeObject {
+ enumProperty: undefined
+ }
+
+ // test assignment codepaths
+ function testAssignmentOne() {
+ child.enumProperty = function() { return "Hello, world!" }; // cannot assign function to non-var prop.
+ }
+ function testAssignmentTwo() {
+ child.enumProperty = MyUnregisteredEnumTypeObject.Firstvalue; // note: incorrect capitalisation
+ }
+ function testAssignmentThree() {
+ child.enumProperty = undefined; // directly set undefined value
+ }
}
qmlRegisterType<WriteCounter>("Qt.test", 1, 0, "WriteCounter");
qmlRegisterType<MySequenceConversionObject>("Qt.test", 1, 0, "MySequenceConversionObject");
+
+ qmlRegisterType<MyUnregisteredEnumTypeObject>("Qt.test", 1, 0, "MyUnregisteredEnumTypeObject");
}
#include "testtypes.moc"
void done(const QString &result);
};
+class MyUnregisteredEnumTypeObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(MyEnum enumProperty READ enumProperty WRITE setEnumProperty)
+
+public:
+ MyUnregisteredEnumTypeObject() : QObject(), m_ev(FirstValue) {}
+ ~MyUnregisteredEnumTypeObject() {}
+
+ enum MyEnum {
+ FirstValue = 1,
+ SecondValue = 2
+ };
+
+ MyEnum enumProperty() const { return m_ev; }
+ void setEnumProperty(MyEnum v) { m_ev = v; }
+
+private:
+ MyEnum m_ev;
+};
+
void registerTypes();
#endif // TESTTYPES_H
{
QQmlComponent component(&engine, testFileUrl("enums.2.qml"));
- QString warning1 = component.url().toString() + ":5: Unable to assign [undefined] to int";
- QString warning2 = component.url().toString() + ":6: Unable to assign [undefined] to int";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
+ QString w1 = QLatin1String("QMetaProperty::read: Unable to handle unregistered datatype 'MyEnum' for property 'MyUnregisteredEnumTypeObject::enumProperty'");
+ QString w2 = QLatin1String("QQmlExpression: Expression ") + testFileUrl("enums.2.qml").toString() + QLatin1String(":7 depends on non-NOTIFYable properties:");
+ QString w3 = QLatin1String(" MyUnregisteredEnumTypeObject::enumProperty");
+ QString w4 = component.url().toString() + ":5: Unable to assign [undefined] to int";
+ QString w5 = component.url().toString() + ":6: Unable to assign [undefined] to int";
+ QString w6 = component.url().toString() + ":7: Unable to assign [undefined] to int";
+ QString w7 = component.url().toString() + ":11: Unable to assign [undefined] to [unknown property type]";
+ QString w8 = component.url().toString() + ":16: Error: Cannot assign JavaScript function to [unknown property type]";
+ QString w9 = component.url().toString() + ":19: Error: Cannot assign [undefined] to [unknown property type]";
+ QString w10 = component.url().toString() + ":22: Error: Cannot assign [undefined] to [unknown property type]";
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(w1));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(w2));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(w3));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(w4));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(w5));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(w6));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(w7));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(w8));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(w9));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(w10));
QObject *object = component.create();
QVERIFY(object != 0);
QCOMPARE(object->property("a").toInt(), 0);
QCOMPARE(object->property("b").toInt(), 0);
+ QCOMPARE(object->property("c").toInt(), 0);
+
+ QMetaObject::invokeMethod(object, "testAssignmentOne");
+ QMetaObject::invokeMethod(object, "testAssignmentTwo");
+ QMetaObject::invokeMethod(object, "testAssignmentThree");
delete object;
}