tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp
branchRCL_3
changeset 4 3b1da2848fc7
parent 3 41300fa6a67c
child 14 c0432d11811c
equal deleted inserted replaced
3:41300fa6a67c 4:3b1da2848fc7
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the test suite of the Qt Toolkit.
     7 ** This file is part of the test suite of the Qt Toolkit.
     8 **
     8 **
   110     Q_PROPERTY(int writeOnlyProperty WRITE setWriteOnlyProperty)
   110     Q_PROPERTY(int writeOnlyProperty WRITE setWriteOnlyProperty)
   111     Q_PROPERTY(int readOnlyProperty READ readOnlyProperty)
   111     Q_PROPERTY(int readOnlyProperty READ readOnlyProperty)
   112     Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
   112     Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
   113     Q_PROPERTY(CustomType propWithCustomType READ propWithCustomType WRITE setPropWithCustomType)
   113     Q_PROPERTY(CustomType propWithCustomType READ propWithCustomType WRITE setPropWithCustomType)
   114     Q_PROPERTY(Policy enumProperty READ enumProperty WRITE setEnumProperty)
   114     Q_PROPERTY(Policy enumProperty READ enumProperty WRITE setEnumProperty)
       
   115     Q_PROPERTY(Ability flagsProperty READ flagsProperty WRITE setFlagsProperty)
   115     Q_ENUMS(Policy Strategy)
   116     Q_ENUMS(Policy Strategy)
   116     Q_FLAGS(Ability)
   117     Q_FLAGS(Ability)
   117 
   118 
   118 public:
   119 public:
   119     enum Policy {
   120     enum Policy {
   148           m_brushValue(QColor(10, 20, 30, 40)),
   149           m_brushValue(QColor(10, 20, 30, 40)),
   149           m_hiddenValue(456.0),
   150           m_hiddenValue(456.0),
   150           m_writeOnlyValue(789),
   151           m_writeOnlyValue(789),
   151           m_readOnlyValue(987),
   152           m_readOnlyValue(987),
   152           m_enumValue(BarPolicy),
   153           m_enumValue(BarPolicy),
       
   154           m_flagsValue(FooAbility),
   153           m_qtFunctionInvoked(-1)
   155           m_qtFunctionInvoked(-1)
   154         { }
   156         { }
   155 
   157 
   156     int intProperty() const
   158     int intProperty() const
   157         { return m_intValue; }
   159         { return m_intValue; }
   213 
   215 
   214     Policy enumProperty() const
   216     Policy enumProperty() const
   215         { return m_enumValue; }
   217         { return m_enumValue; }
   216     void setEnumProperty(Policy policy)
   218     void setEnumProperty(Policy policy)
   217         { m_enumValue = policy; }
   219         { m_enumValue = policy; }
       
   220 
       
   221     Ability flagsProperty() const
       
   222         { return m_flagsValue; }
       
   223     void setFlagsProperty(Ability ability)
       
   224         { m_flagsValue = ability; }
   218 
   225 
   219     int qtFunctionInvoked() const
   226     int qtFunctionInvoked() const
   220         { return m_qtFunctionInvoked; }
   227         { return m_qtFunctionInvoked; }
   221 
   228 
   222     QVariantList qtFunctionActuals() const
   229     QVariantList qtFunctionActuals() const
   314         { m_qtFunctionInvoked = 55; m_actuals << qVariantFromValue(arg); }
   321         { m_qtFunctionInvoked = 55; m_actuals << qVariantFromValue(arg); }
   315     Q_INVOKABLE QScriptValue myInvokableWithScriptValueArg(const QScriptValue &arg)
   322     Q_INVOKABLE QScriptValue myInvokableWithScriptValueArg(const QScriptValue &arg)
   316         { m_qtFunctionInvoked = 56; return arg; }
   323         { m_qtFunctionInvoked = 56; return arg; }
   317     Q_INVOKABLE QObject* myInvokableReturningMyQObjectAsQObject()
   324     Q_INVOKABLE QObject* myInvokableReturningMyQObjectAsQObject()
   318         { m_qtFunctionInvoked = 57; return this; }
   325         { m_qtFunctionInvoked = 57; return this; }
       
   326     Q_INVOKABLE Ability myInvokableWithFlagsArg(Ability arg)
       
   327         { m_qtFunctionInvoked = 58; m_actuals << int(arg); return arg; }
       
   328     Q_INVOKABLE MyQObject::Ability myInvokableWithQualifiedFlagsArg(MyQObject::Ability arg)
       
   329         { m_qtFunctionInvoked = 59; m_actuals << int(arg); return arg; }
   319 
   330 
   320     Q_INVOKABLE QObjectList findObjects() const
   331     Q_INVOKABLE QObjectList findObjects() const
   321     {  return findChildren<QObject *>();  }
   332     {  return findChildren<QObject *>();  }
   322     Q_INVOKABLE QList<int> myInvokableNumbers() const
   333     Q_INVOKABLE QList<int> myInvokableNumbers() const
   323     {  return QList<int>() << 1 << 2 << 3; }
   334     {  return QList<int>() << 1 << 2 << 3; }
   431     int m_writeOnlyValue;
   442     int m_writeOnlyValue;
   432     int m_readOnlyValue;
   443     int m_readOnlyValue;
   433     QKeySequence m_shortcut;
   444     QKeySequence m_shortcut;
   434     CustomType m_customType;
   445     CustomType m_customType;
   435     Policy m_enumValue;
   446     Policy m_enumValue;
       
   447     Ability m_flagsValue;
   436     int m_qtFunctionInvoked;
   448     int m_qtFunctionInvoked;
   437     QVariantList m_actuals;
   449     QVariantList m_actuals;
   438     QByteArray m_connectedSignal;
   450     QByteArray m_connectedSignal;
   439     QByteArray m_disconnectedSignal;
   451     QByteArray m_disconnectedSignal;
   440 };
   452 };
   518     void enumerateSpecial();
   530     void enumerateSpecial();
   519     void wrapOptions();
   531     void wrapOptions();
   520     void prototypes();
   532     void prototypes();
   521     void objectDeleted();
   533     void objectDeleted();
   522     void connectToDestroyedSignal();
   534     void connectToDestroyedSignal();
       
   535     void emitAfterReceiverDeleted();
   523 
   536 
   524 private:
   537 private:
   525     QScriptEngine *m_engine;
   538     QScriptEngine *m_engine;
   526     MyQObject *m_myObject;
   539     MyQObject *m_myObject;
   527     QScriptValue m_signalHandlerException;
   540     QScriptValue m_signalHandlerException;
   824     // enum property
   837     // enum property
   825     QCOMPARE(m_myObject->enumProperty(), MyQObject::BarPolicy);
   838     QCOMPARE(m_myObject->enumProperty(), MyQObject::BarPolicy);
   826     {
   839     {
   827         QScriptValue val = m_engine->evaluate("myObject.enumProperty");
   840         QScriptValue val = m_engine->evaluate("myObject.enumProperty");
   828         QVERIFY(val.isNumber());
   841         QVERIFY(val.isNumber());
   829         QCOMPARE(val.toInt32(), (int)MyQObject::BarPolicy);
   842         QCOMPARE(val.toInt32(), int(MyQObject::BarPolicy));
   830     }
   843     }
   831     m_engine->evaluate("myObject.enumProperty = 2");
   844     m_engine->evaluate("myObject.enumProperty = 2");
   832     QCOMPARE(m_myObject->enumProperty(), MyQObject::BazPolicy);
   845     QCOMPARE(m_myObject->enumProperty(), MyQObject::BazPolicy);
   833     m_engine->evaluate("myObject.enumProperty = 'BarPolicy'");
   846     m_engine->evaluate("myObject.enumProperty = 'BarPolicy'");
   834     QCOMPARE(m_myObject->enumProperty(), MyQObject::BarPolicy);
   847     QCOMPARE(m_myObject->enumProperty(), MyQObject::BarPolicy);
   843     QCOMPARE(m_myObject->enumProperty(), MyQObject::BarPolicy);
   856     QCOMPARE(m_myObject->enumProperty(), MyQObject::BarPolicy);
   844     m_engine->evaluate("myObject.enumProperty = 'blue'");
   857     m_engine->evaluate("myObject.enumProperty = 'blue'");
   845     QCOMPARE(m_myObject->enumProperty(), MyQObject::BazPolicy);
   858     QCOMPARE(m_myObject->enumProperty(), MyQObject::BazPolicy);
   846     m_engine->evaluate("myObject.enumProperty = 'nada'");
   859     m_engine->evaluate("myObject.enumProperty = 'nada'");
   847     QCOMPARE(m_myObject->enumProperty(), (MyQObject::Policy)-1);
   860     QCOMPARE(m_myObject->enumProperty(), (MyQObject::Policy)-1);
       
   861 
       
   862     // flags property
       
   863     QCOMPARE(m_myObject->flagsProperty(), MyQObject::FooAbility);
       
   864     {
       
   865         QScriptValue val = m_engine->evaluate("myObject.flagsProperty");
       
   866         QVERIFY(val.isNumber());
       
   867         QCOMPARE(val.toInt32(), int(MyQObject::FooAbility));
       
   868     }
       
   869     m_engine->evaluate("myObject.flagsProperty = 0x80");
       
   870     QCOMPARE(m_myObject->flagsProperty(), MyQObject::BarAbility);
       
   871     m_engine->evaluate("myObject.flagsProperty = 0x81");
       
   872     QCOMPARE(m_myObject->flagsProperty(), MyQObject::Ability(MyQObject::FooAbility | MyQObject::BarAbility));
       
   873     m_engine->evaluate("myObject.flagsProperty = 123"); // bogus values are accepted
       
   874     QCOMPARE(int(m_myObject->flagsProperty()), 123);
       
   875     m_engine->evaluate("myObject.flagsProperty = 'BazAbility'");
       
   876     QCOMPARE(m_myObject->flagsProperty(),  MyQObject::BazAbility);
       
   877     m_engine->evaluate("myObject.flagsProperty = 'ScoobyDoo'");
       
   878     // ### ouch! Shouldn't QMetaProperty::write() rather not change the value...?
       
   879     QCOMPARE(m_myObject->flagsProperty(), (MyQObject::Ability)-1);
   848 
   880 
   849     // auto-dereferencing of pointers
   881     // auto-dereferencing of pointers
   850     {
   882     {
   851         QBrush b = QColor(0xCA, 0xFE, 0xBA, 0xBE);
   883         QBrush b = QColor(0xCA, 0xFE, 0xBA, 0xBE);
   852         QBrush *bp = &b;
   884         QBrush *bp = &b;
  2015 void tst_QScriptExtQObject::classEnums()
  2047 void tst_QScriptExtQObject::classEnums()
  2016 {
  2048 {
  2017     QScriptValue myClass = m_engine->newQMetaObject(m_myObject->metaObject(), m_engine->undefinedValue());
  2049     QScriptValue myClass = m_engine->newQMetaObject(m_myObject->metaObject(), m_engine->undefinedValue());
  2018     m_engine->globalObject().setProperty("MyQObject", myClass);
  2050     m_engine->globalObject().setProperty("MyQObject", myClass);
  2019 
  2051 
       
  2052     QVERIFY(m_engine->evaluate("MyQObject.FooPolicy").isNumber()); // no strong typing
  2020     QCOMPARE(static_cast<MyQObject::Policy>(m_engine->evaluate("MyQObject.FooPolicy").toInt32()),
  2053     QCOMPARE(static_cast<MyQObject::Policy>(m_engine->evaluate("MyQObject.FooPolicy").toInt32()),
  2021              MyQObject::FooPolicy);
  2054              MyQObject::FooPolicy);
  2022     QCOMPARE(static_cast<MyQObject::Policy>(m_engine->evaluate("MyQObject.BarPolicy").toInt32()),
  2055     QCOMPARE(static_cast<MyQObject::Policy>(m_engine->evaluate("MyQObject.BarPolicy").toInt32()),
  2023              MyQObject::BarPolicy);
  2056              MyQObject::BarPolicy);
  2024     QCOMPARE(static_cast<MyQObject::Policy>(m_engine->evaluate("MyQObject.BazPolicy").toInt32()),
  2057     QCOMPARE(static_cast<MyQObject::Policy>(m_engine->evaluate("MyQObject.BazPolicy").toInt32()),
  2029     QCOMPARE(static_cast<MyQObject::Strategy>(m_engine->evaluate("MyQObject.BarStrategy").toInt32()),
  2062     QCOMPARE(static_cast<MyQObject::Strategy>(m_engine->evaluate("MyQObject.BarStrategy").toInt32()),
  2030              MyQObject::BarStrategy);
  2063              MyQObject::BarStrategy);
  2031     QCOMPARE(static_cast<MyQObject::Strategy>(m_engine->evaluate("MyQObject.BazStrategy").toInt32()),
  2064     QCOMPARE(static_cast<MyQObject::Strategy>(m_engine->evaluate("MyQObject.BazStrategy").toInt32()),
  2032              MyQObject::BazStrategy);
  2065              MyQObject::BazStrategy);
  2033 
  2066 
       
  2067     QVERIFY(m_engine->evaluate("MyQObject.NoAbility").isNumber()); // no strong typing
  2034     QCOMPARE(MyQObject::Ability(m_engine->evaluate("MyQObject.NoAbility").toInt32()),
  2068     QCOMPARE(MyQObject::Ability(m_engine->evaluate("MyQObject.NoAbility").toInt32()),
  2035              MyQObject::NoAbility);
  2069              MyQObject::NoAbility);
  2036     QCOMPARE(MyQObject::Ability(m_engine->evaluate("MyQObject.FooAbility").toInt32()),
  2070     QCOMPARE(MyQObject::Ability(m_engine->evaluate("MyQObject.FooAbility").toInt32()),
  2037              MyQObject::FooAbility);
  2071              MyQObject::FooAbility);
  2038     QCOMPARE(MyQObject::Ability(m_engine->evaluate("MyQObject.BarAbility").toInt32()),
  2072     QCOMPARE(MyQObject::Ability(m_engine->evaluate("MyQObject.BarAbility").toInt32()),
  2040     QCOMPARE(MyQObject::Ability(m_engine->evaluate("MyQObject.BazAbility").toInt32()),
  2074     QCOMPARE(MyQObject::Ability(m_engine->evaluate("MyQObject.BazAbility").toInt32()),
  2041              MyQObject::BazAbility);
  2075              MyQObject::BazAbility);
  2042     QCOMPARE(MyQObject::Ability(m_engine->evaluate("MyQObject.AllAbility").toInt32()),
  2076     QCOMPARE(MyQObject::Ability(m_engine->evaluate("MyQObject.AllAbility").toInt32()),
  2043              MyQObject::AllAbility);
  2077              MyQObject::AllAbility);
  2044 
  2078 
       
  2079     // Constructors for flags are not provided
       
  2080     QVERIFY(m_engine->evaluate("MyQObject.Ability").isUndefined());
       
  2081 
  2045     QScriptValue::PropertyFlags expectedEnumFlags = QScriptValue::ReadOnly | QScriptValue::Undeletable;
  2082     QScriptValue::PropertyFlags expectedEnumFlags = QScriptValue::ReadOnly | QScriptValue::Undeletable;
  2046     QCOMPARE(myClass.propertyFlags("FooPolicy"), expectedEnumFlags);
  2083     QCOMPARE(myClass.propertyFlags("FooPolicy"), expectedEnumFlags);
  2047     QCOMPARE(myClass.propertyFlags("BarPolicy"), expectedEnumFlags);
  2084     QCOMPARE(myClass.propertyFlags("BarPolicy"), expectedEnumFlags);
  2048     QCOMPARE(myClass.propertyFlags("BazPolicy"), expectedEnumFlags);
  2085     QCOMPARE(myClass.propertyFlags("BazPolicy"), expectedEnumFlags);
  2049 
  2086 
  2090     {
  2127     {
  2091         QScriptValue ret = m_engine->evaluate("myObject.myInvokableReturningQualifiedEnum()");
  2128         QScriptValue ret = m_engine->evaluate("myObject.myInvokableReturningQualifiedEnum()");
  2092         QCOMPARE(m_myObject->qtFunctionInvoked(), 38);
  2129         QCOMPARE(m_myObject->qtFunctionInvoked(), 38);
  2093         QCOMPARE(m_myObject->qtFunctionActuals().size(), 0);
  2130         QCOMPARE(m_myObject->qtFunctionActuals().size(), 0);
  2094         QCOMPARE(ret.isNumber(), true);
  2131         QCOMPARE(ret.isNumber(), true);
       
  2132     }
       
  2133 
       
  2134     m_myObject->resetQtFunctionInvoked();
       
  2135     {
       
  2136         QScriptValue ret = m_engine->evaluate("myObject.myInvokableWithFlagsArg(MyQObject.FooAbility)");
       
  2137         QCOMPARE(m_myObject->qtFunctionInvoked(), 58);
       
  2138         QCOMPARE(m_myObject->qtFunctionActuals().size(), 1);
       
  2139         QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), int(MyQObject::FooAbility));
       
  2140         QCOMPARE(ret.isNumber(), true);
       
  2141         QCOMPARE(ret.toInt32(), int(MyQObject::FooAbility));
       
  2142     }
       
  2143     m_myObject->resetQtFunctionInvoked();
       
  2144     {
       
  2145         QScriptValue ret = m_engine->evaluate("myObject.myInvokableWithQualifiedFlagsArg(MyQObject.BarAbility)");
       
  2146         QCOMPARE(m_myObject->qtFunctionInvoked(), 59);
       
  2147         QCOMPARE(m_myObject->qtFunctionActuals().size(), 1);
       
  2148         QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), int(MyQObject::BarAbility));
       
  2149         QCOMPARE(ret.isNumber(), true);
       
  2150         QCOMPARE(ret.toInt32(), int(MyQObject::BarAbility));
  2095     }
  2151     }
  2096 
  2152 
  2097     // enum properties are not deletable or writable
  2153     // enum properties are not deletable or writable
  2098     QVERIFY(!m_engine->evaluate("delete MyQObject.BazPolicy").toBool());
  2154     QVERIFY(!m_engine->evaluate("delete MyQObject.BazPolicy").toBool());
  2099     myClass.setProperty("BazPolicy", QScriptValue());
  2155     myClass.setProperty("BazPolicy", QScriptValue());
  2856     v.setProperty("objectName", QScriptValue(&eng, "foo"));
  2912     v.setProperty("objectName", QScriptValue(&eng, "foo"));
  2857     QCOMPARE(qobj->objectName(), QLatin1String("foo"));
  2913     QCOMPARE(qobj->objectName(), QLatin1String("foo"));
  2858     v.setProperty("intProperty", QScriptValue(&eng, 123));
  2914     v.setProperty("intProperty", QScriptValue(&eng, 123));
  2859     QCOMPARE(qobj->intProperty(), 123);
  2915     QCOMPARE(qobj->intProperty(), 123);
  2860     qobj->resetQtFunctionInvoked();
  2916     qobj->resetQtFunctionInvoked();
  2861     v.property("myInvokable").call(v);
  2917     QScriptValue invokable = v.property("myInvokable");
       
  2918     invokable.call(v);
  2862     QCOMPARE(qobj->qtFunctionInvoked(), 0);
  2919     QCOMPARE(qobj->qtFunctionInvoked(), 0);
  2863 
  2920 
  2864     // now delete the object
  2921     // now delete the object
  2865     delete qobj;
  2922     delete qobj;
  2866 
  2923 
  2892     // myInvokableWithIntArg is not stored in member table (since we've not accessed it)
  2949     // myInvokableWithIntArg is not stored in member table (since we've not accessed it)
  2893     {
  2950     {
  2894         QScriptValue ret = v.property("myInvokableWithIntArg");
  2951         QScriptValue ret = v.property("myInvokableWithIntArg");
  2895         QVERIFY(ret.isError());
  2952         QVERIFY(ret.isError());
  2896         QCOMPARE(ret.toString(), QLatin1String("Error: cannot access member `myInvokableWithIntArg' of deleted QObject"));
  2953         QCOMPARE(ret.toString(), QLatin1String("Error: cannot access member `myInvokableWithIntArg' of deleted QObject"));
       
  2954     }
       
  2955 
       
  2956     // Meta-method wrappers are still valid, but throw error when called
       
  2957     QVERIFY(invokable.isFunction());
       
  2958     {
       
  2959         QScriptValue ret = invokable.call(v);
       
  2960         QVERIFY(ret.isError());
       
  2961         QCOMPARE(ret.toString(), QString::fromLatin1("Error: cannot call function of deleted QObject"));
  2897     }
  2962     }
  2898 
  2963 
  2899     // access from script
  2964     // access from script
  2900     eng.globalObject().setProperty("o", v);
  2965     eng.globalObject().setProperty("o", v);
  2901     {
  2966     {
  2954         // the signal handler won't get called -- we don't want to crash
  3019         // the signal handler won't get called -- we don't want to crash
  2955     }
  3020     }
  2956 #endif
  3021 #endif
  2957 }
  3022 }
  2958 
  3023 
       
  3024 void tst_QScriptExtQObject::emitAfterReceiverDeleted()
       
  3025 {
       
  3026     for (int x = 0; x < 2; ++x) {
       
  3027         MyQObject *obj = new MyQObject;
       
  3028         QScriptValue scriptObj = m_engine->newQObject(obj);
       
  3029         if (x == 0) {
       
  3030             // Connecting from JS
       
  3031             m_engine->globalObject().setProperty("obj", scriptObj);
       
  3032             QVERIFY(m_engine->evaluate("myObject.mySignal.connect(obj, 'mySlot()')").isUndefined());
       
  3033         } else {
       
  3034             // Connecting from C++
       
  3035             qScriptConnect(m_myObject, SIGNAL(mySignal()), scriptObj, scriptObj.property("mySlot"));
       
  3036         }
       
  3037         delete obj;
       
  3038         QSignalSpy signalHandlerExceptionSpy(m_engine, SIGNAL(signalHandlerException(QScriptValue)));
       
  3039         QVERIFY(!m_engine->hasUncaughtException());
       
  3040         m_myObject->emitMySignal();
       
  3041         QCOMPARE(signalHandlerExceptionSpy.count(), 0);
       
  3042         QVERIFY(!m_engine->hasUncaughtException());
       
  3043     }
       
  3044 }
       
  3045 
  2959 QTEST_MAIN(tst_QScriptExtQObject)
  3046 QTEST_MAIN(tst_QScriptExtQObject)
  2960 #include "tst_qscriptextqobject.moc"
  3047 #include "tst_qscriptextqobject.moc"