diff options
author | kh1 <karsten.heimrich@digia.com> | 2014-06-04 13:17:30 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-06-04 18:52:58 +0200 |
commit | 0f9cf70501fdcf60d87615b3f998c85f134948ac (patch) | |
tree | 880891b10c44647226682c660dd1811ce6722443 /tests/auto/qml/qjsengine/tst_qjsengine.cpp | |
parent | 297ee9cc2cfbc9e797aee3ce660484f682bb4e61 (diff) |
Fix method overload calling of Qt slots from JavaScript
After commit ac57f185d1a2203cd4b585df7bd7af01c3ec33ed we succeed in selecting
the correct overload based on the supplied arguments. However when calling
slots on objects without a property cache, we end up using the local "dummy"
variable to store the synthetic propert data. We also store the currently best
patch in the "best" variable, which is a _pointer_ to the property data of the
match. Suppose we have 5 overloads to choose from, we find that the 3rd is
the best. Then we try the fourth but find it unsufficient and break out of
the loop. Unfortunately the "dummy" property data at this point contains the
data of the fourth (wrong) overload, and our best match variable points to it.
So then when we finally call the method, we do it based on the wrong property
data.
The easy patch is to simply copy the few bytes of property data, so "best" is
stored by value instead of pointer.
Change-Id: Ie2ebbdb88a117770b6c7b9490e1c634077020e9d
Reviewed-by: Karsten Heimrich <karsten.heimrich@digia.com>
Diffstat (limited to 'tests/auto/qml/qjsengine/tst_qjsengine.cpp')
-rw-r--r-- | tests/auto/qml/qjsengine/tst_qjsengine.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 17acb4fd32..51cd69998a 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -187,6 +187,7 @@ signals: void slotWithSingleArgCalled(const QString &arg); void slotWithArgumentsCalled(const QString &arg1, const QString &arg2, const QString &arg3); void slotWithOverloadedArgumentsCalled(const QString &arg, Qt::KeyboardModifier modifier, Qt::KeyboardModifiers moreModifiers); + void slotWithTwoOverloadedArgumentsCalled(const QString &arg, Qt::KeyboardModifiers moreModifiers, Qt::KeyboardModifier modifier); public slots: void slotToCall() { emit slotWithoutArgCalled(); } @@ -199,6 +200,10 @@ public slots: { emit slotWithOverloadedArgumentsCalled(arg, modifier, blah); } + void slotToCallTwoDefault(const QString &arg, Qt::KeyboardModifiers modifiers = Qt::ShiftModifier | Qt::ControlModifier, Qt::KeyboardModifier modifier = Qt::AltModifier) + { + emit slotWithTwoOverloadedArgumentsCalled(arg, modifiers, modifier); + } }; void tst_QJSEngine::callQObjectSlot() @@ -256,6 +261,50 @@ void tst_QJSEngine::callQObjectSlot() QCOMPARE(int(qvariant_cast<Qt::KeyboardModifiers>(arguments.at(2))), int(Qt::ShiftModifier)); } + + { + QSignalSpy spy(&dummy, SIGNAL(slotWithTwoOverloadedArgumentsCalled(QString, Qt::KeyboardModifiers, Qt::KeyboardModifier))); + QJSValue v = eng.evaluate(QStringLiteral("dummy.slotToCallTwoDefault('arg', %1);").arg(QString::number(Qt::MetaModifier | Qt::KeypadModifier))); + QCOMPARE(spy.count(), 1); + + const QList<QVariant> arguments = spy.first(); + QCOMPARE(arguments.at(0).toString(), QString("arg")); + QCOMPARE(int(qvariant_cast<Qt::KeyboardModifiers>(arguments.at(1))), int(Qt::MetaModifier | Qt::KeypadModifier)); + QCOMPARE(int(qvariant_cast<Qt::KeyboardModifier>(arguments.at(2))), int(Qt::AltModifier)); + } + + QJSValue jsArray = eng.newArray(); + jsArray.setProperty(QStringLiteral("MetaModifier"), QJSValue(Qt::MetaModifier)); + jsArray.setProperty(QStringLiteral("ShiftModifier"), QJSValue(Qt::ShiftModifier)); + jsArray.setProperty(QStringLiteral("ControlModifier"), QJSValue(Qt::ControlModifier)); + jsArray.setProperty(QStringLiteral("KeypadModifier"), QJSValue(Qt::KeypadModifier)); + + QJSValue value = eng.newQObject(new QObject); + value.setPrototype(jsArray); + eng.globalObject().setProperty(QStringLiteral("Qt"), value); + + { + QSignalSpy spy(&dummy, SIGNAL(slotWithOverloadedArgumentsCalled(QString, Qt::KeyboardModifier, Qt::KeyboardModifiers))); + QJSValue v = eng.evaluate(QStringLiteral("dummy.slotToCall('arg', Qt.ControlModifier);")); + QCOMPARE(spy.count(), 1); + + const QList<QVariant> arguments = spy.first(); + QCOMPARE(arguments.at(0).toString(), QString("arg")); + QCOMPARE(arguments.at(1).toInt(), int(Qt::ControlModifier)); + QCOMPARE(int(qvariant_cast<Qt::KeyboardModifiers>(arguments.at(2))), int(Qt::ShiftModifier)); + } + + { + QSignalSpy spy(&dummy, SIGNAL(slotWithTwoOverloadedArgumentsCalled(QString, Qt::KeyboardModifiers, Qt::KeyboardModifier))); + QJSValue v = eng.evaluate(QStringLiteral("dummy.slotToCallTwoDefault('arg', Qt.MetaModifier | Qt.KeypadModifier);")); + QCOMPARE(spy.count(), 1); + + const QList<QVariant> arguments = spy.first(); + QCOMPARE(arguments.at(0).toString(), QString("arg")); + QCOMPARE(int(qvariant_cast<Qt::KeyboardModifiers>(arguments.at(1))), int(Qt::MetaModifier | Qt::KeypadModifier)); + QCOMPARE(int(qvariant_cast<Qt::KeyboardModifier>(arguments.at(2))), int(Qt::AltModifier)); + } + } void tst_QJSEngine::constructWithParent() |