From 12a5ddf456ba8549645a8cb28a8b4ed6197a14da Mon Sep 17 00:00:00 2001 From: Matthew Vogt Date: Mon, 30 Jan 2012 14:16:15 +1000 Subject: Import relevant source from Qt 4.8 Change-Id: I5078db4081d95290c54f39d3c0efc2fc2f62e6a6 --- .../data/AliasBindingsAssignCorrectlyType.qml | 9 + .../data/AliasBindingsOverrideTargetType.qml | 14 + .../data/AliasBindingsOverrideTargetType3.qml | 9 + .../data/ConstantsOverrideBindings.qml | 12 + .../qdeclarativeecmascript/data/CustomObject.qml | 5 + .../qdeclarativeecmascript/data/MethodsObject.qml | 6 + .../data/NestedTypeTransientErrors.qml | 11 + .../qdeclarativeecmascript/data/ScopeObject.qml | 12 + .../data/SpuriousWarning.qml | 5 + .../data/TypeForDynamicCreation.qml | 2 + .../data/aliasBindingsAssignCorrectly.qml | 59 + .../data/aliasBindingsOverrideTarget.2.qml | 29 + .../data/aliasBindingsOverrideTarget.3.qml | 24 + .../data/aliasBindingsOverrideTarget.qml | 28 + .../data/aliasPropertyAndBinding.qml | 14 + .../data/aliasWritesOverrideBindings.2.qml | 29 + .../data/aliasWritesOverrideBindings.3.qml | 23 + .../data/aliasWritesOverrideBindings.qml | 23 + .../data/assignBasicTypes.2.qml | 26 + .../data/assignBasicTypes.qml | 29 + .../data/attachedProperty.2.qml | 22 + .../data/attachedProperty.qml | 11 + .../data/attachedPropertyScope.qml | 9 + .../qdeclarativeecmascript/data/bindingLoop.qml | 14 + .../qdeclarativeecmascript/data/blank.js | 0 .../data/boolPropertiesEvaluateAsBool.1.qml | 5 + .../data/boolPropertiesEvaluateAsBool.2.qml | 5 + .../qdeclarativeecmascript/data/bug.1.qml | 10 + .../data/canAssignNullToQObject.1.qml | 9 + .../data/canAssignNullToQObject.2.qml | 11 + .../qdeclarativeecmascript/data/compiled.qml | 48 + .../data/compositePropertyType.qml | 8 + .../data/constantsOverrideBindings.1.qml | 8 + .../data/constantsOverrideBindings.2.qml | 11 + .../data/constantsOverrideBindings.3.qml | 7 + .../data/constantsOverrideBindings.4.qml | 11 + .../data/declarativeToString.qml | 11 + .../data/deferredProperties.qml | 10 + .../data/deferredPropertiesErrors.qml | 10 + .../qdeclarativeecmascript/data/deleteLater.qml | 14 + .../qdeclarativeecmascript/data/deletedEngine.qml | 11 + .../qdeclarativeecmascript/data/deletedObject.qml | 25 + .../data/dynamicCreation.helper.qml | 6 + .../data/dynamicCreation.qml | 27 + .../data/dynamicDeletion.qml | 20 + .../qdeclarativeecmascript/data/enums.1.qml | 20 + .../qdeclarativeecmascript/data/enums.2.qml | 8 + .../qdeclarativeecmascript/data/eval.qml | 27 + .../qdeclarativeecmascript/data/exception.js | 1 + .../data/exceptionClearsOnReeval.qml | 6 + .../data/exceptionProducesWarning.qml | 8 + .../data/exceptionProducesWarning2.qml | 7 + .../data/extendedObjectPropertyLookup.qml | 8 + .../data/extensionObjects.qml | 19 + .../data/extensionObjectsPropertyOverride.qml | 7 + .../qdeclarativeecmascript/data/function.qml | 23 + .../data/functionAssignment.1.qml | 5 + .../data/functionAssignment.2.qml | 73 + .../data/functionAssignment.js | 17 + .../qdeclarativeecmascript/data/functionErrors.qml | 10 + .../data/idShortcutInvalidates.1.qml | 13 + .../data/idShortcutInvalidates.qml | 12 + .../declarative/qdeclarativeecmascript/data/in.qml | 7 + .../qdeclarativeecmascript/data/include.js | 8 + .../qdeclarativeecmascript/data/include.qml | 23 + .../data/include_callback.js | 11 + .../data/include_callback.qml | 15 + .../qdeclarativeecmascript/data/include_pragma.qml | 11 + .../data/include_pragma_inner.js | 5 + .../data/include_pragma_outer.js | 6 + .../qdeclarativeecmascript/data/include_remote.js | 26 + .../qdeclarativeecmascript/data/include_remote.qml | 21 + .../data/include_remote_missing.js | 13 + .../data/include_remote_missing.qml | 12 + .../qdeclarativeecmascript/data/include_shared.js | 12 + .../qdeclarativeecmascript/data/include_shared.qml | 22 + .../data/invokableObjectArg.qml | 9 + .../data/invokableObjectRet.qml | 11 + .../qdeclarativeecmascript/data/js/include2.js | 4 + .../qdeclarativeecmascript/data/js/include3.js | 3 + .../qdeclarativeecmascript/data/jsObject.qml | 12 + .../data/libraryScriptAssert.js | 6 + .../data/libraryScriptAssert.qml | 7 + .../qdeclarativeecmascript/data/listProperties.qml | 24 + .../qdeclarativeecmascript/data/listToVariant.qml | 5 + .../data/metaobjectRevision.qml | 7 + .../data/metaobjectRevision2.qml | 9 + .../data/metaobjectRevision3.qml | 8 + .../data/metaobjectRevision4.qml | 14 + .../data/metaobjectRevisionErrors.qml | 14 + .../data/metaobjectRevisionErrors2.qml | 24 + .../data/metaobjectRevisionErrors3.qml | 36 + .../qdeclarativeecmascript/data/methods.1.qml | 6 + .../qdeclarativeecmascript/data/methods.2.qml | 6 + .../qdeclarativeecmascript/data/methods.3.qml | 7 + .../qdeclarativeecmascript/data/methods.4.qml | 11 + .../qdeclarativeecmascript/data/methods.5.qml | 9 + .../data/multiEngineObject.qml | 5 + .../data/noSpuriousWarningsAtShutdown.2.qml | 10 + .../data/noSpuriousWarningsAtShutdown.qml | 9 + .../data/nonExistentAttachedObject.qml | 5 + .../qdeclarativeecmascript/data/nonscriptable.qml | 19 + .../data/nullObjectBinding.qml | 8 + .../data/numberAssignment.qml | 18 + .../qdeclarativeecmascript/data/objectName.qml | 8 + .../data/objectsCompareAsEqual.qml | 15 + .../data/outerBindingOverridesInnerBinding.qml | 15 + .../qdeclarativeecmascript/data/ownership.qml | 5 + .../data/propertyAssignmentErrors.qml | 22 + .../data/propertySplicing.qml | 10 + .../data/qlistqobjectMethods.qml | 6 + .../qdeclarativeecmascript/data/qtbug_10696.qml | 26 + .../qdeclarativeecmascript/data/qtbug_11600.js | 1 + .../qdeclarativeecmascript/data/qtbug_11600.qml | 8 + .../qdeclarativeecmascript/data/qtbug_11606.qml | 12 + .../qdeclarativeecmascript/data/qtbug_20648.qml | 7 + .../qdeclarativeecmascript/data/qtbug_9792.qml | 5 + .../data/qtcreatorbug_1289.qml | 13 + .../qdeclarativeecmascript/data/realToInt.qml | 11 + .../qdeclarativeecmascript/data/regExp.qml | 7 + .../qdeclarativeecmascript/data/remote_file.js | 2 + .../qdeclarativeecmascript/data/scope.2.qml | 40 + .../qdeclarativeecmascript/data/scope.3.qml | 13 + .../qdeclarativeecmascript/data/scope.4.qml | 12 + .../qdeclarativeecmascript/data/scope.qml | 44 + .../qdeclarativeecmascript/data/scriptConnect.1.js | 4 + .../data/scriptConnect.1.qml | 10 + .../qdeclarativeecmascript/data/scriptConnect.2.js | 5 + .../data/scriptConnect.2.qml | 16 + .../data/scriptConnect.3.qml | 15 + .../data/scriptConnect.4.qml | 12 + .../data/scriptConnect.5.qml | 11 + .../qdeclarativeecmascript/data/scriptConnect.6.js | 3 + .../data/scriptConnect.6.qml | 15 + .../data/scriptDisconnect.1.js | 6 + .../data/scriptDisconnect.1.qml | 13 + .../data/scriptDisconnect.2.qml | 14 + .../data/scriptDisconnect.3.qml | 14 + .../data/scriptDisconnect.4.qml | 13 + .../qdeclarativeecmascript/data/scriptErrors.js | 4 + .../qdeclarativeecmascript/data/scriptErrors.qml | 15 + .../data/selfDeletingBinding.2.qml | 17 + .../data/selfDeletingBinding.qml | 18 + .../data/sharedAttachedObject.qml | 16 + .../qdeclarativeecmascript/data/shutdownErrors.qml | 13 + .../data/signalAssignment.1.qml | 5 + .../data/signalAssignment.2.qml | 5 + .../data/signalParameterTypes.qml | 18 + .../data/signalTriggeredBindings.qml | 20 + .../data/signalWithUnknownTypes.qml | 5 + .../qdeclarativeecmascript/data/strictlyEquals.qml | 17 + .../data/transientErrors.2.qml | 14 + .../data/transientErrors.qml | 10 + .../data/undefinedResetsProperty.2.qml | 10 + .../data/undefinedResetsProperty.qml | 7 + .../data/valueTypeFunctions.qml | 6 + .../data/variantsAssignedUndefined.qml | 9 + .../data/writeAttachedProperty.qml | 6 + .../data/writeRemovesBinding.qml | 46 + .../qdeclarativeecmascript.pro | 24 + .../qdeclarativeecmascript/testtypes.cpp | 134 + .../declarative/qdeclarativeecmascript/testtypes.h | 915 ++++++ .../tst_qdeclarativeecmascript.cpp | 3105 ++++++++++++++++++++ 163 files changed, 6326 insertions(+) create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsAssignCorrectlyType.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/ConstantsOverrideBindings.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/CustomObject.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/MethodsObject.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/NestedTypeTransientErrors.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/ScopeObject.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/SpuriousWarning.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/TypeForDynamicCreation.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsAssignCorrectly.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasPropertyAndBinding.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/assignBasicTypes.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/assignBasicTypes.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/attachedProperty.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/attachedProperty.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/attachedPropertyScope.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/bindingLoop.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/blank.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/boolPropertiesEvaluateAsBool.1.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/boolPropertiesEvaluateAsBool.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/bug.1.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/canAssignNullToQObject.1.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/canAssignNullToQObject.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/compositePropertyType.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.1.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.4.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/declarativeToString.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/deferredProperties.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/deferredPropertiesErrors.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/deleteLater.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/deletedEngine.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/deletedObject.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.helper.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/dynamicDeletion.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/enums.1.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/enums.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/eval.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/exception.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/exceptionClearsOnReeval.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/exceptionProducesWarning.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/exceptionProducesWarning2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/extendedObjectPropertyLookup.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/extensionObjects.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/extensionObjectsPropertyOverride.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/function.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.1.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/functionErrors.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/idShortcutInvalidates.1.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/idShortcutInvalidates.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/in.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include_callback.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include_callback.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include_pragma.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include_pragma_inner.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include_pragma_outer.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include_remote.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include_remote.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include_remote_missing.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include_remote_missing.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include_shared.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/include_shared.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/js/include2.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/js/include3.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/jsObject.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/libraryScriptAssert.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/libraryScriptAssert.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/listProperties.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/listToVariant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision4.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/methods.1.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/methods.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/methods.3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/methods.4.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/methods.5.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/multiEngineObject.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/noSpuriousWarningsAtShutdown.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/noSpuriousWarningsAtShutdown.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/nonExistentAttachedObject.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/nonscriptable.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/nullObjectBinding.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/numberAssignment.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/objectName.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/objectsCompareAsEqual.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/outerBindingOverridesInnerBinding.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/ownership.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/propertyAssignmentErrors.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/propertySplicing.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qlistqobjectMethods.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qtbug_10696.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qtbug_11600.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qtbug_11600.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qtbug_11606.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qtbug_20648.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qtbug_9792.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qtcreatorbug_1289.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/regExp.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/remote_file.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scope.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scope.3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scope.4.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scope.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.1.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.1.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.2.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.4.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.5.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.6.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.6.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.1.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.1.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.4.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptErrors.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scriptErrors.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/selfDeletingBinding.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/selfDeletingBinding.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/sharedAttachedObject.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/shutdownErrors.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/signalAssignment.1.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/signalAssignment.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/signalParameterTypes.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/signalTriggeredBindings.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/signalWithUnknownTypes.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/strictlyEquals.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/transientErrors.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/transientErrors.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/undefinedResetsProperty.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/undefinedResetsProperty.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/valueTypeFunctions.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/variantsAssignedUndefined.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/writeAttachedProperty.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/writeRemovesBinding.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro create mode 100644 tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp create mode 100644 tests/auto/declarative/qdeclarativeecmascript/testtypes.h create mode 100644 tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp (limited to 'tests/auto/declarative/qdeclarativeecmascript') diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsAssignCorrectlyType.qml b/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsAssignCorrectlyType.qml new file mode 100644 index 00000000..0eda67d5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsAssignCorrectlyType.qml @@ -0,0 +1,9 @@ +import QtQuick 1.0 + +QtObject { + id: root + + property real realProperty + property alias aliasProperty: root.realProperty +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType.qml b/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType.qml new file mode 100644 index 00000000..f539fb62 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType.qml @@ -0,0 +1,14 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyTypeObject { + id: root + + property int data: 7 + + property int targetProperty: root.data * 43 - root.data + property alias aliasProperty: root.targetProperty + + pointProperty: Qt.point(data, data); + property alias pointAliasProperty: root.pointProperty +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType3.qml new file mode 100644 index 00000000..a4b05274 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/AliasBindingsOverrideTargetType3.qml @@ -0,0 +1,9 @@ +import QtQuick 1.0 + +QtObject { + id: root + + property int testProperty + property alias aliasProperty: root.testProperty +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/ConstantsOverrideBindings.qml b/tests/auto/declarative/qdeclarativeecmascript/data/ConstantsOverrideBindings.qml new file mode 100644 index 00000000..07bb16b0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/ConstantsOverrideBindings.qml @@ -0,0 +1,12 @@ +import Qt.test 1.0 + +MyQmlObject { + property int c1: 0 + property int c2: c1 + property alias c3: inner.ic1 + + objectProperty: MyQmlObject { + id: inner + property int ic1: c1 + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/CustomObject.qml b/tests/auto/declarative/qdeclarativeecmascript/data/CustomObject.qml new file mode 100644 index 00000000..4a425185 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/CustomObject.qml @@ -0,0 +1,5 @@ +import QtQuick 1.0 + +QtObject { + property string greeting: "hello world" +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/MethodsObject.qml b/tests/auto/declarative/qdeclarativeecmascript/data/MethodsObject.qml new file mode 100644 index 00000000..829d405c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/MethodsObject.qml @@ -0,0 +1,6 @@ +import QtQuick 1.0 + +QtObject { + function testFunction() { return 19; } + function testFunction2() { return 18; } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/NestedTypeTransientErrors.qml b/tests/auto/declarative/qdeclarativeecmascript/data/NestedTypeTransientErrors.qml new file mode 100644 index 00000000..f542c64a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/NestedTypeTransientErrors.qml @@ -0,0 +1,11 @@ +import QtQuick 1.0 + +QtObject { + property int b: obj.prop.a + + property variant prop; + prop: QtObject { + property int a: 10 + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/ScopeObject.qml b/tests/auto/declarative/qdeclarativeecmascript/data/ScopeObject.qml new file mode 100644 index 00000000..df494af5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/ScopeObject.qml @@ -0,0 +1,12 @@ +import QtQuick 1.0 + +Item { + property int a: 3 + property int binding: myFunction(); + property int binding2: myCompFunction(); + + function myCompFunction() { + return a; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/SpuriousWarning.qml b/tests/auto/declarative/qdeclarativeecmascript/data/SpuriousWarning.qml new file mode 100644 index 00000000..3427a3b2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/SpuriousWarning.qml @@ -0,0 +1,5 @@ +import QtQuick 1.0 + +Item { + property int children: root.children.length +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/TypeForDynamicCreation.qml b/tests/auto/declarative/qdeclarativeecmascript/data/TypeForDynamicCreation.qml new file mode 100644 index 00000000..56e06252 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/TypeForDynamicCreation.qml @@ -0,0 +1,2 @@ +import Qt.test 1.0 +MyQmlObject{objectName:"objectThree"} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsAssignCorrectly.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsAssignCorrectly.qml new file mode 100644 index 00000000..f0808c4c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsAssignCorrectly.qml @@ -0,0 +1,59 @@ +import QtQuick 1.0 + +Item { + id: root + + property bool test: false + + property real testData: 9 + property real testData2: 9 + + states: State { + name: "change" + PropertyChanges { + target: myType + realProperty: if (testData2 > 3) 9; else 11; + } + } + + AliasBindingsAssignCorrectlyType { + id: myType + + aliasProperty: if (testData > 3) 14; else 12; + } + + Component.onCompleted: { + // Check original binding works + if (myType.aliasProperty != 14) return; + + testData = 2; + if (myType.aliasProperty != 12) return; + + // Change binding indirectly by modifying the "realProperty" + root.state = "change"; + if (myType.aliasProperty != 9) return; + + // Check the new binding works + testData2 = 1; + if (myType.aliasProperty != 11) return; + + // Try and trigger the old binding (that should have been removed) + testData = 6; + if (myType.aliasProperty != 11) return; + + // Restore the original binding + root.state = ""; + if (myType.aliasProperty != 14) return; + + // Test the restored binding works + testData = 0; + if (myType.aliasProperty != 12) return; + + // Test the old binding isn't somehow hanging around and still in effect + testData2 = 13; + if (myType.aliasProperty != 12) return; + + test = true; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.2.qml new file mode 100644 index 00000000..4f07cbf6 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.2.qml @@ -0,0 +1,29 @@ +import QtQuick 1.0 + +Item { + id: me + property bool test: false + + property int value: 9 + + AliasBindingsOverrideTargetType { + id: aliasType + pointAliasProperty.x: me.value + } + + Component.onCompleted: { + if (aliasType.pointAliasProperty.x != 9) return; + + me.value = 11; + if (aliasType.pointAliasProperty.x != 11) return; + + aliasType.data = 8; + if (aliasType.pointAliasProperty.x != 11) return; + + me.value = 4; + if (aliasType.pointAliasProperty.x != 4) return; + + test = true; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.3.qml new file mode 100644 index 00000000..937ae91c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.3.qml @@ -0,0 +1,24 @@ +import QtQuick 1.0 + +Item { + id: root + property bool test: false; + + property int value1: 10 + property int value2: 11 + + AliasBindingsOverrideTargetType3 { + id: obj + + testProperty: root.value1 * 9 + aliasProperty: root.value2 * 10 + } + + Component.onCompleted: { + if (obj.testProperty != 110) return; + if (obj.aliasProperty != 110) return; + + test = true; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.qml new file mode 100644 index 00000000..a01dc5b0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasBindingsOverrideTarget.qml @@ -0,0 +1,28 @@ +import QtQuick 1.0 + +Item { + id: me + property bool test: false + + property int value: 9 + + AliasBindingsOverrideTargetType { + id: aliasType + aliasProperty: me.value + } + + Component.onCompleted: { + if (aliasType.aliasProperty != 9) return; + + me.value = 11; + if (aliasType.aliasProperty != 11) return; + + aliasType.data = 8; + if (aliasType.aliasProperty != 11) return; + + me.value = 4; + if (aliasType.aliasProperty != 4) return; + + test = true; + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasPropertyAndBinding.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasPropertyAndBinding.qml new file mode 100644 index 00000000..da6c795b --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasPropertyAndBinding.qml @@ -0,0 +1,14 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyQmlObject { + property alias c1: myObject.c1 + property int c2: 3 + property int c3: c2 + objectProperty: QtObject { + id: myObject + property int c1 + } +} + + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.2.qml new file mode 100644 index 00000000..5bf9f6a2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.2.qml @@ -0,0 +1,29 @@ +import QtQuick 1.0 + +Item { + id: me + property bool test: false + + property int value: 9 + + AliasBindingsOverrideTargetType { + id: aliasType + } + + Component.onCompleted: { + if (aliasType.aliasProperty != 294) return; + + aliasType.data = 8; + if (aliasType.aliasProperty != 336) return; + + aliasType.aliasProperty = 4; + if (aliasType.aliasProperty != 4) return; + + aliasType.data = 7; + if (aliasType.aliasProperty != 4) return; + + test = true; + } +} + + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.3.qml new file mode 100644 index 00000000..a23ad4a0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.3.qml @@ -0,0 +1,23 @@ +import QtQuick 1.0 + +Item { + id: me + property bool test: false + + property int value: 9 + + AliasBindingsOverrideTargetType { + id: aliasType + pointAliasProperty.x: 9 + } + + Component.onCompleted: { + if (aliasType.pointAliasProperty.x != 9) return; + + aliasType.data = 8; + if (aliasType.pointAliasProperty.x != 9) return; + + test = true; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.qml b/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.qml new file mode 100644 index 00000000..ac203714 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/aliasWritesOverrideBindings.qml @@ -0,0 +1,23 @@ +import QtQuick 1.0 + +Item { + id: me + property bool test: false + + property int value: 9 + + AliasBindingsOverrideTargetType { + id: aliasType + aliasProperty: 11 + } + + Component.onCompleted: { + if (aliasType.aliasProperty != 11) return; + + aliasType.data = 8; + if (aliasType.aliasProperty != 11) return; + + test = true; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/assignBasicTypes.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/assignBasicTypes.2.qml new file mode 100644 index 00000000..2c797296 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/assignBasicTypes.2.qml @@ -0,0 +1,26 @@ +import Qt.test 1.0 + +MyTypeObject { + flagProperty: if(1) "FlagVal1 | FlagVal3" + enumProperty: if(1) "EnumVal2" + stringProperty: if(1) "Hello World!" + uintProperty: if(1) 10 + intProperty: if(1) -19 + realProperty: if(1) 23.2 + doubleProperty: if(1) -19.75 + floatProperty: if(1) 8.5 + colorProperty: if(1) "red" + dateProperty: if(1) "1982-11-25" + timeProperty: if(1) "11:11:32" + dateTimeProperty: if(1) "2009-05-12T13:22:01" + pointProperty: if(1) "99,13" + pointFProperty: if(1) "-10.1,12.3" + sizeProperty: if(1) "99x13" + sizeFProperty: if(1) "0.1x0.2" + rectProperty: if(1) "9,7,100x200" + rectFProperty: if(1) "1000.1,-10.9,400x90.99" + boolProperty: if(1) true + variantProperty: if(1) "Hello World!" + vectorProperty: if(1) "10,1,2.2" + urlProperty: if(1) "main.qml" +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/assignBasicTypes.qml b/tests/auto/declarative/qdeclarativeecmascript/data/assignBasicTypes.qml new file mode 100644 index 00000000..9443c01d --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/assignBasicTypes.qml @@ -0,0 +1,29 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyTypeObject { + Component.onCompleted: { + flagProperty = "FlagVal1 | FlagVal3" + enumProperty = "EnumVal2" + stringProperty = "Hello World!" + uintProperty = 10 + intProperty = -19 + realProperty = 23.2 + doubleProperty = -19.75 + floatProperty = 8.5 + colorProperty = "red" + dateProperty = "1982-11-25" + timeProperty = "11:11:32" + dateTimeProperty = "2009-05-12T13:22:01" + pointProperty = "99,13" + pointFProperty = "-10.1,12.3" + sizeProperty = "99x13" + sizeFProperty = "0.1x0.2" + rectProperty = "9,7,100x200" + rectFProperty = "1000.1,-10.9,400x90.99" + boolProperty = true + variantProperty = "Hello World!" + vectorProperty = "10,1,2.2" + urlProperty = "main.qml" + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/attachedProperty.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/attachedProperty.2.qml new file mode 100644 index 00000000..a7184c92 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/attachedProperty.2.qml @@ -0,0 +1,22 @@ +import Qt.test 1.0 +import Qt.test 1.0 as Namespace + +MyQmlObject { + property alias a: me.a + property alias b: me.a + property alias c: me.a + property alias d: me.a + + property MyQmlObject obj + obj: MyQmlObject { + MyQmlObject.value2: 13 + + id: me + property int a: MyQmlObject.value2 * 2 + property int b: Namespace.MyQmlObject.value2 * 2 + property int c: me.Namespace.MyQmlObject.value * 2 + property int d: me.Namespace.MyQmlObject.value * 2 + } +} + + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/attachedProperty.qml b/tests/auto/declarative/qdeclarativeecmascript/data/attachedProperty.qml new file mode 100644 index 00000000..061eda0e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/attachedProperty.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 +import Qt.test 1.0 as Namespace + +MyQmlObject { + id: me + property int a: MyQmlObject.value + property int b: Namespace.MyQmlObject.value + property int c: me.Namespace.MyQmlObject.value + property int d: me.Namespace.MyQmlObject.value +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/attachedPropertyScope.qml b/tests/auto/declarative/qdeclarativeecmascript/data/attachedPropertyScope.qml new file mode 100644 index 00000000..c66ef693 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/attachedPropertyScope.qml @@ -0,0 +1,9 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +QtObject { + property int value: 9 + property int value2 + + MyQmlObject.onMySignal: value2 = value +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/bindingLoop.qml b/tests/auto/declarative/qdeclarativeecmascript/data/bindingLoop.qml new file mode 100644 index 00000000..80545cf7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/bindingLoop.qml @@ -0,0 +1,14 @@ +import Qt.test 1.0 + +MyQmlContainer { + children : [ + MyQmlObject { + id: object1 + stringProperty: "hello" + object2.stringProperty + }, + MyQmlObject { + id: object2 + stringProperty: "hello" + object1.stringProperty + } + ] +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/blank.js b/tests/auto/declarative/qdeclarativeecmascript/data/blank.js new file mode 100644 index 00000000..e69de29b diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/boolPropertiesEvaluateAsBool.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/boolPropertiesEvaluateAsBool.1.qml new file mode 100644 index 00000000..3147f639 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/boolPropertiesEvaluateAsBool.1.qml @@ -0,0 +1,5 @@ +import Qt.test 1.0 + +MyQmlObject { + stringProperty: trueProperty?'pass':'fail' +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/boolPropertiesEvaluateAsBool.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/boolPropertiesEvaluateAsBool.2.qml new file mode 100644 index 00000000..c89bb49b --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/boolPropertiesEvaluateAsBool.2.qml @@ -0,0 +1,5 @@ +import Qt.test 1.0 + +MyQmlObject { + stringProperty: falseProperty?'fail':'pass' +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/bug.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/bug.1.qml new file mode 100644 index 00000000..68dbcfad --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/bug.1.qml @@ -0,0 +1,10 @@ +import QtQuick 1.0 + +QtObject { + property int a: 10 + property bool b: false + + property int test + + test: ((a == 10)?(a + 1):0) + ((b == true)?9:3) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/canAssignNullToQObject.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/canAssignNullToQObject.1.qml new file mode 100644 index 00000000..3fd9131b --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/canAssignNullToQObject.1.qml @@ -0,0 +1,9 @@ +import Qt.test 1.0 + +MyQmlObject { + property bool runTest: false + + property variant a: MyQmlObject {} + + objectProperty: (runTest == false)?a:null +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/canAssignNullToQObject.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/canAssignNullToQObject.2.qml new file mode 100644 index 00000000..0f232975 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/canAssignNullToQObject.2.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyQmlObject { + objectProperty: MyQmlObject {} + + Component.onCompleted: { + objectProperty = null; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml b/tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml new file mode 100644 index 00000000..58b7adb8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/compiled.qml @@ -0,0 +1,48 @@ +import QtQuick 1.0 + +QtObject { + //real + property real test1: a + b + property real test2: a - b + property bool test3: (a < b) + property bool test4: (a > b) + property bool test5: (a == b) + property bool test6: (a != b) + + //int + property int test7: c + d + property int test8: d - c + property bool test9: (c < d) + property bool test10: (c > d) + property bool test11: (c == d) + property bool test12: (c != d) + + //string + property string test13: e + f + property string test14: e + " " + f + property bool test15: (e == f) + property bool test16: (e != f) + + //type conversion + property int test17: a + property real test18: d + property int test19: g + property real test20: g + property string test21: g + property string test22: h + property bool test23: i + property color test24: j + property color test25: k + + property real a: 4.5 + property real b: 11.2 + property int c: 9 + property int d: 176 + property string e: "Hello" + property string f: "World" + property variant g: 6.7 + property variant h: "!" + property variant i: true + property string j: "#112233" + property string k: "#aa112233" +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/compositePropertyType.qml b/tests/auto/declarative/qdeclarativeecmascript/data/compositePropertyType.qml new file mode 100644 index 00000000..1af77d5a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/compositePropertyType.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 + +QtObject { + property CustomObject myObject + myObject: CustomObject { } + + Component.onCompleted: console.log(myObject.greeting) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.1.qml new file mode 100644 index 00000000..13c5ae5f --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.1.qml @@ -0,0 +1,8 @@ +import Qt.test 1.0 + +MyQmlObject { + property int c1: 0 + property int c2: c1 + + onBasicSignal: c2 = 13 +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.2.qml new file mode 100644 index 00000000..207a06b7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.2.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 + +MyQmlObject { + property alias c1: myConstants.c1 + property alias c2: myConstants.c2 + + objectProperty: ConstantsOverrideBindings { + id: myConstants + c2: 10 + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.3.qml new file mode 100644 index 00000000..ca9d1d8a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.3.qml @@ -0,0 +1,7 @@ +import Qt.test 1.0 + +MyQmlObject { + property int c1: 0 + property int c2: c1 +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.4.qml new file mode 100644 index 00000000..5a2091f7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/constantsOverrideBindings.4.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 + +MyQmlObject { + property alias c1: myConstants.c1 + property alias c3: myConstants.c3 + + objectProperty: ConstantsOverrideBindings { + id: myConstants + c3: 10 + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/declarativeToString.qml b/tests/auto/declarative/qdeclarativeecmascript/data/declarativeToString.qml new file mode 100644 index 00000000..ac296ce2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/declarativeToString.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 + +MyQmlObject{ + id: obj + objectName: "objName" + function testToString() + { + obj.stringProperty = obj.toString(); + } + +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/deferredProperties.qml b/tests/auto/declarative/qdeclarativeecmascript/data/deferredProperties.qml new file mode 100644 index 00000000..e01f708a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/deferredProperties.qml @@ -0,0 +1,10 @@ +import Qt.test 1.0 + +MyDeferredObject { + id: root + value: 10 + objectProperty: MyQmlObject { + value: root.value + } + objectProperty2: MyQmlObject { id: blah } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/deferredPropertiesErrors.qml b/tests/auto/declarative/qdeclarativeecmascript/data/deferredPropertiesErrors.qml new file mode 100644 index 00000000..18a57ba6 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/deferredPropertiesErrors.qml @@ -0,0 +1,10 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyDeferredObject { + value: undefined // error is resolved before complete + objectProperty: undefined // immediate error + objectProperty2: QtObject { + Component.onCompleted: value = 10 + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/deleteLater.qml b/tests/auto/declarative/qdeclarativeecmascript/data/deleteLater.qml new file mode 100644 index 00000000..131fa6f2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/deleteLater.qml @@ -0,0 +1,14 @@ +import QtQuick 1.0 + +QtObject { + id: root + property bool test: false + + Component.onCompleted: { + try { + root.deleteLater() + } catch(e) { + test = true; + } + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/deletedEngine.qml b/tests/auto/declarative/qdeclarativeecmascript/data/deletedEngine.qml new file mode 100644 index 00000000..4de405dc --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/deletedEngine.qml @@ -0,0 +1,11 @@ +import QtQuick 1.0 + +QtObject { + function calculate() { + return b * 13; + } + + property int a: calculate() + property int b: 3 +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/deletedObject.qml b/tests/auto/declarative/qdeclarativeecmascript/data/deletedObject.qml new file mode 100644 index 00000000..7ba51ef0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/deletedObject.qml @@ -0,0 +1,25 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +QtObject { + property variant obj + obj: MyQmlObject { + id: myObject + value: 92 + } + + property bool test1: false + property bool test2: false + property bool test3: false + property bool test4: false + + Component.onCompleted: { + test1 = myObject.value == 92; + test2 = obj.value == 92; + + myObject.deleteOnSet = 1; + + test3 = myObject == null + test4 = obj == null + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.helper.qml b/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.helper.qml new file mode 100644 index 00000000..d790d634 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.helper.qml @@ -0,0 +1,6 @@ +import Qt.test 1.0 + +MyQmlObject{ + objectName: "objectTwo" +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.qml b/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.qml new file mode 100644 index 00000000..7b132e1e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.qml @@ -0,0 +1,27 @@ +import Qt.test 1.0 + +MyQmlObject{ + id: obj + objectName: "obj" + function createOne() + { + obj.objectProperty = Qt.createQmlObject('import Qt.test 1.0; MyQmlObject{objectName:"objectOne"}', obj); + } + + function createTwo() + { + var component = Qt.createComponent('dynamicCreation.helper.qml'); + obj.objectProperty = component.createObject(obj); + } + + function createThree() + { + obj.objectProperty = Qt.createQmlObject('TypeForDynamicCreation{}', obj); + } + + function dontCrash() + { + var component = Qt.createComponent('file-doesnt-exist.qml'); + obj.objectProperty = component.createObject(obj); + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/dynamicDeletion.qml b/tests/auto/declarative/qdeclarativeecmascript/data/dynamicDeletion.qml new file mode 100644 index 00000000..f41e5262 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/dynamicDeletion.qml @@ -0,0 +1,20 @@ +import Qt.test 1.0 + +MyQmlObject{ + id: obj + objectName: "obj" + function create() + { + obj.objectProperty = Qt.createQmlObject('import Qt.test 1.0; MyQmlObject{objectName:"emptyObject"}', obj); + } + + function killOther() + { + obj.objectProperty.destroy(500); + } + + function killMe() + { + obj.destroy();//Must not segfault + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/enums.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/enums.1.qml new file mode 100644 index 00000000..63518232 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/enums.1.qml @@ -0,0 +1,20 @@ +import Qt.test 1.0 +import Qt.test 1.0 as Namespace + +MyQmlObject { + // Enums from non-namespaced type + property int a: MyQmlObject.EnumValue1 + property int b: MyQmlObject.EnumValue2 + property int c: MyQmlObject.EnumValue3 + property int d: MyQmlObject.EnumValue4 + + // Enums from namespaced type + property int e: Namespace.MyQmlObject.EnumValue1 + property int f: Namespace.MyQmlObject.EnumValue2 + property int g: Namespace.MyQmlObject.EnumValue3 + property int h: Namespace.MyQmlObject.EnumValue4 + + // Test that enums don't mask attached properties + property int i: MyQmlObject.value + property int j: Namespace.MyQmlObject.value +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/enums.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/enums.2.qml new file mode 100644 index 00000000..bdc672fa --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/enums.2.qml @@ -0,0 +1,8 @@ +import Qt.test 1.0 +import Qt.test 1.0 as Namespace + +MyQmlObject { + property int a: MyQmlObject.EnumValue10 + property int b: Namespace.MyQmlObject.EnumValue10 +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/eval.qml b/tests/auto/declarative/qdeclarativeecmascript/data/eval.qml new file mode 100644 index 00000000..661cd5c4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/eval.qml @@ -0,0 +1,27 @@ +import QtQuick 1.0 + +QtObject { + property bool test1: false; + property bool test2: false; + property bool test3: false; + property bool test4: false; + property bool test5: false; + + + property int a: 7 + property int b: 8 + + Component.onCompleted: { + var b = 9; + + test1 = (eval("a") == 7); + test2 = (eval("b") == 9); + try { + eval("c"); + } catch(e) { + test3 = true; + } + test4 = (eval("console") == console); + test5 = (eval("Qt") == Qt); + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/exception.js b/tests/auto/declarative/qdeclarativeecmascript/data/exception.js new file mode 100644 index 00000000..160bbfa5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/exception.js @@ -0,0 +1 @@ +throw("Whoops!"); diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/exceptionClearsOnReeval.qml b/tests/auto/declarative/qdeclarativeecmascript/data/exceptionClearsOnReeval.qml new file mode 100644 index 00000000..a2f0d1a8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/exceptionClearsOnReeval.qml @@ -0,0 +1,6 @@ +import Qt.test 1.0 + +MyQmlObject { + property bool test: objectProperty.objectProperty.trueProperty +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/exceptionProducesWarning.qml b/tests/auto/declarative/qdeclarativeecmascript/data/exceptionProducesWarning.qml new file mode 100644 index 00000000..2102821a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/exceptionProducesWarning.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyQmlObject { + Component.onCompleted: + { throw(new Error("JS exception")) } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/exceptionProducesWarning2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/exceptionProducesWarning2.qml new file mode 100644 index 00000000..c197ef83 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/exceptionProducesWarning2.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyQmlObject { + value: { throw(new Error("JS exception")) } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/extendedObjectPropertyLookup.qml b/tests/auto/declarative/qdeclarativeecmascript/data/extendedObjectPropertyLookup.qml new file mode 100644 index 00000000..9738d2cf --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/extendedObjectPropertyLookup.qml @@ -0,0 +1,8 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +QtObject { + property MyExtendedObject a; + a: MyExtendedObject { id: root } + property int b: Math.max(root.extendedProperty, 0) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/extensionObjects.qml b/tests/auto/declarative/qdeclarativeecmascript/data/extensionObjects.qml new file mode 100644 index 00000000..b0e897ef --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/extensionObjects.qml @@ -0,0 +1,19 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyExtendedObject +{ + baseProperty: baseExtendedProperty + baseExtendedProperty: 13 + + coreProperty: extendedProperty + extendedProperty: 9 + + property QtObject nested: MyExtendedObject { + baseProperty: baseExtendedProperty + baseExtendedProperty: 13 + + coreProperty: extendedProperty + extendedProperty: 9 + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/extensionObjectsPropertyOverride.qml b/tests/auto/declarative/qdeclarativeecmascript/data/extensionObjectsPropertyOverride.qml new file mode 100644 index 00000000..3c443cb9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/extensionObjectsPropertyOverride.qml @@ -0,0 +1,7 @@ +import Qt.test 1.0 + +OverrideDefaultPropertyObject +{ + MyBaseExtendedObject { + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/function.qml b/tests/auto/declarative/qdeclarativeecmascript/data/function.qml new file mode 100644 index 00000000..6cd8751c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/function.qml @@ -0,0 +1,23 @@ +import QtQuick 1.0 + +QtObject { + property bool test1: false; + property bool test2: false; + property bool test3: false; + + Component.onCompleted: { + var a = 10; + + var func1 = new Function("a", "return a + 7"); + var func2 = new Function("a", "return Qt.atob(a)"); + var func3 = new Function("return a"); + + test1 = (func1(4) == 11); + test2 = (func2("Hello World!") == Qt.atob("Hello World!")); + try { + func3(); + } catch(e) { + test3 = true; + } + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.1.qml new file mode 100644 index 00000000..09540f1f --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.1.qml @@ -0,0 +1,5 @@ +import Qt.test 1.0 + +MyQmlObject { + property variant a: function myFunction() { return 2; } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.2.qml new file mode 100644 index 00000000..c8c926ae --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.2.qml @@ -0,0 +1,73 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +import "functionAssignment.js" as Script + +MyQmlObject { + property variant a + property int aNumber: 10 + + property bool assignToProperty: false + property bool assignToPropertyFromJsFile: false + + property bool assignWithThis: false + property bool assignWithThisFromJsFile: false + + property bool assignToValueType: false + + property bool assignFuncWithoutReturn: false + property bool assignWrongType: false + property bool assignWrongTypeToValueType: false + + + onAssignToPropertyChanged: { + function myFunction() { + return aNumber * 10; + } + a = myFunction; + } + + property QtObject obj: QtObject { + property int aNumber: 4212 + function myFunction() { + return this.aNumber * 10; // should use the aNumber from root, not this object + } + } + onAssignWithThisChanged: { + a = obj.myFunction; + } + + onAssignToPropertyFromJsFileChanged: { + Script.bindPropertyWithThis() + } + + onAssignWithThisFromJsFileChanged: { + Script.bindProperty() + } + + property Text text: Text { } + onAssignToValueTypeChanged: { + text.font.pixelSize = (function() { return aNumber * 10; }) + a = (function() { return text.font.pixelSize; }) + } + + + // detecting errors: + + onAssignFuncWithoutReturnChanged: { + function myFunction() { + } + a = myFunction; + } + + onAssignWrongTypeChanged: { + function myFunction() { + return 'a string'; + } + aNumber = myFunction; + } + + onAssignWrongTypeToValueTypeChanged: { + text.font.pixelSize = (function() { return 'a string'; }) + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.js b/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.js new file mode 100644 index 00000000..14daa762 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.js @@ -0,0 +1,17 @@ +function bindProperty() +{ + a = (function(){ return aNumber * 10 }) +} + + +function TestObject() { } +TestObject.prototype.aNumber = 928349 +TestObject.prototype.bindFunction = function() { + return this.aNumber * 10 // this should not use the TestObject's aNumber +} +var testObj = new TestObject() + +function bindPropertyWithThis() +{ + a = testObj.bindFunction +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/functionErrors.qml b/tests/auto/declarative/qdeclarativeecmascript/data/functionErrors.qml new file mode 100644 index 00000000..2ba02d1d --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/functionErrors.qml @@ -0,0 +1,10 @@ +import QtQuick 1.0 + +QtObject { + function myFunction() { + a = 10; + } + + Component.onCompleted: myFunction(); +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/idShortcutInvalidates.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/idShortcutInvalidates.1.qml new file mode 100644 index 00000000..6dcdefcb --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/idShortcutInvalidates.1.qml @@ -0,0 +1,13 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyQmlObject { + objectProperty: if(1) otherObject + + property variant obj + + obj: QtObject { + id: otherObject + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/idShortcutInvalidates.qml b/tests/auto/declarative/qdeclarativeecmascript/data/idShortcutInvalidates.qml new file mode 100644 index 00000000..32b86110 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/idShortcutInvalidates.qml @@ -0,0 +1,12 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyQmlObject { + objectProperty: otherObject + + property variant obj + + obj: QtObject { + id: otherObject + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/in.qml b/tests/auto/declarative/qdeclarativeecmascript/data/in.qml new file mode 100644 index 00000000..f9cccb5a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/in.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 + +Item { + id: root + property bool test1: "x" in root + property bool test2: !("foo" in root) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include.js b/tests/auto/declarative/qdeclarativeecmascript/data/include.js new file mode 100644 index 00000000..232fd808 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include.js @@ -0,0 +1,8 @@ +var test1 = true +var test2 = false +var test3 = false + +function go() { + Qt.include("js/include2.js"); +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include.qml b/tests/auto/declarative/qdeclarativeecmascript/data/include.qml new file mode 100644 index 00000000..61b04618 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include.qml @@ -0,0 +1,23 @@ +import QtQuick 1.0 +import "include.js" as IncludeTest + +QtObject { + property int test0: 0 + property bool test1: false + property bool test2: false + property bool test2_1: false + property bool test3: false + property bool test3_1: false + + property int testValue: 99 + + Component.onCompleted: { + IncludeTest.go(); + test0 = IncludeTest.value + test1 = IncludeTest.test1 + test2 = IncludeTest.test2 + test2_1 = IncludeTest.test2_1 + test3 = IncludeTest.test3 + test3_1 = IncludeTest.test3_1 + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include_callback.js b/tests/auto/declarative/qdeclarativeecmascript/data/include_callback.js new file mode 100644 index 00000000..ea19eba3 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include_callback.js @@ -0,0 +1,11 @@ +function go() { + var a = Qt.include("missing.js", function(o) { test2 = o.status == o.NETWORK_ERROR }); + test1 = a.status == a.NETWORK_ERROR + + var b = Qt.include("blank.js", function(o) { test4 = o.status == o.OK }); + test3 = b.status == b.OK + + var c = Qt.include("exception.js", function(o) { test6 = o.status == o.EXCEPTION }); + test5 = c.status == c.EXCEPTION +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include_callback.qml b/tests/auto/declarative/qdeclarativeecmascript/data/include_callback.qml new file mode 100644 index 00000000..1633ebaa --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include_callback.qml @@ -0,0 +1,15 @@ +import QtQuick 1.0 +import "include_callback.js" as IncludeTest + +QtObject { + property bool test1: false + property bool test2: false + property bool test3: false + property bool test4: false + property bool test5: false + property bool test6: false + + Component.onCompleted: { + IncludeTest.go(); + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include_pragma.qml b/tests/auto/declarative/qdeclarativeecmascript/data/include_pragma.qml new file mode 100644 index 00000000..a6489694 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include_pragma.qml @@ -0,0 +1,11 @@ +import QtQuick 1.0 +import "include_pragma_outer.js" as Script + +Item { + property int test1 + + Component.onCompleted: { + test1 = Script.callFunction() + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include_pragma_inner.js b/tests/auto/declarative/qdeclarativeecmascript/data/include_pragma_inner.js new file mode 100644 index 00000000..a0380a25 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include_pragma_inner.js @@ -0,0 +1,5 @@ +.pragma library + +function getValue() { + return 100; +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include_pragma_outer.js b/tests/auto/declarative/qdeclarativeecmascript/data/include_pragma_outer.js new file mode 100644 index 00000000..d87bafc8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include_pragma_outer.js @@ -0,0 +1,6 @@ +Qt.include("include_pragma_inner.js") + +function callFunction() { + return getValue(); +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include_remote.js b/tests/auto/declarative/qdeclarativeecmascript/data/include_remote.js new file mode 100644 index 00000000..e6a46768 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include_remote.js @@ -0,0 +1,26 @@ +var myvar = 10; + +function go() +{ + var a = Qt.include("http://127.0.0.1:8111/remote_file.js", + function(o) { + test2 = o.status == o.OK + test3 = a.status == a.OK + test4 = myvar == 13 + + done = true; + }); + test1 = a.status == a.LOADING + + + var b = Qt.include("http://127.0.0.1:8111/exception.js", + function(o) { + test7 = o.status == o.EXCEPTION + test8 = b.status == a.EXCEPTION + test9 = b.exception.toString() == "Whoops!"; + test10 = o.exception.toString() == "Whoops!"; + + done2 = true; + }); + test6 = b.status == b.LOADING +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include_remote.qml b/tests/auto/declarative/qdeclarativeecmascript/data/include_remote.qml new file mode 100644 index 00000000..0dfc74ff --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include_remote.qml @@ -0,0 +1,21 @@ +import QtQuick 1.0 +import "include_remote.js" as IncludeTest + +QtObject { + property bool done: false + property bool done2: false + + property bool test1: false + property bool test2: false + property bool test3: false + property bool test4: false + property bool test5: false + + property bool test6: false + property bool test7: false + property bool test8: false + property bool test9: false + property bool test10: false + + Component.onCompleted: IncludeTest.go(); +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include_remote_missing.js b/tests/auto/declarative/qdeclarativeecmascript/data/include_remote_missing.js new file mode 100644 index 00000000..cc90860c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include_remote_missing.js @@ -0,0 +1,13 @@ +function go() +{ + var a = Qt.include("http://127.0.0.1:8111/missing.js", + function(o) { + test2 = o.status == o.NETWORK_ERROR + test3 = a.status == a.NETWORK_ERROR + + done = true; + }); + + test1 = a.status == a.LOADING +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include_remote_missing.qml b/tests/auto/declarative/qdeclarativeecmascript/data/include_remote_missing.qml new file mode 100644 index 00000000..05a73996 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include_remote_missing.qml @@ -0,0 +1,12 @@ +import QtQuick 1.0 +import "include_remote_missing.js" as IncludeTest + +QtObject { + property bool done: false + + property bool test1: false + property bool test2: false + property bool test3: false + + Component.onCompleted: IncludeTest.go(); +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include_shared.js b/tests/auto/declarative/qdeclarativeecmascript/data/include_shared.js new file mode 100644 index 00000000..a49c07bb --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include_shared.js @@ -0,0 +1,12 @@ +.pragma library + +var test1 = true +var test2 = false +var test3 = false + +var testValue = 99; + +function go() { + Qt.include("js/include2.js"); +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/include_shared.qml b/tests/auto/declarative/qdeclarativeecmascript/data/include_shared.qml new file mode 100644 index 00000000..e9f1c89b --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/include_shared.qml @@ -0,0 +1,22 @@ +import QtQuick 1.0 +import "include_shared.js" as IncludeTest + +QtObject { + property int test0: 0 + property bool test1: false + property bool test2: false + property bool test2_1: false + property bool test3: false + property bool test3_1: false + + Component.onCompleted: { + IncludeTest.go(); + test0 = IncludeTest.value + test1 = IncludeTest.test1 + test2 = IncludeTest.test2 + test2_1 = IncludeTest.test2_1 + test3 = IncludeTest.test3 + test3_1 = IncludeTest.test3_1 + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml new file mode 100644 index 00000000..6ab25f27 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml @@ -0,0 +1,9 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyQmlObject { + id: root + Component.onCompleted: { + root.myinvokable(root); + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml new file mode 100644 index 00000000..87b2d7e4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyQmlObject { + id: root + property bool test: false + Component.onCompleted: { + test = (root.returnme() == root) + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/js/include2.js b/tests/auto/declarative/qdeclarativeecmascript/data/js/include2.js new file mode 100644 index 00000000..2a0c039d --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/js/include2.js @@ -0,0 +1,4 @@ +test2 = true +var test2_1 = true + +Qt.include("include3.js"); diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/js/include3.js b/tests/auto/declarative/qdeclarativeecmascript/data/js/include3.js new file mode 100644 index 00000000..84b2770b --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/js/include3.js @@ -0,0 +1,3 @@ +test3 = true +var test3_1 = true +var value = testValue diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/jsObject.qml b/tests/auto/declarative/qdeclarativeecmascript/data/jsObject.qml new file mode 100644 index 00000000..e93007ab --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/jsObject.qml @@ -0,0 +1,12 @@ +import QtQuick 1.0 + +QtObject { + property int test + + Component.onCompleted: { + var o = new Object; + o.test = 92; + test = o.test; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/libraryScriptAssert.js b/tests/auto/declarative/qdeclarativeecmascript/data/libraryScriptAssert.js new file mode 100644 index 00000000..3ffdb339 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/libraryScriptAssert.js @@ -0,0 +1,6 @@ +.pragma library + +function test(target) +{ + var a = target.a; +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/libraryScriptAssert.qml b/tests/auto/declarative/qdeclarativeecmascript/data/libraryScriptAssert.qml new file mode 100644 index 00000000..c0789424 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/libraryScriptAssert.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 +import "libraryScriptAssert.js" as Test + +QtObject { + id: root + Component.onCompleted: Test.test(root); +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/listProperties.qml b/tests/auto/declarative/qdeclarativeecmascript/data/listProperties.qml new file mode 100644 index 00000000..7b940758 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/listProperties.qml @@ -0,0 +1,24 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyQmlObject { + id: root + + objectListProperty: [ + QtObject { property int a: 10 }, + QtObject { property int a: 11 } + ] + + function calcTest1() { + var rv = 0; + for (var ii = 0; ii < root.objectListProperty.length; ++ii) { + rv += root.objectListProperty[ii].a; + } + return rv; + } + + property int test1: calcTest1(); + property int test2: root.objectListProperty.length + property bool test3: root.objectListProperty[1] != undefined + property bool test4: root.objectListProperty[100] == undefined +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/listToVariant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/listToVariant.qml new file mode 100644 index 00000000..7940ab8c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/listToVariant.qml @@ -0,0 +1,5 @@ +import QtQuick 1.0 + +QtObject { + property variant test: children +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision.qml new file mode 100644 index 00000000..77accd80 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision.qml @@ -0,0 +1,7 @@ +import Qt.test 1.1 + +MyRevisionedClass +{ + prop1: prop2 + onSignal1: method2() +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision2.qml new file mode 100644 index 00000000..36057cb9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision2.qml @@ -0,0 +1,9 @@ +import Qt.test 1.1 + +MyRevisionedSubclass +{ + prop1: prop3 + onSignal1: method2() + prop3: prop4 + onSignal3: method4() +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision3.qml new file mode 100644 index 00000000..81769e98 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision3.qml @@ -0,0 +1,8 @@ +import Qt.test 1.0 + +MyRevisionedSubclass +{ + prop1: prop3 + onSignal1: method1() + onSignal3: method3() +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision4.qml new file mode 100644 index 00000000..81ea5366 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision4.qml @@ -0,0 +1,14 @@ +import Qt.test 1.1 +import QtQuick 1.0 + +QtObject { + property variant a + property real test + + a: MyRevisionedClass { + prop2: 11 + + Component.onCompleted: test = prop2 + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors.qml new file mode 100644 index 00000000..44d421e8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors.qml @@ -0,0 +1,14 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyRevisionedClass +{ + // Will not hit optimizer + property real p1: prop1 % 3 + property real p2: prop2 % 3 + + // Should hit optimizer + property real p3: prop2 + + Component.onCompleted: method2() +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors2.qml new file mode 100644 index 00000000..121642e0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors2.qml @@ -0,0 +1,24 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyRevisionedSubclass +{ + // Will not hit optimizer + property real p1: prop1 % 3 + property real p2: prop2 % 3 + property real p3: prop3 % 3 + property real p4: prop4 % 3 + + // Should hit optimizer + property real p5: prop1 + property real p6: prop2 + property real p7: prop3 + property real p8: prop4 + + Component.onCompleted: { + method1() + method2() + method3() + method4() + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors3.qml new file mode 100644 index 00000000..123650e4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors3.qml @@ -0,0 +1,36 @@ +import QtQuick 1.0 +import Qt.test 1.1 + +MyRevisionedSubclass +{ + // Will not hit optimizer + property real pA: propA % 3 + property real pB: propB % 3 + property real pC: propC % 3 + property real pD: propD % 3 + property real p1: prop1 % 3 + property real p2: prop2 % 3 + property real p3: prop3 % 3 + property real p4: prop4 % 3 + + // Should hit optimizer + property real pE: propA + property real pF: propB + property real pG: propC + property real pH: propD + property real p5: prop1 + property real p6: prop2 + property real p7: prop3 + property real p8: prop4 + + Component.onCompleted: { + methodA() + methodB() + methodC() + methodD() + method1() + method2() + method3() + method4() + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/methods.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/methods.1.qml new file mode 100644 index 00000000..0bbee16d --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/methods.1.qml @@ -0,0 +1,6 @@ +import Qt.test 1.0 + +MyQmlObject { + id: myObject + onBasicSignal: myObject.methodNoArgs() +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/methods.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/methods.2.qml new file mode 100644 index 00000000..9f0c6b15 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/methods.2.qml @@ -0,0 +1,6 @@ +import Qt.test 1.0 + +MyQmlObject { + id: myObject + onBasicSignal: myObject.method(163) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/methods.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/methods.3.qml new file mode 100644 index 00000000..1090b48f --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/methods.3.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 + +QtObject { + function testFunction() { return 19; } + + property int test: testFunction() +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/methods.4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/methods.4.qml new file mode 100644 index 00000000..34c50d66 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/methods.4.qml @@ -0,0 +1,11 @@ +import QtQuick 1.0 + +MethodsObject { + function testFunction2() { return 17; } + function testFunction3() { return 16; } + + property int test: testFunction() + property int test2: testFunction2() + property int test3: testFunction3() +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/methods.5.qml b/tests/auto/declarative/qdeclarativeecmascript/data/methods.5.qml new file mode 100644 index 00000000..bebdf3d8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/methods.5.qml @@ -0,0 +1,9 @@ +import QtQuick 1.0 + +Item { + property alias blah: item.x + Item { id: item } + + function testFunction() { return 9; } + property int test: testFunction(); +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/multiEngineObject.qml b/tests/auto/declarative/qdeclarativeecmascript/data/multiEngineObject.qml new file mode 100644 index 00000000..d9c63e67 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/multiEngineObject.qml @@ -0,0 +1,5 @@ +import QtQuick 1.0 + +QtObject { + property string test: thing.stringProperty +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/noSpuriousWarningsAtShutdown.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/noSpuriousWarningsAtShutdown.2.qml new file mode 100644 index 00000000..9e0bcf09 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/noSpuriousWarningsAtShutdown.2.qml @@ -0,0 +1,10 @@ +import QtQuick 1.0 + +Item { + id: root + + Item {} + + SpuriousWarning {} +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/noSpuriousWarningsAtShutdown.qml b/tests/auto/declarative/qdeclarativeecmascript/data/noSpuriousWarningsAtShutdown.qml new file mode 100644 index 00000000..7e7da8d7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/noSpuriousWarningsAtShutdown.qml @@ -0,0 +1,9 @@ +import QtQuick 1.0 + +Item { + id: root + + property int childrenCount: root.children.length + + Item {} +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/nonExistentAttachedObject.qml b/tests/auto/declarative/qdeclarativeecmascript/data/nonExistentAttachedObject.qml new file mode 100644 index 00000000..f9585db0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/nonExistentAttachedObject.qml @@ -0,0 +1,5 @@ +import Qt.test 1.0 + +MyQmlObject { + stringProperty: MyQmlContainer.prop +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/nonscriptable.qml b/tests/auto/declarative/qdeclarativeecmascript/data/nonscriptable.qml new file mode 100644 index 00000000..e86cc961 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/nonscriptable.qml @@ -0,0 +1,19 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyQmlObject { + id: root + + property bool readOk: false; + property bool writeOk: false + + Component.onCompleted: { + readOk = (root.nonscriptable == undefined); + + try { + root.nonscriptable = 10 + } catch (e) { + writeOk = true; + } + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/nullObjectBinding.qml b/tests/auto/declarative/qdeclarativeecmascript/data/nullObjectBinding.qml new file mode 100644 index 00000000..cbd2d3e7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/nullObjectBinding.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 + +QtObject { + property QtObject test + test: if (1) model + property ListModel model +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/numberAssignment.qml b/tests/auto/declarative/qdeclarativeecmascript/data/numberAssignment.qml new file mode 100644 index 00000000..30a77e8a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/numberAssignment.qml @@ -0,0 +1,18 @@ +import Qt.test 1.0 + +NumberAssignment { + test1: if (1) 6.7 + test2: if (1) "6.7" + test3: if (1) 6 + test4: if (1) "6" + + test5: if (1) 6.7 + test6: if (1) "6.7" + test7: if (1) 6 + test8: if (1) "6" + + test9: if (1) 6.7 + test10: if (1) "6.7" + test11: if (1) 6 + test12: if (1) "6" +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/objectName.qml b/tests/auto/declarative/qdeclarativeecmascript/data/objectName.qml new file mode 100644 index 00000000..ca8c90d8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/objectName.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 + +QtObject { + objectName: "hello" + + property string test1: objectName + property string test2: objectName.substr(1, 3) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/objectsCompareAsEqual.qml b/tests/auto/declarative/qdeclarativeecmascript/data/objectsCompareAsEqual.qml new file mode 100644 index 00000000..ef0e304a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/objectsCompareAsEqual.qml @@ -0,0 +1,15 @@ +import QtQuick 1.0 + +Item { + id: root + + property variant item: child + Item { id: child } + + property bool test1: child == child + property bool test2: child.parent == root + property bool test3: root != child + property bool test4: item == child + property bool test5: item != root +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/outerBindingOverridesInnerBinding.qml b/tests/auto/declarative/qdeclarativeecmascript/data/outerBindingOverridesInnerBinding.qml new file mode 100644 index 00000000..090c948f --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/outerBindingOverridesInnerBinding.qml @@ -0,0 +1,15 @@ +import Qt.test 1.0 + +MyQmlObject { + id: obj + property alias c1: myConstants.c1 + property alias c2: myConstants.c2 + property int c3: 0 + + objectProperty: ConstantsOverrideBindings { + id: myConstants + c2: obj.c3 + } + +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/ownership.qml b/tests/auto/declarative/qdeclarativeecmascript/data/ownership.qml new file mode 100644 index 00000000..53427b76 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/ownership.qml @@ -0,0 +1,5 @@ +import QtQuick 1.0 + +QtObject { + Component.onCompleted: { var a = getObject(); a = null; } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyAssignmentErrors.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyAssignmentErrors.qml new file mode 100644 index 00000000..a778dcc8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyAssignmentErrors.qml @@ -0,0 +1,22 @@ +import QtQuick 1.0 + +QtObject { + id: root + + property int a + property variant b + + Component.onCompleted: { + try { + root.a = undefined; + } catch(e) { + console.log (e.fileName + ":" + e.lineNumber + ":" + e); + } + + try { + root.a = "Hello"; + } catch(e) { + console.log (e.fileName + ":" + e.lineNumber + ":" + e); + } + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertySplicing.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertySplicing.qml new file mode 100644 index 00000000..7deb84a1 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertySplicing.qml @@ -0,0 +1,10 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyDerivedObject { + property bool test: false + + Component.onCompleted: { + test = intProperty() + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistqobjectMethods.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistqobjectMethods.qml new file mode 100644 index 00000000..2e9e1736 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qlistqobjectMethods.qml @@ -0,0 +1,6 @@ +import QtQuick 1.0 + +QtObject { + property int test: getObjects().length + property bool test2: getObjects()[0].trueProperty +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_10696.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_10696.qml new file mode 100644 index 00000000..02357d45 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_10696.qml @@ -0,0 +1,26 @@ +import QtQuick 1.0 + +QtObject { + property string test: "aaaa" + + "bbbb" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc" + + "cccc"; +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_11600.js b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_11600.js new file mode 100644 index 00000000..092bc2b0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_11600.js @@ -0,0 +1 @@ +; diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_11600.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_11600.qml new file mode 100644 index 00000000..b7bb3666 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_11600.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 +import "qtbug_11600.js" as Test + +QtObject { + id: goo + + property bool test: undefined == goo.Test.foo +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_11606.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_11606.qml new file mode 100644 index 00000000..05c482ca --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_11606.qml @@ -0,0 +1,12 @@ +import QtQuick 1.0 + +QtObject { + property bool test: false + Component.onCompleted: { + try { + console.log(sorryNoSuchProperty); + } catch (e) { + test = true; + } + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_20648.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_20648.qml new file mode 100644 index 00000000..40f21ef7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_20648.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 + +QtObject { + property bool hd: true + + property real test: ((hd ? 100 : 20) + 0) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_9792.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_9792.qml new file mode 100644 index 00000000..9ac44308 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_9792.qml @@ -0,0 +1,5 @@ +import Qt.test 1.0 + +MyQmlObject { + onBasicSignal: print("Hello world!"); +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qtcreatorbug_1289.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qtcreatorbug_1289.qml new file mode 100644 index 00000000..e531efcd --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qtcreatorbug_1289.qml @@ -0,0 +1,13 @@ +import QtQuick 1.0 + +QtObject { + id: root + property QtObject object: QtObject { + id: nested + property QtObject nestedObject + } + + Component.onCompleted: { + nested.nestedObject = root; + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml b/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml new file mode 100644 index 00000000..cbbbbf92 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml @@ -0,0 +1,11 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyQmlObject { + function test1() { + value = 4.2 + } + function test2() { + value = 7.9 + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/regExp.qml b/tests/auto/declarative/qdeclarativeecmascript/data/regExp.qml new file mode 100644 index 00000000..0dc404b5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/regExp.qml @@ -0,0 +1,7 @@ +import Qt.test 1.0 + +MyQmlObject{ + id: obj + objectName: "obj" + regExp: /[a-zA-z]/ +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/remote_file.js b/tests/auto/declarative/qdeclarativeecmascript/data/remote_file.js new file mode 100644 index 00000000..1b123aee --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/remote_file.js @@ -0,0 +1,2 @@ +myvar = 13; +test5 = true; diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scope.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scope.2.qml new file mode 100644 index 00000000..9555b7f9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scope.2.qml @@ -0,0 +1,40 @@ +import QtQuick 1.0 + +Item { + property int a: 0 + property int b: 14 + + function b() { return 11; } + function c() { return 33; } + + QtObject { + id: a + property int value: 19 + } + + QtObject { + id: c + property int value: 24 + } + + QtObject { + id: nested + property int a: 1 + property int test: a.value + property int test2: b + property int test3: c.value + } + + + // id takes precedence over local, and root properties + property int test1: a.value + property alias test2: nested.test + + // properties takes precedence over local, and root methods + property int test3: b + property alias test4: nested.test2 + + // id takes precedence over methods + property int test5: c.value + property alias test6: nested.test3 +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scope.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scope.3.qml new file mode 100644 index 00000000..0b0770e6 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scope.3.qml @@ -0,0 +1,13 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyQmlObject { + id: root + + property int foo: 12 + + property bool test1: foo == 12 + property bool test2: console != 11 + property bool test3: root.console == 11 +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scope.4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scope.4.qml new file mode 100644 index 00000000..d65b6e7c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scope.4.qml @@ -0,0 +1,12 @@ +import Qt.test 1.0 + +MyQmlObject { + id: a + property int b: 9 + + property int test + property string test2 + + // Should resolve to signal arguments, not to other elements in the file + onArgumentSignal: { test = a; test2 = b; } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scope.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scope.qml new file mode 100644 index 00000000..63dba2fc --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scope.qml @@ -0,0 +1,44 @@ +import QtQuick 1.0 + +Item { + id: root + + property int a: 1 + property int binding: a + property string binding2: a + "Test" + property int binding3: myFunction() + property int binding4: nestedObject.myNestedFunction() + + function myFunction() { + return a; + } + + Item { + id: nestedObject + + function myNestedFunction() { + return a; + } + + property int a: 2 + property int binding: a + property string binding2: a + "Test" + property int binding3: myFunction() + property int binding4: myNestedFunction() + } + + ScopeObject { + id: compObject + } + + property alias test1: root.binding + property alias test2: nestedObject.binding + property alias test3: root.binding2 + property alias test4: nestedObject.binding2 + property alias test5: root.binding3 + property alias test6: nestedObject.binding3 + property alias test7: root.binding4 + property alias test8: nestedObject.binding4 + property alias test9: compObject.binding + property alias test10: compObject.binding2 +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.1.js b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.1.js new file mode 100644 index 00000000..54284fea --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.1.js @@ -0,0 +1,4 @@ +function testFunction() { + test = true; +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.1.qml new file mode 100644 index 00000000..65697d93 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.1.qml @@ -0,0 +1,10 @@ +import Qt.test 1.0 +import QtQuick 1.0 +import "scriptConnect.1.js" as Script +MyQmlObject { + property bool test: false + + id: root + + Component.onCompleted: root.argumentSignal.connect(Script.testFunction); +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.2.js b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.2.js new file mode 100644 index 00000000..595c778a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.2.js @@ -0,0 +1,5 @@ +function testFunction() { + if (this.b == 12) + test = true; +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.2.qml new file mode 100644 index 00000000..86ff7987 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.2.qml @@ -0,0 +1,16 @@ +import Qt.test 1.0 +import QtQuick 1.0 +import "scriptConnect.2.js" as Script + +MyQmlObject { + property bool test: false + + id: root + + Component.onCompleted: { + var a = new Object; + a.b = 12; + root.argumentSignal.connect(a, Script.testFunction); + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.3.qml new file mode 100644 index 00000000..db2f0057 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.3.qml @@ -0,0 +1,15 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyQmlObject { + property bool test: false + + id: root + + function testFunction() { + test = true; + } + + Component.onCompleted: root.argumentSignal.connect(testFunction); +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.4.qml new file mode 100644 index 00000000..a2d90ff8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.4.qml @@ -0,0 +1,12 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyQmlObject { + property bool test: false + + id: root + + Component.onCompleted: root.argumentSignal.connect(methodNoArgs); +} + + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.5.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.5.qml new file mode 100644 index 00000000..21fac15d --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.5.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyQmlObject { + property bool test: false + + id: root + + Component.onCompleted: root.argumentSignal.connect(root, methodNoArgs); +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.6.js b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.6.js new file mode 100644 index 00000000..71bdd088 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.6.js @@ -0,0 +1,3 @@ +function testFunction() { + test++; +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.6.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.6.qml new file mode 100644 index 00000000..40530919 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptConnect.6.qml @@ -0,0 +1,15 @@ +import Qt.test 1.0 +import QtQuick 1.0 +import "scriptConnect.6.js" as Script + +MyQmlObject { + property int test: 0 + + id: root + + Component.onCompleted: { + root.argumentSignal.connect(Script.testFunction); + root.argumentSignal.connect(Script.testFunction); + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.1.js b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.1.js new file mode 100644 index 00000000..407426fc --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.1.js @@ -0,0 +1,6 @@ +function testFunction() { + test++; +} + +function otherFunction() { +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.1.qml new file mode 100644 index 00000000..bbe70249 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.1.qml @@ -0,0 +1,13 @@ +import Qt.test 1.0 +import QtQuick 1.0 +import "scriptDisconnect.1.js" as Script + +MyQmlObject { + property int test: 0 + + id: root + + Component.onCompleted: root.argumentSignal.connect(Script.testFunction); + + onBasicSignal: root.argumentSignal.disconnect(Script.testFunction); +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.2.qml new file mode 100644 index 00000000..8a166f41 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.2.qml @@ -0,0 +1,14 @@ +import Qt.test 1.0 +import QtQuick 1.0 +import "scriptDisconnect.1.js" as Script + +MyQmlObject { + property int test: 0 + + id: root + + Component.onCompleted: root.argumentSignal.connect(root, Script.testFunction); + + onBasicSignal: root.argumentSignal.disconnect(root, Script.testFunction); +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.3.qml new file mode 100644 index 00000000..548f2a12 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.3.qml @@ -0,0 +1,14 @@ +import Qt.test 1.0 +import QtQuick 1.0 +import "scriptDisconnect.1.js" as Script + +MyQmlObject { + property int test: 0 + + id: root + + Component.onCompleted: root.argumentSignal.connect(root, Script.testFunction); + + onBasicSignal: root.argumentSignal.disconnect(Script.testFunction); +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.4.qml new file mode 100644 index 00000000..11b22d72 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptDisconnect.4.qml @@ -0,0 +1,13 @@ +import Qt.test 1.0 +import QtQuick 1.0 +import "scriptDisconnect.1.js" as Script + +MyQmlObject { + property int test: 0 + + id: root + + Component.onCompleted: root.argumentSignal.connect(Script.testFunction); + + onBasicSignal: root.argumentSignal.disconnect(Script.otherFunction); +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptErrors.js b/tests/auto/declarative/qdeclarativeecmascript/data/scriptErrors.js new file mode 100644 index 00000000..d22f623e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptErrors.js @@ -0,0 +1,4 @@ +// Comment +a = 10 + +function getValue() { a = 10; return 0; } diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptErrors.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptErrors.qml new file mode 100644 index 00000000..f601f497 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptErrors.qml @@ -0,0 +1,15 @@ +import Qt.test 1.0 +import "scriptErrors.js" as Script + +MyQmlObject { + property int t: a.value + property int w: Script.getValue(); + property int x: undefined + property int y: (a.value, undefinedObject) + + onBasicSignal: { console.log(a.value); } + id: myObj + onAnotherBasicSignal: myObj.trueProperty = false; + onThirdBasicSignal: myObj.fakeProperty = ""; +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/selfDeletingBinding.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/selfDeletingBinding.2.qml new file mode 100644 index 00000000..58cf8051 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/selfDeletingBinding.2.qml @@ -0,0 +1,17 @@ +import Qt.test 1.0 + +MyQmlContainer { + property bool triggerDelete: false + + children: [ + MyQmlObject { + // Will trigger deletion on binding assignment + deleteOnSet: Math.max(0, 1) + }, + + MyQmlObject { + // Will trigger deletion on binding assignment, but after component creation + deleteOnSet: if (triggerDelete) 1; else 0; + } + ] +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/selfDeletingBinding.qml b/tests/auto/declarative/qdeclarativeecmascript/data/selfDeletingBinding.qml new file mode 100644 index 00000000..074851a6 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/selfDeletingBinding.qml @@ -0,0 +1,18 @@ +import Qt.test 1.0 + +MyQmlContainer { + property bool triggerDelete: false + + children: [ + MyQmlObject { + // Will trigger deletion during binding evaluation + stringProperty: {deleteMe(), "Hello"} + }, + + MyQmlObject { + // Will trigger deletion during binding evaluation, but after component creation + stringProperty: if (triggerDelete) { deleteMe(), "Hello" } else { "World" } + } + + ] +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/sharedAttachedObject.qml b/tests/auto/declarative/qdeclarativeecmascript/data/sharedAttachedObject.qml new file mode 100644 index 00000000..2d090b8f --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/sharedAttachedObject.qml @@ -0,0 +1,16 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyQmlObject { + id: root + property bool test1: false + property bool test2: false + + MyQmlObject.value2: 7 + + Component.onCompleted: { + test1 = root.MyQmlObject.value2 == 7; + test2 = root.MyQmlObjectAlias.value2 == 7; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/shutdownErrors.qml b/tests/auto/declarative/qdeclarativeecmascript/data/shutdownErrors.qml new file mode 100644 index 00000000..7a6aba74 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/shutdownErrors.qml @@ -0,0 +1,13 @@ +import QtQuick 1.0 + +Item { + property int test: myObject.object.a + + Item { + id: myObject + property QtObject object; + object: QtObject { + property int a: 10 + } + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/signalAssignment.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/signalAssignment.1.qml new file mode 100644 index 00000000..fbd09142 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/signalAssignment.1.qml @@ -0,0 +1,5 @@ +import Qt.test 1.0 + +MyQmlObject { + onBasicSignal: setString('pass') +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/signalAssignment.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/signalAssignment.2.qml new file mode 100644 index 00000000..6467c42b --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/signalAssignment.2.qml @@ -0,0 +1,5 @@ +import Qt.test 1.0 + +MyQmlObject { + onArgumentSignal: setString('pass ' + a + ' ' + b + ' ' + c + ' ' + d + ' ' + e) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/signalParameterTypes.qml b/tests/auto/declarative/qdeclarativeecmascript/data/signalParameterTypes.qml new file mode 100644 index 00000000..4fc2dab9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/signalParameterTypes.qml @@ -0,0 +1,18 @@ +import Qt.test 1.0 + +MyQmlObject +{ + id: root + property int intProperty + property real realProperty + property color colorProperty + property variant variantProperty + property int enumProperty + property int qtEnumProperty + + signal mySignal(int a, real b, color c, variant d, int e, int f) + + onMySignal: { intProperty = a; realProperty = b; colorProperty = c; variantProperty = d; enumProperty = e; qtEnumProperty = f; } + + onBasicSignal: root.mySignal(10, 19.2, Qt.rgba(1, 1, 0, 1), Qt.rgba(1, 0, 1, 1), MyQmlObject.EnumValue3, Qt.LeftButton) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/signalTriggeredBindings.qml b/tests/auto/declarative/qdeclarativeecmascript/data/signalTriggeredBindings.qml new file mode 100644 index 00000000..8410d333 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/signalTriggeredBindings.qml @@ -0,0 +1,20 @@ +import Qt.test 1.0 +import QtQuick 1.0 + +MyQmlObject { + property real base: 50 + property alias test1: myObject.test1 + property alias test2: myObject.test2 + + objectProperty: QtObject { + id: myObject + property real test1: base + property real test2: Math.max(0, base) + } + + // Signal with no args + onBasicSignal: base = 200 + // Signal with args + onArgumentSignal: base = 400 +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/signalWithUnknownTypes.qml b/tests/auto/declarative/qdeclarativeecmascript/data/signalWithUnknownTypes.qml new file mode 100644 index 00000000..49293edf --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/signalWithUnknownTypes.qml @@ -0,0 +1,5 @@ +import Qt.test 1.0 + +MyQmlObject { + onSignalWithUnknownType: variantMethod(arg); +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/strictlyEquals.qml b/tests/auto/declarative/qdeclarativeecmascript/data/strictlyEquals.qml new file mode 100644 index 00000000..2932c778 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/strictlyEquals.qml @@ -0,0 +1,17 @@ +import QtQuick 1.0 + +QtObject { + property bool test1: (a === true) + property bool test2: !(a === false) + property bool test3: (b === 11.2) + property bool test4: !(b === 9) + property bool test5: (c === 9) + property bool test6: !(c === 13) + property bool test7: (d === "Hello world") + property bool test8: !(d === "Hi") + + property bool a: true + property real b: 11.2 + property int c: 9 + property string d: "Hello world" +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/transientErrors.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/transientErrors.2.qml new file mode 100644 index 00000000..1e5afdf5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/transientErrors.2.qml @@ -0,0 +1,14 @@ +import QtQuick 1.0 + +QtObject { + id: root + + property variant a: 10 + property int x: 10 + property int test: a.x + + Component.onCompleted: { + a = 11; + a = root; + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/transientErrors.qml b/tests/auto/declarative/qdeclarativeecmascript/data/transientErrors.qml new file mode 100644 index 00000000..60d39fa1 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/transientErrors.qml @@ -0,0 +1,10 @@ +import QtQuick 1.0 + +QtObject { + property variant obj: nested + + property variant obj2 + obj2: NestedTypeTransientErrors { + id: nested + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/undefinedResetsProperty.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/undefinedResetsProperty.2.qml new file mode 100644 index 00000000..e73d38e2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/undefinedResetsProperty.2.qml @@ -0,0 +1,10 @@ +import Qt.test 1.0 + +MyQmlObject { + resettableProperty: 19 + + function doReset() { + resettableProperty = undefined; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/undefinedResetsProperty.qml b/tests/auto/declarative/qdeclarativeecmascript/data/undefinedResetsProperty.qml new file mode 100644 index 00000000..eceff60a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/undefinedResetsProperty.qml @@ -0,0 +1,7 @@ +import Qt.test 1.0 + +MyQmlObject { + property bool setUndefined: false + + resettableProperty: setUndefined?undefined:92 +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/valueTypeFunctions.qml b/tests/auto/declarative/qdeclarativeecmascript/data/valueTypeFunctions.qml new file mode 100644 index 00000000..33b4a68c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/valueTypeFunctions.qml @@ -0,0 +1,6 @@ +import Qt.test 1.0 + +MyTypeObject { + rectProperty: Qt.rect(0,0,100,100) + rectFProperty: Qt.rect(0,0.5,100,99.5) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/variantsAssignedUndefined.qml b/tests/auto/declarative/qdeclarativeecmascript/data/variantsAssignedUndefined.qml new file mode 100644 index 00000000..849dfadd --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/variantsAssignedUndefined.qml @@ -0,0 +1,9 @@ +import QtQuick 1.0 + +QtObject { + property bool runTest: false + onRunTestChanged: test1 = undefined + + property variant test1: 10 + property variant test2: (runTest == false)?11:undefined +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/writeAttachedProperty.qml b/tests/auto/declarative/qdeclarativeecmascript/data/writeAttachedProperty.qml new file mode 100644 index 00000000..31bf69d3 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/writeAttachedProperty.qml @@ -0,0 +1,6 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +QtObject { + function writeValue2() { MyQmlObject.value2 = 9 } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/writeRemovesBinding.qml b/tests/auto/declarative/qdeclarativeecmascript/data/writeRemovesBinding.qml new file mode 100644 index 00000000..035f0374 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/writeRemovesBinding.qml @@ -0,0 +1,46 @@ +import QtQuick 1.0 + +QtObject { + id: root + + property bool test: false + + property real data: 9 + property real binding: data + + property alias aliasProperty: root.aliasBinding + property real aliasBinding: data + + Component.onCompleted: { + // Non-aliased properties + if (binding != 9) return; + + data = 11; + if (binding != 11) return; + + binding = 6; + if (binding != 6) return; + + data = 3; + if (binding != 6) return; + + + // Writing through an aliased property + if (aliasProperty != 3) return; + if (aliasBinding != 3) return; + + data = 4; + if (aliasProperty != 4) return; + if (aliasBinding != 4) return; + + aliasProperty = 19; + if (aliasProperty != 19) return; + if (aliasBinding != 19) return; + + data = 5; + if (aliasProperty != 19) return; + if (aliasBinding != 19) return; + + test = true; + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro b/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro new file mode 100644 index 00000000..69d25a42 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro @@ -0,0 +1,24 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative script network +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativeecmascript.cpp \ + testtypes.cpp \ + ../shared/testhttpserver.cpp +HEADERS += testtypes.h \ + ../shared/testhttpserver.h +INCLUDEPATH += ../shared + +# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage +# LIBS += -lgcov + +symbian: { + importFiles.files = data + importFiles.path = . + DEPLOYMENT += importFiles +} else { + DEFINES += SRCDIR=\\\"$$PWD\\\" +} + +CONFIG += parallel_test + diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp new file mode 100644 index 00000000..903fafa9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2012 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$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "testtypes.h" +#include +#include + +class BaseExtensionObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int baseExtendedProperty READ extendedProperty WRITE setExtendedProperty NOTIFY extendedPropertyChanged) +public: + BaseExtensionObject(QObject *parent) : QObject(parent), m_value(0) {} + + int extendedProperty() const { return m_value; } + void setExtendedProperty(int v) { m_value = v; emit extendedPropertyChanged(); } + +signals: + void extendedPropertyChanged(); +private: + int m_value; +}; + +class ExtensionObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int extendedProperty READ extendedProperty WRITE setExtendedProperty NOTIFY extendedPropertyChanged) +public: + ExtensionObject(QObject *parent) : QObject(parent), m_value(0) {} + + int extendedProperty() const { return m_value; } + void setExtendedProperty(int v) { m_value = v; emit extendedPropertyChanged(); } + +signals: + void extendedPropertyChanged(); +private: + int m_value; +}; + +class DefaultPropertyExtensionObject : public QObject +{ + Q_OBJECT + Q_CLASSINFO("DefaultProperty", "firstProperty") +public: + DefaultPropertyExtensionObject(QObject *parent) : QObject(parent) {} +}; + +class QWidgetDeclarativeUI : public QObject +{ + Q_OBJECT + + Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged) + +signals: + void widthChanged(); + +public: + QWidgetDeclarativeUI(QObject *other) : QObject(other) { } + +public: + int width() const { return 0; } + void setWidth(int) { } +}; + + +void registerTypes() +{ + qmlRegisterType("Qt.test", 1,0, "MyQmlObjectAlias"); + qmlRegisterType("Qt.test", 1,0, "MyQmlObject"); + qmlRegisterType("Qt.test", 1,0, "MyDeferredObject"); + qmlRegisterType("Qt.test", 1,0, "MyQmlContainer"); + qmlRegisterExtendedType("Qt.test", 1,0, "MyBaseExtendedObject"); + qmlRegisterExtendedType("Qt.test", 1,0, "MyExtendedObject"); + qmlRegisterType("Qt.test", 1,0, "MyTypeObject"); + qmlRegisterType("Qt.test", 1,0, "MyDerivedObject"); + qmlRegisterType("Qt.test", 1,0, "NumberAssignment"); + qmlRegisterExtendedType("Qt.test", 1,0, "DefaultPropertyExtendedObject"); + qmlRegisterType("Qt.test", 1,0, "OverrideDefaultPropertyObject"); + qmlRegisterType("Qt.test",1,0,"MyRevisionedClass"); + qmlRegisterType("Qt.test",1,1,"MyRevisionedClass"); + + // Register the uncreatable base class + qmlRegisterRevision("Qt.test",1,1); + // MyRevisionedSubclass 1.0 uses MyRevisionedClass revision 0 + qmlRegisterType("Qt.test",1,0,"MyRevisionedSubclass"); + // MyRevisionedSubclass 1.1 uses MyRevisionedClass revision 1 + qmlRegisterType("Qt.test",1,1,"MyRevisionedSubclass"); + + qmlRegisterExtendedType("Qt.test",1,0,"QWidget"); + qmlRegisterType("Qt.test",1,0,"QPlainTextEdit"); + + qRegisterMetaType("MyQmlObject::MyType"); + qRegisterMetaType("MyEnum2"); + qRegisterMetaType("Qt::MouseButtons"); +} + +#include "testtypes.moc" diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h new file mode 100644 index 00000000..8c7326f6 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h @@ -0,0 +1,915 @@ +/**************************************************************************** +** +** Copyright (C) 2012 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$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef TESTTYPES_H +#define TESTTYPES_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class MyQmlAttachedObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int value READ value CONSTANT) + Q_PROPERTY(int value2 READ value2 WRITE setValue2 NOTIFY value2Changed) +public: + MyQmlAttachedObject(QObject *parent) : QObject(parent), m_value2(0) {} + + int value() const { return 19; } + int value2() const { return m_value2; } + void setValue2(int v) { if (m_value2 == v) return; m_value2 = v; emit value2Changed(); } + + void emitMySignal() { emit mySignal(); } + +signals: + void value2Changed(); + void mySignal(); + +private: + int m_value2; +}; + +class MyQmlObject : public QObject +{ + Q_OBJECT + Q_ENUMS(MyEnum) + Q_ENUMS(MyEnum2) + Q_PROPERTY(int deleteOnSet READ deleteOnSet WRITE setDeleteOnSet) + Q_PROPERTY(bool trueProperty READ trueProperty CONSTANT) + Q_PROPERTY(bool falseProperty READ falseProperty CONSTANT) + Q_PROPERTY(int value READ value WRITE setValue) + Q_PROPERTY(int console READ console CONSTANT) + Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty NOTIFY stringChanged) + Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty NOTIFY objectChanged) + Q_PROPERTY(QDeclarativeListProperty objectListProperty READ objectListProperty CONSTANT) + Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty) + Q_PROPERTY(QRegExp regExp READ regExp WRITE setRegExp) + Q_PROPERTY(int nonscriptable READ nonscriptable WRITE setNonscriptable SCRIPTABLE false) + +public: + MyQmlObject(): myinvokableObject(0), m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13) {} + + enum MyEnum { EnumValue1 = 0, EnumValue2 = 1 }; + enum MyEnum2 { EnumValue3 = 2, EnumValue4 = 3 }; + + bool trueProperty() const { return true; } + bool falseProperty() const { return false; } + + QString stringProperty() const { return m_string; } + void setStringProperty(const QString &s) + { + if (s == m_string) + return; + m_string = s; + emit stringChanged(); + } + + QObject *objectProperty() const { return m_object; } + void setObjectProperty(QObject *obj) { + if (obj == m_object) + return; + m_object = obj; + emit objectChanged(); + } + + QDeclarativeListProperty objectListProperty() { return QDeclarativeListProperty(this, m_objectQList); } + + bool methodCalled() const { return m_methodCalled; } + bool methodIntCalled() const { return m_methodIntCalled; } + + QString string() const { return m_string; } + + static MyQmlAttachedObject *qmlAttachedProperties(QObject *o) { + return new MyQmlAttachedObject(o); + } + + int deleteOnSet() const { return 1; } + void setDeleteOnSet(int v) { if(v) delete this; } + + int value() const { return m_value; } + void setValue(int v) { m_value = v; } + + int resettableProperty() const { return m_resetProperty; } + void setResettableProperty(int v) { m_resetProperty = v; } + void resetProperty() { m_resetProperty = 13; } + + QRegExp regExp() { return m_regExp; } + void setRegExp(const QRegExp ®Exp) { m_regExp = regExp; } + + int console() const { return 11; } + + int nonscriptable() const { return 0; } + void setNonscriptable(int) {} + + MyQmlObject *myinvokableObject; + Q_INVOKABLE MyQmlObject *returnme() { return this; } + + struct MyType { + int value; + }; + QVariant variant() const { return m_variant; } + +signals: + void basicSignal(); + void argumentSignal(int a, QString b, qreal c, MyEnum2 d, Qt::MouseButtons e); + void stringChanged(); + void objectChanged(); + void anotherBasicSignal(); + void thirdBasicSignal(); + void signalWithUnknownType(const MyQmlObject::MyType &arg); + +public slots: + void deleteMe() { delete this; } + void methodNoArgs() { m_methodCalled = true; } + void method(int a) { if(a == 163) m_methodIntCalled = true; } + void setString(const QString &s) { m_string = s; } + void myinvokable(MyQmlObject *o) { myinvokableObject = o; } + void variantMethod(const QVariant &v) { m_variant = v; } + +private: + friend class tst_qdeclarativeecmascript; + bool m_methodCalled; + bool m_methodIntCalled; + + QObject *m_object; + QString m_string; + QList m_objectQList; + int m_value; + int m_resetProperty; + QRegExp m_regExp; + QVariant m_variant; +}; + +QML_DECLARE_TYPEINFO(MyQmlObject, QML_HAS_ATTACHED_PROPERTIES) + +class MyQmlContainer : public QObject +{ + Q_OBJECT + Q_PROPERTY(QDeclarativeListProperty children READ children CONSTANT) +public: + MyQmlContainer() {} + + QDeclarativeListProperty children() { return QDeclarativeListProperty(this, m_children); } + +private: + QList m_children; +}; + + +class MyExpression : public QDeclarativeExpression +{ + Q_OBJECT +public: + MyExpression(QDeclarativeContext *ctxt, const QString &expr) + : QDeclarativeExpression(ctxt, 0, expr), changed(false) + { + QObject::connect(this, SIGNAL(valueChanged()), this, SLOT(expressionValueChanged())); + setNotifyOnValueChanged(true); + } + + bool changed; + +public slots: + void expressionValueChanged() { + changed = true; + } +}; + + +class MyDefaultObject1 : public QObject +{ + Q_OBJECT + Q_PROPERTY(int horseLegs READ horseLegs CONSTANT) + Q_PROPERTY(int antLegs READ antLegs CONSTANT) + Q_PROPERTY(int emuLegs READ emuLegs CONSTANT) +public: + int horseLegs() const { return 4; } + int antLegs() const { return 6; } + int emuLegs() const { return 2; } +}; + +class MyDefaultObject3 : public QObject +{ + Q_OBJECT + Q_PROPERTY(int antLegs READ antLegs CONSTANT) + Q_PROPERTY(int humanLegs READ humanLegs CONSTANT) +public: + int antLegs() const { return 7; } // Mutant + int humanLegs() const { return 2; } + int millipedeLegs() const { return 1000; } +}; + +class MyDeferredObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged) + Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty) + Q_PROPERTY(QObject *objectProperty2 READ objectProperty2 WRITE setObjectProperty2) + Q_CLASSINFO("DeferredPropertyNames", "value,objectProperty,objectProperty2") + +public: + MyDeferredObject() : m_value(0), m_object(0), m_object2(0) {} + + int value() const { return m_value; } + void setValue(int v) { m_value = v; emit valueChanged(); } + + QObject *objectProperty() const { return m_object; } + void setObjectProperty(QObject *obj) { m_object = obj; } + + QObject *objectProperty2() const { return m_object2; } + void setObjectProperty2(QObject *obj) { m_object2 = obj; } + +signals: + void valueChanged(); + +private: + int m_value; + QObject *m_object; + QObject *m_object2; +}; + +class MyBaseExtendedObject : public QObject +{ +Q_OBJECT +Q_PROPERTY(int baseProperty READ baseProperty WRITE setBaseProperty) +public: + MyBaseExtendedObject() : m_value(0) {} + + int baseProperty() const { return m_value; } + void setBaseProperty(int v) { m_value = v; } + +private: + int m_value; +}; + +class MyExtendedObject : public MyBaseExtendedObject +{ +Q_OBJECT +Q_PROPERTY(int coreProperty READ coreProperty WRITE setCoreProperty) +public: + MyExtendedObject() : m_value(0) {} + + int coreProperty() const { return m_value; } + void setCoreProperty(int v) { m_value = v; } + +private: + int m_value; +}; + +class MyTypeObject : public QObject +{ + Q_OBJECT + Q_ENUMS(MyEnum) + Q_FLAGS(MyFlags) + + Q_PROPERTY(QString id READ id WRITE setId) + Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty) + Q_PROPERTY(QDeclarativeComponent *componentProperty READ componentProperty WRITE setComponentProperty) + Q_PROPERTY(MyFlags flagProperty READ flagProperty WRITE setFlagProperty) + Q_PROPERTY(MyEnum enumProperty READ enumProperty WRITE setEnumProperty) + Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty) + Q_PROPERTY(uint uintProperty READ uintProperty WRITE setUintProperty) + Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty) + Q_PROPERTY(qreal realProperty READ realProperty WRITE setRealProperty) + Q_PROPERTY(double doubleProperty READ doubleProperty WRITE setDoubleProperty) + Q_PROPERTY(float floatProperty READ floatProperty WRITE setFloatProperty) + Q_PROPERTY(QColor colorProperty READ colorProperty WRITE setColorProperty) + Q_PROPERTY(QDate dateProperty READ dateProperty WRITE setDateProperty) + Q_PROPERTY(QTime timeProperty READ timeProperty WRITE setTimeProperty) + Q_PROPERTY(QDateTime dateTimeProperty READ dateTimeProperty WRITE setDateTimeProperty) + Q_PROPERTY(QPoint pointProperty READ pointProperty WRITE setPointProperty) + Q_PROPERTY(QPointF pointFProperty READ pointFProperty WRITE setPointFProperty) + Q_PROPERTY(QSize sizeProperty READ sizeProperty WRITE setSizeProperty) + Q_PROPERTY(QSizeF sizeFProperty READ sizeFProperty WRITE setSizeFProperty) + Q_PROPERTY(QRect rectProperty READ rectProperty WRITE setRectProperty NOTIFY rectPropertyChanged) + Q_PROPERTY(QRect rectProperty2 READ rectProperty2 WRITE setRectProperty2) + Q_PROPERTY(QRectF rectFProperty READ rectFProperty WRITE setRectFProperty) + Q_PROPERTY(bool boolProperty READ boolProperty WRITE setBoolProperty) + Q_PROPERTY(QVariant variantProperty READ variantProperty WRITE setVariantProperty) + Q_PROPERTY(QVector3D vectorProperty READ vectorProperty WRITE setVectorProperty) + Q_PROPERTY(QUrl urlProperty READ urlProperty WRITE setUrlProperty) + + Q_PROPERTY(QDeclarativeScriptString scriptProperty READ scriptProperty WRITE setScriptProperty) + +public: + MyTypeObject() + : objectPropertyValue(0), componentPropertyValue(0) {} + + QString idValue; + QString id() const { + return idValue; + } + void setId(const QString &v) { + idValue = v; + } + + QObject *objectPropertyValue; + QObject *objectProperty() const { + return objectPropertyValue; + } + void setObjectProperty(QObject *v) { + objectPropertyValue = v; + } + + QDeclarativeComponent *componentPropertyValue; + QDeclarativeComponent *componentProperty() const { + return componentPropertyValue; + } + void setComponentProperty(QDeclarativeComponent *v) { + componentPropertyValue = v; + } + + enum MyFlag { FlagVal1 = 0x01, FlagVal2 = 0x02, FlagVal3 = 0x04 }; + Q_DECLARE_FLAGS(MyFlags, MyFlag) + MyFlags flagPropertyValue; + MyFlags flagProperty() const { + return flagPropertyValue; + } + void setFlagProperty(MyFlags v) { + flagPropertyValue = v; + } + + enum MyEnum { EnumVal1, EnumVal2 }; + MyEnum enumPropertyValue; + MyEnum enumProperty() const { + return enumPropertyValue; + } + void setEnumProperty(MyEnum v) { + enumPropertyValue = v; + } + + QString stringPropertyValue; + QString stringProperty() const { + return stringPropertyValue; + } + void setStringProperty(const QString &v) { + stringPropertyValue = v; + } + + uint uintPropertyValue; + uint uintProperty() const { + return uintPropertyValue; + } + void setUintProperty(const uint &v) { + uintPropertyValue = v; + } + + int intPropertyValue; + int intProperty() const { + return intPropertyValue; + } + void setIntProperty(const int &v) { + intPropertyValue = v; + } + + qreal realPropertyValue; + qreal realProperty() const { + return realPropertyValue; + } + void setRealProperty(const qreal &v) { + realPropertyValue = v; + } + + double doublePropertyValue; + double doubleProperty() const { + return doublePropertyValue; + } + void setDoubleProperty(const double &v) { + doublePropertyValue = v; + } + + float floatPropertyValue; + float floatProperty() const { + return floatPropertyValue; + } + void setFloatProperty(const float &v) { + floatPropertyValue = v; + } + + QColor colorPropertyValue; + QColor colorProperty() const { + return colorPropertyValue; + } + void setColorProperty(const QColor &v) { + colorPropertyValue = v; + } + + QDate datePropertyValue; + QDate dateProperty() const { + return datePropertyValue; + } + void setDateProperty(const QDate &v) { + datePropertyValue = v; + } + + QTime timePropertyValue; + QTime timeProperty() const { + return timePropertyValue; + } + void setTimeProperty(const QTime &v) { + timePropertyValue = v; + } + + QDateTime dateTimePropertyValue; + QDateTime dateTimeProperty() const { + return dateTimePropertyValue; + } + void setDateTimeProperty(const QDateTime &v) { + dateTimePropertyValue = v; + } + + QPoint pointPropertyValue; + QPoint pointProperty() const { + return pointPropertyValue; + } + void setPointProperty(const QPoint &v) { + pointPropertyValue = v; + } + + QPointF pointFPropertyValue; + QPointF pointFProperty() const { + return pointFPropertyValue; + } + void setPointFProperty(const QPointF &v) { + pointFPropertyValue = v; + } + + QSize sizePropertyValue; + QSize sizeProperty() const { + return sizePropertyValue; + } + void setSizeProperty(const QSize &v) { + sizePropertyValue = v; + } + + QSizeF sizeFPropertyValue; + QSizeF sizeFProperty() const { + return sizeFPropertyValue; + } + void setSizeFProperty(const QSizeF &v) { + sizeFPropertyValue = v; + } + + QRect rectPropertyValue; + QRect rectProperty() const { + return rectPropertyValue; + } + void setRectProperty(const QRect &v) { + rectPropertyValue = v; + emit rectPropertyChanged(); + } + + QRect rectPropertyValue2; + QRect rectProperty2() const { + return rectPropertyValue2; + } + void setRectProperty2(const QRect &v) { + rectPropertyValue2 = v; + } + + QRectF rectFPropertyValue; + QRectF rectFProperty() const { + return rectFPropertyValue; + } + void setRectFProperty(const QRectF &v) { + rectFPropertyValue = v; + } + + bool boolPropertyValue; + bool boolProperty() const { + return boolPropertyValue; + } + void setBoolProperty(const bool &v) { + boolPropertyValue = v; + } + + QVariant variantPropertyValue; + QVariant variantProperty() const { + return variantPropertyValue; + } + void setVariantProperty(const QVariant &v) { + variantPropertyValue = v; + } + + QVector3D vectorPropertyValue; + QVector3D vectorProperty() const { + return vectorPropertyValue; + } + void setVectorProperty(const QVector3D &v) { + vectorPropertyValue = v; + } + + QUrl urlPropertyValue; + QUrl urlProperty() const { + return urlPropertyValue; + } + void setUrlProperty(const QUrl &v) { + urlPropertyValue = v; + } + + QDeclarativeScriptString scriptPropertyValue; + QDeclarativeScriptString scriptProperty() const { + return scriptPropertyValue; + } + void setScriptProperty(const QDeclarativeScriptString &v) { + scriptPropertyValue = v; + } + + void doAction() { emit action(); } +signals: + void action(); + void rectPropertyChanged(); +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(MyTypeObject::MyFlags) + +class MyDerivedObject : public MyTypeObject +{ + Q_OBJECT +public: + Q_INVOKABLE bool intProperty() const { + return true; + } +}; + +Q_DECLARE_METATYPE(QScriptValue); +class MyInvokableBaseObject : public QObject +{ + Q_OBJECT +public: + inline ~MyInvokableBaseObject() = 0; + + Q_INVOKABLE inline void method_inherited(int a); + Q_INVOKABLE inline void method_overload(); +}; + +class MyInvokableObject : public MyInvokableBaseObject +{ + Q_OBJECT + Q_ENUMS(TestEnum) +public: + enum TestEnum { EnumValue1, EnumValue2 }; + MyInvokableObject() { reset(); } + + int invoked() const { return m_invoked; } + bool error() const { return m_invokedError; } + const QVariantList &actuals() const { return m_actuals; } + void reset() { m_invoked = -1; m_invokedError = false; m_actuals.clear(); } + + Q_INVOKABLE QPointF method_get_QPointF() { return QPointF(99.3, -10.2); } + Q_INVOKABLE QPoint method_get_QPoint() { return QPoint(9, 12); } + + Q_INVOKABLE void method_NoArgs() { invoke(0); } + Q_INVOKABLE int method_NoArgs_int() { invoke(1); return 6; } + Q_INVOKABLE qreal method_NoArgs_real() { invoke(2); return 19.75; } + Q_INVOKABLE QPointF method_NoArgs_QPointF() { invoke(3); return QPointF(123, 4.5); } + Q_INVOKABLE QObject *method_NoArgs_QObject() { invoke(4); return this; } + Q_INVOKABLE MyInvokableObject *method_NoArgs_unknown() { invoke(5); return this; } + Q_INVOKABLE QScriptValue method_NoArgs_QScriptValue() { invoke(6); return QScriptValue("Hello world"); } + Q_INVOKABLE QVariant method_NoArgs_QVariant() { invoke(7); return QVariant("QML rocks"); } + + Q_INVOKABLE void method_int(int a) { invoke(8); m_actuals << a; } + Q_INVOKABLE void method_intint(int a, int b) { invoke(9); m_actuals << a << b; } + Q_INVOKABLE void method_real(qreal a) { invoke(10); m_actuals << a; } + Q_INVOKABLE void method_QString(QString a) { invoke(11); m_actuals << a; } + Q_INVOKABLE void method_QPointF(QPointF a) { invoke(12); m_actuals << a; } + Q_INVOKABLE void method_QObject(QObject *a) { invoke(13); m_actuals << qVariantFromValue(a); } + Q_INVOKABLE void method_QScriptValue(QScriptValue a) { invoke(14); m_actuals << qVariantFromValue(a); } + Q_INVOKABLE void method_intQScriptValue(int a, QScriptValue b) { invoke(15); m_actuals << a << qVariantFromValue(b); } + + Q_INVOKABLE void method_overload(int a) { invoke(16); m_actuals << a; } + Q_INVOKABLE void method_overload(int a, int b) { invoke(17); m_actuals << a << b; } + Q_INVOKABLE void method_overload(QString a) { invoke(18); m_actuals << a; } + + Q_INVOKABLE void method_with_enum(TestEnum e) { invoke(19); m_actuals << (int)e; } + + Q_INVOKABLE int method_default(int a, int b = 19) { invoke(20); m_actuals << a << b; return b; } + + Q_INVOKABLE void method_QVariant(QVariant a, QVariant b = QVariant()) { invoke(21); m_actuals << a << b; } + +private: + friend class MyInvokableBaseObject; + void invoke(int idx) { if (m_invoked != -1) m_invokedError = true; m_invoked = idx;} + int m_invoked; + bool m_invokedError; + QVariantList m_actuals; +}; + +MyInvokableBaseObject::~MyInvokableBaseObject() {} + +void MyInvokableBaseObject::method_inherited(int a) +{ + static_cast(this)->invoke(-3); + static_cast(this)->m_actuals << a; +} + +// This is a hidden overload of the MyInvokableObject::method_overload() method +void MyInvokableBaseObject::method_overload() +{ + static_cast(this)->invoke(-2); +} + +class NumberAssignment : public QObject +{ + Q_OBJECT +public: + Q_PROPERTY(qreal test1 READ test1 WRITE setTest1) + qreal _test1; + qreal test1() const { return _test1; } + void setTest1(qreal v) { _test1 = v; } + + Q_PROPERTY(qreal test2 READ test2 WRITE setTest2) + qreal _test2; + qreal test2() const { return _test2; } + void setTest2(qreal v) { _test2 = v; } + + Q_PROPERTY(qreal test3 READ test3 WRITE setTest3) + qreal _test3; + qreal test3() const { return _test3; } + void setTest3(qreal v) { _test3 = v; } + + Q_PROPERTY(qreal test4 READ test4 WRITE setTest4) + qreal _test4; + qreal test4() const { return _test4; } + void setTest4(qreal v) { _test4 = v; } + + Q_PROPERTY(int test5 READ test5 WRITE setTest5) + int _test5; + int test5() const { return _test5; } + void setTest5(int v) { _test5 = v; } + + Q_PROPERTY(int test6 READ test6 WRITE setTest6) + int _test6; + int test6() const { return _test6; } + void setTest6(int v) { _test6 = v; } + + Q_PROPERTY(int test7 READ test7 WRITE setTest7) + int _test7; + int test7() const { return _test7; } + void setTest7(int v) { _test7 = v; } + + Q_PROPERTY(int test8 READ test8 WRITE setTest8) + int _test8; + int test8() const { return _test8; } + void setTest8(int v) { _test8 = v; } + + Q_PROPERTY(unsigned int test9 READ test9 WRITE setTest9) + unsigned int _test9; + unsigned int test9() const { return _test9; } + void setTest9(unsigned int v) { _test9 = v; } + + Q_PROPERTY(unsigned int test10 READ test10 WRITE setTest10) + unsigned int _test10; + unsigned int test10() const { return _test10; } + void setTest10(unsigned int v) { _test10 = v; } + + Q_PROPERTY(unsigned int test11 READ test11 WRITE setTest11) + unsigned int _test11; + unsigned int test11() const { return _test11; } + void setTest11(unsigned int v) { _test11 = v; } + + Q_PROPERTY(unsigned int test12 READ test12 WRITE setTest12) + unsigned int _test12; + unsigned int test12() const { return _test12; } + void setTest12(unsigned int v) { _test12 = v; } +}; + +class DefaultPropertyExtendedObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(QObject *firstProperty READ firstProperty WRITE setFirstProperty) + Q_PROPERTY(QObject *secondProperty READ secondProperty WRITE setSecondProperty) +public: + DefaultPropertyExtendedObject(QObject *parent = 0) : QObject(parent), m_firstProperty(0), m_secondProperty(0) {} + + QObject *firstProperty() const { return m_firstProperty; } + QObject *secondProperty() const { return m_secondProperty; } + void setFirstProperty(QObject *property) { m_firstProperty = property; } + void setSecondProperty(QObject *property) { m_secondProperty = property; } +private: + QObject* m_firstProperty; + QObject* m_secondProperty; +}; + +class OverrideDefaultPropertyObject : public DefaultPropertyExtendedObject +{ + Q_OBJECT + Q_CLASSINFO("DefaultProperty", "secondProperty") +public: + OverrideDefaultPropertyObject() {} +}; + +class MyRevisionedBaseClassRegistered : public QObject +{ +Q_OBJECT + Q_PROPERTY(qreal propA READ propA WRITE setPropA NOTIFY propAChanged) + Q_PROPERTY(qreal propB READ propB WRITE setPropB NOTIFY propBChanged REVISION 1) + +public: + MyRevisionedBaseClassRegistered() : m_pa(1), m_pb(2) {} + + qreal propA() const { return m_pa; } + void setPropA(qreal p) { + if (p != m_pa) { + m_pa = p; + emit propAChanged(); + } + } + qreal propB() const { return m_pb; } + void setPropB(qreal p) { + if (p != m_pb) { + m_pb = p; + emit propBChanged(); + } + } + + Q_INVOKABLE void methodA() { } + Q_INVOKABLE Q_REVISION(1) void methodB() { } + +signals: + void propAChanged(); + void propBChanged(); + + void signalA(); + Q_REVISION(1) void signalB(); + +protected: + qreal m_pa; + qreal m_pb; +}; + +class MyRevisionedBaseClassUnregistered : public MyRevisionedBaseClassRegistered +{ +Q_OBJECT + Q_PROPERTY(qreal propC READ propC WRITE setPropC NOTIFY propCChanged) + Q_PROPERTY(qreal propD READ propD WRITE setPropD NOTIFY propDChanged REVISION 1) + +public: + MyRevisionedBaseClassUnregistered() : m_pc(1), m_pd(2) {} + + qreal propC() const { return m_pc; } + void setPropC(qreal p) { + if (p != m_pc) { + m_pc = p; + emit propCChanged(); + } + } + qreal propD() const { return m_pd; } + void setPropD(qreal p) { + if (p != m_pd) { + m_pd = p; + emit propDChanged(); + } + } + + Q_INVOKABLE void methodC() { } + Q_INVOKABLE Q_REVISION(1) void methodD() { } + +signals: + void propCChanged(); + void propDChanged(); + + void signalC(); + Q_REVISION(1) void signalD(); + +protected: + qreal m_pc; + qreal m_pd; +}; + +class MyRevisionedClass : public MyRevisionedBaseClassUnregistered +{ + Q_OBJECT + Q_PROPERTY(qreal prop1 READ prop1 WRITE setProp1 NOTIFY prop1Changed) + Q_PROPERTY(qreal prop2 READ prop2 WRITE setProp2 NOTIFY prop2Changed REVISION 1) + +public: + MyRevisionedClass() {} + + qreal prop1() const { return m_p1; } + void setProp1(qreal p) { + if (p != m_p1) { + m_p1 = p; + emit prop1Changed(); + } + } + qreal prop2() const { return m_p2; } + void setProp2(qreal p) { + if (p != m_p2) { + m_p2 = p; + emit prop2Changed(); + } + } + + Q_INVOKABLE void method1() { } + Q_INVOKABLE Q_REVISION(1) void method2() { } + +signals: + void prop1Changed(); + void prop2Changed(); + + void signal1(); + Q_REVISION(1) void signal2(); + +protected: + qreal m_p1; + qreal m_p2; +}; + +class MyRevisionedSubclass : public MyRevisionedClass +{ + Q_OBJECT + Q_PROPERTY(qreal prop3 READ prop3 WRITE setProp3 NOTIFY prop3Changed) + Q_PROPERTY(qreal prop4 READ prop4 WRITE setProp4 NOTIFY prop4Changed REVISION 1) + +public: + MyRevisionedSubclass() : m_p3(3), m_p4(4) {} + + qreal prop3() const { return m_p3; } + void setProp3(qreal p) { + if (p != m_p3) { + m_p3 = p; + emit prop3Changed(); + } + } + qreal prop4() const { return m_p4; } + void setProp4(qreal p) { + if (p != m_p4) { + m_p4 = p; + emit prop4Changed(); + } + } + + Q_INVOKABLE void method3() { } + Q_INVOKABLE Q_REVISION(1) void method4() { } + +signals: + void prop3Changed(); + void prop4Changed(); + + void signal3(); + Q_REVISION(1) void signal4(); + +protected: + qreal m_p3; + qreal m_p4; +}; + +QML_DECLARE_TYPE(MyRevisionedBaseClassRegistered) +QML_DECLARE_TYPE(MyRevisionedBaseClassUnregistered) +QML_DECLARE_TYPE(MyRevisionedClass) +QML_DECLARE_TYPE(MyRevisionedSubclass) +Q_DECLARE_METATYPE(MyQmlObject::MyType) + +void registerTypes(); + +#endif // TESTTYPES_H + diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp new file mode 100644 index 00000000..f5b2061d --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -0,0 +1,3105 @@ +/**************************************************************************** +** +** Copyright (C) 2012 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$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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(); + + 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(); + void realToInt(); + void qtbug_20648(); + + 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(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(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(component.create()); + QVERIFY(object != 0); + QVERIFY(object->objectProperty() != 0); + delete object->objectProperty(); + QVERIFY(object->objectProperty() == 0); + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("idShortcutInvalidates.1.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + QVERIFY(object->objectProperty() != 0); + delete object->objectProperty(); + QVERIFY(object->objectProperty() == 0); + } +} + +void tst_qdeclarativeecmascript::boolPropertiesEvaluateAsBool() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("boolPropertiesEvaluateAsBool.1.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->stringProperty(), QLatin1String("pass")); + } + { + QDeclarativeComponent component(&engine, TEST_FILE("boolPropertiesEvaluateAsBool.2.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->stringProperty(), QLatin1String("pass")); + } +} + +void tst_qdeclarativeecmascript::signalAssignment() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("signalAssignment.1.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->string(), QString()); + emit object->basicSignal(); + QCOMPARE(object->string(), QString("pass")); + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("signalAssignment.2.qml")); + MyQmlObject *object = qobject_cast(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")); + } +} + +void tst_qdeclarativeecmascript::methods() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("methods.1.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->methodCalled(), false); + QCOMPARE(object->methodIntCalled(), false); + emit object->basicSignal(); + QCOMPARE(object->methodCalled(), true); + QCOMPARE(object->methodIntCalled(), false); + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("methods.2.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->methodCalled(), false); + QCOMPARE(object->methodIntCalled(), false); + emit object->basicSignal(); + QCOMPARE(object->methodCalled(), false); + QCOMPARE(object->methodIntCalled(), true); + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("methods.3.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("test").toInt(), 19); + } + + { + 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); + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("methods.5.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("test").toInt(), 9); + } +} + +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); +} + +void tst_qdeclarativeecmascript::basicExpressions_data() +{ + QTest::addColumn("expression"); + QTest::addColumn("result"); + QTest::addColumn("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 list = qvariant_cast >(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)); + } + +} + +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(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(object->objectProperty()); + QVERIFY(qmlObject != 0); + QCOMPARE(qmlObject->value(), 10); + object->setValue(19); + QCOMPARE(qmlObject->value(), 19); +} + +// Check errors on deferred properties are correctly emitted +void tst_qdeclarativeecmascript::deferredPropertiesErrors() +{ + QDeclarativeComponent component(&engine, TEST_FILE("deferredPropertiesErrors.qml")); + MyDeferredObject *object = + qobject_cast(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(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(qvariant_cast(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); + +} + +void tst_qdeclarativeecmascript::overrideExtensionProperties() +{ + QDeclarativeComponent component(&engine, TEST_FILE("extensionObjectsPropertyOverride.qml")); + OverrideDefaultPropertyObject *object = + qobject_cast(component.create()); + QVERIFY(object != 0); + QVERIFY(object->secondProperty() != 0); + QVERIFY(object->firstProperty() == 0); +} + +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); + } + + { + 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(qmlAttachedPropertiesObject(object)); + QVERIFY(attached != 0); + + QCOMPARE(attached->value2(), 9); + } +} + +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); + } + // 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); + } +} + +void tst_qdeclarativeecmascript::valueTypeFunctions() +{ + QDeclarativeComponent component(&engine, TEST_FILE("valueTypeFunctions.qml")); + MyTypeObject *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->rectProperty(), QRect(0,0,100,100)); + QCOMPARE(obj->rectFProperty(), QRectF(0,0.5,100,99.5)); +} + +/* +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(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); + } + + // During construction + { + QDeclarativeComponent component(&engine, TEST_FILE("constantsOverrideBindings.2.qml")); + MyQmlObject *object = qobject_cast(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); + } + +#if 0 + // From C++ + { + QDeclarativeComponent component(&engine, TEST_FILE("constantsOverrideBindings.3.qml")); + MyQmlObject *object = qobject_cast(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); + } +#endif + + // Using an alias + { + QDeclarativeComponent component(&engine, TEST_FILE("constantsOverrideBindings.4.qml")); + MyQmlObject *object = qobject_cast(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); + } +} + +/* +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(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); +} + +/* +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); +} + +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); + } + + { + 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); + } + + { + 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); + } + + // Signal argument scope + { + QDeclarativeComponent component(&engine, TEST_FILE("scope.4.qml")); + MyQmlObject *object = qobject_cast(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; + } +} + +/* +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(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(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); +} + +/* +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); +} + +/* +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); +} + +void tst_qdeclarativeecmascript::dynamicCreation_data() +{ + QTest::addColumn("method"); + QTest::addColumn("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(component.create()); + QVERIFY(object != 0); + + QMetaObject::invokeMethod(object, method.toUtf8()); + QObject *created = object->objectProperty(); + QVERIFY(created); + QCOMPARE(created->objectName(), createdName); +} + +/* + Tests the destroy function +*/ +void tst_qdeclarativeecmascript::dynamicDestruction() +{ + QDeclarativeComponent component(&engine, TEST_FILE("dynamicDeletion.qml")); + QDeclarativeGuard object = qobject_cast(component.create()); + QVERIFY(object != 0); + QDeclarativeGuard 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(component.create()); + QVERIFY(object != 0); + QMetaObject::invokeMethod(object, "testToString"); + QVERIFY(object->stringProperty().startsWith("MyQmlObject_QML_")); + QVERIFY(object->stringProperty().endsWith(", \"objName\")")); +} + +/* +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); + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("selfDeletingBinding.2.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + object->setProperty("triggerDelete", true); + } +} + +/* +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); +} + +/* +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(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(); +} + +/* +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; +} + +/* +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(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.); +} + +/* +Test that list properties can be iterated from ECMAScript +*/ +void tst_qdeclarativeecmascript::listProperties() +{ + QDeclarativeComponent component(&engine, TEST_FILE("listProperties.qml")); + MyQmlObject *object = qobject_cast(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); +} + +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(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); +} + +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(component.create()); + QVERIFY(object != 0); +} + +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(component.create()); + QVERIFY(object != 0); +} + +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); + } + + // 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); + } +} + +// 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(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;\nQPlainTextEdit { 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(component.create()); + QVERIFY(object != 0); + + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready"); + QMetaObject::invokeMethod(object, "dontCrash"); + QObject *created = object->objectProperty(); + QVERIFY(created == 0); +} + +//QTBUG-9367 +void tst_qdeclarativeecmascript::regExpBug() +{ + QDeclarativeComponent component(&engine, TEST_FILE("regExp.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->regExp().pattern(), QLatin1String("[a-zA-z]")); +} + +void tst_qdeclarativeecmascript::callQtInvokables() +{ + MyInvokableObject o; + + QDeclarativeEngine qmlengine; + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(&qmlengine); + QScriptEngine *engine = &ep->scriptEngine; + + QStringList names; QList 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(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(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(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(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(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(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(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(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(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()); + QVERIFY(qvariant_cast(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(qmlAttachedPropertiesObject(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(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(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(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(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(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(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(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(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(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(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 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; + } +} + +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 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\nQtObject {\nComponent.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\nQtObject {\nComponent.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 getObjects() { return m_objects; } + +private: + QList m_objects; +}; + +// Tests that returning a QList 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; +} + +// 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(object->property("test24")), QColor(0x11,0x22,0x33)); + QCOMPARE(qvariant_cast(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(component.create()); + QVERIFY(object != 0); + + MyQmlObject::MyType type; + type.value = 0x8971123; + emit object->signalWithUnknownType(type); + + MyQmlObject::MyType result = qvariant_cast(object->variant()); + + QCOMPARE(result.value, type.value); + + + delete object; +} + +// 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(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(o->property("object")); + QVERIFY(nested != 0); + + QVERIFY(qvariant_cast(nested->property("nestedObject")) == o); + + delete nested; + nested = qvariant_cast(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(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(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(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(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("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(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(component.create()); + QVERIFY(object != 0); + } + { + 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(component.create()); + QVERIFY(object != 0); + } + { + 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(component.create()); + QVERIFY(object != 0); + } +} + +void tst_qdeclarativeecmascript::revision() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision.qml")); + QString url = component.url().toString(); + + MyRevisionedClass *object = qobject_cast(component.create()); + QVERIFY(object != 0); + } + { + QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision2.qml")); + QString url = component.url().toString(); + + MyRevisionedClass *object = qobject_cast(component.create()); + QVERIFY(object != 0); + } + { + QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision3.qml")); + QString url = component.url().toString(); + + MyRevisionedClass *object = qobject_cast(component.create()); + QVERIFY(object != 0); + } + // 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); +} + +void tst_qdeclarativeecmascript::realToInt() +{ + QDeclarativeComponent component(&engine, TEST_FILE("realToInt.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + + QMetaObject::invokeMethod(object, "test1"); + QCOMPARE(object->value(), int(4)); + QMetaObject::invokeMethod(object, "test2"); + QCOMPARE(object->value(), int(8)); +} + +void tst_qdeclarativeecmascript::qtbug_20648() +{ + QDeclarativeComponent component(&engine, TEST_FILE("qtbug_20648.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + QCOMPARE(o->property("test").toInt(), 100); + delete o; +} + +QTEST_MAIN(tst_qdeclarativeecmascript) + +#include "tst_qdeclarativeecmascript.moc" -- cgit v1.2.3