diff options
Diffstat (limited to 'tests/auto/qml')
-rw-r--r-- | tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp | 29 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml | 3 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 102 | ||||
-rw-r--r-- | tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp | 42 |
4 files changed, 137 insertions, 39 deletions
diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp index e0cde6c86f..f49fd391ac 100644 --- a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp +++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp @@ -61,6 +61,7 @@ private slots: void qtbug_22535(); void evalAfterInvalidate(); void qobjectDerived(); + void qtbug_49232(); private: QQmlEngine engine; @@ -200,6 +201,8 @@ class TestObject : public QObject Q_PROPERTY(int a READ a NOTIFY aChanged) Q_PROPERTY(int b READ b NOTIFY bChanged) Q_PROPERTY(int c READ c NOTIFY cChanged) + Q_PROPERTY(char d READ d NOTIFY dChanged) + Q_PROPERTY(uchar e READ e NOTIFY eChanged) public: TestObject() : _a(10), _b(10), _c(10) {} @@ -213,15 +216,25 @@ public: int c() const { return _c; } void setC(int c) { _c = c; emit cChanged(); } + char d() const { return _d; } + void setD(char d) { _d = d; emit dChanged(); } + + uchar e() const { return _e; } + void setE(uchar e) { _e = e; emit eChanged(); } + signals: void aChanged(); void bChanged(); void cChanged(); + void dChanged(); + void eChanged(); private: int _a; int _b; int _c; + char _d; + uchar _e; }; #define TEST_CONTEXT_PROPERTY(ctxt, name, value) \ @@ -694,6 +707,22 @@ void tst_qqmlcontext::qobjectDerived() QCOMPARE(command.count, 2); } +void tst_qqmlcontext::qtbug_49232() +{ + TestObject testObject; + testObject.setD('a'); + testObject.setE(97); + + QQmlEngine engine; + engine.rootContext()->setContextProperty("TestObject", &testObject); + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { property int valueOne: TestObject.d; property int valueTwo: TestObject.e }", QUrl()); + QScopedPointer<QObject> obj(component.create()); + + QCOMPARE(obj->property("valueOne"), QVariant('a')); + QCOMPARE(obj->property("valueTwo"), QVariant(97)); +} + QTEST_MAIN(tst_qqmlcontext) #include "tst_qqmlcontext.moc" diff --git a/tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml b/tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml new file mode 100644 index 0000000000..8bb0a3554e --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml @@ -0,0 +1,3 @@ +import Test 1.0 +WeakReferenceMutator { +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 2c9f08c82a..b6d2e303cb 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -44,6 +44,8 @@ #include <private/qv4scopedvalue_p.h> #include <private/qv4alloca_p.h> #include <private/qv4runtime_p.h> +#include <private/qv4object_p.h> +#include <private/qqmlcomponentattached_p.h> #ifdef Q_CC_MSVC #define NO_INLINE __declspec(noinline) @@ -282,6 +284,7 @@ private slots: void replaceBinding(); void deleteRootObjectInCreation(); void onDestruction(); + void onDestructionViaGC(); void bindingSuppression(); void signalEmitted(); void threadSignal(); @@ -7150,6 +7153,105 @@ void tst_qqmlecmascript::onDestruction() } } +class WeakReferenceMutator : public QObject +{ + Q_OBJECT +public: + WeakReferenceMutator() + : resultPtr(Q_NULLPTR) + , weakRef(Q_NULLPTR) + {} + + void init(QV4::ExecutionEngine *v4, QV4::WeakValue *weakRef, bool *resultPtr) + { + QV4::QObjectWrapper::wrap(v4, this); + QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); + + this->resultPtr = resultPtr; + this->weakRef = weakRef; + + QObject::connect(QQmlComponent::qmlAttachedProperties(this), &QQmlComponentAttached::destruction, this, &WeakReferenceMutator::reviveFirstWeakReference); + } + +private slots: + void reviveFirstWeakReference() { + *resultPtr = weakRef->valueRef() && weakRef->isNullOrUndefined(); + if (!*resultPtr) + return; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine(this)); + weakRef->set(v4, v4->newObject()); + *resultPtr = weakRef->valueRef() && !weakRef->isNullOrUndefined(); + } + +public: + bool *resultPtr; + + QV4::WeakValue *weakRef; +}; + +QT_BEGIN_NAMESPACE + +namespace QV4 { + +namespace Heap { +struct WeakReferenceSentinel : public Object { + WeakReferenceSentinel(WeakValue *weakRef, bool *resultPtr) + : weakRef(weakRef) + , resultPtr(resultPtr) { + + } + + ~WeakReferenceSentinel() { + *resultPtr = weakRef->isNullOrUndefined(); + } + + WeakValue *weakRef; + bool *resultPtr; +}; +} // namespace Heap + +struct WeakReferenceSentinel : public Object { + V4_OBJECT2(WeakReferenceSentinel, Object) + V4_NEEDS_DESTROY +}; + +} // namespace QV4 + +QT_END_NAMESPACE + +DEFINE_OBJECT_VTABLE(QV4::WeakReferenceSentinel); + +void tst_qqmlecmascript::onDestructionViaGC() +{ + qmlRegisterType<WeakReferenceMutator>("Test", 1, 0, "WeakReferenceMutator"); + + QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); + + QQmlComponent component(&engine, testFileUrl("DestructionHelper.qml")); + + QScopedPointer<QV4::WeakValue> weakRef; + + bool mutatorResult = false; + bool sentinelResult = false; + + { + weakRef.reset(new QV4::WeakValue); + weakRef->set(v4, v4->newObject()); + QVERIFY(!weakRef->isNullOrUndefined()); + + QPointer<WeakReferenceMutator> weakReferenceMutator = qobject_cast<WeakReferenceMutator *>(component.create()); + QVERIFY2(!weakReferenceMutator.isNull(), qPrintable(component.errorString())); + weakReferenceMutator->init(v4, weakRef.data(), &mutatorResult); + + v4->memoryManager->allocObject<QV4::WeakReferenceSentinel>(weakRef.data(), &sentinelResult); + } + gc(engine); + + QVERIFY2(mutatorResult, "We failed to re-assign the weak reference a new value during GC"); + QVERIFY2(sentinelResult, "The weak reference was not cleared properly"); +} + struct EventProcessor : public QObject { Q_OBJECT diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index e140747881..1d01f69d9b 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -326,11 +326,8 @@ class PropertyObject : public QObject Q_PROPERTY(MyQmlObject *qmlObject READ qmlObject) Q_PROPERTY(MyQObject *qObject READ qObject WRITE setQObject NOTIFY qObjectChanged) Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty) - Q_PROPERTY(char charProperty READ charProperty WRITE setCharProperty) Q_PROPERTY(QChar qcharProperty READ qcharProperty WRITE setQcharProperty) Q_PROPERTY(QChar constQChar READ constQChar STORED false CONSTANT FINAL) - Q_PROPERTY(char constChar READ constChar STORED false CONSTANT FINAL) - Q_PROPERTY(int constInt READ constInt STORED false CONSTANT FINAL) Q_CLASSINFO("DefaultProperty", "defaultProperty") public: @@ -367,15 +364,11 @@ public: } QString stringProperty() const { return m_stringProperty;} - char charProperty() const { return m_charProperty; } QChar qcharProperty() const { return m_qcharProperty; } QChar constQChar() const { return 0x25cf; /* Unicode: black circle */ } - char constChar() const { return 'A'; } - int constInt() const { return 123456; } void setStringProperty(QString arg) { m_stringProperty = arg; } - void setCharProperty(char arg) { m_charProperty = arg; } void setQcharProperty(QChar arg) { m_qcharProperty = arg; } signals: @@ -392,7 +385,6 @@ private: MyQmlObject m_qmlObject; MyQObject *m_qObject; QString m_stringProperty; - char m_charProperty; QChar m_qcharProperty; }; @@ -1405,23 +1397,14 @@ void tst_qqmlproperty::write() // Char/string-property { PropertyObject o; - QQmlProperty charProperty(&o, "charProperty"); QQmlProperty qcharProperty(&o, "qcharProperty"); QQmlProperty stringProperty(&o, "stringProperty"); const int black_circle = 0x25cf; - QCOMPARE(charProperty.write(QString("foo")), false); - QCOMPARE(charProperty.write('Q'), true); - QCOMPARE(charProperty.read(), QVariant('Q')); - QCOMPARE(charProperty.write(QString("t")), true); - QCOMPARE(charProperty.read(), QVariant('t')); - QCOMPARE(qcharProperty.write(QString("foo")), false); QCOMPARE(qcharProperty.write('Q'), true); QCOMPARE(qcharProperty.read(), QVariant('Q')); - QCOMPARE(qcharProperty.write(QString("t")), true); - QCOMPARE(qcharProperty.read(), QVariant('t')); QCOMPARE(qcharProperty.write(QChar(black_circle)), true); QCOMPARE(qcharProperty.read(), QVariant(QChar(black_circle))); @@ -1430,19 +1413,10 @@ void tst_qqmlproperty::write() QCOMPARE(o.stringProperty(), QString("bar")); QCOMPARE(stringProperty.write(QVariant(1234)), true); QCOMPARE(stringProperty.read().toString(), QString::number(1234)); + QCOMPARE(stringProperty.write('A'), true); + QCOMPARE(stringProperty.read().toString(), QString::number('A')); QCOMPARE(stringProperty.write(QChar(black_circle)), true); - QCOMPARE(stringProperty.read(), QVariant(QString(QChar(black_circle)))); - - { // char -> QString - QQmlComponent component(&engine); - component.setData("import Test 1.0\nPropertyObject { stringProperty: constChar }", QUrl()); - PropertyObject *obj = qobject_cast<PropertyObject*>(component.create()); - QVERIFY(obj != 0); - if (obj) { - QQmlProperty stringProperty(obj, "stringProperty"); - QCOMPARE(stringProperty.read(), QVariant(QString(obj->constChar()))); - } - } + QCOMPARE(stringProperty.read(), QVariant(QChar(black_circle))); { // QChar -> QString QQmlComponent component(&engine); @@ -1455,16 +1429,6 @@ void tst_qqmlproperty::write() } } - { // int -> QString - QQmlComponent component(&engine); - component.setData("import Test 1.0\nPropertyObject { stringProperty: constInt }", QUrl()); - PropertyObject *obj = qobject_cast<PropertyObject*>(component.create()); - QVERIFY(obj != 0); - if (obj) { - QQmlProperty stringProperty(obj, "stringProperty"); - QCOMPARE(stringProperty.read(), QVariant(QString::number(obj->constInt()))); - } - } } // VariantMap-property |