diff options
Diffstat (limited to 'tests/auto/qml/qqmllanguage')
22 files changed, 321 insertions, 36 deletions
diff --git a/tests/auto/qml/qqmllanguage/data/alias.12.qml b/tests/auto/qml/qqmllanguage/data/alias.12.qml new file mode 100644 index 0000000000..cc17318092 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/alias.12.qml @@ -0,0 +1,15 @@ +import QtQml 2.0 + +QtObject { + id: root + property alias topLevelAlias: subObject.targetProperty + + property QtObject referencingSubObject: QtObject { + property alias success: root.topLevelAlias + } + + property QtObject foo: QtObject { + id: subObject + property bool targetProperty: true + } +} diff --git a/tests/auto/qml/qqmllanguage/data/alias.13.qml b/tests/auto/qml/qqmllanguage/data/alias.13.qml new file mode 100644 index 0000000000..cff8a72d9a --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/alias.13.qml @@ -0,0 +1,16 @@ +import QtQml 2.0 + +QtObject { + id: root + property bool targetProperty: true + + property QtObject foo: QtObject { + id: otherSubObject + property alias theAlias: root.targetProperty + } + + property QtObject referencingSubObject: QtObject { + property alias success: otherSubObject.theAlias + } + +} diff --git a/tests/auto/qml/qqmllanguage/data/alias.14.errors.txt b/tests/auto/qml/qqmllanguage/data/alias.14.errors.txt new file mode 100644 index 0000000000..90a3ea4317 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/alias.14.errors.txt @@ -0,0 +1 @@ +10:34:References to other aliases within the same object are not supported at the moment diff --git a/tests/auto/qml/qqmllanguage/data/alias.14.qml b/tests/auto/qml/qqmllanguage/data/alias.14.qml new file mode 100644 index 0000000000..ff3c36d990 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/alias.14.qml @@ -0,0 +1,17 @@ +import QtQml 2.0 + +QtObject { + id: root + property bool targetProperty: true + + property QtObject foo: QtObject { + id: otherSubObject + property alias theAliasOrigin: root.targetProperty + property alias theAlias: otherSubObject.theAliasOrigin + } + + property QtObject referencingSubObject: QtObject { + property alias success: otherSubObject.theAlias + } + +} diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_method_arg.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_arg.qml new file mode 100644 index 0000000000..b64a2e23c0 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_arg.qml @@ -0,0 +1,11 @@ +import QtQuick 2.7 +import Test 1.0 + +MyArrayBufferTestClass { + property bool ok: false + Component.onCompleted: { + var data = new Uint8Array([1, 2, 3]); + var sum = byteArrayMethod_Sum(data.buffer); + ok = sum == 6; + } +} diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_method_overload.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_overload.qml new file mode 100644 index 0000000000..9e1c91810a --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_overload.qml @@ -0,0 +1,7 @@ +import QtQuick 2.7 +import Test 1.0 + +MyArrayBufferTestClass { + property bool ok: false + Component.onCompleted: ok = byteArrayMethod_Overloaded(new ArrayBuffer()); +} diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_method_return.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_return.qml new file mode 100644 index 0000000000..5a4f9fec0b --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_return.qml @@ -0,0 +1,15 @@ +import QtQuick 2.7 +import Test 1.0 + +MyArrayBufferTestClass { + property bool ok: false + Component.onCompleted: { + var buf = byteArrayMethod_CountUp(1, 3); + var view = new DataView(buf); + ok = buf instanceof ArrayBuffer + && buf.byteLength == 3 + && view.getUint8(0) == 1 + && view.getUint8(1) == 2 + && view.getUint8(2) == 3; + } +} diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_property_get.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_property_get.qml new file mode 100644 index 0000000000..78ebb1abe1 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_property_get.qml @@ -0,0 +1,5 @@ +import Test 1.0 + +MyArrayBufferTestClass { + property bool ok: byteArrayProperty instanceof ArrayBuffer +} diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_property_set.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_property_set.qml new file mode 100644 index 0000000000..e8a51273ca --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_property_set.qml @@ -0,0 +1,11 @@ +import QtQuick 2.7 +import Test 1.0 + +MyArrayBufferTestClass { + property bool ok: false + onByteArraySignal: ok = byteArrayProperty instanceof ArrayBuffer + Component.onCompleted: { + byteArrayProperty = new ArrayBuffer(42); + ok = byteArrayProperty instanceof ArrayBuffer && byteArrayProperty.byteLength == 42; + } +} diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_signal_arg.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_signal_arg.qml new file mode 100644 index 0000000000..d9f436e788 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_signal_arg.qml @@ -0,0 +1,14 @@ +import QtQuick 2.7 +import Test 1.0 + +MyArrayBufferTestClass { + property bool ok: false + onByteArraySignal: { + var view = new DataView(arg); + ok = arg instanceof ArrayBuffer + && arg.byteLength == 2 + && view.getUint8(0) == 42 + && view.getUint8(1) == 43; + } + Component.onCompleted: emitByteArraySignal(42, 2) +} diff --git a/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.errors.txt b/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.errors.txt index 7a75447a62..acf0d1da84 100644 --- a/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.errors.txt +++ b/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.errors.txt @@ -1,2 +1,2 @@ 3:1:Type RegisteredCompositeType2 unavailable --1:-1:File not found +-1:-1:No such file or directory diff --git a/tests/auto/qml/qqmllanguage/data/cppnamespace.qml b/tests/auto/qml/qqmllanguage/data/cppnamespace.qml index e1daf3b78f..efedf2b14a 100644 --- a/tests/auto/qml/qqmllanguage/data/cppnamespace.qml +++ b/tests/auto/qml/qqmllanguage/data/cppnamespace.qml @@ -1,4 +1,5 @@ import Test 1.0 MyNamespacedType { + myEnum: MyNamespace.Key5 } diff --git a/tests/auto/qml/qqmllanguage/data/invalidAlias.11.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidAlias.11.errors.txt new file mode 100644 index 0000000000..b79b660c46 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/invalidAlias.11.errors.txt @@ -0,0 +1 @@ +5:5:Circular alias reference detected diff --git a/tests/auto/qml/qqmllanguage/data/invalidAlias.11.qml b/tests/auto/qml/qqmllanguage/data/invalidAlias.11.qml new file mode 100644 index 0000000000..9b50b48df8 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/invalidAlias.11.qml @@ -0,0 +1,10 @@ +import QtQml 2.0 + +QtObject { + id: root + property alias a: subObject.b + property QtObject foo: QtObject { + id: subObject + property alias b: root.a + } +} diff --git a/tests/auto/qml/qqmllanguage/data/rootItemIsComponent.qml b/tests/auto/qml/qqmllanguage/data/rootItemIsComponent.qml new file mode 100644 index 0000000000..dd653352d9 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/rootItemIsComponent.qml @@ -0,0 +1,6 @@ +import QtQml 2.0 +Component { + QtObject { + id: blah + } +} diff --git a/tests/auto/qml/qqmllanguage/data/singletonTest10.error.txt b/tests/auto/qml/qqmllanguage/data/singletonTest10.error.txt deleted file mode 100644 index 32d2ed857e..0000000000 --- a/tests/auto/qml/qqmllanguage/data/singletonTest10.error.txt +++ /dev/null @@ -1 +0,0 @@ -4:1:Composite Singleton Type SingletonType is not creatable. diff --git a/tests/auto/qml/qqmllanguage/data/singletonTest12.error.txt b/tests/auto/qml/qqmllanguage/data/singletonTest12.error.txt index 716cf5709a..b3082d80e6 100644 --- a/tests/auto/qml/qqmllanguage/data/singletonTest12.error.txt +++ b/tests/auto/qml/qqmllanguage/data/singletonTest12.error.txt @@ -1,2 +1,2 @@ 5:5:Type RegisteredCompositeType unavailable -2:1:pragma Singleton used with a non composite singleton type CompositeSingletonTest/RegisteredCompositeType +-1:-1:pragma Singleton used with a non composite singleton type CompositeSingletonTest/RegisteredCompositeType diff --git a/tests/auto/qml/qqmllanguage/data/singletonTest4.error.txt b/tests/auto/qml/qqmllanguage/data/singletonTest4.error.txt index 77c26df310..ebeab6987b 100644 --- a/tests/auto/qml/qqmllanguage/data/singletonTest4.error.txt +++ b/tests/auto/qml/qqmllanguage/data/singletonTest4.error.txt @@ -1 +1 @@ -2:1:No matching type found, pragma Singleton files cannot be used by QQmlComponent. +-1:-1:No matching type found, pragma Singleton files cannot be used by QQmlComponent. diff --git a/tests/auto/qml/qqmllanguage/data/uncreatableTypeAsProperty.qml b/tests/auto/qml/qqmllanguage/data/uncreatableTypeAsProperty.qml new file mode 100644 index 0000000000..8369ab1eea --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/uncreatableTypeAsProperty.qml @@ -0,0 +1,6 @@ +import QtQml 2.0 +import Test 1.0 + +QtObject { + property MyUncreateableBaseClass someProperty; +} diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp index 9593bfc940..3af7645ff7 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.cpp +++ b/tests/auto/qml/qqmllanguage/testtypes.cpp @@ -27,8 +27,6 @@ ****************************************************************************/ #include "testtypes.h" -#include <private/qqmlcompiler_p.h> - static QObject *myTypeObjectSingleton(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine) @@ -47,6 +45,7 @@ void registerTypes() qmlRegisterType<MyDotPropertyObject>("Test",1,0,"MyDotPropertyObject"); qmlRegisterType<MyNamespace::MyNamespacedType>("Test",1,0,"MyNamespacedType"); qmlRegisterType<MyNamespace::MySecondNamespacedType>("Test",1,0,"MySecondNamespacedType"); + qmlRegisterUncreatableMetaObject(MyNamespace::staticMetaObject, "Test", 1, 0, "MyNamespace", "Access to enums & flags only"); qmlRegisterType<MyParserStatus>("Test",1,0,"MyParserStatus"); qmlRegisterType<MyGroupedObject>(); qmlRegisterType<MyRevisionedClass>("Test",1,0,"MyRevisionedClass"); @@ -98,6 +97,8 @@ void registerTypes() qmlRegisterType<MyCompositeBaseType>("Test", 1, 0, "MyCompositeBaseType"); qmlRegisterSingletonType<MyTypeObjectSingleton>("Test", 1, 0, "MyTypeObjectSingleton", myTypeObjectSingleton); + + qmlRegisterType<MyArrayBufferTestClass>("Test", 1, 0, "MyArrayBufferTestClass"); } QVariant myCustomVariantTypeConverter(const QString &data) @@ -108,11 +109,11 @@ QVariant myCustomVariantTypeConverter(const QString &data) } -void CustomBindingParser::applyBindings(QObject *object, QQmlCompiledData *cdata, const QList<const QV4::CompiledData::Binding *> &bindings) +void CustomBindingParser::applyBindings(QObject *object, QV4::CompiledData::CompilationUnit *compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) { CustomBinding *customBinding = qobject_cast<CustomBinding*>(object); Q_ASSERT(customBinding); - customBinding->cdata = cdata; + customBinding->compilationUnit = compilationUnit; customBinding->bindings = bindings; } @@ -121,17 +122,18 @@ void CustomBinding::componentComplete() Q_ASSERT(m_target); foreach (const QV4::CompiledData::Binding *binding, bindings) { - QString name = cdata->compilationUnit->data->stringAt(binding->propertyNameIndex); + QString name = compilationUnit->data->stringAt(binding->propertyNameIndex); int bindingId = binding->value.compiledScriptIndex; QQmlContextData *context = QQmlContextData::get(qmlContext(this)); QV4::Scope scope(QQmlEnginePrivate::getV4Engine(qmlEngine(this))); - QV4::ScopedValue function(scope, QV4::FunctionObject::createQmlFunction(context, m_target, cdata->compilationUnit->runtimeFunctions[bindingId])); - QQmlBinding *qmlBinding = new QQmlBinding(function, m_target, context); + QV4::ScopedValue function(scope, QV4::FunctionObject::createQmlFunction(context, m_target, compilationUnit->runtimeFunctions[bindingId])); QQmlProperty property(m_target, name, qmlContext(this)); + QQmlBinding *qmlBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, + function, m_target, context); qmlBinding->setTarget(property); QQmlPropertyPrivate::setBinding(property, qmlBinding); } @@ -167,7 +169,7 @@ void EnumSupportingCustomParser::verifyBindings(const QV4::CompiledData::Unit *q } } -void SimpleObjectCustomParser::applyBindings(QObject *object, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &bindings) +void SimpleObjectCustomParser::applyBindings(QObject *object, QV4::CompiledData::CompilationUnit *, const QList<const QV4::CompiledData::Binding *> &bindings) { SimpleObjectWithCustomParser *o = qobject_cast<SimpleObjectWithCustomParser*>(object); Q_ASSERT(o); diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 337ba91532..6c62bcf7b9 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -43,7 +43,6 @@ #include <QtQml/qqmlpropertyvaluesource.h> #include <QtQml/qqmlscriptstring.h> #include <QtQml/qqmlproperty.h> -#include <private/qqmlcompiler_p.h> #include <private/qqmlcustomparser_p.h> QVariant myCustomVariantTypeConverter(const QString &data); @@ -731,9 +730,19 @@ private: namespace MyNamespace { + Q_NAMESPACE + enum MyNSEnum { + Key1 = 1, + Key2, + Key5 = 5 + }; + Q_ENUM_NS(MyNSEnum); + class MyNamespacedType : public QObject { Q_OBJECT + Q_PROPERTY(MyNamespace::MyNSEnum myEnum MEMBER m_myEnum) + MyNamespace::MyNSEnum m_myEnum = MyNSEnum::Key1; }; class MySecondNamespacedType : public QObject @@ -757,14 +766,14 @@ class MyCustomParserTypeParser : public QQmlCustomParser { public: virtual void verifyBindings(const QV4::CompiledData::Unit *, const QList<const QV4::CompiledData::Binding *> &) {} - virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &) {} + virtual void applyBindings(QObject *, QV4::CompiledData::CompilationUnit *, const QList<const QV4::CompiledData::Binding *> &) {} }; class EnumSupportingCustomParser : public QQmlCustomParser { public: virtual void verifyBindings(const QV4::CompiledData::Unit *, const QList<const QV4::CompiledData::Binding *> &); - virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &) {} + virtual void applyBindings(QObject *, QV4::CompiledData::CompilationUnit *, const QList<const QV4::CompiledData::Binding *> &) {} }; class MyParserStatus : public QObject, public QQmlParserStatus @@ -1114,6 +1123,58 @@ public: static QObject *qmlAttachedProperties(QObject *parent) { return new QObject(parent); } }; +class MyArrayBufferTestClass : public QObject +{ + Q_OBJECT + Q_PROPERTY(QByteArray byteArrayProperty READ byteArrayProperty WRITE setByteArrayProperty NOTIFY byteArrayPropertyChanged) + +signals: + void byteArrayPropertyChanged(); + void byteArraySignal(QByteArray arg); + +public: + QByteArray byteArrayPropertyValue; + QByteArray byteArrayProperty() const { + return byteArrayPropertyValue; + } + void setByteArrayProperty(const QByteArray &v) { + byteArrayPropertyValue = v; + emit byteArrayPropertyChanged(); + } + Q_INVOKABLE void emitByteArraySignal(char begin, char num) { + byteArraySignal(byteArrayMethod_CountUp(begin, num)); + } + Q_INVOKABLE int byteArrayMethod_Sum(QByteArray arg) { + int sum = 0; + for (int i = 0; i < arg.size(); ++i) { + sum += arg[i]; + } + return sum; + } + Q_INVOKABLE QByteArray byteArrayMethod_CountUp(char begin, int num) { + QByteArray ret; + for (int i = 0; i < num; ++i) { + ret.push_back(begin++); + } + return ret; + } + Q_INVOKABLE bool byteArrayMethod_Overloaded(QByteArray) { + return true; + } + Q_INVOKABLE bool byteArrayMethod_Overloaded(int) { + return false; + } + Q_INVOKABLE bool byteArrayMethod_Overloaded(QString) { + return false; + } + Q_INVOKABLE bool byteArrayMethod_Overloaded(QJSValue) { + return false; + } + Q_INVOKABLE bool byteArrayMethod_Overloaded(QVariant) { + return false; + } +}; + Q_DECLARE_METATYPE(MyEnum2Class::EnumB) Q_DECLARE_METATYPE(MyEnum1Class::EnumA) Q_DECLARE_METATYPE(Qt::TextFormat) @@ -1142,7 +1203,7 @@ public: void setTarget(QObject *newTarget) { m_target = newTarget; } QPointer<QObject> m_target; - QQmlRefPointer<QQmlCompiledData> cdata; + QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit; QList<const QV4::CompiledData::Binding*> bindings; QByteArray m_bindingData; }; @@ -1150,7 +1211,7 @@ public: class CustomBindingParser : public QQmlCustomParser { virtual void verifyBindings(const QV4::CompiledData::Unit *, const QList<const QV4::CompiledData::Binding *> &) {} - virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &); + virtual void applyBindings(QObject *, QV4::CompiledData::CompilationUnit *, const QList<const QV4::CompiledData::Binding *> &); }; class SimpleObjectWithCustomParser : public QObject @@ -1196,7 +1257,7 @@ private: class SimpleObjectCustomParser : public QQmlCustomParser { virtual void verifyBindings(const QV4::CompiledData::Unit *, const QList<const QV4::CompiledData::Binding *> &) {} - virtual void applyBindings(QObject *, QQmlCompiledData *, const QList<const QV4::CompiledData::Binding *> &); + virtual void applyBindings(QObject *, QV4::CompiledData::CompilationUnit *, const QList<const QV4::CompiledData::Binding *> &); }; class RootObjectInCreationTester : public QObject diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 4e4b939e8b..ad06946b0b 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -108,6 +108,7 @@ private slots: void bindTypeToJSValue(); void customParserTypes(); void rootAsQmlComponent(); + void rootItemIsComponent(); void inlineQmlComponents(); void idProperty(); void autoNotifyConnection(); @@ -188,6 +189,8 @@ private slots: void subclassedUncreateableRevision_data(); void subclassedUncreateableRevision(); + void uncreatableTypesAsProperties(); + void propertyInit(); void remoteLoadCrash(); void signalWithDefaultArg(); @@ -246,10 +249,11 @@ private slots: void earlyIdObjectAccess(); - void dataAlignment(); - void deleteSingletons(); + void arrayBuffer_data(); + void arrayBuffer(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -490,6 +494,7 @@ void tst_qqmllanguage::errors_data() QTest::newRow("invalidAlias.8") << "invalidAlias.8.qml" << "invalidAlias.8.errors.txt" << false; QTest::newRow("invalidAlias.9") << "invalidAlias.9.qml" << "invalidAlias.9.errors.txt" << false; QTest::newRow("invalidAlias.10") << "invalidAlias.10.qml" << "invalidAlias.10.errors.txt" << false; + QTest::newRow("invalidAlias.11") << "invalidAlias.11.qml" << "invalidAlias.11.errors.txt" << false; QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false; QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false; @@ -1193,6 +1198,19 @@ void tst_qqmllanguage::rootAsQmlComponent() QCOMPARE(object->getChildren()->count(), 2); } +void tst_qqmllanguage::rootItemIsComponent() +{ + QQmlComponent component(&engine, testFileUrl("rootItemIsComponent.qml")); + VERIFY_ERRORS(0); + QScopedPointer<QObject> root(component.create()); + QVERIFY(qobject_cast<QQmlComponent*>(root.data())); + QScopedPointer<QObject> other(qobject_cast<QQmlComponent*>(root.data())->create()); + QVERIFY(!other.isNull()); + QQmlContext *context = qmlContext(other.data()); + QVERIFY(context); + QCOMPARE(context->nameForObject(other.data()), QStringLiteral("blah")); +} + // Tests that components can be specified inline void tst_qqmllanguage::inlineQmlComponents() { @@ -1787,6 +1805,48 @@ void tst_qqmllanguage::aliasProperties() delete object; } + + // Nested aliases with a qml file + { + QQmlComponent component(&engine, testFileUrl("alias.12.qml")); + VERIFY_ERRORS(0); + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + + QPointer<QObject> subObject = qvariant_cast<QObject*>(object->property("referencingSubObject")); + QVERIFY(!subObject.isNull()); + + QVERIFY(subObject->property("success").toBool()); + } + + // Nested aliases with a qml file with reverse ordering + { + // This is known to fail at the moment. + QQmlComponent component(&engine, testFileUrl("alias.13.qml")); + VERIFY_ERRORS(0); + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + + QPointer<QObject> subObject = qvariant_cast<QObject*>(object->property("referencingSubObject")); + QVERIFY(!subObject.isNull()); + + QVERIFY(subObject->property("success").toBool()); + } + + // "Nested" aliases within an object that require iterative resolution + { + // This is known to fail at the moment. + QQmlComponent component(&engine, testFileUrl("alias.14.qml")); + VERIFY_ERRORS(0); + + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + + QPointer<QObject> subObject = qvariant_cast<QObject*>(object->property("referencingSubObject")); + QVERIFY(!subObject.isNull()); + + QVERIFY(subObject->property("success").toBool()); + } } // QTBUG-13374 Test that alias properties and signals can coexist @@ -2058,8 +2118,13 @@ void tst_qqmllanguage::scriptStringWithoutSourceCode() QQmlTypeData *td = eng->typeLoader.getType(url); Q_ASSERT(td); - QV4::CompiledData::Unit *qmlUnit = td->compiledData()->compilationUnit->data; - Q_ASSERT(qmlUnit); + const QV4::CompiledData::Unit *readOnlyQmlUnit = td->compilationUnit()->data; + Q_ASSERT(readOnlyQmlUnit); + QV4::CompiledData::Unit *qmlUnit = reinterpret_cast<QV4::CompiledData::Unit *>(malloc(readOnlyQmlUnit->unitSize)); + memcpy(qmlUnit, readOnlyQmlUnit, readOnlyQmlUnit->unitSize); + qmlUnit->flags &= ~QV4::CompiledData::Unit::StaticData; + td->compilationUnit()->data = qmlUnit; + const QV4::CompiledData::Object *rootObject = qmlUnit->objectAt(qmlUnit->indexOfRootObject); QCOMPARE(qmlUnit->stringAt(rootObject->inheritedTypeNameIndex), QString("MyTypeObject")); quint32 i; @@ -2536,7 +2601,7 @@ void tst_qqmllanguage::basicRemote_data() QTest::newRow("no need for qmldir") << QUrl(serverdir+"Test.qml") << "" << ""; QTest::newRow("absent qmldir") << QUrl(serverdir+"/noqmldir/Test.qml") << "" << ""; - QTest::newRow("need qmldir") << QUrl(serverdir+"TestLocal.qml") << "" << ""; + QTest::newRow("need qmldir") << QUrl(serverdir+"TestNamed.qml") << "" << ""; } void tst_qqmllanguage::basicRemote() @@ -2576,6 +2641,8 @@ void tst_qqmllanguage::importsRemote_data() << ""; QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QQuickImage" << ""; + QTest::newRow("remote import with qualifier") << "import \""+serverdir+"\" as NS\nNS.NamedLocal {}" << "QQuickImage" + << ""; QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << "" << "WrongTestLocal is not a type"; QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << "" @@ -2882,7 +2949,7 @@ void tst_qqmllanguage::importIncorrectCase() QCOMPARE(errors.count(), 1); const QString expectedError = isCaseSensitiveFileSystem(dataDirectory()) ? - QStringLiteral("File not found") : + QStringLiteral("No such file or directory") : QStringLiteral("File name case mismatch"); QCOMPARE(errors.at(0).description(), expectedError); @@ -3156,6 +3223,14 @@ void tst_qqmllanguage::subclassedUncreateableRevision() delete obj; } +void tst_qqmllanguage::uncreatableTypesAsProperties() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("uncreatableTypeAsProperty.qml")); + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); +} + void tst_qqmllanguage::initTestCase() { QQmlDataTest::initTestCase(); @@ -3861,12 +3936,11 @@ void tst_qqmllanguage::compositeSingletonInstantiateError() VERIFY_ERRORS("singletonTest9.error.txt"); } -// Having a composite singleton type as dynamic property type fails -// (like C++ singleton) +// Having a composite singleton type as dynamic property type is allowed void tst_qqmllanguage::compositeSingletonDynamicPropertyError() { QQmlComponent component(&engine, testFile("singletonTest10.qml")); - VERIFY_ERRORS("singletonTest10.error.txt"); + VERIFY_ERRORS(0); } // Having a composite singleton type as dynamic signal parameter succeeds @@ -4054,7 +4128,7 @@ void tst_qqmllanguage::preservePropertyCacheOnGroupObjects() QVERIFY(subCache); QQmlPropertyData *pd = subCache->property(QStringLiteral("newProperty"), /*object*/0, /*context*/0); QVERIFY(pd); - QCOMPARE(pd->propType, qMetaTypeId<int>()); + QCOMPARE(pd->propType(), qMetaTypeId<int>()); } void tst_qqmllanguage::propertyCacheInSync() @@ -4120,14 +4194,6 @@ void tst_qqmllanguage::earlyIdObjectAccess() QVERIFY(o->property("success").toBool()); } -void tst_qqmllanguage::dataAlignment() -{ - QVERIFY(sizeof(QQmlVMEMetaData) % sizeof(int) == 0); - QVERIFY(sizeof(QQmlVMEMetaData::AliasData) % sizeof(int) == 0); - QVERIFY(sizeof(QQmlVMEMetaData::PropertyData) % sizeof(int) == 0); - QVERIFY(sizeof(QQmlVMEMetaData::MethodData) % sizeof(int) == 0); -} - void tst_qqmllanguage::deleteSingletons() { QPointer<QObject> singleton; @@ -4146,6 +4212,27 @@ void tst_qqmllanguage::deleteSingletons() QVERIFY(singleton.data() == 0); } +void tst_qqmllanguage::arrayBuffer_data() +{ + QTest::addColumn<QString>("file"); + QTest::newRow("arraybuffer_property_get") << "arraybuffer_property_get.qml"; + QTest::newRow("arraybuffer_property_set") << "arraybuffer_property_set.qml"; + QTest::newRow("arraybuffer_signal_arg") << "arraybuffer_signal_arg.qml"; + QTest::newRow("arraybuffer_method_arg") << "arraybuffer_method_arg.qml"; + QTest::newRow("arraybuffer_method_return") << "arraybuffer_method_return.qml"; + QTest::newRow("arraybuffer_method_overload") << "arraybuffer_method_overload.qml"; +} + +void tst_qqmllanguage::arrayBuffer() +{ + QFETCH(QString, file); + QQmlComponent component(&engine, testFile(file)); + VERIFY_ERRORS(0); + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("ok").toBool(), true); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" |