From 7a04df50d6ea4c2d7ee1c8fdea7a7c259636db17 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Tue, 30 Jun 2009 16:10:56 +0200 Subject: implement name-based connection, make more tests work --- src/script/api/qscriptengine.cpp | 20 +++++++----- tests/auto/qscriptqobject/tst_qscriptqobject.cpp | 40 +++++++++++++++++------- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 9e789bf..d644a73 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -329,6 +329,8 @@ JSC::JSValue functionDisconnect(JSC::ExecState *exec, JSC::JSObject */*callee*/, return JSC::throwError(exec, JSC::TypeError, QScript::qtStringToJSCUString(message)); } + QScriptEnginePrivate *engine = static_cast(exec->dynamicGlobalObject())->engine; + JSC::JSValue receiver; JSC::JSValue slot; JSC::JSValue arg0 = args.at(0); @@ -340,8 +342,10 @@ JSC::JSValue functionDisconnect(JSC::ExecState *exec, JSC::JSObject */*callee*/, if (isFunction(arg1)) slot = arg1; else { - Q_ASSERT_X(false, Q_FUNC_INFO, "implement me"); -// slot = receiver.property(arg1.toString(), QScriptValue::ResolvePrototype); + // ### don't go via QScriptValue + QScriptValue tmp = engine->scriptValueFromJSCValue(arg0); + QString propertyName = QScript::qtStringFromJSCUString(arg1.toString(exec)); + slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype)); } } @@ -349,7 +353,6 @@ JSC::JSValue functionDisconnect(JSC::ExecState *exec, JSC::JSObject */*callee*/, return JSC::throwError(exec, JSC::TypeError, "Function.prototype.disconnect: target is not a function"); } - QScriptEnginePrivate *engine = static_cast(exec->dynamicGlobalObject())->engine; bool ok = engine->scriptDisconnect(thisObject, receiver, slot); if (!ok) { QString message = QString::fromLatin1("Function.prototype.disconnect: failed to disconnect from %0::%1") @@ -373,7 +376,7 @@ JSC::JSValue functionConnect(JSC::ExecState *exec, JSC::JSObject */*callee*/, JS } if (!JSC::asObject(thisObject)->inherits(&QScript::QtFunction::info)) { - return JSC::throwError(exec, JSC::TypeError, "Function.prototype.disconnect: this object is not a signal"); + return JSC::throwError(exec, JSC::TypeError, "Function.prototype.connect: this object is not a signal"); } QScript::QtFunction *qtSignal = static_cast(JSC::asObject(thisObject)); @@ -409,6 +412,8 @@ JSC::JSValue functionConnect(JSC::ExecState *exec, JSC::JSObject */*callee*/, JS } } + QScriptEnginePrivate *engine = static_cast(exec->dynamicGlobalObject())->engine; + JSC::JSValue receiver; JSC::JSValue slot; JSC::JSValue arg0 = args.at(0); @@ -420,8 +425,10 @@ JSC::JSValue functionConnect(JSC::ExecState *exec, JSC::JSObject */*callee*/, JS if (isFunction(arg1)) slot = arg1; else { - Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented"); -// slot = receiver.property(arg1.toString(), QScriptValue::ResolvePrototype); + // ### don't go via QScriptValue + QScriptValue tmp = engine->scriptValueFromJSCValue(arg0); + QString propertyName = QScript::qtStringFromJSCUString(arg1.toString(exec)); + slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype)); } } @@ -429,7 +436,6 @@ JSC::JSValue functionConnect(JSC::ExecState *exec, JSC::JSObject */*callee*/, JS return JSC::throwError(exec, JSC::TypeError, "Function.prototype.connect: target is not a function"); } - QScriptEnginePrivate *engine = static_cast(exec->dynamicGlobalObject())->engine; bool ok = engine->scriptConnect(thisObject, receiver, slot); if (!ok) { QString message = QString::fromLatin1("Function.prototype.connect: failed to connect to %0::%1") diff --git a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp index 969e80f..9fd4eae 100644 --- a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp +++ b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp @@ -494,6 +494,7 @@ private slots: void getSetChildren(); void callQtInvokable(); void connectAndDisconnect(); + void connectAndDisconnectWithBadArgs(); void cppConnectAndDisconnect(); void classEnums(); void classConstructor(); @@ -741,6 +742,8 @@ void tst_QScriptExtQObject::getSetStaticProperty() // test that we do value conversion if necessary when setting properties { QScriptValue br = m_engine->evaluate("myObject.brushProperty"); + QVERIFY(br.isVariant()); + QVERIFY(!br.strictlyEquals(m_engine->evaluate("myObject.brushProperty"))); QCOMPARE(qscriptvalue_cast(br), m_myObject->brushProperty()); QCOMPARE(qscriptvalue_cast(br), m_myObject->brushProperty().color()); @@ -848,6 +851,15 @@ void tst_QScriptExtQObject::getSetStaticProperty() mobj.setProperty("intProperty", m_engine->newFunction(getSetProperty), QScriptValue::PropertyGetter | QScriptValue::PropertySetter); } + + // method properties are persistent + { + QScriptValue slot = m_engine->evaluate("myObject.mySlot"); + QVERIFY(slot.isFunction()); + QScriptValue sameSlot = m_engine->evaluate("myObject.mySlot"); + QEXPECT_FAIL("", "Slot wrappers aren't persistent yet", Continue); + QVERIFY(sameSlot.strictlyEquals(slot)); + } } void tst_QScriptExtQObject::getSetDynamicProperty() @@ -1644,6 +1656,7 @@ void tst_QScriptExtQObject::connectAndDisconnect() QVERIFY(m_engine->evaluate("myObject.mySignal.connect(yetAnotherObject, 'func')").isUndefined()); QVERIFY(m_engine->evaluate("myObject.mySignal.connect(myObject, 'mySlot')").isUndefined()); QVERIFY(m_engine->evaluate("myObject.mySignal.disconnect(yetAnotherObject, 'func')").isUndefined()); + QEXPECT_FAIL("", "Slot wrappers aren't persistent yet", Continue); QVERIFY(m_engine->evaluate("myObject.mySignal.disconnect(myObject, 'mySlot')").isUndefined()); // check that emitting signals from script works @@ -1653,6 +1666,7 @@ void tst_QScriptExtQObject::connectAndDisconnect() m_myObject->resetQtFunctionInvoked(); QCOMPARE(m_engine->evaluate("myObject.mySignal()").isUndefined(), true); QCOMPARE(m_myObject->qtFunctionInvoked(), 20); + QEXPECT_FAIL("", "Slot wrappers aren't persistent yet", Continue); QVERIFY(m_engine->evaluate("myObject.mySignal.disconnect(myObject.mySlot)").isUndefined()); // one argument @@ -1697,7 +1711,20 @@ void tst_QScriptExtQObject::connectAndDisconnect() QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 456); QVERIFY(m_engine->evaluate("myObject.mySignalWithIntArg.disconnect(myObject['myOverloadedSlot(int)'])").isUndefined()); - // erroneous input + // when the wrapper dies, the connection stays alive + QVERIFY(m_engine->evaluate("myObject.mySignal.connect(myObject.mySlot)").isUndefined()); + m_myObject->resetQtFunctionInvoked(); + m_myObject->emitMySignal(); + QCOMPARE(m_myObject->qtFunctionInvoked(), 20); + m_engine->evaluate("myObject = null"); + m_engine->collectGarbage(); + m_myObject->resetQtFunctionInvoked(); + m_myObject->emitMySignal(); + QCOMPARE(m_myObject->qtFunctionInvoked(), 20); +} + +void tst_QScriptExtQObject::connectAndDisconnectWithBadArgs() +{ { QScriptValue ret = m_engine->evaluate("(function() { }).connect()"); QVERIFY(ret.isError()); @@ -1781,17 +1808,6 @@ void tst_QScriptExtQObject::connectAndDisconnect() QVERIFY(ret.isError()); QCOMPARE(ret.toString(), QLatin1String("Error: Function.prototype.disconnect: failed to disconnect from MyQObject::mySignal()")); } - - // when the wrapper dies, the connection stays alive - QVERIFY(m_engine->evaluate("myObject.mySignal.connect(myObject.mySlot)").isUndefined()); - m_myObject->resetQtFunctionInvoked(); - m_myObject->emitMySignal(); - QCOMPARE(m_myObject->qtFunctionInvoked(), 20); - m_engine->evaluate("myObject = null"); - m_engine->collectGarbage(); - m_myObject->resetQtFunctionInvoked(); - m_myObject->emitMySignal(); - QCOMPARE(m_myObject->qtFunctionInvoked(), 20); } void tst_QScriptExtQObject::cppConnectAndDisconnect() -- cgit v0.12