2011-04-27 10:05:43 +00:00
/****************************************************************************
* *
* * Copyright ( C ) 2011 Nokia Corporation and / or its subsidiary ( - ies ) .
* * All rights reserved .
* * Contact : Nokia Corporation ( qt - info @ nokia . com )
* *
* * This file is part of the test suite of the Qt Toolkit .
* *
* * $ QT_BEGIN_LICENSE : LGPL $
* * No Commercial Usage
* * This file contains pre - release code and may not be distributed .
* * You may use this file in accordance with the terms and conditions
* * contained in the Technology Preview License Agreement accompanying
* * this package .
* *
* * GNU Lesser General Public License Usage
* * Alternatively , this file may be used under the terms of the GNU Lesser
* * General Public License version 2.1 as published by the Free Software
* * Foundation and appearing in the file LICENSE . LGPL included in the
* * packaging of this file . Please review the following information to
* * ensure the GNU Lesser General Public License version 2.1 requirements
* * will be met : http : //www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
* *
* * In addition , as a special exception , Nokia gives you certain additional
* * rights . These rights are described in the Nokia Qt LGPL Exception
* * version 1.1 , included in the file LGPL_EXCEPTION . txt in this package .
* *
* * If you have questions regarding the use of this file , please contact
* * Nokia at qt - info @ nokia . com .
* *
* *
* *
* *
* *
* *
* *
* *
* * $ QT_END_LICENSE $
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <qtest.h>
# include <QtDeclarative/qdeclarativecomponent.h>
# include <QtDeclarative/qdeclarativeengine.h>
# include <QtDeclarative/qdeclarativeexpression.h>
# include <QtDeclarative/qdeclarativecontext.h>
# include <QtCore/qfileinfo.h>
# include <QtCore/qdebug.h>
# include <QtDeclarative/private/qdeclarativeguard_p.h>
# include <QtCore/qdir.h>
# include <QtCore/qnumeric.h>
# include <private/qdeclarativeengine_p.h>
# include <private/qdeclarativeglobalscriptclass_p.h>
# include <private/qscriptdeclarativeclass_p.h>
# include "testtypes.h"
# include "testhttpserver.h"
# include "../../../shared/util.h"
# ifdef Q_OS_SYMBIAN
// In Symbian OS test data is located in applications private dir
# define SRCDIR "."
# endif
/*
This test covers evaluation of ECMAScript expressions and bindings from within
QML . This does not include static QML language issues .
Static QML language issues are covered in qmllanguage
*/
inline QUrl TEST_FILE ( const QString & filename )
{
QFileInfo fileInfo ( __FILE__ ) ;
return QUrl : : fromLocalFile ( fileInfo . absoluteDir ( ) . filePath ( " data/ " + filename ) ) ;
}
inline QUrl TEST_FILE ( const char * filename )
{
return TEST_FILE ( QLatin1String ( filename ) ) ;
}
class tst_qdeclarativeecmascript : public QObject
{
Q_OBJECT
public :
tst_qdeclarativeecmascript ( ) { }
private slots :
void initTestCase ( ) ;
void assignBasicTypes ( ) ;
void idShortcutInvalidates ( ) ;
void boolPropertiesEvaluateAsBool ( ) ;
void methods ( ) ;
void signalAssignment ( ) ;
void bindingLoop ( ) ;
void basicExpressions ( ) ;
void basicExpressions_data ( ) ;
void arrayExpressions ( ) ;
void contextPropertiesTriggerReeval ( ) ;
void objectPropertiesTriggerReeval ( ) ;
void deferredProperties ( ) ;
void deferredPropertiesErrors ( ) ;
void extensionObjects ( ) ;
void overrideExtensionProperties ( ) ;
void attachedProperties ( ) ;
void enums ( ) ;
void valueTypeFunctions ( ) ;
void constantsOverrideBindings ( ) ;
void outerBindingOverridesInnerBinding ( ) ;
void aliasPropertyAndBinding ( ) ;
void nonExistentAttachedObject ( ) ;
void scope ( ) ;
void signalParameterTypes ( ) ;
void objectsCompareAsEqual ( ) ;
void dynamicCreation_data ( ) ;
void dynamicCreation ( ) ;
void dynamicDestruction ( ) ;
void objectToString ( ) ;
void selfDeletingBinding ( ) ;
void extendedObjectPropertyLookup ( ) ;
void scriptErrors ( ) ;
void functionErrors ( ) ;
void propertyAssignmentErrors ( ) ;
void signalTriggeredBindings ( ) ;
void listProperties ( ) ;
void exceptionClearsOnReeval ( ) ;
void exceptionSlotProducesWarning ( ) ;
void exceptionBindingProducesWarning ( ) ;
void transientErrors ( ) ;
void shutdownErrors ( ) ;
void compositePropertyType ( ) ;
void jsObject ( ) ;
void undefinedResetsProperty ( ) ;
void listToVariant ( ) ;
void multiEngineObject ( ) ;
void deletedObject ( ) ;
void attachedPropertyScope ( ) ;
void scriptConnect ( ) ;
void scriptDisconnect ( ) ;
void ownership ( ) ;
void cppOwnershipReturnValue ( ) ;
void ownershipCustomReturnValue ( ) ;
void qlistqobjectMethods ( ) ;
void strictlyEquals ( ) ;
void compiled ( ) ;
void numberAssignment ( ) ;
void propertySplicing ( ) ;
void signalWithUnknownTypes ( ) ;
2011-04-27 12:13:26 +00:00
void moduleApi ( ) ;
void importScripts ( ) ;
void scarceResources ( ) ;
2011-04-27 10:05:43 +00:00
void bug1 ( ) ;
void bug2 ( ) ;
void dynamicCreationCrash ( ) ;
void regExpBug ( ) ;
void nullObjectBinding ( ) ;
void deletedEngine ( ) ;
void libraryScriptAssert ( ) ;
void variantsAssignedUndefined ( ) ;
void qtbug_9792 ( ) ;
void qtcreatorbug_1289 ( ) ;
void noSpuriousWarningsAtShutdown ( ) ;
void canAssignNullToQObject ( ) ;
void functionAssignment_fromBinding ( ) ;
void functionAssignment_fromJS ( ) ;
void functionAssignment_fromJS_data ( ) ;
void functionAssignmentfromJS_invalid ( ) ;
void eval ( ) ;
void function ( ) ;
void qtbug_10696 ( ) ;
void qtbug_11606 ( ) ;
void qtbug_11600 ( ) ;
void nonscriptable ( ) ;
void deleteLater ( ) ;
void in ( ) ;
void sharedAttachedObject ( ) ;
void objectName ( ) ;
void writeRemovesBinding ( ) ;
void aliasBindingsAssignCorrectly ( ) ;
void aliasBindingsOverrideTarget ( ) ;
void aliasWritesOverrideBindings ( ) ;
void pushCleanContext ( ) ;
2011-04-27 12:13:26 +00:00
void realToInt ( ) ;
2011-04-27 10:05:43 +00:00
void include ( ) ;
void callQtInvokables ( ) ;
void invokableObjectArg ( ) ;
void invokableObjectRet ( ) ;
void revisionErrors ( ) ;
void revision ( ) ;
private :
QDeclarativeEngine engine ;
} ;
void tst_qdeclarativeecmascript : : initTestCase ( ) { registerTypes ( ) ; }
void tst_qdeclarativeecmascript : : assignBasicTypes ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " assignBasicTypes.qml " ) ) ;
MyTypeObject * object = qobject_cast < MyTypeObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > flagProperty ( ) , MyTypeObject : : FlagVal1 | MyTypeObject : : FlagVal3 ) ;
QCOMPARE ( object - > enumProperty ( ) , MyTypeObject : : EnumVal2 ) ;
QCOMPARE ( object - > stringProperty ( ) , QString ( " Hello World! " ) ) ;
QCOMPARE ( object - > uintProperty ( ) , uint ( 10 ) ) ;
QCOMPARE ( object - > intProperty ( ) , - 19 ) ;
QCOMPARE ( ( float ) object - > realProperty ( ) , float ( 23.2 ) ) ;
QCOMPARE ( ( float ) object - > doubleProperty ( ) , float ( - 19.75 ) ) ;
QCOMPARE ( ( float ) object - > floatProperty ( ) , float ( 8.5 ) ) ;
QCOMPARE ( object - > colorProperty ( ) , QColor ( " red " ) ) ;
QCOMPARE ( object - > dateProperty ( ) , QDate ( 1982 , 11 , 25 ) ) ;
QCOMPARE ( object - > timeProperty ( ) , QTime ( 11 , 11 , 32 ) ) ;
QCOMPARE ( object - > dateTimeProperty ( ) , QDateTime ( QDate ( 2009 , 5 , 12 ) , QTime ( 13 , 22 , 1 ) ) ) ;
QCOMPARE ( object - > pointProperty ( ) , QPoint ( 99 , 13 ) ) ;
QCOMPARE ( object - > pointFProperty ( ) , QPointF ( - 10.1 , 12.3 ) ) ;
QCOMPARE ( object - > sizeProperty ( ) , QSize ( 99 , 13 ) ) ;
QCOMPARE ( object - > sizeFProperty ( ) , QSizeF ( 0.1 , 0.2 ) ) ;
QCOMPARE ( object - > rectProperty ( ) , QRect ( 9 , 7 , 100 , 200 ) ) ;
QCOMPARE ( object - > rectFProperty ( ) , QRectF ( 1000.1 , - 10.9 , 400 , 90.99 ) ) ;
QCOMPARE ( object - > boolProperty ( ) , true ) ;
QCOMPARE ( object - > variantProperty ( ) , QVariant ( " Hello World! " ) ) ;
QCOMPARE ( object - > vectorProperty ( ) , QVector3D ( 10 , 1 , 2.2 ) ) ;
QCOMPARE ( object - > urlProperty ( ) , component . url ( ) . resolved ( QUrl ( " main.qml " ) ) ) ;
delete object ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " assignBasicTypes.2.qml " ) ) ;
MyTypeObject * object = qobject_cast < MyTypeObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > flagProperty ( ) , MyTypeObject : : FlagVal1 | MyTypeObject : : FlagVal3 ) ;
QCOMPARE ( object - > enumProperty ( ) , MyTypeObject : : EnumVal2 ) ;
QCOMPARE ( object - > stringProperty ( ) , QString ( " Hello World! " ) ) ;
QCOMPARE ( object - > uintProperty ( ) , uint ( 10 ) ) ;
QCOMPARE ( object - > intProperty ( ) , - 19 ) ;
QCOMPARE ( ( float ) object - > realProperty ( ) , float ( 23.2 ) ) ;
QCOMPARE ( ( float ) object - > doubleProperty ( ) , float ( - 19.75 ) ) ;
QCOMPARE ( ( float ) object - > floatProperty ( ) , float ( 8.5 ) ) ;
QCOMPARE ( object - > colorProperty ( ) , QColor ( " red " ) ) ;
QCOMPARE ( object - > dateProperty ( ) , QDate ( 1982 , 11 , 25 ) ) ;
QCOMPARE ( object - > timeProperty ( ) , QTime ( 11 , 11 , 32 ) ) ;
QCOMPARE ( object - > dateTimeProperty ( ) , QDateTime ( QDate ( 2009 , 5 , 12 ) , QTime ( 13 , 22 , 1 ) ) ) ;
QCOMPARE ( object - > pointProperty ( ) , QPoint ( 99 , 13 ) ) ;
QCOMPARE ( object - > pointFProperty ( ) , QPointF ( - 10.1 , 12.3 ) ) ;
QCOMPARE ( object - > sizeProperty ( ) , QSize ( 99 , 13 ) ) ;
QCOMPARE ( object - > sizeFProperty ( ) , QSizeF ( 0.1 , 0.2 ) ) ;
QCOMPARE ( object - > rectProperty ( ) , QRect ( 9 , 7 , 100 , 200 ) ) ;
QCOMPARE ( object - > rectFProperty ( ) , QRectF ( 1000.1 , - 10.9 , 400 , 90.99 ) ) ;
QCOMPARE ( object - > boolProperty ( ) , true ) ;
QCOMPARE ( object - > variantProperty ( ) , QVariant ( " Hello World! " ) ) ;
QCOMPARE ( object - > vectorProperty ( ) , QVector3D ( 10 , 1 , 2.2 ) ) ;
QCOMPARE ( object - > urlProperty ( ) , component . url ( ) . resolved ( QUrl ( " main.qml " ) ) ) ;
delete object ;
}
}
void tst_qdeclarativeecmascript : : idShortcutInvalidates ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " idShortcutInvalidates.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( object - > objectProperty ( ) ! = 0 ) ;
delete object - > objectProperty ( ) ;
QVERIFY ( object - > objectProperty ( ) = = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " idShortcutInvalidates.1.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( object - > objectProperty ( ) ! = 0 ) ;
delete object - > objectProperty ( ) ;
QVERIFY ( object - > objectProperty ( ) = = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
}
void tst_qdeclarativeecmascript : : boolPropertiesEvaluateAsBool ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " boolPropertiesEvaluateAsBool.1.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > stringProperty ( ) , QLatin1String ( " pass " ) ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " boolPropertiesEvaluateAsBool.2.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > stringProperty ( ) , QLatin1String ( " pass " ) ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
}
void tst_qdeclarativeecmascript : : signalAssignment ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " signalAssignment.1.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > string ( ) , QString ( ) ) ;
emit object - > basicSignal ( ) ;
QCOMPARE ( object - > string ( ) , QString ( " pass " ) ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " signalAssignment.2.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > string ( ) , QString ( ) ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > string ( ) , QString ( " pass 19 Hello world! 10.25 3 2 " ) ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
}
void tst_qdeclarativeecmascript : : methods ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " methods.1.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > methodCalled ( ) , false ) ;
QCOMPARE ( object - > methodIntCalled ( ) , false ) ;
emit object - > basicSignal ( ) ;
QCOMPARE ( object - > methodCalled ( ) , true ) ;
QCOMPARE ( object - > methodIntCalled ( ) , false ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " methods.2.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > methodCalled ( ) , false ) ;
QCOMPARE ( object - > methodIntCalled ( ) , false ) ;
emit object - > basicSignal ( ) ;
QCOMPARE ( object - > methodCalled ( ) , false ) ;
QCOMPARE ( object - > methodIntCalled ( ) , true ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " methods.3.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 19 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " methods.4.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 19 ) ;
QCOMPARE ( object - > property ( " test2 " ) . toInt ( ) , 17 ) ;
QCOMPARE ( object - > property ( " test3 " ) . toInt ( ) , 16 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " methods.5.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 9 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
}
void tst_qdeclarativeecmascript : : bindingLoop ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " bindingLoop.qml " ) ) ;
QString warning = component . url ( ) . toString ( ) + " :9:9: QML MyQmlObject: Binding loop detected for property \" stringProperty \" " ;
QTest : : ignoreMessage ( QtWarningMsg , warning . toLatin1 ( ) . constData ( ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
void tst_qdeclarativeecmascript : : basicExpressions_data ( )
{
QTest : : addColumn < QString > ( " expression " ) ;
QTest : : addColumn < QVariant > ( " result " ) ;
QTest : : addColumn < bool > ( " nest " ) ;
QTest : : newRow ( " Syntax error (self test) " ) < < " {console.log({'a':1'}.a)} " < < QVariant ( ) < < false ;
QTest : : newRow ( " Context property " ) < < " a " < < QVariant ( 1944 ) < < false ;
QTest : : newRow ( " Context property " ) < < " a " < < QVariant ( 1944 ) < < true ;
QTest : : newRow ( " Context property expression " ) < < " a * 2 " < < QVariant ( 3888 ) < < false ;
QTest : : newRow ( " Context property expression " ) < < " a * 2 " < < QVariant ( 3888 ) < < true ;
QTest : : newRow ( " Overridden context property " ) < < " b " < < QVariant ( " Milk " ) < < false ;
QTest : : newRow ( " Overridden context property " ) < < " b " < < QVariant ( " Cow " ) < < true ;
QTest : : newRow ( " Object property " ) < < " object.stringProperty " < < QVariant ( " Object1 " ) < < false ;
QTest : : newRow ( " Object property " ) < < " object.stringProperty " < < QVariant ( " Object1 " ) < < true ;
QTest : : newRow ( " Overridden object property " ) < < " objectOverride.stringProperty " < < QVariant ( " Object2 " ) < < false ;
QTest : : newRow ( " Overridden object property " ) < < " objectOverride.stringProperty " < < QVariant ( " Object3 " ) < < true ;
QTest : : newRow ( " Default object property " ) < < " horseLegs " < < QVariant ( 4 ) < < false ;
QTest : : newRow ( " Default object property " ) < < " antLegs " < < QVariant ( 6 ) < < false ;
QTest : : newRow ( " Default object property " ) < < " emuLegs " < < QVariant ( 2 ) < < false ;
QTest : : newRow ( " Nested default object property " ) < < " horseLegs " < < QVariant ( 4 ) < < true ;
QTest : : newRow ( " Nested default object property " ) < < " antLegs " < < QVariant ( 7 ) < < true ;
QTest : : newRow ( " Nested default object property " ) < < " emuLegs " < < QVariant ( 2 ) < < true ;
QTest : : newRow ( " Nested default object property " ) < < " humanLegs " < < QVariant ( 2 ) < < true ;
QTest : : newRow ( " Context property override default object property " ) < < " millipedeLegs " < < QVariant ( 100 ) < < true ;
}
void tst_qdeclarativeecmascript : : basicExpressions ( )
{
QFETCH ( QString , expression ) ;
QFETCH ( QVariant , result ) ;
QFETCH ( bool , nest ) ;
MyQmlObject object1 ;
MyQmlObject object2 ;
MyQmlObject object3 ;
MyDefaultObject1 default1 ;
MyDefaultObject3 default3 ;
object1 . setStringProperty ( " Object1 " ) ;
object2 . setStringProperty ( " Object2 " ) ;
object3 . setStringProperty ( " Object3 " ) ;
QDeclarativeContext context ( engine . rootContext ( ) ) ;
QDeclarativeContext nestedContext ( & context ) ;
context . setContextObject ( & default1 ) ;
context . setContextProperty ( " a " , QVariant ( 1944 ) ) ;
context . setContextProperty ( " b " , QVariant ( " Milk " ) ) ;
context . setContextProperty ( " object " , & object1 ) ;
context . setContextProperty ( " objectOverride " , & object2 ) ;
nestedContext . setContextObject ( & default3 ) ;
nestedContext . setContextProperty ( " b " , QVariant ( " Cow " ) ) ;
nestedContext . setContextProperty ( " objectOverride " , & object3 ) ;
nestedContext . setContextProperty ( " millipedeLegs " , QVariant ( 100 ) ) ;
MyExpression expr ( nest ? & nestedContext : & context , expression ) ;
QCOMPARE ( expr . evaluate ( ) , result ) ;
}
void tst_qdeclarativeecmascript : : arrayExpressions ( )
{
QObject obj1 ;
QObject obj2 ;
QObject obj3 ;
QDeclarativeContext context ( engine . rootContext ( ) ) ;
context . setContextProperty ( " a " , & obj1 ) ;
context . setContextProperty ( " b " , & obj2 ) ;
context . setContextProperty ( " c " , & obj3 ) ;
MyExpression expr ( & context , " [a, b, c, 10] " ) ;
QVariant result = expr . evaluate ( ) ;
QCOMPARE ( result . userType ( ) , qMetaTypeId < QList < QObject * > > ( ) ) ;
QList < QObject * > list = qvariant_cast < QList < QObject * > > ( result ) ;
QCOMPARE ( list . count ( ) , 4 ) ;
QCOMPARE ( list . at ( 0 ) , & obj1 ) ;
QCOMPARE ( list . at ( 1 ) , & obj2 ) ;
QCOMPARE ( list . at ( 2 ) , & obj3 ) ;
QCOMPARE ( list . at ( 3 ) , ( QObject * ) 0 ) ;
}
// Tests that modifying a context property will reevaluate expressions
void tst_qdeclarativeecmascript : : contextPropertiesTriggerReeval ( )
{
QDeclarativeContext context ( engine . rootContext ( ) ) ;
MyQmlObject object1 ;
MyQmlObject object2 ;
MyQmlObject * object3 = new MyQmlObject ;
object1 . setStringProperty ( " Hello " ) ;
object2 . setStringProperty ( " World " ) ;
context . setContextProperty ( " testProp " , QVariant ( 1 ) ) ;
context . setContextProperty ( " testObj " , & object1 ) ;
context . setContextProperty ( " testObj2 " , object3 ) ;
{
MyExpression expr ( & context , " testProp + 1 " ) ;
QCOMPARE ( expr . changed , false ) ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( 2 ) ) ;
context . setContextProperty ( " testProp " , QVariant ( 2 ) ) ;
QCOMPARE ( expr . changed , true ) ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( 3 ) ) ;
}
{
MyExpression expr ( & context , " testProp + testProp + testProp " ) ;
QCOMPARE ( expr . changed , false ) ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( 6 ) ) ;
context . setContextProperty ( " testProp " , QVariant ( 4 ) ) ;
QCOMPARE ( expr . changed , true ) ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( 12 ) ) ;
}
{
MyExpression expr ( & context , " testObj.stringProperty " ) ;
QCOMPARE ( expr . changed , false ) ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( " Hello " ) ) ;
context . setContextProperty ( " testObj " , & object2 ) ;
QCOMPARE ( expr . changed , true ) ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( " World " ) ) ;
}
{
MyExpression expr ( & context , " testObj.stringProperty /**/ " ) ;
QCOMPARE ( expr . changed , false ) ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( " World " ) ) ;
context . setContextProperty ( " testObj " , & object1 ) ;
QCOMPARE ( expr . changed , true ) ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( " Hello " ) ) ;
}
{
MyExpression expr ( & context , " testObj2 " ) ;
QCOMPARE ( expr . changed , false ) ;
QCOMPARE ( expr . evaluate ( ) , QVariant : : fromValue ( ( QObject * ) object3 ) ) ;
}
2011-04-27 12:13:26 +00:00
delete object3 ;
2011-04-27 10:05:43 +00:00
}
void tst_qdeclarativeecmascript : : objectPropertiesTriggerReeval ( )
{
QDeclarativeContext context ( engine . rootContext ( ) ) ;
MyQmlObject object1 ;
MyQmlObject object2 ;
MyQmlObject object3 ;
context . setContextProperty ( " testObj " , & object1 ) ;
object1 . setStringProperty ( QLatin1String ( " Hello " ) ) ;
object2 . setStringProperty ( QLatin1String ( " Dog " ) ) ;
object3 . setStringProperty ( QLatin1String ( " Cat " ) ) ;
{
MyExpression expr ( & context , " testObj.stringProperty " ) ;
QCOMPARE ( expr . changed , false ) ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( " Hello " ) ) ;
object1 . setStringProperty ( QLatin1String ( " World " ) ) ;
QCOMPARE ( expr . changed , true ) ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( " World " ) ) ;
}
{
MyExpression expr ( & context , " testObj.objectProperty.stringProperty " ) ;
QCOMPARE ( expr . changed , false ) ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( ) ) ;
object1 . setObjectProperty ( & object2 ) ;
QCOMPARE ( expr . changed , true ) ;
expr . changed = false ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( " Dog " ) ) ;
object1 . setObjectProperty ( & object3 ) ;
QCOMPARE ( expr . changed , true ) ;
expr . changed = false ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( " Cat " ) ) ;
object1 . setObjectProperty ( 0 ) ;
QCOMPARE ( expr . changed , true ) ;
expr . changed = false ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( ) ) ;
object1 . setObjectProperty ( & object3 ) ;
QCOMPARE ( expr . changed , true ) ;
expr . changed = false ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( " Cat " ) ) ;
object3 . setStringProperty ( " Donkey " ) ;
QCOMPARE ( expr . changed , true ) ;
expr . changed = false ;
QCOMPARE ( expr . evaluate ( ) , QVariant ( " Donkey " ) ) ;
}
}
void tst_qdeclarativeecmascript : : deferredProperties ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " deferredProperties.qml " ) ) ;
MyDeferredObject * object =
qobject_cast < MyDeferredObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > value ( ) , 0 ) ;
QVERIFY ( object - > objectProperty ( ) = = 0 ) ;
QVERIFY ( object - > objectProperty2 ( ) ! = 0 ) ;
qmlExecuteDeferred ( object ) ;
QCOMPARE ( object - > value ( ) , 10 ) ;
QVERIFY ( object - > objectProperty ( ) ! = 0 ) ;
MyQmlObject * qmlObject =
qobject_cast < MyQmlObject * > ( object - > objectProperty ( ) ) ;
QVERIFY ( qmlObject ! = 0 ) ;
QCOMPARE ( qmlObject - > value ( ) , 10 ) ;
object - > setValue ( 19 ) ;
QCOMPARE ( qmlObject - > value ( ) , 19 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
// Check errors on deferred properties are correctly emitted
void tst_qdeclarativeecmascript : : deferredPropertiesErrors ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " deferredPropertiesErrors.qml " ) ) ;
MyDeferredObject * object =
qobject_cast < MyDeferredObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > value ( ) , 0 ) ;
QVERIFY ( object - > objectProperty ( ) = = 0 ) ;
QVERIFY ( object - > objectProperty2 ( ) = = 0 ) ;
QString warning = component . url ( ) . toString ( ) + " :6: Unable to assign [undefined] to QObject* objectProperty " ;
QTest : : ignoreMessage ( QtWarningMsg , qPrintable ( warning ) ) ;
qmlExecuteDeferred ( object ) ;
delete object ;
}
void tst_qdeclarativeecmascript : : extensionObjects ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " extensionObjects.qml " ) ) ;
MyExtendedObject * object =
qobject_cast < MyExtendedObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > baseProperty ( ) , 13 ) ;
QCOMPARE ( object - > coreProperty ( ) , 9 ) ;
object - > setProperty ( " extendedProperty " , QVariant ( 11 ) ) ;
object - > setProperty ( " baseExtendedProperty " , QVariant ( 92 ) ) ;
QCOMPARE ( object - > coreProperty ( ) , 11 ) ;
QCOMPARE ( object - > baseProperty ( ) , 92 ) ;
MyExtendedObject * nested = qobject_cast < MyExtendedObject * > ( qvariant_cast < QObject * > ( object - > property ( " nested " ) ) ) ;
QVERIFY ( nested ) ;
QCOMPARE ( nested - > baseProperty ( ) , 13 ) ;
QCOMPARE ( nested - > coreProperty ( ) , 9 ) ;
nested - > setProperty ( " extendedProperty " , QVariant ( 11 ) ) ;
nested - > setProperty ( " baseExtendedProperty " , QVariant ( 92 ) ) ;
QCOMPARE ( nested - > coreProperty ( ) , 11 ) ;
QCOMPARE ( nested - > baseProperty ( ) , 92 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
void tst_qdeclarativeecmascript : : overrideExtensionProperties ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " extensionObjectsPropertyOverride.qml " ) ) ;
OverrideDefaultPropertyObject * object =
qobject_cast < OverrideDefaultPropertyObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( object - > secondProperty ( ) ! = 0 ) ;
QVERIFY ( object - > firstProperty ( ) = = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
void tst_qdeclarativeecmascript : : attachedProperties ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " attachedProperty.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " a " ) . toInt ( ) , 19 ) ;
QCOMPARE ( object - > property ( " b " ) . toInt ( ) , 19 ) ;
QCOMPARE ( object - > property ( " c " ) . toInt ( ) , 19 ) ;
QCOMPARE ( object - > property ( " d " ) . toInt ( ) , 19 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " attachedProperty.2.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " a " ) . toInt ( ) , 26 ) ;
QCOMPARE ( object - > property ( " b " ) . toInt ( ) , 26 ) ;
QCOMPARE ( object - > property ( " c " ) . toInt ( ) , 26 ) ;
QCOMPARE ( object - > property ( " d " ) . toInt ( ) , 26 ) ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " writeAttachedProperty.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QMetaObject : : invokeMethod ( object , " writeValue2 " ) ;
MyQmlAttachedObject * attached =
qobject_cast < MyQmlAttachedObject * > ( qmlAttachedPropertiesObject < MyQmlObject > ( object ) ) ;
QVERIFY ( attached ! = 0 ) ;
QCOMPARE ( attached - > value2 ( ) , 9 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
}
void tst_qdeclarativeecmascript : : enums ( )
{
// Existent enums
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " enums.1.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " a " ) . toInt ( ) , 0 ) ;
QCOMPARE ( object - > property ( " b " ) . toInt ( ) , 1 ) ;
QCOMPARE ( object - > property ( " c " ) . toInt ( ) , 2 ) ;
QCOMPARE ( object - > property ( " d " ) . toInt ( ) , 3 ) ;
QCOMPARE ( object - > property ( " e " ) . toInt ( ) , 0 ) ;
QCOMPARE ( object - > property ( " f " ) . toInt ( ) , 1 ) ;
QCOMPARE ( object - > property ( " g " ) . toInt ( ) , 2 ) ;
QCOMPARE ( object - > property ( " h " ) . toInt ( ) , 3 ) ;
QCOMPARE ( object - > property ( " i " ) . toInt ( ) , 19 ) ;
QCOMPARE ( object - > property ( " j " ) . toInt ( ) , 19 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
// Non-existent enums
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " enums.2.qml " ) ) ;
QString warning1 = component . url ( ) . toString ( ) + " :5: Unable to assign [undefined] to int a " ;
QString warning2 = component . url ( ) . toString ( ) + " :6: Unable to assign [undefined] to int b " ;
QTest : : ignoreMessage ( QtWarningMsg , qPrintable ( warning1 ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , qPrintable ( warning2 ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " a " ) . toInt ( ) , 0 ) ;
QCOMPARE ( object - > property ( " b " ) . toInt ( ) , 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
}
void tst_qdeclarativeecmascript : : valueTypeFunctions ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " valueTypeFunctions.qml " ) ) ;
MyTypeObject * obj = qobject_cast < MyTypeObject * > ( component . create ( ) ) ;
QVERIFY ( obj ! = 0 ) ;
QCOMPARE ( obj - > rectProperty ( ) , QRect ( 0 , 0 , 100 , 100 ) ) ;
QCOMPARE ( obj - > rectFProperty ( ) , QRectF ( 0 , 0.5 , 100 , 99.5 ) ) ;
2011-04-27 12:13:26 +00:00
delete obj ;
2011-04-27 10:05:43 +00:00
}
/*
Tests that writing a constant to a property with a binding on it disables the
binding .
*/
void tst_qdeclarativeecmascript : : constantsOverrideBindings ( )
{
// From ECMAScript
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " constantsOverrideBindings.1.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 0 ) ;
object - > setProperty ( " c1 " , QVariant ( 9 ) ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 9 ) ;
emit object - > basicSignal ( ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 13 ) ;
object - > setProperty ( " c1 " , QVariant ( 8 ) ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 13 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
// During construction
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " constantsOverrideBindings.2.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " c1 " ) . toInt ( ) , 0 ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 10 ) ;
object - > setProperty ( " c1 " , QVariant ( 9 ) ) ;
QCOMPARE ( object - > property ( " c1 " ) . toInt ( ) , 9 ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 10 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
#if 0
// From C++
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " constantsOverrideBindings.3.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 0 ) ;
object - > setProperty ( " c1 " , QVariant ( 9 ) ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 9 ) ;
object - > setProperty ( " c2 " , QVariant ( 13 ) ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 13 ) ;
object - > setProperty ( " c1 " , QVariant ( 7 ) ) ;
QCOMPARE ( object - > property ( " c1 " ) . toInt ( ) , 7 ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 13 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
# endif
// Using an alias
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " constantsOverrideBindings.4.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " c1 " ) . toInt ( ) , 0 ) ;
QCOMPARE ( object - > property ( " c3 " ) . toInt ( ) , 10 ) ;
object - > setProperty ( " c1 " , QVariant ( 9 ) ) ;
QCOMPARE ( object - > property ( " c1 " ) . toInt ( ) , 9 ) ;
QCOMPARE ( object - > property ( " c3 " ) . toInt ( ) , 10 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
}
/*
Tests that assigning a binding to a property that already has a binding causes
the original binding to be disabled .
*/
void tst_qdeclarativeecmascript : : outerBindingOverridesInnerBinding ( )
{
QDeclarativeComponent component ( & engine ,
TEST_FILE ( " outerBindingOverridesInnerBinding.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " c1 " ) . toInt ( ) , 0 ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 0 ) ;
QCOMPARE ( object - > property ( " c3 " ) . toInt ( ) , 0 ) ;
object - > setProperty ( " c1 " , QVariant ( 9 ) ) ;
QCOMPARE ( object - > property ( " c1 " ) . toInt ( ) , 9 ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 0 ) ;
QCOMPARE ( object - > property ( " c3 " ) . toInt ( ) , 0 ) ;
object - > setProperty ( " c3 " , QVariant ( 8 ) ) ;
QCOMPARE ( object - > property ( " c1 " ) . toInt ( ) , 9 ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 8 ) ;
QCOMPARE ( object - > property ( " c3 " ) . toInt ( ) , 8 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
/*
Access a non - existent attached object .
Tests for a regression where this used to crash .
*/
void tst_qdeclarativeecmascript : : nonExistentAttachedObject ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " nonExistentAttachedObject.qml " ) ) ;
QString warning = component . url ( ) . toString ( ) + " :4: Unable to assign [undefined] to QString stringProperty " ;
QTest : : ignoreMessage ( QtWarningMsg , qPrintable ( warning ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
void tst_qdeclarativeecmascript : : scope ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scope.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test1 " ) . toInt ( ) , 1 ) ;
QCOMPARE ( object - > property ( " test2 " ) . toInt ( ) , 2 ) ;
QCOMPARE ( object - > property ( " test3 " ) . toString ( ) , QString ( " 1Test " ) ) ;
QCOMPARE ( object - > property ( " test4 " ) . toString ( ) , QString ( " 2Test " ) ) ;
QCOMPARE ( object - > property ( " test5 " ) . toInt ( ) , 1 ) ;
QCOMPARE ( object - > property ( " test6 " ) . toInt ( ) , 1 ) ;
QCOMPARE ( object - > property ( " test7 " ) . toInt ( ) , 2 ) ;
QCOMPARE ( object - > property ( " test8 " ) . toInt ( ) , 2 ) ;
QCOMPARE ( object - > property ( " test9 " ) . toInt ( ) , 1 ) ;
QCOMPARE ( object - > property ( " test10 " ) . toInt ( ) , 3 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scope.2.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test1 " ) . toInt ( ) , 19 ) ;
QCOMPARE ( object - > property ( " test2 " ) . toInt ( ) , 19 ) ;
QCOMPARE ( object - > property ( " test3 " ) . toInt ( ) , 14 ) ;
QCOMPARE ( object - > property ( " test4 " ) . toInt ( ) , 14 ) ;
QCOMPARE ( object - > property ( " test5 " ) . toInt ( ) , 24 ) ;
QCOMPARE ( object - > property ( " test6 " ) . toInt ( ) , 24 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scope.3.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test2 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test3 " ) . toBool ( ) , true ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
// Signal argument scope
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scope.4.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 0 ) ;
QCOMPARE ( object - > property ( " test2 " ) . toString ( ) , QString ( ) ) ;
emit object - > argumentSignal ( 13 , " Argument Scope " , 9 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 13 ) ;
QCOMPARE ( object - > property ( " test2 " ) . toString ( ) , QString ( " Argument Scope " ) ) ;
delete object ;
}
2011-04-27 12:13:26 +00:00
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scope.5.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test2 " ) . toBool ( ) , true ) ;
delete object ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scope.6.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toBool ( ) , true ) ;
delete object ;
}
2011-04-27 10:05:43 +00:00
}
/*
Tests that " any " type passes through a synthesized signal parameter . This
is essentially a test of QDeclarativeMetaType : : copy ( )
*/
void tst_qdeclarativeecmascript : : signalParameterTypes ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " signalParameterTypes.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
emit object - > basicSignal ( ) ;
QCOMPARE ( object - > property ( " intProperty " ) . toInt ( ) , 10 ) ;
QCOMPARE ( object - > property ( " realProperty " ) . toReal ( ) , 19.2 ) ;
QVERIFY ( object - > property ( " colorProperty " ) . value < QColor > ( ) = = QColor ( 255 , 255 , 0 , 255 ) ) ;
QVERIFY ( object - > property ( " variantProperty " ) = = QVariant : : fromValue ( QColor ( 255 , 0 , 255 , 255 ) ) ) ;
QVERIFY ( object - > property ( " enumProperty " ) = = MyQmlObject : : EnumValue3 ) ;
QVERIFY ( object - > property ( " qtEnumProperty " ) = = Qt : : LeftButton ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
/*
Test that two JS objects for the same QObject compare as equal .
*/
void tst_qdeclarativeecmascript : : objectsCompareAsEqual ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " objectsCompareAsEqual.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test2 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test3 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test4 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test5 " ) . toBool ( ) , true ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
/*
Confirm bindings and alias properties can coexist .
Tests for a regression where the binding would not reevaluate .
*/
void tst_qdeclarativeecmascript : : aliasPropertyAndBinding ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " aliasPropertyAndBinding.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 3 ) ;
QCOMPARE ( object - > property ( " c3 " ) . toInt ( ) , 3 ) ;
object - > setProperty ( " c2 " , QVariant ( 19 ) ) ;
QCOMPARE ( object - > property ( " c2 " ) . toInt ( ) , 19 ) ;
QCOMPARE ( object - > property ( " c3 " ) . toInt ( ) , 19 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
void tst_qdeclarativeecmascript : : dynamicCreation_data ( )
{
QTest : : addColumn < QString > ( " method " ) ;
QTest : : addColumn < QString > ( " createdName " ) ;
QTest : : newRow ( " One " ) < < " createOne " < < " objectOne " ;
QTest : : newRow ( " Two " ) < < " createTwo " < < " objectTwo " ;
QTest : : newRow ( " Three " ) < < " createThree " < < " objectThree " ;
}
/*
Test using createQmlObject to dynamically generate an item
Also using createComponent is tested .
*/
void tst_qdeclarativeecmascript : : dynamicCreation ( )
{
QFETCH ( QString , method ) ;
QFETCH ( QString , createdName ) ;
QDeclarativeComponent component ( & engine , TEST_FILE ( " dynamicCreation.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QMetaObject : : invokeMethod ( object , method . toUtf8 ( ) ) ;
QObject * created = object - > objectProperty ( ) ;
QVERIFY ( created ) ;
QCOMPARE ( created - > objectName ( ) , createdName ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
/*
Tests the destroy function
*/
void tst_qdeclarativeecmascript : : dynamicDestruction ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " dynamicDeletion.qml " ) ) ;
QDeclarativeGuard < MyQmlObject > object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QDeclarativeGuard < QObject > createdQmlObject = 0 ;
QMetaObject : : invokeMethod ( object , " create " ) ;
createdQmlObject = object - > objectProperty ( ) ;
QVERIFY ( createdQmlObject ) ;
QCOMPARE ( createdQmlObject - > objectName ( ) , QString ( " emptyObject " ) ) ;
QMetaObject : : invokeMethod ( object , " killOther " ) ;
QVERIFY ( createdQmlObject ) ;
QCoreApplication : : instance ( ) - > processEvents ( QEventLoop : : DeferredDeletion ) ;
QVERIFY ( createdQmlObject ) ;
for ( int ii = 0 ; createdQmlObject & & ii < 50 ; + + ii ) { // After 5 seconds we should give up
if ( createdQmlObject ) {
QTest : : qWait ( 100 ) ;
QCoreApplication : : instance ( ) - > processEvents ( QEventLoop : : DeferredDeletion ) ;
}
}
QVERIFY ( ! createdQmlObject ) ;
QDeclarativeEngine : : setObjectOwnership ( object , QDeclarativeEngine : : JavaScriptOwnership ) ;
QMetaObject : : invokeMethod ( object , " killMe " ) ;
QVERIFY ( object ) ;
QTest : : qWait ( 0 ) ;
QCoreApplication : : instance ( ) - > processEvents ( QEventLoop : : DeferredDeletion ) ;
QVERIFY ( ! object ) ;
}
/*
tests that id . toString ( ) works
*/
void tst_qdeclarativeecmascript : : objectToString ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " declarativeToString.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QMetaObject : : invokeMethod ( object , " testToString " ) ;
QVERIFY ( object - > stringProperty ( ) . startsWith ( " MyQmlObject_QML_ " ) ) ;
QVERIFY ( object - > stringProperty ( ) . endsWith ( " , \" objName \" ) " ) ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
/*
Tests bindings that indirectly cause their own deletion work .
This test is best run under valgrind to ensure no invalid memory access occur .
*/
void tst_qdeclarativeecmascript : : selfDeletingBinding ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " selfDeletingBinding.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
object - > setProperty ( " triggerDelete " , true ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " selfDeletingBinding.2.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
object - > setProperty ( " triggerDelete " , true ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
}
/*
Test that extended object properties can be accessed .
This test a regression where this used to crash . The issue was specificially
for extended objects that did not include a synthesized meta object ( so non - root
and no synthesiszed properties ) .
*/
void tst_qdeclarativeecmascript : : extendedObjectPropertyLookup ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " extendedObjectPropertyLookup.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
/*
Test file / lineNumbers for binding / Script errors .
*/
void tst_qdeclarativeecmascript : : scriptErrors ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scriptErrors.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
QString warning1 = url . left ( url . length ( ) - 3 ) + " js:2: Error: Invalid write to global property \" a \" " ;
QString warning2 = url + " :5: ReferenceError: Can't find variable: a " ;
QString warning3 = url . left ( url . length ( ) - 3 ) + " js:4: Error: Invalid write to global property \" a \" " ;
QString warning4 = url + " :10: ReferenceError: Can't find variable: a " ;
QString warning5 = url + " :8: ReferenceError: Can't find variable: a " ;
QString warning6 = url + " :7: Unable to assign [undefined] to int x " ;
QString warning7 = url + " :12: Error: Cannot assign to read-only property \" trueProperty \" " ;
QString warning8 = url + " :13: Error: Cannot assign to non-existent property \" fakeProperty \" " ;
QTest : : ignoreMessage ( QtWarningMsg , warning1 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning2 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning3 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning5 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning6 . toLatin1 ( ) . constData ( ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning4 . toLatin1 ( ) . constData ( ) ) ;
emit object - > basicSignal ( ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning7 . toLatin1 ( ) . constData ( ) ) ;
emit object - > anotherBasicSignal ( ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning8 . toLatin1 ( ) . constData ( ) ) ;
emit object - > thirdBasicSignal ( ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
/*
Test file / lineNumbers for inline functions .
*/
void tst_qdeclarativeecmascript : : functionErrors ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " functionErrors.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
QString warning = url + " :5: Error: Invalid write to global property \" a \" " ;
QTest : : ignoreMessage ( QtWarningMsg , warning . toLatin1 ( ) . constData ( ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
delete object ;
2011-04-27 12:13:26 +00:00
// test that if an exception occurs while invoking js function from cpp, it is reported as expected.
QDeclarativeComponent componentTwo ( & engine , TEST_FILE ( " scarceresources/scarceResourceFunctionFail.qml " ) ) ;
url = componentTwo . url ( ) . toString ( ) ;
object = componentTwo . create ( ) ;
QVERIFY ( object ! = 0 ) ;
warning = url + QLatin1String ( " :16: TypeError: Result of expression 'scarceResourceProvider.scarceResource' [[object Object]] is not a function. " ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning . toLatin1 ( ) . constData ( ) ) ; // we expect a meaningful warning to be printed.
QMetaObject : : invokeMethod ( object , " retrieveScarceResource " ) ;
delete object ;
2011-04-27 10:05:43 +00:00
}
/*
Test various errors that can occur when assigning a property from script
*/
void tst_qdeclarativeecmascript : : propertyAssignmentErrors ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " propertyAssignmentErrors.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
QString warning1 = url + " :11:Error: Cannot assign [undefined] to int " ;
QString warning2 = url + " :17:Error: Cannot assign QString to int " ;
QTest : : ignoreMessage ( QtDebugMsg , warning1 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtDebugMsg , warning2 . toLatin1 ( ) . constData ( ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
delete object ;
}
/*
Test bindings still work when the reeval is triggered from within
a signal script .
*/
void tst_qdeclarativeecmascript : : signalTriggeredBindings ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " signalTriggeredBindings.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " base " ) . toReal ( ) , 50. ) ;
QCOMPARE ( object - > property ( " test1 " ) . toReal ( ) , 50. ) ;
QCOMPARE ( object - > property ( " test2 " ) . toReal ( ) , 50. ) ;
object - > basicSignal ( ) ;
QCOMPARE ( object - > property ( " base " ) . toReal ( ) , 200. ) ;
QCOMPARE ( object - > property ( " test1 " ) . toReal ( ) , 200. ) ;
QCOMPARE ( object - > property ( " test2 " ) . toReal ( ) , 200. ) ;
object - > argumentSignal ( 10 , QString ( ) , 10 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " base " ) . toReal ( ) , 400. ) ;
QCOMPARE ( object - > property ( " test1 " ) . toReal ( ) , 400. ) ;
QCOMPARE ( object - > property ( " test2 " ) . toReal ( ) , 400. ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
/*
Test that list properties can be iterated from ECMAScript
*/
void tst_qdeclarativeecmascript : : listProperties ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " listProperties.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test1 " ) . toInt ( ) , 21 ) ;
QCOMPARE ( object - > property ( " test2 " ) . toInt ( ) , 2 ) ;
QCOMPARE ( object - > property ( " test3 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test4 " ) . toBool ( ) , true ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
void tst_qdeclarativeecmascript : : exceptionClearsOnReeval ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " exceptionClearsOnReeval.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
QString warning = url + " :4: TypeError: Result of expression 'objectProperty' [null] is not an object. " ;
QTest : : ignoreMessage ( QtWarningMsg , warning . toLatin1 ( ) . constData ( ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toBool ( ) , false ) ;
MyQmlObject object2 ;
MyQmlObject object3 ;
object2 . setObjectProperty ( & object3 ) ;
object - > setObjectProperty ( & object2 ) ;
QCOMPARE ( object - > property ( " test " ) . toBool ( ) , true ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
void tst_qdeclarativeecmascript : : exceptionSlotProducesWarning ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " exceptionProducesWarning.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
QString warning = component . url ( ) . toString ( ) + " :6: Error: JS exception " ;
QTest : : ignoreMessage ( QtWarningMsg , warning . toLatin1 ( ) . constData ( ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
void tst_qdeclarativeecmascript : : exceptionBindingProducesWarning ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " exceptionProducesWarning2.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
QString warning = component . url ( ) . toString ( ) + " :5: Error: JS exception " ;
QTest : : ignoreMessage ( QtWarningMsg , warning . toLatin1 ( ) . constData ( ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
static int transientErrorsMsgCount = 0 ;
static void transientErrorsMsgHandler ( QtMsgType , const char * )
{
+ + transientErrorsMsgCount ;
}
// Check that transient binding errors are not displayed
void tst_qdeclarativeecmascript : : transientErrors ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " transientErrors.qml " ) ) ;
transientErrorsMsgCount = 0 ;
QtMsgHandler old = qInstallMsgHandler ( transientErrorsMsgHandler ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
qInstallMsgHandler ( old ) ;
QCOMPARE ( transientErrorsMsgCount , 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
// One binding erroring multiple times, but then resolving
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " transientErrors.2.qml " ) ) ;
transientErrorsMsgCount = 0 ;
QtMsgHandler old = qInstallMsgHandler ( transientErrorsMsgHandler ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
qInstallMsgHandler ( old ) ;
QCOMPARE ( transientErrorsMsgCount , 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
}
// Check that errors during shutdown are minimized
void tst_qdeclarativeecmascript : : shutdownErrors ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " shutdownErrors.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
transientErrorsMsgCount = 0 ;
QtMsgHandler old = qInstallMsgHandler ( transientErrorsMsgHandler ) ;
delete object ;
qInstallMsgHandler ( old ) ;
QCOMPARE ( transientErrorsMsgCount , 0 ) ;
}
void tst_qdeclarativeecmascript : : compositePropertyType ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " compositePropertyType.qml " ) ) ;
QTest : : ignoreMessage ( QtDebugMsg , " hello world " ) ;
QObject * object = qobject_cast < QObject * > ( component . create ( ) ) ;
delete object ;
}
// QTBUG-5759
void tst_qdeclarativeecmascript : : jsObject ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " jsObject.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 92 ) ;
delete object ;
}
void tst_qdeclarativeecmascript : : undefinedResetsProperty ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " undefinedResetsProperty.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " resettableProperty " ) . toInt ( ) , 92 ) ;
object - > setProperty ( " setUndefined " , true ) ;
QCOMPARE ( object - > property ( " resettableProperty " ) . toInt ( ) , 13 ) ;
object - > setProperty ( " setUndefined " , false ) ;
QCOMPARE ( object - > property ( " resettableProperty " ) . toInt ( ) , 92 ) ;
delete object ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " undefinedResetsProperty.2.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " resettableProperty " ) . toInt ( ) , 19 ) ;
QMetaObject : : invokeMethod ( object , " doReset " ) ;
QCOMPARE ( object - > property ( " resettableProperty " ) . toInt ( ) , 13 ) ;
delete object ;
}
}
// QTBUG-6781
void tst_qdeclarativeecmascript : : bug1 ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " bug.1.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 14 ) ;
object - > setProperty ( " a " , 11 ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 3 ) ;
object - > setProperty ( " b " , true ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 9 ) ;
delete object ;
}
void tst_qdeclarativeecmascript : : bug2 ( )
{
QDeclarativeComponent component ( & engine ) ;
component . setData ( " import Qt.test 1.0; \n QPlainTextEdit { width: 100 } " , QUrl ( ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
delete object ;
}
// Don't crash in createObject when the component has errors.
void tst_qdeclarativeecmascript : : dynamicCreationCrash ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " dynamicCreation.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QTest : : ignoreMessage ( QtWarningMsg , " QDeclarativeComponent: Component is not ready " ) ;
QMetaObject : : invokeMethod ( object , " dontCrash " ) ;
QObject * created = object - > objectProperty ( ) ;
QVERIFY ( created = = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
//QTBUG-9367
void tst_qdeclarativeecmascript : : regExpBug ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " regExp.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > regExp ( ) . pattern ( ) , QLatin1String ( " [a-zA-z] " ) ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
void tst_qdeclarativeecmascript : : callQtInvokables ( )
{
MyInvokableObject o ;
QDeclarativeEngine qmlengine ;
QDeclarativeEnginePrivate * ep = QDeclarativeEnginePrivate : : get ( & qmlengine ) ;
QScriptEngine * engine = & ep - > scriptEngine ;
QStringList names ; QList < QScriptValue > values ;
names < < QLatin1String ( " object " ) ; values < < ep - > objectClass - > newQObject ( & o ) ;
names < < QLatin1String ( " undefined " ) ; values < < engine - > undefinedValue ( ) ;
ep - > globalClass - > explicitSetProperty ( names , values ) ;
// Non-existent methods
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_nonexistent() " ) . isError ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , - 1 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_nonexistent(10, 11) " ) . isError ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , - 1 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
// Insufficient arguments
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_int() " ) . isError ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , - 1 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_intint(10) " ) . isError ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , - 1 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
// Excessive arguments
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_int(10, 11) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 8 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 10 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_intint(10, 11, 12) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 9 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 2 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 10 ) ) ;
QCOMPARE ( o . actuals ( ) . at ( 1 ) , QVariant ( 11 ) ) ;
// Test return types
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_NoArgs() " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 0 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
o . reset ( ) ;
QVERIFY ( engine - > evaluate ( " object.method_NoArgs_int() " ) . strictlyEquals ( QScriptValue ( engine , 6 ) ) ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
o . reset ( ) ;
QVERIFY ( engine - > evaluate ( " object.method_NoArgs_real() " ) . strictlyEquals ( QScriptValue ( engine , 19.75 ) ) ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 2 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
o . reset ( ) ;
{
QScriptValue ret = engine - > evaluate ( " object.method_NoArgs_QPointF() " ) ;
QCOMPARE ( ret . toVariant ( ) , QVariant ( QPointF ( 123 , 4.5 ) ) ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 3 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
}
o . reset ( ) ;
{
QScriptValue ret = engine - > evaluate ( " object.method_NoArgs_QObject() " ) ;
QVERIFY ( ret . isQObject ( ) ) ;
QCOMPARE ( ret . toQObject ( ) , ( QObject * ) & o ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 4 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
}
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_NoArgs_unknown() " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 5 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
o . reset ( ) ;
{
QScriptValue ret = engine - > evaluate ( " object.method_NoArgs_QScriptValue() " ) ;
QVERIFY ( ret . isString ( ) ) ;
QCOMPARE ( ret . toString ( ) , QString ( " Hello world " ) ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 6 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
}
o . reset ( ) ;
QVERIFY ( engine - > evaluate ( " object.method_NoArgs_QVariant() " ) . strictlyEquals ( QScriptValue ( engine , " QML rocks " ) ) ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 7 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
// Test arg types
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_int(94) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 8 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 94 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_int( \" 94 \" ) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 8 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 94 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_int( \" not a number \" ) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 8 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 0 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_int(null) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 8 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 0 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_int(undefined) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 8 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 0 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_int(object) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 8 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 0 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_intint(122, 9) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 9 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 2 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 122 ) ) ;
QCOMPARE ( o . actuals ( ) . at ( 1 ) , QVariant ( 9 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_real(94.3) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 10 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 94.3 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_real( \" 94.3 \" ) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 10 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 94.3 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_real( \" not a number \" ) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 10 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QVERIFY ( qIsNaN ( o . actuals ( ) . at ( 0 ) . toDouble ( ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_real(null) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 10 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 0 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_real(undefined) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 10 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QVERIFY ( qIsNaN ( o . actuals ( ) . at ( 0 ) . toDouble ( ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_real(object) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 10 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QVERIFY ( qIsNaN ( o . actuals ( ) . at ( 0 ) . toDouble ( ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QString( \" Hello world \" ) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 11 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( " Hello world " ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QString(19) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 11 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( " 19 " ) ) ;
o . reset ( ) ;
{
QString expected = " MyInvokableObject(0x " + QString : : number ( ( quintptr ) & o , 16 ) + " ) " ;
QCOMPARE ( engine - > evaluate ( " object.method_QString(object) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 11 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( expected ) ) ;
}
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QString(null) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 11 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( QString ( ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QString(undefined) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 11 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( QString ( ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QPointF(0) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 12 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( QPointF ( ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QPointF(null) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 12 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( QPointF ( ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QPointF(undefined) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 12 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( QPointF ( ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QPointF(object) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 12 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( QPointF ( ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QPointF(object.method_get_QPointF()) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 12 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( QPointF ( 99.3 , - 10.2 ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QPointF(object.method_get_QPoint()) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 12 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( QPointF ( 9 , 12 ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QObject(0) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 13 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , qVariantFromValue ( ( QObject * ) 0 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QObject( \" Hello world \" ) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 13 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , qVariantFromValue ( ( QObject * ) 0 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QObject(null) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 13 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , qVariantFromValue ( ( QObject * ) 0 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QObject(undefined) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 13 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , qVariantFromValue ( ( QObject * ) 0 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QObject(object) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 13 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , qVariantFromValue ( ( QObject * ) & o ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QScriptValue(null) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 14 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QVERIFY ( qvariant_cast < QScriptValue > ( o . actuals ( ) . at ( 0 ) ) . isNull ( ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QScriptValue(undefined) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 14 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QVERIFY ( qvariant_cast < QScriptValue > ( o . actuals ( ) . at ( 0 ) ) . isUndefined ( ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QScriptValue(19) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 14 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QVERIFY ( qvariant_cast < QScriptValue > ( o . actuals ( ) . at ( 0 ) ) . strictlyEquals ( QScriptValue ( engine , 19 ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QScriptValue([19, 20]) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 14 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QVERIFY ( qvariant_cast < QScriptValue > ( o . actuals ( ) . at ( 0 ) ) . isArray ( ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_intQScriptValue(4, null) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 15 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 2 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 4 ) ) ;
QVERIFY ( qvariant_cast < QScriptValue > ( o . actuals ( ) . at ( 1 ) ) . isNull ( ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_intQScriptValue(8, undefined) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 15 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 2 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 8 ) ) ;
QVERIFY ( qvariant_cast < QScriptValue > ( o . actuals ( ) . at ( 1 ) ) . isUndefined ( ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_intQScriptValue(3, 19) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 15 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 2 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 3 ) ) ;
QVERIFY ( qvariant_cast < QScriptValue > ( o . actuals ( ) . at ( 1 ) ) . strictlyEquals ( QScriptValue ( engine , 19 ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_intQScriptValue(44, [19, 20]) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 15 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 2 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 44 ) ) ;
QVERIFY ( qvariant_cast < QScriptValue > ( o . actuals ( ) . at ( 1 ) ) . isArray ( ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_overload() " ) . isError ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , - 1 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 0 ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_overload(10) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 16 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 10 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_overload(10, 11) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 17 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 2 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 10 ) ) ;
QCOMPARE ( o . actuals ( ) . at ( 1 ) , QVariant ( 11 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_overload( \" Hello \" ) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 18 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( QString ( " Hello " ) ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_with_enum(9) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 19 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 9 ) ) ;
o . reset ( ) ;
QVERIFY ( engine - > evaluate ( " object.method_default(10) " ) . strictlyEquals ( QScriptValue ( 19 ) ) ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 20 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 2 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 10 ) ) ;
QCOMPARE ( o . actuals ( ) . at ( 1 ) , QVariant ( 19 ) ) ;
o . reset ( ) ;
QVERIFY ( engine - > evaluate ( " object.method_default(10, 13) " ) . strictlyEquals ( QScriptValue ( 13 ) ) ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 20 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 2 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 10 ) ) ;
QCOMPARE ( o . actuals ( ) . at ( 1 ) , QVariant ( 13 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_inherited(9) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , - 3 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 1 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 9 ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QVariant(9) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 21 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 2 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( 9 ) ) ;
QCOMPARE ( o . actuals ( ) . at ( 1 ) , QVariant ( ) ) ;
o . reset ( ) ;
QCOMPARE ( engine - > evaluate ( " object.method_QVariant( \" Hello \" , \" World \" ) " ) . isUndefined ( ) , true ) ;
QCOMPARE ( o . error ( ) , false ) ;
QCOMPARE ( o . invoked ( ) , 21 ) ;
QCOMPARE ( o . actuals ( ) . count ( ) , 2 ) ;
QCOMPARE ( o . actuals ( ) . at ( 0 ) , QVariant ( QString ( " Hello " ) ) ) ;
QCOMPARE ( o . actuals ( ) . at ( 1 ) , QVariant ( QString ( " World " ) ) ) ;
}
// QTBUG-13047 (check that you can pass registered object types as args)
void tst_qdeclarativeecmascript : : invokableObjectArg ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " invokableObjectArg.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ) ;
MyQmlObject * qmlobject = qobject_cast < MyQmlObject * > ( o ) ;
QVERIFY ( qmlobject ) ;
QCOMPARE ( qmlobject - > myinvokableObject , qmlobject ) ;
delete o ;
}
// QTBUG-13047 (check that you can return registered object types from methods)
void tst_qdeclarativeecmascript : : invokableObjectRet ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " invokableObjectRet.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ) ;
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
delete o ;
}
// QTBUG-5675
void tst_qdeclarativeecmascript : : listToVariant ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " listToVariant.qml " ) ) ;
MyQmlContainer container ;
QDeclarativeContext context ( engine . rootContext ( ) ) ;
context . setContextObject ( & container ) ;
QObject * object = component . create ( & context ) ;
QVERIFY ( object ! = 0 ) ;
QVariant v = object - > property ( " test " ) ;
QCOMPARE ( v . userType ( ) , qMetaTypeId < QDeclarativeListReference > ( ) ) ;
QVERIFY ( qvariant_cast < QDeclarativeListReference > ( v ) . object ( ) = = & container ) ;
delete object ;
}
// QTBUG-7957
void tst_qdeclarativeecmascript : : multiEngineObject ( )
{
MyQmlObject obj ;
obj . setStringProperty ( " Howdy planet " ) ;
QDeclarativeEngine e1 ;
e1 . rootContext ( ) - > setContextProperty ( " thing " , & obj ) ;
QDeclarativeComponent c1 ( & e1 , TEST_FILE ( " multiEngineObject.qml " ) ) ;
QDeclarativeEngine e2 ;
e2 . rootContext ( ) - > setContextProperty ( " thing " , & obj ) ;
QDeclarativeComponent c2 ( & e2 , TEST_FILE ( " multiEngineObject.qml " ) ) ;
QObject * o1 = c1 . create ( ) ;
QObject * o2 = c2 . create ( ) ;
QCOMPARE ( o1 - > property ( " test " ) . toString ( ) , QString ( " Howdy planet " ) ) ;
QCOMPARE ( o2 - > property ( " test " ) . toString ( ) , QString ( " Howdy planet " ) ) ;
delete o2 ;
delete o1 ;
}
// Test that references to QObjects are cleanup when the object is destroyed
void tst_qdeclarativeecmascript : : deletedObject ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " deletedObject.qml " ) ) ;
QObject * object = component . create ( ) ;
QCOMPARE ( object - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test2 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test3 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test4 " ) . toBool ( ) , true ) ;
delete object ;
}
void tst_qdeclarativeecmascript : : attachedPropertyScope ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " attachedPropertyScope.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
MyQmlAttachedObject * attached =
qobject_cast < MyQmlAttachedObject * > ( qmlAttachedPropertiesObject < MyQmlObject > ( object ) ) ;
QVERIFY ( attached ! = 0 ) ;
QCOMPARE ( object - > property ( " value2 " ) . toInt ( ) , 0 ) ;
attached - > emitMySignal ( ) ;
QCOMPARE ( object - > property ( " value2 " ) . toInt ( ) , 9 ) ;
delete object ;
}
void tst_qdeclarativeecmascript : : scriptConnect ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scriptConnect.1.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toBool ( ) , false ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toBool ( ) , true ) ;
delete object ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scriptConnect.2.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toBool ( ) , false ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toBool ( ) , true ) ;
delete object ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scriptConnect.3.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toBool ( ) , false ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toBool ( ) , true ) ;
delete object ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scriptConnect.4.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > methodCalled ( ) , false ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > methodCalled ( ) , true ) ;
delete object ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scriptConnect.5.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > methodCalled ( ) , false ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > methodCalled ( ) , true ) ;
delete object ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scriptConnect.6.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 0 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 2 ) ;
delete object ;
}
}
void tst_qdeclarativeecmascript : : scriptDisconnect ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scriptDisconnect.1.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 0 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 1 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 2 ) ;
emit object - > basicSignal ( ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 2 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 2 ) ;
delete object ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scriptDisconnect.2.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 0 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 1 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 2 ) ;
emit object - > basicSignal ( ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 2 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 2 ) ;
delete object ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scriptDisconnect.3.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 0 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 1 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 2 ) ;
emit object - > basicSignal ( ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 2 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 3 ) ;
delete object ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " scriptDisconnect.4.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 0 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 1 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 2 ) ;
emit object - > basicSignal ( ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 2 ) ;
emit object - > argumentSignal ( 19 , " Hello world! " , 10.25 , MyQmlObject : : EnumValue4 , Qt : : RightButton ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 3 ) ;
delete object ;
}
}
class OwnershipObject : public QObject
{
Q_OBJECT
public :
OwnershipObject ( ) { object = new QObject ; }
QPointer < QObject > object ;
public slots :
QObject * getObject ( ) { return object ; }
} ;
void tst_qdeclarativeecmascript : : ownership ( )
{
OwnershipObject own ;
QDeclarativeContext * context = new QDeclarativeContext ( engine . rootContext ( ) ) ;
context - > setContextObject ( & own ) ;
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " ownership.qml " ) ) ;
QVERIFY ( own . object ! = 0 ) ;
QObject * object = component . create ( context ) ;
QDeclarativeEnginePrivate : : getScriptEngine ( & engine ) - > collectGarbage ( ) ;
QCoreApplication : : processEvents ( QEventLoop : : DeferredDeletion ) ;
QVERIFY ( own . object = = 0 ) ;
delete object ;
}
own . object = new QObject ( & own ) ;
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " ownership.qml " ) ) ;
QVERIFY ( own . object ! = 0 ) ;
QObject * object = component . create ( context ) ;
QDeclarativeEnginePrivate : : getScriptEngine ( & engine ) - > collectGarbage ( ) ;
QCoreApplication : : processEvents ( QEventLoop : : DeferredDeletion ) ;
QVERIFY ( own . object ! = 0 ) ;
delete object ;
}
2011-04-27 12:13:26 +00:00
delete context ;
2011-04-27 10:05:43 +00:00
}
class CppOwnershipReturnValue : public QObject
{
Q_OBJECT
public :
CppOwnershipReturnValue ( ) : value ( 0 ) { }
~ CppOwnershipReturnValue ( ) { delete value ; }
Q_INVOKABLE QObject * create ( ) {
value = new QObject ;
QDeclarativeEngine : : setObjectOwnership ( value , QDeclarativeEngine : : CppOwnership ) ;
return value ;
}
Q_INVOKABLE MyQmlObject * createQmlObject ( ) {
MyQmlObject * rv = new MyQmlObject ;
value = rv ;
return rv ;
}
QPointer < QObject > value ;
} ;
// QTBUG-15695.
// Test setObjectOwnership(CppOwnership) works even when there is no QDeclarativeData
void tst_qdeclarativeecmascript : : cppOwnershipReturnValue ( )
{
CppOwnershipReturnValue source ;
{
QDeclarativeEngine engine ;
engine . rootContext ( ) - > setContextProperty ( " source " , & source ) ;
QVERIFY ( source . value = = 0 ) ;
QDeclarativeComponent component ( & engine ) ;
component . setData ( " import QtQuick 1.0 \n QtObject { \n Component.onCompleted: { var a = source.create(); } \n } \n " , QUrl ( ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( source . value ! = 0 ) ;
delete object ;
}
QCoreApplication : : instance ( ) - > processEvents ( QEventLoop : : DeferredDeletion ) ;
QVERIFY ( source . value ! = 0 ) ;
}
// QTBUG-15697
void tst_qdeclarativeecmascript : : ownershipCustomReturnValue ( )
{
CppOwnershipReturnValue source ;
{
QDeclarativeEngine engine ;
engine . rootContext ( ) - > setContextProperty ( " source " , & source ) ;
QVERIFY ( source . value = = 0 ) ;
QDeclarativeComponent component ( & engine ) ;
component . setData ( " import QtQuick 1.0 \n QtObject { \n Component.onCompleted: { var a = source.createQmlObject(); } \n } \n " , QUrl ( ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( source . value ! = 0 ) ;
delete object ;
}
QCoreApplication : : instance ( ) - > processEvents ( QEventLoop : : DeferredDeletion ) ;
QVERIFY ( source . value = = 0 ) ;
}
class QListQObjectMethodsObject : public QObject
{
Q_OBJECT
public :
QListQObjectMethodsObject ( ) {
m_objects . append ( new MyQmlObject ( ) ) ;
m_objects . append ( new MyQmlObject ( ) ) ;
}
~ QListQObjectMethodsObject ( ) {
qDeleteAll ( m_objects ) ;
}
public slots :
QList < QObject * > getObjects ( ) { return m_objects ; }
private :
QList < QObject * > m_objects ;
} ;
// Tests that returning a QList<QObject*> from a method works
void tst_qdeclarativeecmascript : : qlistqobjectMethods ( )
{
QListQObjectMethodsObject obj ;
QDeclarativeContext * context = new QDeclarativeContext ( engine . rootContext ( ) ) ;
context - > setContextObject ( & obj ) ;
QDeclarativeComponent component ( & engine , TEST_FILE ( " qlistqobjectMethods.qml " ) ) ;
QObject * object = component . create ( context ) ;
QCOMPARE ( object - > property ( " test " ) . toInt ( ) , 2 ) ;
QCOMPARE ( object - > property ( " test2 " ) . toBool ( ) , true ) ;
delete object ;
2011-04-27 12:13:26 +00:00
delete context ;
2011-04-27 10:05:43 +00:00
}
// QTBUG-9205
void tst_qdeclarativeecmascript : : strictlyEquals ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " strictlyEquals.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test2 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test3 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test4 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test5 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test6 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test7 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test8 " ) . toBool ( ) , true ) ;
delete object ;
}
void tst_qdeclarativeecmascript : : compiled ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " compiled.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test1 " ) . toReal ( ) , qreal ( 15.7 ) ) ;
QCOMPARE ( object - > property ( " test2 " ) . toReal ( ) , qreal ( - 6.7 ) ) ;
QCOMPARE ( object - > property ( " test3 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test4 " ) . toBool ( ) , false ) ;
QCOMPARE ( object - > property ( " test5 " ) . toBool ( ) , false ) ;
QCOMPARE ( object - > property ( " test6 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test7 " ) . toInt ( ) , 185 ) ;
QCOMPARE ( object - > property ( " test8 " ) . toInt ( ) , 167 ) ;
QCOMPARE ( object - > property ( " test9 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test10 " ) . toBool ( ) , false ) ;
QCOMPARE ( object - > property ( " test11 " ) . toBool ( ) , false ) ;
QCOMPARE ( object - > property ( " test12 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test13 " ) . toString ( ) , QLatin1String ( " HelloWorld " ) ) ;
QCOMPARE ( object - > property ( " test14 " ) . toString ( ) , QLatin1String ( " Hello World " ) ) ;
QCOMPARE ( object - > property ( " test15 " ) . toBool ( ) , false ) ;
QCOMPARE ( object - > property ( " test16 " ) . toBool ( ) , true ) ;
QCOMPARE ( object - > property ( " test17 " ) . toInt ( ) , 5 ) ;
QCOMPARE ( object - > property ( " test18 " ) . toReal ( ) , qreal ( 176 ) ) ;
QCOMPARE ( object - > property ( " test19 " ) . toInt ( ) , 7 ) ;
QCOMPARE ( object - > property ( " test20 " ) . toReal ( ) , qreal ( 6.7 ) ) ;
QCOMPARE ( object - > property ( " test21 " ) . toString ( ) , QLatin1String ( " 6.7 " ) ) ;
QCOMPARE ( object - > property ( " test22 " ) . toString ( ) , QLatin1String ( " ! " ) ) ;
QCOMPARE ( object - > property ( " test23 " ) . toBool ( ) , true ) ;
QCOMPARE ( qvariant_cast < QColor > ( object - > property ( " test24 " ) ) , QColor ( 0x11 , 0x22 , 0x33 ) ) ;
QCOMPARE ( qvariant_cast < QColor > ( object - > property ( " test25 " ) ) , QColor ( 0x11 , 0x22 , 0x33 , 0xAA ) ) ;
delete object ;
}
// Test that numbers assigned in bindings as strings work consistently
void tst_qdeclarativeecmascript : : numberAssignment ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " numberAssignment.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test1 " ) , QVariant ( ( qreal ) 6.7 ) ) ;
QCOMPARE ( object - > property ( " test2 " ) , QVariant ( ( qreal ) 6.7 ) ) ;
QCOMPARE ( object - > property ( " test2 " ) , QVariant ( ( qreal ) 6.7 ) ) ;
QCOMPARE ( object - > property ( " test3 " ) , QVariant ( ( qreal ) 6 ) ) ;
QCOMPARE ( object - > property ( " test4 " ) , QVariant ( ( qreal ) 6 ) ) ;
QCOMPARE ( object - > property ( " test5 " ) , QVariant ( ( int ) 7 ) ) ;
QCOMPARE ( object - > property ( " test6 " ) , QVariant ( ( int ) 7 ) ) ;
QCOMPARE ( object - > property ( " test7 " ) , QVariant ( ( int ) 6 ) ) ;
QCOMPARE ( object - > property ( " test8 " ) , QVariant ( ( int ) 6 ) ) ;
QCOMPARE ( object - > property ( " test9 " ) , QVariant ( ( unsigned int ) 7 ) ) ;
QCOMPARE ( object - > property ( " test10 " ) , QVariant ( ( unsigned int ) 7 ) ) ;
QCOMPARE ( object - > property ( " test11 " ) , QVariant ( ( unsigned int ) 6 ) ) ;
QCOMPARE ( object - > property ( " test12 " ) , QVariant ( ( unsigned int ) 6 ) ) ;
delete object ;
}
void tst_qdeclarativeecmascript : : propertySplicing ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " propertySplicing.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toBool ( ) , true ) ;
delete object ;
}
// QTBUG-16683
void tst_qdeclarativeecmascript : : signalWithUnknownTypes ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " signalWithUnknownTypes.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
MyQmlObject : : MyType type ;
type . value = 0x8971123 ;
emit object - > signalWithUnknownType ( type ) ;
MyQmlObject : : MyType result = qvariant_cast < MyQmlObject : : MyType > ( object - > variant ( ) ) ;
QCOMPARE ( result . value , type . value ) ;
delete object ;
}
2011-04-27 12:13:26 +00:00
void tst_qdeclarativeecmascript : : moduleApi ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " moduleApi.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " existingUriTest " ) . toInt ( ) , 20 ) ;
QCOMPARE ( object - > property ( " scriptTest " ) . toInt ( ) , 13 ) ;
QCOMPARE ( object - > property ( " qobjectTest " ) . toInt ( ) , 20 ) ;
2011-05-06 03:18:19 +00:00
QCOMPARE ( object - > property ( " qobjectMethodTest " ) . toInt ( ) , 1 ) ; // first call of method, so count = 1.
2011-04-27 12:13:26 +00:00
QCOMPARE ( object - > property ( " qobjectMinorVersionTest " ) . toInt ( ) , 20 ) ;
QCOMPARE ( object - > property ( " qobjectMajorVersionTest " ) . toInt ( ) , 20 ) ;
QCOMPARE ( object - > property ( " qobjectParentedTest " ) . toInt ( ) , 26 ) ;
delete object ;
// test that caching of module apis works correctly.
QDeclarativeComponent componentTwo ( & engine , TEST_FILE ( " moduleApiCaching.qml " ) ) ;
object = componentTwo . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " existingUriTest " ) . toInt ( ) , 20 ) ;
QCOMPARE ( object - > property ( " scriptTest " ) . toInt ( ) , 13 ) ; // shouldn't have incremented.
QCOMPARE ( object - > property ( " qobjectParentedTest " ) . toInt ( ) , 26 ) ; // shouldn't have incremented.
delete object ;
// test that writing to a property of module apis works correctly.
QDeclarativeComponent componentThree ( & engine , TEST_FILE ( " moduleApiWriting.qml " ) ) ;
QString expectedWarning = QLatin1String ( " file:// " ) + TEST_FILE ( " moduleApiWriting.qml " ) . toLocalFile ( ) + QLatin1String ( " :15: Error: Cannot assign to read-only property \" qobjectTestProperty \" " ) ;
QTest : : ignoreMessage ( QtWarningMsg , expectedWarning . toAscii ( ) . constData ( ) ) ;
object = componentThree . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " readOnlyProperty " ) . toInt ( ) , 20 ) ;
QCOMPARE ( object - > property ( " writableProperty " ) . toInt ( ) , 50 ) ;
QVERIFY ( object - > setProperty ( " firstProperty " , QVariant ( 30 ) ) ) ; // shouldn't affect value of readOnlyProperty
QVERIFY ( object - > setProperty ( " writableProperty " , QVariant ( 30 ) ) ) ; // SHOULD affect value of writableProperty
QCOMPARE ( object - > property ( " readOnlyProperty " ) . toInt ( ) , 20 ) ;
QCOMPARE ( object - > property ( " writableProperty " ) . toInt ( ) , 30 ) ;
delete object ;
QDeclarativeComponent failOne ( & engine , TEST_FILE ( " moduleApiMajorVersionFail.qml " ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , " QDeclarativeComponent: Component is not ready " ) ;
object = failOne . create ( ) ;
QVERIFY ( object = = 0 ) ; // should have failed: invalid major version
QDeclarativeComponent failTwo ( & engine , TEST_FILE ( " moduleApiMinorVersionFail.qml " ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , " QDeclarativeComponent: Component is not ready " ) ;
object = failTwo . create ( ) ;
QVERIFY ( object = = 0 ) ; // should have failed: invalid minor version
}
void tst_qdeclarativeecmascript : : importScripts ( )
{
QObject * object = 0 ;
// first, ensure that the required behaviour works.
QDeclarativeComponent component ( & engine , TEST_FILE ( " jsimport/testImport.qml " ) ) ;
object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " importedScriptStringValue " ) , QVariant ( QString ( QLatin1String ( " Hello, World! " ) ) ) ) ;
QCOMPARE ( object - > property ( " importedScriptFunctionValue " ) , QVariant ( 20 ) ) ;
QCOMPARE ( object - > property ( " importedModuleAttachedPropertyValue " ) , QVariant ( 19 ) ) ;
QCOMPARE ( object - > property ( " importedModuleEnumValue " ) , QVariant ( 2 ) ) ;
delete object ;
QDeclarativeComponent componentTwo ( & engine , TEST_FILE ( " jsimport/testImportScoping.qml " ) ) ;
object = componentTwo . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " componentError " ) , QVariant ( 5 ) ) ;
delete object ;
// then, ensure that unintended behaviour does not work.
QDeclarativeComponent failOneComponent ( & engine , TEST_FILE ( " jsimportfail/failOne.qml " ) ) ;
QString expectedWarning = QLatin1String ( " file:// " ) + TEST_FILE ( " jsimportfail/failOne.qml " ) . toLocalFile ( ) + QLatin1String ( " :6: TypeError: Result of expression 'TestScriptImport.ImportOneJs' [undefined] is not an object. " ) ;
QTest : : ignoreMessage ( QtWarningMsg , expectedWarning . toAscii ( ) . constData ( ) ) ;
object = failOneComponent . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( object - > property ( " importScriptFunctionValue " ) . toString ( ) . isEmpty ( ) ) ;
delete object ;
QDeclarativeComponent failTwoComponent ( & engine , TEST_FILE ( " jsimportfail/failTwo.qml " ) ) ;
expectedWarning = QLatin1String ( " file:// " ) + TEST_FILE ( " jsimportfail/failTwo.qml " ) . toLocalFile ( ) + QLatin1String ( " :6: ReferenceError: Can't find variable: ImportOneJs " ) ;
QTest : : ignoreMessage ( QtWarningMsg , expectedWarning . toAscii ( ) . constData ( ) ) ;
object = failTwoComponent . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( object - > property ( " importScriptFunctionValue " ) . toString ( ) . isEmpty ( ) ) ;
delete object ;
QDeclarativeComponent failThreeComponent ( & engine , TEST_FILE ( " jsimportfail/failThree.qml " ) ) ;
expectedWarning = QLatin1String ( " file:// " ) + TEST_FILE ( " jsimportfail/failThree.qml " ) . toLocalFile ( ) + QLatin1String ( " :7: TypeError: Result of expression 'testQtObject.TestModuleImport.JsQtTest' [undefined] is not an object. " ) ;
QTest : : ignoreMessage ( QtWarningMsg , expectedWarning . toAscii ( ) . constData ( ) ) ;
object = failThreeComponent . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " importedModuleAttachedPropertyValue " ) , QVariant ( false ) ) ;
delete object ;
QDeclarativeComponent failFourComponent ( & engine , TEST_FILE ( " jsimportfail/failFour.qml " ) ) ;
expectedWarning = QLatin1String ( " file:// " ) + TEST_FILE ( " jsimportfail/failFour.qml " ) . toLocalFile ( ) + QLatin1String ( " :6: ReferenceError: Can't find variable: JsQtTest " ) ;
QTest : : ignoreMessage ( QtWarningMsg , expectedWarning . toAscii ( ) . constData ( ) ) ;
object = failFourComponent . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " importedModuleEnumValue " ) , QVariant ( 0 ) ) ;
delete object ;
QDeclarativeComponent failFiveComponent ( & engine , TEST_FILE ( " jsimportfail/failFive.qml " ) ) ;
expectedWarning = QLatin1String ( " file:// " ) + TEST_FILE ( " jsimportfail/importWithImports.js " ) . toLocalFile ( ) + QLatin1String ( " :8: ReferenceError: Can't find variable: Component " ) ;
QTest : : ignoreMessage ( QtWarningMsg , expectedWarning . toAscii ( ) . constData ( ) ) ;
expectedWarning = QLatin1String ( " file:// " ) + TEST_FILE ( " jsimportfail/importPragmaLibrary.js " ) . toLocalFile ( ) + QLatin1String ( " :6: ReferenceError: Can't find variable: Component " ) ;
QTest : : ignoreMessage ( QtWarningMsg , expectedWarning . toAscii ( ) . constData ( ) ) ;
object = failFiveComponent . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " componentError " ) , QVariant ( 0 ) ) ;
delete object ;
// also, test that importing scripts with .pragma library works as required
QDeclarativeComponent pragmaLibraryComponent ( & engine , TEST_FILE ( " jsimport/testImportPragmaLibrary.qml " ) ) ;
object = pragmaLibraryComponent . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " testValue " ) , QVariant ( 31 ) ) ;
delete object ;
// and that .pragma library scripts don't inherit imports from any .qml file
QDeclarativeComponent pragmaLibraryComponentTwo ( & engine , TEST_FILE ( " jsimportfail/testImportPragmaLibrary.qml " ) ) ;
object = pragmaLibraryComponentTwo . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " testValue " ) , QVariant ( 0 ) ) ;
delete object ;
}
void tst_qdeclarativeecmascript : : scarceResources ( )
{
QPixmap origPixmap ( 100 , 100 ) ;
origPixmap . fill ( Qt : : blue ) ;
QDeclarativeEnginePrivate * ep = QDeclarativeEnginePrivate : : get ( & engine ) ;
ScarceResourceObject * eo = 0 ;
QObject * object = 0 ;
// in the following three cases, the instance created from the component
// has a property which is a copy of the scarce resource; hence, the
// resource should NOT be detached prior to deletion of the object instance,
// unless the resource is destroyed explicitly.
QDeclarativeComponent component ( & engine , TEST_FILE ( " scarceresources/scarceResourceCopy.qml " ) ) ;
object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( object - > property ( " scarceResourceCopy " ) . isValid ( ) ) ;
QCOMPARE ( object - > property ( " scarceResourceCopy " ) . value < QPixmap > ( ) , origPixmap ) ;
QVERIFY ( ep - > scarceResources = = 0 ) ; // should have been released by this point.
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( ! eo - > scarceResourceIsDetached ( ) ) ; // there are two copies of it in existence: the property of object, and the property of eo.
delete object ;
QDeclarativeComponent componentTwo ( & engine , TEST_FILE ( " scarceresources/scarceResourceCopyFromJs.qml " ) ) ;
object = componentTwo . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( object - > property ( " scarceResourceCopy " ) . isValid ( ) ) ;
QCOMPARE ( object - > property ( " scarceResourceCopy " ) . value < QPixmap > ( ) , origPixmap ) ;
QVERIFY ( ep - > scarceResources = = 0 ) ; // should have been released by this point.
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( ! eo - > scarceResourceIsDetached ( ) ) ; // there are two copies of it in existence: the property of object, and the property of eo.
delete object ;
QDeclarativeComponent componentThree ( & engine , TEST_FILE ( " scarceresources/scarceResourceDestroyedCopy.qml " ) ) ;
object = componentThree . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( ! ( object - > property ( " scarceResourceCopy " ) . isValid ( ) ) ) ; // was manually released prior to being returned.
QVERIFY ( ep - > scarceResources = = 0 ) ; // should have been released by this point.
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( eo - > scarceResourceIsDetached ( ) ) ; // should have explicitly been released during the evaluation of the binding.
delete object ;
// in the following three cases, no other copy should exist in memory,
// and so it should be detached (unless explicitly preserved).
QDeclarativeComponent componentFour ( & engine , TEST_FILE ( " scarceresources/scarceResourceTest.qml " ) ) ;
object = componentFour . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( object - > property ( " scarceResourceTest " ) . isValid ( ) ) ;
QCOMPARE ( object - > property ( " scarceResourceTest " ) . toInt ( ) , 100 ) ;
QVERIFY ( ep - > scarceResources = = 0 ) ; // should have been released by this point.
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( eo - > scarceResourceIsDetached ( ) ) ; // the resource should have been released after the binding was evaluated.
delete object ;
QDeclarativeComponent componentFive ( & engine , TEST_FILE ( " scarceresources/scarceResourceTestPreserve.qml " ) ) ;
object = componentFive . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( object - > property ( " scarceResourceTest " ) . isValid ( ) ) ;
QCOMPARE ( object - > property ( " scarceResourceTest " ) . toInt ( ) , 100 ) ;
QVERIFY ( ep - > scarceResources = = 0 ) ; // should have been released by this point.
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( ! eo - > scarceResourceIsDetached ( ) ) ; // this won't be detached since we explicitly preserved it.
delete object ;
QDeclarativeComponent componentSix ( & engine , TEST_FILE ( " scarceresources/scarceResourceTestMultiple.qml " ) ) ;
object = componentSix . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( object - > property ( " scarceResourceTest " ) . isValid ( ) ) ;
QCOMPARE ( object - > property ( " scarceResourceTest " ) . toInt ( ) , 100 ) ;
QVERIFY ( ep - > scarceResources = = 0 ) ; // should have been released by this point.
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( eo - > scarceResourceIsDetached ( ) ) ; // all resources were released manually or automatically released.
delete object ;
// test that scarce resources are handled correctly for imports
QDeclarativeComponent componentSeven ( & engine , TEST_FILE ( " scarceresources/scarceResourceCopyImportNoBinding.qml " ) ) ;
object = componentSeven . create ( ) ;
QVERIFY ( object ! = 0 ) ; // the import should have caused the addition of a resource to the ScarceResources list
QVERIFY ( ep - > scarceResources = = 0 ) ; // but they should have been released by this point.
delete object ;
QDeclarativeComponent componentEight ( & engine , TEST_FILE ( " scarceresources/scarceResourceCopyImportFail.qml " ) ) ;
object = componentEight . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( ! object - > property ( " scarceResourceCopy " ) . isValid ( ) ) ; // wasn't preserved, so shouldn't be valid.
QVERIFY ( ep - > scarceResources = = 0 ) ; // should have been released by this point.
delete object ;
QDeclarativeComponent componentNine ( & engine , TEST_FILE ( " scarceresources/scarceResourceCopyImport.qml " ) ) ;
object = componentNine . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( object - > property ( " scarceResourceCopy " ) . isValid ( ) ) ; // preserved, so should be valid.
QCOMPARE ( object - > property ( " scarceResourceCopy " ) . value < QPixmap > ( ) , origPixmap ) ;
QVERIFY ( object - > property ( " scarceResourceAssignedCopyOne " ) . isValid ( ) ) ; // assigned before destroy(), so should be valid.
QCOMPARE ( object - > property ( " scarceResourceAssignedCopyOne " ) . value < QPixmap > ( ) , origPixmap ) ;
QVERIFY ( ! object - > property ( " scarceResourceAssignedCopyTwo " ) . isValid ( ) ) ; // assigned after destroy(), so should be invalid.
QVERIFY ( ep - > scarceResources = = 0 ) ; // this will still be zero, because "preserve()" REMOVES it from this list.
delete object ;
// test that scarce resources are handled properly in signal invocation
QDeclarativeComponent componentTen ( & engine , TEST_FILE ( " scarceresources/scarceResourceSignal.qml " ) ) ;
object = componentTen . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QObject * srsc = object - > findChild < QObject * > ( " srsc " ) ;
QVERIFY ( srsc ) ;
QVERIFY ( ! srsc - > property ( " scarceResourceCopy " ) . isValid ( ) ) ; // hasn't been instantiated yet.
QCOMPARE ( srsc - > property ( " width " ) , QVariant ( 5 ) ) ; // default value is 5.
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( eo - > scarceResourceIsDetached ( ) ) ; // should be no other copies of it at this stage.
QMetaObject : : invokeMethod ( srsc , " testSignal " ) ;
QVERIFY ( ! srsc - > property ( " scarceResourceCopy " ) . isValid ( ) ) ; // still hasn't been instantiated
QCOMPARE ( srsc - > property ( " width " ) , QVariant ( 10 ) ) ; // but width was assigned to 10.
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( eo - > scarceResourceIsDetached ( ) ) ; // should still be no other copies of it at this stage.
QMetaObject : : invokeMethod ( srsc , " testSignal2 " ) ; // assigns scarceResourceCopy to the scarce pixmap.
QVERIFY ( srsc - > property ( " scarceResourceCopy " ) . isValid ( ) ) ;
QCOMPARE ( srsc - > property ( " scarceResourceCopy " ) . value < QPixmap > ( ) , origPixmap ) ;
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( ! ( eo - > scarceResourceIsDetached ( ) ) ) ; // should be another copy of the resource now.
QVERIFY ( ep - > scarceResources = = 0 ) ; // should have been released by this point.
delete object ;
// test that scarce resources are handled properly from js functions in qml files
QDeclarativeComponent componentEleven ( & engine , TEST_FILE ( " scarceresources/scarceResourceFunction.qml " ) ) ;
object = componentEleven . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( ! object - > property ( " scarceResourceCopy " ) . isValid ( ) ) ; // not yet assigned, so should not be valid
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( eo - > scarceResourceIsDetached ( ) ) ; // should be no other copies of it at this stage.
QMetaObject : : invokeMethod ( object , " retrieveScarceResource " ) ;
QVERIFY ( object - > property ( " scarceResourceCopy " ) . isValid ( ) ) ; // assigned, so should be valid.
QCOMPARE ( object - > property ( " scarceResourceCopy " ) . value < QPixmap > ( ) , origPixmap ) ;
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( ! eo - > scarceResourceIsDetached ( ) ) ; // should be a copy of the resource at this stage.
QMetaObject : : invokeMethod ( object , " releaseScarceResource " ) ;
QVERIFY ( ! object - > property ( " scarceResourceCopy " ) . isValid ( ) ) ; // just released, so should not be valid
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( eo - > scarceResourceIsDetached ( ) ) ; // should be no other copies of it at this stage.
QVERIFY ( ep - > scarceResources = = 0 ) ; // should have been released by this point.
delete object ;
// test that if an exception occurs while invoking js function from cpp, that the resources are released.
QDeclarativeComponent componentTwelve ( & engine , TEST_FILE ( " scarceresources/scarceResourceFunctionFail.qml " ) ) ;
object = componentTwelve . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( ! object - > property ( " scarceResourceCopy " ) . isValid ( ) ) ; // not yet assigned, so should not be valid
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( eo - > scarceResourceIsDetached ( ) ) ; // should be no other copies of it at this stage.
QString expectedWarning = QLatin1String ( " file:// " ) + TEST_FILE ( " scarceresources/scarceResourceFunctionFail.qml " ) . toLocalFile ( ) + QLatin1String ( " :16: TypeError: Result of expression 'scarceResourceProvider.scarceResource' [[object Object]] is not a function. " ) ;
QTest : : ignoreMessage ( QtWarningMsg , expectedWarning . toAscii ( ) . constData ( ) ) ; // we expect a meaningful warning to be printed.
QMetaObject : : invokeMethod ( object , " retrieveScarceResource " ) ;
QVERIFY ( ! object - > property ( " scarceResourceCopy " ) . isValid ( ) ) ; // due to exception, assignment will NOT have occurred.
eo = qobject_cast < ScarceResourceObject * > ( QDeclarativeProperty : : read ( object , " a " ) . value < QObject * > ( ) ) ;
QVERIFY ( eo - > scarceResourceIsDetached ( ) ) ; // should be no other copies of it at this stage.
QVERIFY ( ep - > scarceResources = = 0 ) ; // should have been released by this point.
delete object ;
}
2011-04-27 10:05:43 +00:00
// Test that assigning a null object works
// Regressed with: df1788b4dbbb2826ae63f26bdf166342595343f4
void tst_qdeclarativeecmascript : : nullObjectBinding ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " nullObjectBinding.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QVERIFY ( object - > property ( " test " ) = = QVariant : : fromValue ( ( QObject * ) 0 ) ) ;
delete object ;
}
// Test that bindings don't evaluate once the engine has been destroyed
void tst_qdeclarativeecmascript : : deletedEngine ( )
{
QDeclarativeEngine * engine = new QDeclarativeEngine ;
QDeclarativeComponent component ( engine , TEST_FILE ( " deletedEngine.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " a " ) . toInt ( ) , 39 ) ;
object - > setProperty ( " b " , QVariant ( 9 ) ) ;
QCOMPARE ( object - > property ( " a " ) . toInt ( ) , 117 ) ;
delete engine ;
QCOMPARE ( object - > property ( " a " ) . toInt ( ) , 117 ) ;
object - > setProperty ( " b " , QVariant ( 10 ) ) ;
QCOMPARE ( object - > property ( " a " ) . toInt ( ) , 117 ) ;
delete object ;
}
// Test the crashing part of QTBUG-9705
void tst_qdeclarativeecmascript : : libraryScriptAssert ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " libraryScriptAssert.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
delete object ;
}
void tst_qdeclarativeecmascript : : variantsAssignedUndefined ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " variantsAssignedUndefined.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test1 " ) . toInt ( ) , 10 ) ;
QCOMPARE ( object - > property ( " test2 " ) . toInt ( ) , 11 ) ;
object - > setProperty ( " runTest " , true ) ;
QCOMPARE ( object - > property ( " test1 " ) , QVariant ( ) ) ;
QCOMPARE ( object - > property ( " test2 " ) , QVariant ( ) ) ;
delete object ;
}
void tst_qdeclarativeecmascript : : qtbug_9792 ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " qtbug_9792.qml " ) ) ;
QDeclarativeContext * context = new QDeclarativeContext ( engine . rootContext ( ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( context ) ) ;
QVERIFY ( object ! = 0 ) ;
QTest : : ignoreMessage ( QtDebugMsg , " Hello world! " ) ;
object - > basicSignal ( ) ;
delete context ;
transientErrorsMsgCount = 0 ;
QtMsgHandler old = qInstallMsgHandler ( transientErrorsMsgHandler ) ;
object - > basicSignal ( ) ;
qInstallMsgHandler ( old ) ;
QCOMPARE ( transientErrorsMsgCount , 0 ) ;
delete object ;
}
// Verifies that QDeclarativeGuard<>s used in the vmemetaobject are cleaned correctly
void tst_qdeclarativeecmascript : : qtcreatorbug_1289 ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " qtcreatorbug_1289.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QObject * nested = qvariant_cast < QObject * > ( o - > property ( " object " ) ) ;
QVERIFY ( nested ! = 0 ) ;
QVERIFY ( qvariant_cast < QObject * > ( nested - > property ( " nestedObject " ) ) = = o ) ;
delete nested ;
nested = qvariant_cast < QObject * > ( o - > property ( " object " ) ) ;
QVERIFY ( nested = = 0 ) ;
// If the bug is present, the next line will crash
delete o ;
}
// Test that we shut down without stupid warnings
void tst_qdeclarativeecmascript : : noSpuriousWarningsAtShutdown ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " noSpuriousWarningsAtShutdown.qml " ) ) ;
QObject * o = component . create ( ) ;
transientErrorsMsgCount = 0 ;
QtMsgHandler old = qInstallMsgHandler ( transientErrorsMsgHandler ) ;
delete o ;
qInstallMsgHandler ( old ) ;
QCOMPARE ( transientErrorsMsgCount , 0 ) ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " noSpuriousWarningsAtShutdown.2.qml " ) ) ;
QObject * o = component . create ( ) ;
transientErrorsMsgCount = 0 ;
QtMsgHandler old = qInstallMsgHandler ( transientErrorsMsgHandler ) ;
delete o ;
qInstallMsgHandler ( old ) ;
QCOMPARE ( transientErrorsMsgCount , 0 ) ;
}
}
void tst_qdeclarativeecmascript : : canAssignNullToQObject ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " canAssignNullToQObject.1.qml " ) ) ;
MyQmlObject * o = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( o ! = 0 ) ;
QVERIFY ( o - > objectProperty ( ) ! = 0 ) ;
o - > setProperty ( " runTest " , true ) ;
QVERIFY ( o - > objectProperty ( ) = = 0 ) ;
delete o ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " canAssignNullToQObject.2.qml " ) ) ;
MyQmlObject * o = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( o ! = 0 ) ;
QVERIFY ( o - > objectProperty ( ) = = 0 ) ;
delete o ;
}
}
void tst_qdeclarativeecmascript : : functionAssignment_fromBinding ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " functionAssignment.1.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
QString warning = url + " :4: Unable to assign a function to a property. " ;
QTest : : ignoreMessage ( QtWarningMsg , warning . toLatin1 ( ) . constData ( ) ) ;
MyQmlObject * o = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( o ! = 0 ) ;
QVERIFY ( ! o - > property ( " a " ) . isValid ( ) ) ;
delete o ;
}
void tst_qdeclarativeecmascript : : functionAssignment_fromJS ( )
{
QFETCH ( QString , triggerProperty ) ;
QDeclarativeComponent component ( & engine , TEST_FILE ( " functionAssignment.2.qml " ) ) ;
QVERIFY2 ( component . errorString ( ) . isEmpty ( ) , qPrintable ( component . errorString ( ) ) ) ;
MyQmlObject * o = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( o ! = 0 ) ;
QVERIFY ( ! o - > property ( " a " ) . isValid ( ) ) ;
o - > setProperty ( " aNumber " , QVariant ( 5 ) ) ;
o - > setProperty ( triggerProperty . toUtf8 ( ) . constData ( ) , true ) ;
QCOMPARE ( o - > property ( " a " ) , QVariant ( 50 ) ) ;
o - > setProperty ( " aNumber " , QVariant ( 10 ) ) ;
QCOMPARE ( o - > property ( " a " ) , QVariant ( 100 ) ) ;
delete o ;
}
void tst_qdeclarativeecmascript : : functionAssignment_fromJS_data ( )
{
QTest : : addColumn < QString > ( " triggerProperty " ) ;
QTest : : newRow ( " assign to property " ) < < " assignToProperty " ;
QTest : : newRow ( " assign to property, from JS file " ) < < " assignToPropertyFromJsFile " ;
QTest : : newRow ( " assign to value type " ) < < " assignToValueType " ;
QTest : : newRow ( " use 'this' " ) < < " assignWithThis " ;
QTest : : newRow ( " use 'this' from JS file " ) < < " assignWithThisFromJsFile " ;
}
void tst_qdeclarativeecmascript : : functionAssignmentfromJS_invalid ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " functionAssignment.2.qml " ) ) ;
QVERIFY2 ( component . errorString ( ) . isEmpty ( ) , qPrintable ( component . errorString ( ) ) ) ;
MyQmlObject * o = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( o ! = 0 ) ;
QVERIFY ( ! o - > property ( " a " ) . isValid ( ) ) ;
o - > setProperty ( " assignFuncWithoutReturn " , true ) ;
QVERIFY ( ! o - > property ( " a " ) . isValid ( ) ) ;
QString url = component . url ( ) . toString ( ) ;
QString warning = url + " :63: Unable to assign QString to int " ;
QTest : : ignoreMessage ( QtWarningMsg , warning . toLatin1 ( ) . constData ( ) ) ;
o - > setProperty ( " assignWrongType " , true ) ;
warning = url + " :70: Unable to assign QString to int " ;
QTest : : ignoreMessage ( QtWarningMsg , warning . toLatin1 ( ) . constData ( ) ) ;
o - > setProperty ( " assignWrongTypeToValueType " , true ) ;
delete o ;
}
void tst_qdeclarativeecmascript : : eval ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " eval.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test2 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test3 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test4 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test5 " ) . toBool ( ) , true ) ;
delete o ;
}
void tst_qdeclarativeecmascript : : function ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " function.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test2 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test3 " ) . toBool ( ) , true ) ;
delete o ;
}
// Test the "Qt.include" method
void tst_qdeclarativeecmascript : : include ( )
{
// Non-library relative include
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " include.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test0 " ) . toInt ( ) , 99 ) ;
QCOMPARE ( o - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test2 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test2_1 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test3 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test3_1 " ) . toBool ( ) , true ) ;
delete o ;
}
// Library relative include
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " include_shared.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test0 " ) . toInt ( ) , 99 ) ;
QCOMPARE ( o - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test2 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test2_1 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test3 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test3_1 " ) . toBool ( ) , true ) ;
delete o ;
}
// Callback
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " include_callback.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test2 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test3 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test4 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test5 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test6 " ) . toBool ( ) , true ) ;
delete o ;
}
// Including file with ".pragma library"
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " include_pragma.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test1 " ) . toInt ( ) , 100 ) ;
delete o ;
}
// Remote - success
{
TestHTTPServer server ( 8111 ) ;
QVERIFY ( server . isValid ( ) ) ;
server . serveDirectory ( SRCDIR " /data " ) ;
QDeclarativeComponent component ( & engine , TEST_FILE ( " include_remote.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QTRY_VERIFY ( o - > property ( " done " ) . toBool ( ) = = true ) ;
QTRY_VERIFY ( o - > property ( " done2 " ) . toBool ( ) = = true ) ;
QCOMPARE ( o - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test2 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test3 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test4 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test5 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test6 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test7 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test8 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test9 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test10 " ) . toBool ( ) , true ) ;
delete o ;
}
// Remote - error
{
TestHTTPServer server ( 8111 ) ;
QVERIFY ( server . isValid ( ) ) ;
server . serveDirectory ( SRCDIR " /data " ) ;
QDeclarativeComponent component ( & engine , TEST_FILE ( " include_remote_missing.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QTRY_VERIFY ( o - > property ( " done " ) . toBool ( ) = = true ) ;
QCOMPARE ( o - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test2 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test3 " ) . toBool ( ) , true ) ;
delete o ;
}
}
void tst_qdeclarativeecmascript : : qtbug_10696 ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " qtbug_10696.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
delete o ;
}
void tst_qdeclarativeecmascript : : qtbug_11606 ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " qtbug_11606.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
delete o ;
}
void tst_qdeclarativeecmascript : : qtbug_11600 ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " qtbug_11600.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
delete o ;
}
// Reading and writing non-scriptable properties should fail
void tst_qdeclarativeecmascript : : nonscriptable ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " nonscriptable.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " readOk " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " writeOk " ) . toBool ( ) , true ) ;
delete o ;
}
// deleteLater() should not be callable from QML
void tst_qdeclarativeecmascript : : deleteLater ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " deleteLater.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
delete o ;
}
void tst_qdeclarativeecmascript : : in ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " in.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test2 " ) . toBool ( ) , true ) ;
delete o ;
}
void tst_qdeclarativeecmascript : : sharedAttachedObject ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " sharedAttachedObject.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test1 " ) . toBool ( ) , true ) ;
QCOMPARE ( o - > property ( " test2 " ) . toBool ( ) , true ) ;
delete o ;
}
// QTBUG-13999
void tst_qdeclarativeecmascript : : objectName ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " objectName.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test1 " ) . toString ( ) , QString ( " hello " ) ) ;
QCOMPARE ( o - > property ( " test2 " ) . toString ( ) , QString ( " ell " ) ) ;
o - > setObjectName ( " world " ) ;
QCOMPARE ( o - > property ( " test1 " ) . toString ( ) , QString ( " world " ) ) ;
QCOMPARE ( o - > property ( " test2 " ) . toString ( ) , QString ( " orl " ) ) ;
delete o ;
}
void tst_qdeclarativeecmascript : : writeRemovesBinding ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " writeRemovesBinding.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
delete o ;
}
// Test bindings assigned to alias properties actually assign to the alias' target
void tst_qdeclarativeecmascript : : aliasBindingsAssignCorrectly ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " aliasBindingsAssignCorrectly.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
delete o ;
}
// Test bindings assigned to alias properties override a binding on the target (QTBUG-13719)
void tst_qdeclarativeecmascript : : aliasBindingsOverrideTarget ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " aliasBindingsOverrideTarget.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
delete o ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " aliasBindingsOverrideTarget.2.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
delete o ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " aliasBindingsOverrideTarget.3.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
delete o ;
}
}
// Test that writes to alias properties override bindings on the alias target (QTBUG-13719)
void tst_qdeclarativeecmascript : : aliasWritesOverrideBindings ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " aliasWritesOverrideBindings.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
delete o ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " aliasWritesOverrideBindings.2.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
delete o ;
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " aliasWritesOverrideBindings.3.qml " ) ) ;
QObject * o = component . create ( ) ;
QVERIFY ( o ! = 0 ) ;
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
delete o ;
}
}
void tst_qdeclarativeecmascript : : revisionErrors ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " metaobjectRevisionErrors.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
QString warning1 = url + " :8: ReferenceError: Can't find variable: prop2 " ;
QString warning2 = url + " :11: ReferenceError: Can't find variable: prop2 " ;
QString warning3 = url + " :13: ReferenceError: Can't find variable: method2 " ;
QTest : : ignoreMessage ( QtWarningMsg , warning1 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning2 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning3 . toLatin1 ( ) . constData ( ) ) ;
MyRevisionedClass * object = qobject_cast < MyRevisionedClass * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " metaobjectRevisionErrors2.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
// MyRevisionedSubclass 1.0 uses MyRevisionedClass revision 0
// method2, prop2 from MyRevisionedClass not available
// method4, prop4 from MyRevisionedSubclass not available
QString warning1 = url + " :8: ReferenceError: Can't find variable: prop2 " ;
QString warning2 = url + " :14: ReferenceError: Can't find variable: prop2 " ;
QString warning3 = url + " :10: ReferenceError: Can't find variable: prop4 " ;
QString warning4 = url + " :16: ReferenceError: Can't find variable: prop4 " ;
QString warning5 = url + " :20: ReferenceError: Can't find variable: method2 " ;
QTest : : ignoreMessage ( QtWarningMsg , warning1 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning2 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning3 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning4 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning5 . toLatin1 ( ) . constData ( ) ) ;
MyRevisionedClass * object = qobject_cast < MyRevisionedClass * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " metaobjectRevisionErrors3.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
// MyRevisionedSubclass 1.1 uses MyRevisionedClass revision 1
// All properties/methods available, except MyRevisionedBaseClassUnregistered rev 1
QString warning1 = url + " :30: ReferenceError: Can't find variable: methodD " ;
QString warning2 = url + " :10: ReferenceError: Can't find variable: propD " ;
QString warning3 = url + " :20: ReferenceError: Can't find variable: propD " ;
QTest : : ignoreMessage ( QtWarningMsg , warning1 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning2 . toLatin1 ( ) . constData ( ) ) ;
QTest : : ignoreMessage ( QtWarningMsg , warning3 . toLatin1 ( ) . constData ( ) ) ;
MyRevisionedClass * object = qobject_cast < MyRevisionedClass * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
}
void tst_qdeclarativeecmascript : : revision ( )
{
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " metaobjectRevision.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
MyRevisionedClass * object = qobject_cast < MyRevisionedClass * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " metaobjectRevision2.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
MyRevisionedClass * object = qobject_cast < MyRevisionedClass * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " metaobjectRevision3.qml " ) ) ;
QString url = component . url ( ) . toString ( ) ;
MyRevisionedClass * object = qobject_cast < MyRevisionedClass * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
2011-04-27 12:13:26 +00:00
delete object ;
2011-04-27 10:05:43 +00:00
}
// Test that non-root classes can resolve revisioned methods
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " metaobjectRevision4.qml " ) ) ;
QObject * object = component . create ( ) ;
QVERIFY ( object ! = 0 ) ;
QCOMPARE ( object - > property ( " test " ) . toReal ( ) , 11. ) ;
delete object ;
}
}
// Test for QScriptDeclarativeClass::pushCleanContext()
void tst_qdeclarativeecmascript : : pushCleanContext ( )
{
QScriptEngine engine ;
engine . globalObject ( ) . setProperty ( " a " , 6 ) ;
QCOMPARE ( engine . evaluate ( " a " ) . toInt32 ( ) , 6 ) ;
// First confirm pushContext() behaves as we expect
QScriptValue object = engine . newObject ( ) ;
object . setProperty ( " a " , 15 ) ;
QScriptContext * context1 = engine . pushContext ( ) ;
context1 - > pushScope ( object ) ;
QCOMPARE ( engine . evaluate ( " a " ) . toInt32 ( ) , 15 ) ;
QScriptContext * context2 = engine . pushContext ( ) ;
Q_UNUSED ( context2 ) ;
QCOMPARE ( engine . evaluate ( " a " ) . toInt32 ( ) , 15 ) ;
QScriptValue func1 = engine . evaluate ( " (function() { return a; }) " ) ;
// Now check that pushCleanContext() works
QScriptDeclarativeClass : : pushCleanContext ( & engine ) ;
QCOMPARE ( engine . evaluate ( " a " ) . toInt32 ( ) , 6 ) ;
QScriptValue func2 = engine . evaluate ( " (function() { return a; }) " ) ;
engine . popContext ( ) ;
QCOMPARE ( engine . evaluate ( " a " ) . toInt32 ( ) , 15 ) ;
engine . popContext ( ) ;
QCOMPARE ( engine . evaluate ( " a " ) . toInt32 ( ) , 15 ) ;
engine . popContext ( ) ;
QCOMPARE ( engine . evaluate ( " a " ) . toInt32 ( ) , 6 ) ;
// Check that function objects created in these contexts work
QCOMPARE ( func1 . call ( ) . toInt32 ( ) , 15 ) ;
QCOMPARE ( func2 . call ( ) . toInt32 ( ) , 6 ) ;
}
2011-04-27 12:13:26 +00:00
void tst_qdeclarativeecmascript : : realToInt ( )
{
QDeclarativeComponent component ( & engine , TEST_FILE ( " realToInt.qml " ) ) ;
MyQmlObject * object = qobject_cast < MyQmlObject * > ( component . create ( ) ) ;
QVERIFY ( object ! = 0 ) ;
QMetaObject : : invokeMethod ( object , " test1 " ) ;
QCOMPARE ( object - > value ( ) , int ( 4 ) ) ;
QMetaObject : : invokeMethod ( object , " test2 " ) ;
QCOMPARE ( object - > value ( ) , int ( 8 ) ) ;
}
2011-04-27 10:05:43 +00:00
QTEST_MAIN ( tst_qdeclarativeecmascript )
# include "tst_qdeclarativeecmascript.moc"