aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qml')
-rw-r--r--tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp29
-rw-r--r--tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml3
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp102
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp42
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