diff options
Diffstat (limited to 'tests')
14 files changed, 332 insertions, 3 deletions
diff --git a/tests/auto/declarative/qmlecmascript/data/ScopeObject.qml b/tests/auto/declarative/qmlecmascript/data/ScopeObject.qml new file mode 100644 index 0000000..b7bec63 --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/ScopeObject.qml @@ -0,0 +1,14 @@ +import Qt 4.6 + +Item { + property int a: 3 + property int binding: myFunction(); + property int binding2: myCompFunction(); + + Script { + function myCompFunction() { + return a; + } + } +} + diff --git a/tests/auto/declarative/qmlecmascript/data/attachedProperty.qml b/tests/auto/declarative/qmlecmascript/data/attachedProperty.qml new file mode 100644 index 0000000..c5088e3 --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/attachedProperty.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 +import Qt.test 1.0 as Namespace + +MyQmlObject { + id: Me + property int a: MyQmlObject.value + property int b: Namespace.MyQmlObject.value + property int c: Me.Namespace.MyQmlObject.value + property int d: Me.Namespace.MyQmlObject.value +} + diff --git a/tests/auto/declarative/qmlecmascript/data/extendedObjectPropertyLookup.qml b/tests/auto/declarative/qmlecmascript/data/extendedObjectPropertyLookup.qml new file mode 100644 index 0000000..8ff3aeb --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/extendedObjectPropertyLookup.qml @@ -0,0 +1,8 @@ +import Qt.test 1.0 +import Qt 4.6 + +Object { + property MyExtendedObject a; + a: MyExtendedObject { id: Root } + property int b: Math.max(Root.extendedProperty, 0) +} diff --git a/tests/auto/declarative/qmlecmascript/data/objectsCompareAsEqual.qml b/tests/auto/declarative/qmlecmascript/data/objectsCompareAsEqual.qml new file mode 100644 index 0000000..2526576 --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/objectsCompareAsEqual.qml @@ -0,0 +1,15 @@ +import Qt 4.6 + +Item { + id: Root + + property var item: Child + Item { id: Child } + + property bool test1: Child == Child + property bool test2: Child.parent == Root + property bool test3: Root != Child + property bool test4: item == Child + property bool test5: item != Root +} + diff --git a/tests/auto/declarative/qmlecmascript/data/scope.qml b/tests/auto/declarative/qmlecmascript/data/scope.qml new file mode 100644 index 0000000..80222c8 --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/scope.qml @@ -0,0 +1,48 @@ +import Qt 4.6 + +Item { + id: Root + + property int a: 1 + property int binding: a + property string binding2: a + "Test" + property int binding3: myFunction() + property int binding4: myNestedFunction() + + Script { + function myFunction() { + return a; + } + } + + Item { + id: NestedObject + + Script { + function myNestedFunction() { + return a; + } + } + + property int a: 2 + property int binding: a + property string binding2: a + "Test" + property int binding3: myFunction() + property int binding4: myNestedFunction() + } + + ScopeObject { + id: CompObject + } + + property alias test1: Root.binding + property alias test2: NestedObject.binding + property alias test3: Root.binding2 + property alias test4: NestedObject.binding2 + property alias test5: Root.binding3 + property alias test6: NestedObject.binding3 + property alias test7: Root.binding4 + property alias test8: NestedObject.binding4 + property alias test9: CompObject.binding + property alias test10: CompObject.binding2 +} diff --git a/tests/auto/declarative/qmlecmascript/data/scriptAccess.js b/tests/auto/declarative/qmlecmascript/data/scriptAccess.js new file mode 100644 index 0000000..c00d285 --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/scriptAccess.js @@ -0,0 +1,7 @@ +var extVariable = 19; + +function extMethod() +{ + return extVariable; +} + diff --git a/tests/auto/declarative/qmlecmascript/data/scriptAccess.qml b/tests/auto/declarative/qmlecmascript/data/scriptAccess.qml new file mode 100644 index 0000000..feb6d16 --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/scriptAccess.qml @@ -0,0 +1,17 @@ +import Qt 4.6 + +Item { + Script { + function method() { + return 10; + } + } + + Script { + source: "scriptAccess.js" + } + + property int test1: method() + property int test2: extMethod() + property int test3: extVariable +} diff --git a/tests/auto/declarative/qmlecmascript/data/selfDeletingBinding.2.qml b/tests/auto/declarative/qmlecmascript/data/selfDeletingBinding.2.qml new file mode 100644 index 0000000..58cf805 --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/selfDeletingBinding.2.qml @@ -0,0 +1,17 @@ +import Qt.test 1.0 + +MyQmlContainer { + property bool triggerDelete: false + + children: [ + MyQmlObject { + // Will trigger deletion on binding assignment + deleteOnSet: Math.max(0, 1) + }, + + MyQmlObject { + // Will trigger deletion on binding assignment, but after component creation + deleteOnSet: if (triggerDelete) 1; else 0; + } + ] +} diff --git a/tests/auto/declarative/qmlecmascript/data/selfDeletingBinding.qml b/tests/auto/declarative/qmlecmascript/data/selfDeletingBinding.qml new file mode 100644 index 0000000..074851a --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/selfDeletingBinding.qml @@ -0,0 +1,18 @@ +import Qt.test 1.0 + +MyQmlContainer { + property bool triggerDelete: false + + children: [ + MyQmlObject { + // Will trigger deletion during binding evaluation + stringProperty: {deleteMe(), "Hello"} + }, + + MyQmlObject { + // Will trigger deletion during binding evaluation, but after component creation + stringProperty: if (triggerDelete) { deleteMe(), "Hello" } else { "World" } + } + + ] +} diff --git a/tests/auto/declarative/qmlecmascript/data/signalParameterTypes.qml b/tests/auto/declarative/qmlecmascript/data/signalParameterTypes.qml new file mode 100644 index 0000000..42d26a1 --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/signalParameterTypes.qml @@ -0,0 +1,16 @@ +import Qt.test 1.0 + +MyQmlObject +{ + id: Root + property int intProperty + property real realProperty + property color colorProperty + property var variantProperty + + signal mySignal(int a, real b, color c, var d) + + onMySignal: { intProperty = a; realProperty = b; colorProperty = c; variantProperty = d; } + + onBasicSignal: Root.mySignal(10, 19.2, Qt.rgba(1, 1, 0, 1), Qt.rgba(1, 0, 1, 1)) +} diff --git a/tests/auto/declarative/qmlecmascript/testtypes.h b/tests/auto/declarative/qmlecmascript/testtypes.h index ffc8fec..e6c2c20 100644 --- a/tests/auto/declarative/qmlecmascript/testtypes.h +++ b/tests/auto/declarative/qmlecmascript/testtypes.h @@ -23,6 +23,7 @@ class MyQmlObject : public QObject Q_OBJECT Q_ENUMS(MyEnum) Q_ENUMS(MyEnum2) + Q_PROPERTY(int deleteOnSet READ deleteOnSet WRITE setDeleteOnSet); Q_PROPERTY(bool trueProperty READ trueProperty CONSTANT) Q_PROPERTY(bool falseProperty READ falseProperty CONSTANT) Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty NOTIFY stringChanged) @@ -61,6 +62,9 @@ public: static MyQmlAttachedObject *qmlAttachedProperties(QObject *o) { return new MyQmlAttachedObject(o); } + + int deleteOnSet() const { return 1; } + void setDeleteOnSet(int v) { if(v) delete this; } signals: void basicSignal(); void argumentSignal(int a, QString b, qreal c); @@ -68,6 +72,7 @@ signals: void objectChanged(); public slots: + void deleteMe() { delete this; } void method() { m_methodCalled = true; } void method(int a) { if(a == 163) m_methodIntCalled = true; } void setString(const QString &s) { m_string = s; } diff --git a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp index 3f01192..dde3bb7 100644 --- a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp +++ b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp @@ -45,15 +45,22 @@ private slots: void objectPropertiesTriggerReeval(); void deferredProperties(); void extensionObjects(); + void attachedProperties(); void enums(); void valueTypeFunctions(); void constantsOverrideBindings(); void outerBindingOverridesInnerBinding(); void aliasPropertyAndBinding(); void nonExistantAttachedObject(); + void scope(); + void signalParameterTypes(); + void objectsCompareAsEqual(); + void scriptAccess(); void dynamicCreation(); void dynamicDestruction(); void objectToString(); + void selfDeletingBinding(); + void extendedObjectPropertyLookup(); private: QmlEngine engine; @@ -383,6 +390,19 @@ void tst_qmlecmascript::extensionObjects() QCOMPARE(object->baseProperty(), 92); } +void tst_qmlecmascript::attachedProperties() +{ + QmlComponent component(&engine, TEST_FILE("attachedProperty.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("a").toInt(), 19); + QCOMPARE(object->property("b").toInt(), 19); + QCOMPARE(object->property("c").toInt(), 19); + QCOMPARE(object->property("d").toInt(), 19); + + // ### Need to test attached property assignment +} + void tst_qmlecmascript::enums() { // Existant enums @@ -515,6 +535,58 @@ void tst_qmlecmascript::nonExistantAttachedObject() QVERIFY(object != 0); } +void tst_qmlecmascript::scope() +{ + QmlComponent component(&engine, TEST_FILE("scope.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test1").toInt(), 1); + QCOMPARE(object->property("test2").toInt(), 2); + QCOMPARE(object->property("test3").toString(), QString("1Test")); + QCOMPARE(object->property("test4").toString(), QString("2Test")); + QCOMPARE(object->property("test5").toInt(), 1); + QCOMPARE(object->property("test6").toInt(), 1); + QCOMPARE(object->property("test7").toInt(), 2); + QCOMPARE(object->property("test8").toInt(), 2); + QCOMPARE(object->property("test9").toInt(), 1); + QCOMPARE(object->property("test10").toInt(), 3); +} + +/* +Tests that "any" type passes through a synthesized signal parameter. This +is essentially a test of QmlMetaType::copy() +*/ +void tst_qmlecmascript::signalParameterTypes() +{ + QmlComponent component(&engine, TEST_FILE("signalParameterTypes.qml")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + + emit object->basicSignal(); + + QCOMPARE(object->property("intProperty").toInt(), 10); + QCOMPARE(object->property("realProperty").toReal(), 19.2); + QVERIFY(object->property("colorProperty").value<QColor>() == QColor(255, 255, 0, 255)); + QVERIFY(object->property("variantProperty") == QVariant::fromValue(QColor(255, 0, 255, 255))); +} + +/* +Test that two JS objects for the same QObject compare as equal. +*/ +void tst_qmlecmascript::objectsCompareAsEqual() +{ + QmlComponent component(&engine, TEST_FILE("objectsCompareAsEqual.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test1").toBool(), true); + QCOMPARE(object->property("test2").toBool(), true); + QCOMPARE(object->property("test3").toBool(), true); + QCOMPARE(object->property("test4").toBool(), true); + QCOMPARE(object->property("test5").toBool(), true); +} + /* Confirm bindings and alias properties can coexist. @@ -536,8 +608,22 @@ void tst_qmlecmascript::aliasPropertyAndBinding() } /* - Test using createQmlObject to dynamically generate an item - Also using createComponent is tested. +Tests that only methods of Script {} blocks are exposed. +*/ +void tst_qmlecmascript::scriptAccess() +{ + QmlComponent component(&engine, TEST_FILE("scriptAccess.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test1").toInt(), 10); + QCOMPARE(object->property("test2").toInt(), 19); + QCOMPARE(object->property("test3").toInt(), 0); +} + +/* +Test using createQmlObject to dynamically generate an item +Also using createComponent is tested. */ void tst_qmlecmascript::dynamicCreation() { @@ -576,13 +662,16 @@ void tst_qmlecmascript::dynamicDestruction() QMetaObject::invokeMethod(object, "killOther"); QVERIFY(createdQmlObject); QTest::qWait(0); + QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion); QVERIFY(createdQmlObject); QTest::qWait(100); + QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion); QVERIFY(!createdQmlObject); QMetaObject::invokeMethod(object, "killMe"); QVERIFY(object); QTest::qWait(0); + QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion); QVERIFY(!object); } @@ -595,7 +684,44 @@ void tst_qmlecmascript::objectToString() MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); QVERIFY(object != 0); QMetaObject::invokeMethod(object, "testToString"); - QVERIFY(object->stringProperty().startsWith("Qml Object, \"objName\" MyQmlObject_QML_15")); + QVERIFY(object->stringProperty().startsWith("MyQmlObject_QML_")); + QVERIFY(object->stringProperty().endsWith(", \"objName\")")); +} + +/* +Tests bindings that indirectly cause their own deletion work. + +This test is best run under valgrind to ensure no invalid memory access occur. +*/ +void tst_qmlecmascript::selfDeletingBinding() +{ + { + QmlComponent component(&engine, TEST_FILE("selfDeletingBinding.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + object->setProperty("triggerDelete", true); + } + + { + QmlComponent component(&engine, TEST_FILE("selfDeletingBinding.2.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + object->setProperty("triggerDelete", true); + } +} + +/* +Test that extended object properties can be accessed. + +This test a regression where this used to crash. The issue was specificially +for extended objects that did not include a synthesized meta object (so non-root +and no synthesiszed properties). +*/ +void tst_qmlecmascript::extendedObjectPropertyLookup() +{ + QmlComponent component(&engine, TEST_FILE("extendedObjectPropertyLookup.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); } QTEST_MAIN(tst_qmlecmascript) diff --git a/tests/auto/declarative/qmllanguage/data/dynamicObjectProperties.qml b/tests/auto/declarative/qmllanguage/data/dynamicObjectProperties.qml new file mode 100644 index 0000000..e69ccee --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/dynamicObjectProperties.qml @@ -0,0 +1,13 @@ +import Test 1.0 +import Qt 4.6 +import Qt 4.6 as Qt + +Object { + property Object objectProperty + property Object objectProperty2 + objectProperty2: Object {} + + property MyComponent myComponentProperty + property MyComponent myComponentProperty2 + myComponentProperty2: MyComponent {} +} diff --git a/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp b/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp index 1bf98df..3825b62 100644 --- a/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp +++ b/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp @@ -45,6 +45,7 @@ private slots: void idProperty(); void assignSignal(); void dynamicProperties(); + void dynamicObjectProperties(); void dynamicSignalsAndSlots(); void simpleBindings(); void autoComponentCreation(); @@ -404,6 +405,19 @@ void tst_qmllanguage::dynamicProperties() QCOMPARE(object->property("variantProperty"), QVariant(12)); } +// Tests the creation and assignment of dynamic object properties +// ### Not complete +void tst_qmllanguage::dynamicObjectProperties() +{ + QmlComponent component(&engine, TEST_FILE("dynamicObjectProperties.qml")); + VERIFY_ERRORS(0); + QObject *object = component.create(); + QVERIFY(object != 0); + + QVERIFY(object->property("objectProperty") == qVariantFromValue((QObject*)0)); + QVERIFY(object->property("objectProperty2") != qVariantFromValue((QObject*)0)); +} + // Tests the declaration of dynamic signals and slots void tst_qmllanguage::dynamicSignalsAndSlots() { |