diff options
12 files changed, 394 insertions, 0 deletions
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 9b80c2cad1..3b47e208eb 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -72,6 +72,12 @@ #include <QtCore/qdebug.h> #include <QtCore/qdatetime.h> +Q_DECLARE_METATYPE(QList<int>) +Q_DECLARE_METATYPE(QList<qreal>) +Q_DECLARE_METATYPE(QList<bool>) +Q_DECLARE_METATYPE(QList<QString>) +Q_DECLARE_METATYPE(QList<QUrl>) + QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP); @@ -235,6 +241,9 @@ bool QDeclarativeCompiler::testLiteralAssignment(QDeclarativeScript::Property *p case QVariant::String: if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: string expected")); break; + case QVariant::StringList: // we expect a string literal. A string list is not a literal assignment. + if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: string or string list expected")); + break; case QVariant::ByteArray: if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: byte array expected")); break; @@ -344,6 +353,41 @@ bool QDeclarativeCompiler::testLiteralAssignment(QDeclarativeScript::Property *p break; default: { + // check if assigning a literal value to a list property. + // in each case, check the singular, since an Array of the specified type + // will not go via this literal assignment codepath. + if (type == qMetaTypeId<QList<qreal> >()) { + if (!v->value.isNumber()) { + COMPILE_EXCEPTION(v, tr("Invalid property assignment: real or array of reals expected")); + } + break; + } else if (type == qMetaTypeId<QList<int> >()) { + bool ok = v->value.isNumber(); + if (ok) { + double n = v->value.asNumber(); + if (double(int(n)) != n) + ok = false; + } + if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: int or array of ints expected")); + break; + } else if (type == qMetaTypeId<QList<bool> >()) { + if (!v->value.isBoolean()) { + COMPILE_EXCEPTION(v, tr("Invalid property assignment: bool or array of bools expected")); + } + break; + } else if (type == qMetaTypeId<QList<QString> >()) { // we expect a string literal. A string list is not a literal assignment. + if (!v->value.isString()) { + COMPILE_EXCEPTION(v, tr("Invalid property assignment: string or array of strings expected")); + } + break; + } else if (type == qMetaTypeId<QList<QUrl> >()) { + if (!v->value.isString()) { + COMPILE_EXCEPTION(v, tr("Invalid property assignment: url or array of urls expected")); + } + break; + } + + // otherwise, check for existence of string converter to custom type QDeclarativeMetaType::StringConverter converter = QDeclarativeMetaType::customStringConverter(type); if (!converter) COMPILE_EXCEPTION(v, tr("Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QVariant::typeToName((QVariant::Type)type)))); @@ -440,6 +484,14 @@ void QDeclarativeCompiler::genLiteralAssignment(QDeclarativeScript::Property *pr output->addInstruction(instr); } break; + case QVariant::StringList: + { + Instruction::StoreStringList instr; + instr.propertyIndex = prop->index; + instr.value = output->indexForString(v->value.asString()); + output->addInstruction(instr); + } + break; case QVariant::ByteArray: { Instruction::StoreByteArray instr; @@ -638,6 +690,43 @@ void QDeclarativeCompiler::genLiteralAssignment(QDeclarativeScript::Property *pr break; default: { + // generate single literal value assignment to a list property if required + if (type == qMetaTypeId<QList<qreal> >()) { + Instruction::StoreDoubleQList instr; + instr.propertyIndex = prop->index; + instr.value = v->value.asNumber(); + output->addInstruction(instr); + break; + } else if (type == qMetaTypeId<QList<int> >()) { + Instruction::StoreIntegerQList instr; + instr.propertyIndex = prop->index; + instr.value = int(v->value.asNumber()); + output->addInstruction(instr); + break; + } else if (type == qMetaTypeId<QList<bool> >()) { + Instruction::StoreBoolQList instr; + bool b = v->value.asBoolean(); + instr.propertyIndex = prop->index; + instr.value = b; + output->addInstruction(instr); + break; + } else if (type == qMetaTypeId<QList<QUrl> >()) { + Instruction::StoreUrlQList instr; + QString string = v->value.asString(); + QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(QUrl(string)); + instr.propertyIndex = prop->index; + instr.value = output->indexForUrl(u); + output->addInstruction(instr); + break; + } else if (type == qMetaTypeId<QList<QString> >()) { + Instruction::StoreStringQList instr; + instr.propertyIndex = prop->index; + instr.value = output->indexForString(v->value.asString()); + output->addInstruction(instr); + break; + } + + // otherwise, generate custom type literal assignment Instruction::AssignCustomType instr; instr.propertyIndex = prop->index; instr.primitive = output->indexForString(v->value.asString()); diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp index 5f8b253858..da5c29069e 100644 --- a/src/declarative/qml/qdeclarativeinstruction.cpp +++ b/src/declarative/qml/qdeclarativeinstruction.cpp @@ -93,21 +93,39 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) case QDeclarativeInstruction::StoreDouble: qWarning().nospace() << idx << "\t\t" << "STORE_DOUBLE\t\t" << instr->storeDouble.propertyIndex << "\t" << instr->storeDouble.value; break; + case QDeclarativeInstruction::StoreDoubleQList: + qWarning().nospace() << idx << "\t\t" << "STORE_DOUBLE_QLIST\t\t" << instr->storeDouble.propertyIndex << "\t" << instr->storeDouble.value; + break; case QDeclarativeInstruction::StoreInteger: qWarning().nospace() << idx << "\t\t" << "STORE_INTEGER\t\t" << instr->storeInteger.propertyIndex << "\t" << instr->storeInteger.value; break; + case QDeclarativeInstruction::StoreIntegerQList: + qWarning().nospace() << idx << "\t\t" << "STORE_INTEGER_QLIST\t\t" << instr->storeInteger.propertyIndex << "\t" << instr->storeInteger.value; + break; case QDeclarativeInstruction::StoreBool: qWarning().nospace() << idx << "\t\t" << "STORE_BOOL\t\t" << instr->storeBool.propertyIndex << "\t" << instr->storeBool.value; break; + case QDeclarativeInstruction::StoreBoolQList: + qWarning().nospace() << idx << "\t\t" << "STORE_BOOL_QLIST\t\t" << instr->storeBool.propertyIndex << "\t" << instr->storeBool.value; + break; case QDeclarativeInstruction::StoreString: qWarning().nospace() << idx << "\t\t" << "STORE_STRING\t\t" << instr->storeString.propertyIndex << "\t" << instr->storeString.value << "\t\t" << primitives.at(instr->storeString.value); break; + case QDeclarativeInstruction::StoreStringList: + qWarning().nospace() << idx << "\t\t" << "STORE_STRINGLIST\t\t" << instr->storeString.propertyIndex << "\t" << instr->storeString.value << "\t\t" << primitives.at(instr->storeString.value); + break; + case QDeclarativeInstruction::StoreStringQList: + qWarning().nospace() << idx << "\t\t" << "STORE_STRING_QLIST\t\t" << instr->storeString.propertyIndex << "\t" << instr->storeString.value << "\t\t" << primitives.at(instr->storeString.value); + break; case QDeclarativeInstruction::StoreByteArray: qWarning().nospace() << idx << "\t\t" << "STORE_BYTEARRAY" << instr->storeByteArray.propertyIndex << "\t" << instr->storeByteArray.value << "\t\t" << datas.at(instr->storeByteArray.value); break; case QDeclarativeInstruction::StoreUrl: qWarning().nospace() << idx << "\t\t" << "STORE_URL\t\t" << instr->storeUrl.propertyIndex << "\t" << instr->storeUrl.value << "\t\t" << urls.at(instr->storeUrl.value); break; + case QDeclarativeInstruction::StoreUrlQList: + qWarning().nospace() << idx << "\t\t" << "STORE_URL_QLIST\t\t" << instr->storeUrl.propertyIndex << "\t" << instr->storeUrl.value << "\t\t" << urls.at(instr->storeUrl.value); + break; case QDeclarativeInstruction::StoreColor: qWarning().nospace() << idx << "\t\t" << "STORE_COLOR\t\t" << instr->storeColor.propertyIndex << "\t\t\t" << QString::number(instr->storeColor.value, 16); break; diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index d73ce46d7e..b36a664443 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -79,12 +79,18 @@ QT_BEGIN_NAMESPACE F(StoreVarDouble, storeDouble) \ F(StoreVarBool, storeBool) \ F(StoreString, storeString) \ + F(StoreStringList, storeString) \ + F(StoreStringQList, storeString) \ F(StoreByteArray, storeByteArray) \ F(StoreUrl, storeUrl) \ + F(StoreUrlQList, storeUrl) \ F(StoreFloat, storeFloat) \ F(StoreDouble, storeDouble) \ + F(StoreDoubleQList, storeDouble) \ F(StoreBool, storeBool) \ + F(StoreBoolQList, storeBool) \ F(StoreInteger, storeInteger) \ + F(StoreIntegerQList, storeInteger) \ F(StoreColor, storeColor) \ F(StoreDate, storeDate) \ F(StoreTime, storeTime) \ diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index d6a2776b32..795283c41d 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -61,6 +61,12 @@ #include <math.h> +Q_DECLARE_METATYPE(QList<int>) +Q_DECLARE_METATYPE(QList<qreal>) +Q_DECLARE_METATYPE(QList<bool>) +Q_DECLARE_METATYPE(QList<QString>) +Q_DECLARE_METATYPE(QList<QUrl>) + QT_BEGIN_NAMESPACE /*! @@ -1285,6 +1291,59 @@ bool QDeclarativePropertyPrivate::write(QObject *object, } } } + if (!ok) { + // the only other option is that they are assigning a single value + // to a sequence type property (eg, an int to a QList<int> property). + if (variantType == QVariant::Int && propertyType == qMetaTypeId<QList<int> >()) { + QList<int> list; + list << value.toInt(); + v = QVariant::fromValue<QList<int> >(list); + ok = true; + } else if (variantType == QVariant::Double && propertyType == qMetaTypeId<QList<qreal> >()) { + QList<qreal> list; + list << value.toReal(); + v = QVariant::fromValue<QList<qreal> >(list); + ok = true; + } else if (variantType == QVariant::Bool && propertyType == qMetaTypeId<QList<bool> >()) { + QList<bool> list; + list << value.toBool(); + v = QVariant::fromValue<QList<bool> >(list); + ok = true; + } else if ((variantType == QVariant::Url || variantType == QVariant::String || variantType == QVariant::ByteArray) + && propertyType == qMetaTypeId<QList<QUrl> >()) { + QUrl u; + bool found = false; + if (variantType == QVariant::Url) { + u = value.toUrl(); + found = true; + } else if (variantType == QVariant::ByteArray) { + u = QUrl(QString::fromUtf8(value.toByteArray())); + found = true; + } else if (variantType == QVariant::String) { + u = QUrl(value.toString()); + found = true; + } + if (!found) + return false; + if (context && u.isRelative() && !u.isEmpty()) + u = context->resolvedUrl(u); + QList<QUrl> list; + list << u; + v = QVariant::fromValue<QList<QUrl> >(list); + ok = true; + } else if (variantType == QVariant::String && propertyType == qMetaTypeId<QList<QString> >()) { + QList<QString> list; + list << value.toString(); + v = QVariant::fromValue<QList<QString> >(list); + ok = true; + } else if (variantType == QVariant::String && propertyType == qMetaTypeId<QStringList>()) { + QStringList list; + list << value.toString(); + v = QVariant::fromValue<QStringList>(list); + ok = true; + } + } + if (ok) { void *a[] = { (void *)v.constData(), 0, &status, &flags}; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); @@ -1358,6 +1417,10 @@ bool QDeclarativePropertyPrivate::writeBinding(QObject *object, value = v8engine->toVariant(result, qMetaTypeId<QList<QObject *> >()); } else if (result->IsNull() && core.isQObject()) { value = QVariant::fromValue((QObject *)0); + } else if (core.propType == qMetaTypeId<QList<QUrl> >()) { + value = v8engine->toVariant(result, qMetaTypeId<QList<QUrl> >()); + if (value.userType() == qMetaTypeId<QString>()) + value = QVariant(QUrl(value.toString())); } else if (!isVmeProperty) { value = v8engine->toVariant(result, type); } diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 313d7f1dc4..a6fc8ba661 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -624,6 +624,27 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors, instr.propertyIndex, a); QML_END_INSTR(StoreString) + QML_BEGIN_INSTR(StoreStringList) + QObject *target = objects.top(); + CLEAN_PROPERTY(target, instr.propertyIndex); + + QStringList stringlist(PRIMITIVES.at(instr.value)); + void *a[] = { (void *)&stringlist, 0, &status, &flags }; + QMetaObject::metacall(target, QMetaObject::WriteProperty, + instr.propertyIndex, a); + QML_END_INSTR(StoreStringList) + + QML_BEGIN_INSTR(StoreStringQList) + QObject *target = objects.top(); + CLEAN_PROPERTY(target, instr.propertyIndex); + + QList<QString> stringqlist; + stringqlist.append(PRIMITIVES.at(instr.value)); + void *a[] = { (void *)&stringqlist, 0, &status, &flags }; + QMetaObject::metacall(target, QMetaObject::WriteProperty, + instr.propertyIndex, a); + QML_END_INSTR(StoreStringQList) + QML_BEGIN_INSTR(StoreByteArray) QObject *target = objects.top(); void *a[] = { (void *)&DATAS.at(instr.value), 0, &status, &flags }; @@ -640,6 +661,17 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors, instr.propertyIndex, a); QML_END_INSTR(StoreUrl) + QML_BEGIN_INSTR(StoreUrlQList) + QObject *target = objects.top(); + CLEAN_PROPERTY(target, instr.propertyIndex); + + QList<QUrl> urlqlist; + urlqlist.append(URLS.at(instr.value)); + void *a[] = { (void *)&urlqlist, 0, &status, &flags }; + QMetaObject::metacall(target, QMetaObject::WriteProperty, + instr.propertyIndex, a); + QML_END_INSTR(StoreUrlQList) + QML_BEGIN_INSTR(StoreFloat) QObject *target = objects.top(); CLEAN_PROPERTY(target, instr.propertyIndex); @@ -660,6 +692,17 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors, instr.propertyIndex, a); QML_END_INSTR(StoreDouble) + QML_BEGIN_INSTR(StoreDoubleQList) + QObject *target = objects.top(); + CLEAN_PROPERTY(target, instr.propertyIndex); + + QList<double> doubleqlist; + doubleqlist.append(instr.value); + void *a[] = { (void *)&doubleqlist, 0, &status, &flags }; + QMetaObject::metacall(target, QMetaObject::WriteProperty, + instr.propertyIndex, a); + QML_END_INSTR(StoreDoubleQList) + QML_BEGIN_INSTR(StoreBool) QObject *target = objects.top(); CLEAN_PROPERTY(target, instr.propertyIndex); @@ -669,6 +712,17 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors, instr.propertyIndex, a); QML_END_INSTR(StoreBool) + QML_BEGIN_INSTR(StoreBoolQList) + QObject *target = objects.top(); + CLEAN_PROPERTY(target, instr.propertyIndex); + + QList<bool> boolqlist; + boolqlist.append(instr.value); + void *a[] = { (void *)&boolqlist, 0, &status, &flags }; + QMetaObject::metacall(target, QMetaObject::WriteProperty, + instr.propertyIndex, a); + QML_END_INSTR(StoreBoolQList) + QML_BEGIN_INSTR(StoreInteger) QObject *target = objects.top(); CLEAN_PROPERTY(target, instr.propertyIndex); @@ -678,6 +732,17 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors, instr.propertyIndex, a); QML_END_INSTR(StoreInteger) + QML_BEGIN_INSTR(StoreIntegerQList) + QObject *target = objects.top(); + CLEAN_PROPERTY(target, instr.propertyIndex); + + QList<int> intqlist; + intqlist.append(instr.value); + void *a[] = { (void *)&intqlist, 0, &status, &flags }; + QMetaObject::metacall(target, QMetaObject::WriteProperty, + instr.propertyIndex, a); + QML_END_INSTR(StoreIntegerQList) + QML_BEGIN_INSTR(StoreColor) QObject *target = objects.top(); CLEAN_PROPERTY(target, instr.propertyIndex); diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.1.qml new file mode 100644 index 0000000000..be283fdda1 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.1.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +MySequenceConversionObject { + intListProperty: [1, 2] + qrealListProperty: [1.1, 2.2] + boolListProperty: [false, true] + urlListProperty: [ "http://www.example1.com", "http://www.example2.com" ] + stringListProperty: [ "one", "two" ] + qstringListProperty: [ "one", "two" ] +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.2.qml new file mode 100644 index 0000000000..c8fb28b04e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.2.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +MySequenceConversionObject { + intListProperty: 1 + qrealListProperty: 1.1 + boolListProperty: false + urlListProperty: "http://www.example1.com" + stringListProperty: "one" + qstringListProperty: "two" +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.3.qml new file mode 100644 index 0000000000..ad8a92e317 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.3.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +MySequenceConversionObject { + intListProperty: 1 + qrealListProperty: 1.1 + boolListProperty: false + urlListProperty: Qt.resolvedUrl("example.html") +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.4.qml new file mode 100644 index 0000000000..a9f2e642d1 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.4.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +MySequenceConversionObject { + Component.onCompleted: { + intListProperty = [1, 2] + qrealListProperty = [1.1, 2.2] + boolListProperty = [false, true] + urlListProperty = [ "http://www.example1.com", "http://www.example2.com" ] + stringListProperty = [ "one", "two" ] + qstringListProperty = [ "one", "two" ] + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.5.qml b/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.5.qml new file mode 100644 index 0000000000..b8697e4290 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.5.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +MySequenceConversionObject { + Component.onCompleted: { + intListProperty = 1; + qrealListProperty = 1.1; + boolListProperty = false; + urlListProperty = "http://www.example1.com"; + stringListProperty = "one"; + qstringListProperty = "two"; + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.6.qml b/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.6.qml new file mode 100644 index 0000000000..7a794eb694 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/assignSequenceTypes.6.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +MySequenceConversionObject { + Component.onCompleted: { + intListProperty = 1; + qrealListProperty = 1.1; + boolListProperty = false; + urlListProperty = Qt.resolvedUrl("example.html"); + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 3fdf1e905c..52e76614a3 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -177,8 +177,10 @@ private slots: void sequenceConversionThreads(); void sequenceConversionBindings(); void sequenceConversionCopy(); + void assignSequenceTypes(); void qtbug_22464(); void qtbug_21580(); + void bug1(); void bug2(); void dynamicCreationCrash(); @@ -4320,6 +4322,89 @@ void tst_qdeclarativeecmascript::sequenceConversionCopy() delete object; } +void tst_qdeclarativeecmascript::assignSequenceTypes() +{ + // test binding array to sequence type property + { + QDeclarativeComponent component(&engine, TEST_FILE("assignSequenceTypes.1.qml")); + MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->intListProperty(), (QList<int>() << 1 << 2)); + QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1 << 2.2)); + QCOMPARE(object->boolListProperty(), (QList<bool>() << false << true)); + QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl("http://www.example1.com") << QUrl("http://www.example2.com"))); + QCOMPARE(object->stringListProperty(), (QList<QString>() << QLatin1String("one") << QLatin1String("two"))); + QCOMPARE(object->qstringListProperty(), (QStringList() << QLatin1String("one") << QLatin1String("two"))); + delete object; + } + + // test binding literal to sequence type property + { + QDeclarativeComponent component(&engine, TEST_FILE("assignSequenceTypes.2.qml")); + MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->intListProperty(), (QList<int>() << 1)); + QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1)); + QCOMPARE(object->boolListProperty(), (QList<bool>() << false)); + QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl("http://www.example1.com"))); + QCOMPARE(object->stringListProperty(), (QList<QString>() << QLatin1String("one"))); + QCOMPARE(object->qstringListProperty(), (QStringList() << QLatin1String("two"))); + delete object; + } + + // test binding single value to sequence type property + { + QDeclarativeComponent component(&engine, TEST_FILE("assignSequenceTypes.3.qml")); + MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->intListProperty(), (QList<int>() << 1)); + QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1)); + QCOMPARE(object->boolListProperty(), (QList<bool>() << false)); + QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl(TEST_FILE("example.html")))); + delete object; + } + + // test assigning array to sequence type property in js function + { + QDeclarativeComponent component(&engine, TEST_FILE("assignSequenceTypes.4.qml")); + MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->intListProperty(), (QList<int>() << 1 << 2)); + QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1 << 2.2)); + QCOMPARE(object->boolListProperty(), (QList<bool>() << false << true)); + QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl("http://www.example1.com") << QUrl("http://www.example2.com"))); + QCOMPARE(object->stringListProperty(), (QList<QString>() << QLatin1String("one") << QLatin1String("two"))); + QCOMPARE(object->qstringListProperty(), (QStringList() << QLatin1String("one") << QLatin1String("two"))); + delete object; + } + + // test assigning literal to sequence type property in js function + { + QDeclarativeComponent component(&engine, TEST_FILE("assignSequenceTypes.5.qml")); + MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->intListProperty(), (QList<int>() << 1)); + QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1)); + QCOMPARE(object->boolListProperty(), (QList<bool>() << false)); + QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl("http://www.example1.com"))); + QCOMPARE(object->stringListProperty(), (QList<QString>() << QLatin1String("one"))); + QCOMPARE(object->qstringListProperty(), (QStringList() << QLatin1String("two"))); + delete object; + } + + // test assigning single value to sequence type property in js function + { + QDeclarativeComponent component(&engine, TEST_FILE("assignSequenceTypes.6.qml")); + MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->intListProperty(), (QList<int>() << 1)); + QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1)); + QCOMPARE(object->boolListProperty(), (QList<bool>() << false)); + QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl(TEST_FILE("example.html")))); + delete object; + } +} + // Test that assigning a null object works // Regressed with: df1788b4dbbb2826ae63f26bdf166342595343f4 void tst_qdeclarativeecmascript::nullObjectBinding() |