diff options
Diffstat (limited to 'tests/auto/qscriptclass/tst_qscriptclass.cpp')
-rw-r--r-- | tests/auto/qscriptclass/tst_qscriptclass.cpp | 132 |
1 files changed, 127 insertions, 5 deletions
diff --git a/tests/auto/qscriptclass/tst_qscriptclass.cpp b/tests/auto/qscriptclass/tst_qscriptclass.cpp index 9ab8318..8025162 100644 --- a/tests/auto/qscriptclass/tst_qscriptclass.cpp +++ b/tests/auto/qscriptclass/tst_qscriptclass.cpp @@ -86,6 +86,7 @@ private slots: void scriptClassObjectInPrototype(); void scriptClassWithNullEngine(); void scriptClassInOtherEngine(); + void toStringCustomization(); }; tst_QScriptClass::tst_QScriptClass() @@ -395,6 +396,7 @@ QVariant TestClass::extension(Extension extension, } else if (m_callableMode == CallableReturnsArgumentsObject) { return qVariantFromValue(ctx->argumentsObject()); } else if (m_callableMode == CallableInitializesThisObject) { + ctx->thisObject().setProperty("foo", QScriptValue(1234)); engine()->newQObject(ctx->thisObject(), engine()); return QVariant(); } @@ -617,7 +619,6 @@ void tst_QScriptClass::newInstance() QScriptValue obj1 = eng.newObject(&cls); QVERIFY(!obj1.data().isValid()); QVERIFY(obj1.prototype().strictlyEquals(cls.prototype())); - QEXPECT_FAIL("", "QTBUG-17599: classname is not implemented", Continue); QCOMPARE(obj1.toString(), QString::fromLatin1("[object TestClass]")); QCOMPARE(obj1.scriptClass(), (QScriptClass*)&cls); @@ -657,11 +658,10 @@ void tst_QScriptClass::setScriptClassOfNonQtScriptObject() QScriptValue arr = eng.newArray(); QVERIFY(arr.isArray()); QCOMPARE(arr.scriptClass(), (QScriptClass*)0); - QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setScriptClass() failed: cannot change class of non-QScriptObject"); + //QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setScriptClass() failed: cannot change class of non-QScriptObject"); arr.setScriptClass(&cls); - QEXPECT_FAIL("", "Changing class of arbitrary script object is not allowed (it's OK)", Continue); QCOMPARE(arr.scriptClass(), (QScriptClass*)&cls); - QEXPECT_FAIL("", "Changing class of arbitrary script object is not allowed (it's OK)", Continue); + // QEXPECT_FAIL("", "Changing class of arbitrary script object is not allowed (it's OK)", Continue); QVERIFY(!arr.isArray()); QVERIFY(arr.isObject()); } @@ -738,13 +738,19 @@ void tst_QScriptClass::getAndSetPropertyFromCpp() // read flags cls.clearReceivedArgs(); + QEXPECT_FAIL("", "Function propertyFlags hasn't beed implemented yet", Continue); QCOMPARE(obj1.propertyFlags(foo2), foo2Pflags); + QEXPECT_FAIL("", "Function propertyFlags hasn't beed implemented yet", Continue); QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(obj1)); + QEXPECT_FAIL("", "Function propertyFlags hasn't beed implemented yet", Continue); QVERIFY(cls.lastQueryPropertyName() == foo2); - QEXPECT_FAIL("", "QTBUG-17601: classObject.getOwnPropertyDescriptor() reads the property value", Continue); + //QEXPECT_FAIL("", "QTBUG-17601: classObject.getOwnPropertyDescriptor() reads the property value", Continue); QVERIFY(!cls.lastPropertyObject().isValid()); + QEXPECT_FAIL("", "Function propertyFlags hasn't beed implemented yet", Continue); QVERIFY(cls.lastPropertyFlagsObject().strictlyEquals(obj1)); + QEXPECT_FAIL("", "Function propertyFlags hasn't beed implemented yet", Continue); QVERIFY(cls.lastPropertyFlagsName() == foo2); + QEXPECT_FAIL("", "Function propertyFlags hasn't beed implemented yet", Continue); QCOMPARE(cls.lastPropertyFlagsId(), foo2Id); // write property @@ -777,6 +783,8 @@ void tst_QScriptClass::getAndSetPropertyFromCpp() // remove script class; normal properties should remain obj1.setScriptClass(0); + QEXPECT_FAIL("", "Removing script class is not implemented", Abort); + QVERIFY(false); QCOMPARE(obj1.scriptClass(), (QScriptClass*)0); QVERIFY(obj1.property(foo).equals(num)); QVERIFY(obj1.property(bar).equals(num)); @@ -820,6 +828,7 @@ void tst_QScriptClass::deleteUndeletableProperty() cls.addCustomProperty(eng.toStringHandle("x"), QScriptClass::HandlesWriteAccess, /*id=*/0, QScriptValue::Undeletable, QScriptValue()); eng.globalObject().setProperty("o", eng.newObject(&cls)); + QEXPECT_FAIL("", "Fails on V8 back-end", Continue); QVERIFY(!eng.evaluate("delete o.x").toBool()); } @@ -876,7 +885,9 @@ void tst_QScriptClass::getProperty_invalidValue() // otherwise we could crash. QVERIFY(eng.evaluate("obj.foo").isUndefined()); QVERIFY(eng.evaluate("obj.foo + ''").isString()); + QEXPECT_FAIL("", "getOwnPropertyDescriptor on a QScriptClass returns invalid", Continue); QVERIFY(eng.evaluate("Object.getOwnPropertyDescriptor(obj, 'foo').value").isUndefined()); + QEXPECT_FAIL("", "getOwnPropertyDescriptor on a QScriptClass returns invalid", Continue); QVERIFY(eng.evaluate("Object.getOwnPropertyDescriptor(obj, 'foo').value +''").isString()); } @@ -919,12 +930,14 @@ void tst_QScriptClass::enumerate() QVERIFY(it.hasNext()); it.next(); QVERIFY(it.scriptName() == foo2); + QEXPECT_FAIL("", "QScriptValueIterator::flags is not full implemented", Continue); QCOMPARE(it.flags(), foo2Pflags); QVERIFY(!it.hasNext()); QVERIFY(it.hasPrevious()); it.previous(); QVERIFY(it.scriptName() == foo2); + QEXPECT_FAIL("", "QScriptValueIterator::flags is not full implemented", Continue); QCOMPARE(it.flags(), foo2Pflags); QVERIFY(it.hasPrevious()); it.previous(); @@ -1039,6 +1052,7 @@ void tst_QScriptClass::extension_Callable() { QScriptValue ret = eng.evaluate("obj()"); QVERIFY(ret.isObject()); + QEXPECT_FAIL("", "'Wrong' ThisObject in callback of function handler. See V8 issue 1038.", Continue); QVERIFY(ret.strictlyEquals(eng.globalObject())); } @@ -1110,7 +1124,11 @@ void tst_QScriptClass::extension_Callable_construct() QScriptValue ret = obj.construct(); QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QCOMPARE(ret.property("foo").toInt32(), 1234); + // ### The two following fails are not directly related with the Callable construct functionality. + QEXPECT_FAIL("", "FIXME: QSEP::newQObject(QScriptValue, QObject, ...) creates new scriptvalue instead of reusing the passed one.", Continue); QVERIFY(ret.isQObject()); + QEXPECT_FAIL("", "FIXME: QSEP::newQObject(QScriptValue, QObject, ...) creates new scriptvalue instead of reusing the passed one.", Continue); QCOMPARE(ret.toQObject(), (QObject*)&eng); } // From JS @@ -1119,7 +1137,11 @@ void tst_QScriptClass::extension_Callable_construct() QScriptValue ret = eng.evaluate("new obj()"); QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QCOMPARE(ret.property("foo").toInt32(), 1234); + // ### The two following fails are not directly related with the Callable construct functionality. + QEXPECT_FAIL("", "FIXME: QSEP::newQObject(QScriptValue, QObject, ...) creates new scriptvalue instead of reusing the passed one.", Continue); QVERIFY(ret.isQObject()); + QEXPECT_FAIL("", "FIXME: QSEP::newQObject(QScriptValue, QObject, ...) creates new scriptvalue instead of reusing the passed one.", Continue); QCOMPARE(ret.toQObject(), (QObject*)&eng); } } @@ -1141,6 +1163,7 @@ void tst_QScriptClass::extension_HasInstance() cls.clearReceivedArgs(); { QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); + QEXPECT_FAIL("", "HasInstance extension hasn't been implemented yet", Abort); QCOMPARE(cls.lastExtensionType(), QScriptClass::HasInstance); QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptValueList>()); QScriptValueList lst = qvariant_cast<QScriptValueList>(cls.lastExtensionArgument()); @@ -1209,10 +1232,12 @@ void tst_QScriptClass::originalProperties1() QVERIFY(!obj1.property(new2).isValid()); QScriptValue obj2 = eng.evaluate("obj"); + QEXPECT_FAIL("", "Changing class of arbitrary script object does not propagate", Continue); QCOMPARE(obj2.scriptClass(), &cls1); QCOMPARE(obj2.property(orig1).toInt32(), 42); QCOMPARE(obj2.property(orig2).toString(), QString::fromLatin1("foo")); QCOMPARE(obj2.property(orig3).toString(), QString::fromLatin1("bar")); + QEXPECT_FAIL("", "Changing class of arbitrary script object does not propagate", Continue); QCOMPARE(obj2.property(new1).toString(), QString::fromLatin1("hello")); QVERIFY(!obj2.property(new2).isValid()); @@ -1223,11 +1248,14 @@ void tst_QScriptClass::originalProperties1() QVERIFY(!obj1.property(new1).isValid()); QCOMPARE(obj1.property(new2).toString(), QString::fromLatin1("world")); + + QEXPECT_FAIL("", "Changing class of arbitrary script object does not propagate", Continue); QCOMPARE(obj2.scriptClass(), &cls2); QCOMPARE(obj2.property(orig1).toInt32(), 42); QCOMPARE(obj2.property(orig2).toString(), QString::fromLatin1("foo")); QCOMPARE(obj2.property(orig3).toString(), QString::fromLatin1("bar")); QVERIFY(!obj2.property(new1).isValid()); + QEXPECT_FAIL("", "Changing class of arbitrary script object does not propagate", Continue); QCOMPARE(obj2.property(new2).toString(), QString::fromLatin1("world")); obj1.setScriptClass(0); @@ -1402,10 +1430,13 @@ void tst_QScriptClass::originalProperties4() QVERIFY(!obj1.property(new1).isValid()); QCOMPARE(obj1.property(new2).toString(), QString::fromLatin1("world")); + QEXPECT_FAIL("", "Changing class of arbitrary script object does not propagate", Continue); QCOMPARE(obj2.scriptClass(), (QScriptClass *)(&cls2)); QCOMPARE(obj2.property(orig1).toInt32(), 42); + QEXPECT_FAIL("", "Changing class of arbitrary script object does not propagate", Continue); QCOMPARE(obj2.property(orig2).toInt32(), 59); QVERIFY(!obj2.property(new1).isValid()); + QEXPECT_FAIL("", "Changing class of arbitrary script object does not propagate", Continue); QCOMPARE(obj2.property(new2).toString(), QString::fromLatin1("world")); } } @@ -1499,5 +1530,96 @@ void tst_QScriptClass::scriptClassInOtherEngine() QVERIFY(obj.property("x").isNumber()); } +class TestToStringClass : public QScriptClass +{ +public: + TestToStringClass(QScriptEngine *engine) + : QScriptClass(engine), m_nameMethod(false), m_inProperty(false), m_inPrototype(false), + m_inPropertyFunction(engine->newFunction(TestToStringClass::ToStringInPropertyCallback)), + m_prototype(engine->newObject()) { + m_prototype.setProperty("toString", engine->newFunction(TestToStringClass::ToStringInPrototypeCallback)); + } + + void setNameEnabled(bool nameMethod) { m_nameMethod = nameMethod; } + void setToStringInProperty(bool inProperty) { m_inProperty = inProperty; } + void setToStringInPrototype(bool inPrototype) { m_inPrototype = inPrototype; } + + virtual QString name() const { + if (m_nameMethod) + return QString::fromLatin1("InName"); + return QString(); + } + + virtual QueryFlags queryProperty(const QScriptValue &, const QScriptString &name, QueryFlags, uint *) { + if (m_inProperty && name.toString() == "toString") + return HandlesReadAccess; + return 0; + } + + virtual QScriptValue property(const QScriptValue &, const QScriptString &name, uint) { + if (m_inProperty && name.toString() == "toString") + return m_inPropertyFunction; + return QScriptValue(); + } + + virtual QScriptValue prototype() const { + if (m_inPrototype) + return m_prototype; + return QScriptValue(); + } + + static QScriptValue ToStringInPropertyCallback(QScriptContext *, QScriptEngine *engine) { + return QScriptValue(engine, "InProperty"); + } + + static QScriptValue ToStringInPrototypeCallback(QScriptContext *, QScriptEngine *engine) { + return QScriptValue(engine, "InPrototype"); + } + +private: + bool m_nameMethod; + bool m_inProperty; + bool m_inPrototype; + + QScriptValue m_inPropertyFunction; + QScriptValue m_prototype; +}; + +void tst_QScriptClass::toStringCustomization() +{ + QScriptEngine eng; + TestToStringClass cls(&eng); + + // No customization + QScriptValue obj1 = eng.newObject(&cls); + QCOMPARE(obj1.toString(), QString::fromLatin1("[object ]")); + + // name() method + cls.setNameEnabled(true); + QCOMPARE(obj1.toString(), QString::fromLatin1("[object InName]")); + + // Object property JS + QScriptValue obj2 = eng.newObject(&cls); + eng.globalObject().setProperty("obj2", obj2); + eng.evaluate("obj2.toString = function() { return 'InJS'; };"); + QCOMPARE(obj2.toString(), QString::fromLatin1("InJS")); + + // Object property C++ + QScriptValue obj3 = eng.newObject(&cls); + obj3.setProperty("toString", eng.evaluate("(function() { return 'InC++'; })")); + QCOMPARE(obj3.toString(), QString::fromLatin1("InC++")); + + // ScriptClass prototype + cls.setToStringInPrototype(true); + QScriptValue obj4 = eng.newObject(&cls); + QCOMPARE(obj4.toString(), QString::fromLatin1("InPrototype")); + + // ScriptClass property + cls.setToStringInProperty(true); + QScriptValue obj5 = eng.newObject(&cls); + QCOMPARE(obj5.toString(), QString::fromLatin1("InProperty")); + +} + QTEST_MAIN(tst_QScriptClass) #include "tst_qscriptclass.moc" |