From 564d58025e46c825ec763193767defd78f5e13a0 Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Mon, 10 Oct 2011 12:11:21 +1000 Subject: Ensure that scarce resources work with var properties Now that we have a new property type which stores JavaScript handles, we need to ensure that scarce resources can be used with them. Task-number: QMLNG-18 Task-number: QTBUG-21843 Change-Id: I4a920ae39e7d33cf5e33362e5e0ee21c74cb35e3 Reviewed-by: Martin Jones --- .../data/ScarceResourceSignalComponentVar.qml | 9 + .../data/ScarceResourceSignalComponentVariant.qml | 9 + .../data/ScarceResourceVarComponent.qml | 13 + .../data/scarceResourceCopy.var.qml | 14 + .../data/scarceResourceCopy.variant.qml | 15 + .../data/scarceResourceCopyFromJs.var.qml | 14 + .../data/scarceResourceCopyFromJs.variant.qml | 15 + .../data/scarceResourceCopyImport.var.js | 25 ++ .../data/scarceResourceCopyImport.var.qml | 18 + .../data/scarceResourceCopyImport.variant.js | 25 ++ .../data/scarceResourceCopyImport.variant.qml | 18 + .../data/scarceResourceCopyImportDifferent.var.js | 19 + .../data/scarceResourceCopyImportDifferent.var.qml | 22 ++ .../data/scarceResourceCopyImportFail.var.js | 19 + .../data/scarceResourceCopyImportFail.var.qml | 7 + .../data/scarceResourceCopyImportFail.variant.js | 19 + .../data/scarceResourceCopyImportFail.variant.qml | 8 + .../data/scarceResourceCopyImportNoBinding.var.js | 15 + .../data/scarceResourceCopyImportNoBinding.var.qml | 12 + .../scarceResourceCopyImportNoBinding.variant.js | 15 + .../scarceResourceCopyImportNoBinding.variant.qml | 12 + .../data/scarceResourceCopyNoBinding.var.qml | 14 + .../data/scarceResourceCopyNoBinding.variant.qml | 14 + .../data/scarceResourceDestroyedCopy.var.qml | 13 + .../data/scarceResourceDestroyedCopy.variant.qml | 14 + .../data/scarceResourceFunction.var.qml | 23 ++ .../data/scarceResourceFunction.variant.qml | 23 ++ .../data/scarceResourceFunctionFail.var.qml | 23 ++ .../data/scarceResourceFunctionFail.variant.qml | 23 ++ ...scarceResourceMultipleDifferentNoBinding.var.js | 14 + ...carceResourceMultipleDifferentNoBinding.var.qml | 14 + .../scarceResourceMultipleSameNoBinding.var.js | 15 + .../scarceResourceMultipleSameNoBinding.var.qml | 14 + .../scarceResourceMultipleSameWithBinding.var.qml | 12 + .../data/scarceResourceObjectGc.var.qml | 30 ++ .../data/scarceResourceSignal.var.qml | 29 ++ .../data/scarceResourceSignal.variant.qml | 29 ++ .../data/scarceResourceTest.var.js | 48 +++ .../data/scarceResourceTest.var.qml | 14 + .../data/scarceResourceTest.variant.js | 48 +++ .../data/scarceResourceTest.variant.qml | 14 + .../data/scarceResourceTestMultiple.var.qml | 16 + .../data/scarceResourceTestMultiple.variant.qml | 15 + .../data/scarceResourceTestPreserve.var.qml | 15 + .../data/scarceResourceTestPreserve.variant.qml | 15 + .../ScarceResourceSignalComponent.qml | 9 - .../data/scarceresources/scarceResourceCopy.qml | 15 - .../scarceresources/scarceResourceCopyFromJs.qml | 15 - .../scarceresources/scarceResourceCopyImport.js | 24 -- .../scarceresources/scarceResourceCopyImport.qml | 18 - .../scarceResourceCopyImportFail.js | 18 - .../scarceResourceCopyImportFail.qml | 8 - .../scarceResourceCopyImportNoBinding.js | 14 - .../scarceResourceCopyImportNoBinding.qml | 12 - .../scarceResourceCopyNoBinding.qml | 14 - .../scarceResourceDestroyedCopy.qml | 14 - .../scarceresources/scarceResourceFunction.qml | 23 -- .../scarceresources/scarceResourceFunctionFail.qml | 24 -- .../data/scarceresources/scarceResourceSignal.qml | 29 -- .../data/scarceresources/scarceResourceTest.js | 48 --- .../data/scarceresources/scarceResourceTest.qml | 14 - .../scarceresources/scarceResourceTestMultiple.qml | 16 - .../scarceresources/scarceResourceTestPreserve.qml | 15 - .../tst_qdeclarativeecmascript.cpp | 420 ++++++++++++++++----- 64 files changed, 1147 insertions(+), 415 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVar.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVariant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceVarComponent.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.variant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.variant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.variant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.variant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.variant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.variant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameWithBinding.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceObjectGc.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.variant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.js create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.variant.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.var.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.variant.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/ScarceResourceSignalComponent.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopy.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyFromJs.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.js delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.js delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.js delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyNoBinding.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceDestroyedCopy.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunction.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunctionFail.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceSignal.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.js delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestMultiple.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestPreserve.qml (limited to 'tests/auto/declarative/qdeclarativeecmascript') diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVar.qml b/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVar.qml new file mode 100644 index 0000000000..d56bd41a99 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVar.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +QtObject { + property var scarceResourceCopy + property int width: 5 + signal testSignal + signal testSignal2 +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVariant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVariant.qml new file mode 100644 index 0000000000..e10fcfe36a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceSignalComponentVariant.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +QtObject { + property variant scarceResourceCopy + property int width: 5 + signal testSignal + signal testSignal2 +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceVarComponent.qml b/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceVarComponent.qml new file mode 100644 index 0000000000..2cf6b4223b --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/ScarceResourceVarComponent.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +Item { + id: first + property var vp: Item { + id: second + property MyScarceResourceObject srp; + srp: MyScarceResourceObject { id: scarceResourceProvider } + property var sr: scarceResourceProvider.scarceResource + property var canary: 5 + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.var.qml new file mode 100644 index 0000000000..805655fc17 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.var.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +// Here we import a scarce resource directly. +// The instance has a property which is a copy +// of the scarce resource, so it should not be +// detached (but we should automatically release +// the resource from our engine internal list). + +QtObject { + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + property var scarceResourceCopy: scarceResourceProvider.scarceResource +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.variant.qml new file mode 100644 index 0000000000..ee5b05b28a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopy.variant.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +// Here we import a scarce resource directly. +// The instance has a property which is a copy +// of the scarce resource, so it should not be +// detached (but we should automatically release +// the resource from our engine internal list). + +QtObject { + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + property variant scarceResourceCopy: scarceResourceProvider.scarceResource +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.var.qml new file mode 100644 index 0000000000..09868e5e7c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.var.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceTest.var.js" as ScarceResourceProviderJs + +// Here we import a scarce resource directly, from JS module. +// It is not preserved or released manually, so it should be +// automatically released once evaluation of the binding +// is complete. + +QtObject { + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + property var scarceResourceCopy: ScarceResourceProviderJs.importScarceResource(scarceResourceProvider) +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.variant.qml new file mode 100644 index 0000000000..a1ebeb4073 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyFromJs.variant.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceTest.variant.js" as ScarceResourceProviderJs + +// Here we import a scarce resource directly, from JS module. +// It is not preserved or released manually, so it should be +// automatically released once evaluation of the binding +// is complete. + +QtObject { + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + property variant scarceResourceCopy: ScarceResourceProviderJs.importScarceResource(scarceResourceProvider) +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.js new file mode 100644 index 0000000000..468a6b4f2e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.js @@ -0,0 +1,25 @@ +.import Qt.test 1.0 as JsQtTest + +// In this case, the "retn" variable will be evaluated during import. +// Since the "importScarceResource()" function depends on this variable, +// we must explicitly preserve the "retn" variable or the scarce +// resource would automatically be released after import completes +// but before the binding is evaluated. + +var component = Qt.createComponent("scarceResourceCopy.var.qml"); +var scarceResourceElement = component.createObject(null); +var scarceResourceProvider = scarceResourceElement.a; +var retn = scarceResourceProvider.scarceResource; +retn.preserve(); // must preserve manually or it will be released! + +function importScarceResource() { + // if called prior to calling destroyScarceResource(), + // this function should return the preserved scarce resource. + // otherwise, it should return an invalid variant. + return retn; +} + +function destroyScarceResource() { + retn.destroy(); +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.qml new file mode 100644 index 0000000000..9321481f45 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.var.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceCopyImport.var.js" as ScarceResourceCopyImportJs + +QtObject { + // this binding is evaluated once, prior to the resource being released + property var scarceResourceImportedCopy: ScarceResourceCopyImportJs.importScarceResource() + + property bool arePropertiesEqual + property var scarceResourceAssignedCopyOne; + property var scarceResourceAssignedCopyTwo; + Component.onCompleted: { + scarceResourceAssignedCopyOne = ScarceResourceCopyImportJs.importScarceResource(); + arePropertiesEqual = (scarceResourceAssignedCopyOne == scarceResourceImportedCopy); + ScarceResourceCopyImportJs.destroyScarceResource(); // makes all properties invalid. + scarceResourceAssignedCopyTwo = ScarceResourceCopyImportJs.importScarceResource(); + } +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.js new file mode 100644 index 0000000000..9aeb507487 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.js @@ -0,0 +1,25 @@ +.import Qt.test 1.0 as JsQtTest + +// In this case, the "retn" variable will be evaluated during import. +// Since the "importScarceResource()" function depends on this variable, +// we must explicitly preserve the "retn" variable or the scarce +// resource would automatically be released after import completes +// but before the binding is evaluated. + +var component = Qt.createComponent("scarceResourceCopy.variant.qml"); +var scarceResourceElement = component.createObject(null); +var scarceResourceProvider = scarceResourceElement.a; +var retn = scarceResourceProvider.scarceResource; +retn.preserve(); // must preserve manually or it will be released! + +function importScarceResource() { + // if called prior to calling destroyScarceResource(), + // this function should return the preserved scarce resource. + // otherwise, it should return an invalid variant. + return retn; +} + +function destroyScarceResource() { + retn.destroy(); +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.qml new file mode 100644 index 0000000000..e8b53979dd --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImport.variant.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceCopyImport.variant.js" as ScarceResourceCopyImportJs + +QtObject { + // this binding is evaluated once, prior to the resource being released + property variant scarceResourceImportedCopy: ScarceResourceCopyImportJs.importScarceResource() + + // this code is evaluated on completion, and so copy one should be valid, copy two invalid. + property variant scarceResourceAssignedCopyOne; + property variant scarceResourceAssignedCopyTwo; + Component.onCompleted: { + scarceResourceAssignedCopyOne = ScarceResourceCopyImportJs.importScarceResource(); + ScarceResourceCopyImportJs.destroyScarceResource(); + scarceResourceAssignedCopyTwo = ScarceResourceCopyImportJs.importScarceResource(); + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.js new file mode 100644 index 0000000000..000eeddb34 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.js @@ -0,0 +1,19 @@ +.import Qt.test 1.0 as JsQtTest + +// In this case, we create the returned scarce resource each call, +// so the object will be different every time it is returned. + +var mostRecent + +function importScarceResource() { + var component = Qt.createComponent("scarceResourceCopy.var.qml"); + var scarceResourceElement = component.createObject(null); + var scarceResourceProvider = scarceResourceElement.a; + var retn = scarceResourceProvider.scarceResource; + mostRecent = retn; + return retn; +} + +function destroyScarceResource() { + mostRecent.destroy(); +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.qml new file mode 100644 index 0000000000..082d132c24 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportDifferent.var.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceCopyImportDifferent.var.js" as ScarceResourceCopyImportJs + +// in this case, the ScarceResourceCopyImportJs returns a _new_, different +// scarce resource each time. Invalidating one will not invalidate the others. + +QtObject { + // this binding is evaluated once, prior to the resource being released + property var scarceResourceImportedCopy: ScarceResourceCopyImportJs.importScarceResource() + + // the following properties are assigned on component completion. + property bool arePropertiesEqual + property var scarceResourceAssignedCopyOne; + property var scarceResourceAssignedCopyTwo; + Component.onCompleted: { + scarceResourceAssignedCopyOne = ScarceResourceCopyImportJs.importScarceResource(); + arePropertiesEqual = (scarceResourceAssignedCopyOne != scarceResourceImportedCopy); // they're not the same object. + ScarceResourceCopyImportJs.destroyScarceResource(); // makes the MOST RECENT resource invalid (ie, assignedCopyOne). + scarceResourceAssignedCopyTwo = ScarceResourceCopyImportJs.importScarceResource(); + } +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.js new file mode 100644 index 0000000000..ba52b323f0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.js @@ -0,0 +1,19 @@ +.import Qt.test 1.0 as JsQtTest + +// In this case, the "retn" variable will be evaluated during import. +// Since the importScarceResource() function depends on this variable, +// because we DO NOT call "retn.preserve()", the scarce resource will +// be released after the import completes but prior to evaluation of +// any binding which calls "importScarceResource()". +// Thus, "importScarceResource()" will return a released (invalid) +// scarce resource. + +var component = Qt.createComponent("scarceResourceCopy.var.qml"); +var scarceResourceElement = component.createObject(null); +var scarceResourceProvider = scarceResourceElement.a; +var retn = scarceResourceProvider.scarceResource; + +function importScarceResource() { + return retn; // should return a released (invalid) scarce resource +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.qml new file mode 100644 index 0000000000..a1a3c1d66f --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.var.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceCopyImportFail.var.js" as ScarceResourceCopyImportFailJs + +QtObject { + property var scarceResourceCopy: ScarceResourceCopyImportFailJs.importScarceResource() +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.js new file mode 100644 index 0000000000..b59b5b1fa9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.js @@ -0,0 +1,19 @@ +.import Qt.test 1.0 as JsQtTest + +// In this case, the "retn" variable will be evaluated during import. +// Since the importScarceResource() function depends on this variable, +// because we DO NOT call "retn.preserve()", the scarce resource will +// be released after the import completes but prior to evaluation of +// any binding which calls "importScarceResource()". +// Thus, "importScarceResource()" will return a released (invalid) +// scarce resource. + +var component = Qt.createComponent("scarceResourceCopy.variant.qml"); +var scarceResourceElement = component.createObject(null); +var scarceResourceProvider = scarceResourceElement.a; +var retn = scarceResourceProvider.scarceResource; + +function importScarceResource() { + return retn; // should return a released (invalid) scarce resource +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.qml new file mode 100644 index 0000000000..8f6dcd6603 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportFail.variant.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceCopyImportFail.variant.js" as ScarceResourceCopyImportFailJs + +QtObject { + property variant scarceResourceCopy: ScarceResourceCopyImportFailJs.importScarceResource() +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.js new file mode 100644 index 0000000000..130199f78a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.js @@ -0,0 +1,15 @@ +.import Qt.test 1.0 as JsQtTest + +// In this case, the "retn" variable will be evaluated during import. +// Since the importScarceResource() function depends on this variable, +// because we DO NOT call "retn.preserve()", the scarce resource will +// be released after the import completes but prior to evaluation of +// any binding which calls "importScarceResource()". +// Thus, "importScarceResource()" will return a released (invalid) +// scarce resource. + +var component = Qt.createComponent("scarceResourceCopyNoBinding.var.qml"); +var scarceResourceElement = component.createObject(null); +var scarceResourceProvider = scarceResourceElement.a; +var retn = scarceResourceProvider.scarceResource; + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.qml new file mode 100644 index 0000000000..5284b40cc8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.var.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +// the following js import doesn't manually preserve or destroy any resources +import "scarceResourceCopyImportNoBinding.var.js" as ScarceResourceCopyImportNoBindingJs + +QtObject { + // in this case, there is an import but no binding evaluated. + // nonetheless, any resources which are not preserved, should + // be automatically released by the engine. +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.js new file mode 100644 index 0000000000..14a36a19ea --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.js @@ -0,0 +1,15 @@ +.import Qt.test 1.0 as JsQtTest + +// In this case, the "retn" variable will be evaluated during import. +// Since the importScarceResource() function depends on this variable, +// because we DO NOT call "retn.preserve()", the scarce resource will +// be released after the import completes but prior to evaluation of +// any binding which calls "importScarceResource()". +// Thus, "importScarceResource()" will return a released (invalid) +// scarce resource. + +var component = Qt.createComponent("scarceResourceCopyNoBinding.variant.qml"); +var scarceResourceElement = component.createObject(null); +var scarceResourceProvider = scarceResourceElement.a; +var retn = scarceResourceProvider.scarceResource; + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.qml new file mode 100644 index 0000000000..826cbe49fc --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyImportNoBinding.variant.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +// the following js import doesn't manually preserve or destroy any resources +import "scarceResourceCopyImportNoBinding.variant.js" as ScarceResourceCopyImportNoBindingJs + +QtObject { + // in this case, there is an import but no binding evaluated. + // nonetheless, any resources which are not preserved, should + // be automatically released by the engine. +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.var.qml new file mode 100644 index 0000000000..4adef39980 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.var.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +QtObject { + // this component doesn't bind any property to a scarce + // resource from the scarce resource provider, + // so the binding evaluation resource cleanup + // codepath shouldn't be activated; so if the resources + // are released, it will be due to the import evaluation + // resource cleanup codepath being activated correctly. + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.variant.qml new file mode 100644 index 0000000000..4adef39980 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceCopyNoBinding.variant.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +QtObject { + // this component doesn't bind any property to a scarce + // resource from the scarce resource provider, + // so the binding evaluation resource cleanup + // codepath shouldn't be activated; so if the resources + // are released, it will be due to the import evaluation + // resource cleanup codepath being activated correctly. + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.var.qml new file mode 100644 index 0000000000..500f5d5bd7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.var.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceTest.var.js" as ScarceResourceProviderJs + +// In this case, following the evaluation of the binding, +// the scarceResourceTest value should be an invalid variant, +// since the scarce resource will have been released. + +QtObject { + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + property var scarceResourceCopy: ScarceResourceProviderJs.importReleasedScarceResource(scarceResourceProvider); +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.variant.qml new file mode 100644 index 0000000000..7a3b845247 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceDestroyedCopy.variant.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceTest.variant.js" as ScarceResourceProviderJs + +// In this case, following the evaluation of the binding, +// the scarceResourceTest value should be an invalid variant, +// since the scarce resource will have been released. + +QtObject { + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + property variant scarceResourceCopy: ScarceResourceProviderJs.importReleasedScarceResource(scarceResourceProvider); +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.var.qml new file mode 100644 index 0000000000..23e4c8d15e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.var.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +// Here we import a scarce resource directly. +// The copy is only assigned when retrieveScarceResource() +// is called, and so should be detached prior to that. +// The copy should be released when releaseScarceResource() +// is called, and so should be detached after that. + +QtObject { + id: root + property MyScarceResourceObject a: MyScarceResourceObject { id: scarceResourceProvider } + property var scarceResourceCopy; + + function retrieveScarceResource() { + root.scarceResourceCopy = scarceResourceProvider.scarceResource; + } + + function releaseScarceResource() { + root.scarceResourceCopy = null; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.variant.qml new file mode 100644 index 0000000000..fe3707b5d3 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunction.variant.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +// Here we import a scarce resource directly. +// The copy is only assigned when retrieveScarceResource() +// is called, and so should be detached prior to that. +// The copy should be released when releaseScarceResource() +// is called, and so should be detached after that. + +QtObject { + id: root + property MyScarceResourceObject a: MyScarceResourceObject { id: scarceResourceProvider } + property variant scarceResourceCopy; + + function retrieveScarceResource() { + root.scarceResourceCopy = scarceResourceProvider.scarceResource; + } + + function releaseScarceResource() { + root.scarceResourceCopy = null; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.var.qml new file mode 100644 index 0000000000..7b4463773c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.var.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +// In this example, a common syntax error will only be "caught" +// when the function is called via: +// QDeclarativeVMEMetaObject::metaCall->invokeMetaMethod() +// We would like to ensure that a useful error message is printed. + +QtObject { + id: root + property MyScarceResourceObject a: MyScarceResourceObject { id: scarceResourceProvider } + property var scarceResourceCopy; + property string srp_name: a.toString(); + + function retrieveScarceResource() { + root.scarceResourceCopy = scarceResourceProvider.scarceResource(); // common syntax error, should throw exception + } + + function releaseScarceResource() { + root.scarceResourceCopy = null; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.variant.qml new file mode 100644 index 0000000000..45acc53e63 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceFunctionFail.variant.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +// In this example, a common syntax error will only be "caught" +// when the function is called via: +// QDeclarativeVMEMetaObject::metaCall->invokeMetaMethod() +// We would like to ensure that a useful error message is printed. + +QtObject { + id: root + property MyScarceResourceObject a: MyScarceResourceObject { id: scarceResourceProvider } + property variant scarceResourceCopy; + property string srp_name: a.toString(); + + function retrieveScarceResource() { + root.scarceResourceCopy = scarceResourceProvider.scarceResource(); // common syntax error, should throw exception + } + + function releaseScarceResource() { + root.scarceResourceCopy = null; + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.js new file mode 100644 index 0000000000..217f693456 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.js @@ -0,0 +1,14 @@ +.import Qt.test 1.0 as JsQtTest + +function importScarceResource() { + var component = Qt.createComponent("scarceResourceCopy.var.qml"); + var scarceResourceElement = component.createObject(null); + var scarceResourceProvider = scarceResourceElement.a; + var retn = scarceResourceProvider.scarceResource; + retn.preserve(); + return retn; +} + +function releaseScarceResource(resource) { + resource.destroy(); +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.qml new file mode 100644 index 0000000000..205131661f --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleDifferentNoBinding.var.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceMultipleDifferentNoBinding.var.js" as ScarceResourcesMultipleDifferentNoBinding + +QtObject { + property var resourceOne + property var resourceTwo + + Component.onCompleted: { + resourceOne = ScarceResourcesMultipleDifferentNoBinding.importScarceResource(); + resourceTwo = ScarceResourcesMultipleDifferentNoBinding.importScarceResource(); + ScarceResourcesMultipleDifferentNoBinding.releaseScarceResource(resourceTwo); + } +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.js new file mode 100644 index 0000000000..5b2494c8e6 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.js @@ -0,0 +1,15 @@ +.import Qt.test 1.0 as JsQtTest + +var component = Qt.createComponent("scarceResourceCopy.var.qml"); +var scarceResourceElement = component.createObject(null); +var scarceResourceProvider = scarceResourceElement.a; +var retn = scarceResourceProvider.scarceResource; +retn.preserve(); + +function importScarceResource() { + return retn; +} + +function releaseScarceResource(resource) { + resource.destroy(); +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.qml new file mode 100644 index 0000000000..e7f6d7868f --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameNoBinding.var.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceMultipleSameNoBinding.var.js" as ScarceResourcesMultipleSameNoBinding + +QtObject { + property var resourceOne + property var resourceTwo + + Component.onCompleted: { + resourceOne = ScarceResourcesMultipleSameNoBinding.importScarceResource(); + resourceTwo = ScarceResourcesMultipleSameNoBinding.importScarceResource(); + ScarceResourcesMultipleSameNoBinding.releaseScarceResource(resourceTwo); + } +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameWithBinding.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameWithBinding.var.qml new file mode 100644 index 0000000000..34cb97f39c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceMultipleSameWithBinding.var.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceMultipleDifferentNoBinding.var.js" as ScarceResourcesMultipleDifferentNoBinding + +QtObject { + property var resourceOne: ScarceResourcesMultipleDifferentNoBinding.importScarceResource() + property var resourceTwo: resourceOne + + Component.onCompleted: { + ScarceResourcesMultipleDifferentNoBinding.releaseScarceResource(resourceTwo); + } +} \ No newline at end of file diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceObjectGc.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceObjectGc.var.qml new file mode 100644 index 0000000000..7ec98e6619 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceObjectGc.var.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +Item { + id: testScarce + + property var varProperty + + property var canary: 4 + + // constructs an Item which contains a scarce resource. + function constructScarceObject() { + var retn = 1; + var component = Qt.createComponent("ScarceResourceVarComponent.qml"); + if (component.status == Component.Ready) { + retn = component.createObject(null); // has JavaScript ownership + } + return retn; + } + + function assignVarProperty() { + varProperty = constructScarceObject(); + gc(); + } + + function deassignVarProperty() { + varProperty = 2; // causes the original object to be garbage collected. + gc(); // image should be detached; ep->sr should be empty! + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.var.qml new file mode 100644 index 0000000000..0b30e88fa8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.var.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +QtObject { + id: root + + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + + property ScarceResourceSignalComponentVar b; + b: ScarceResourceSignalComponentVar { + objectName: "srsc" + + onTestSignal: { + // this signal will be invoked manually in the test. + // the scarce resource should be released automatically after evaluation + // and since we don't keep a copy of it, the pixmap will be detached. + width = (scarceResourceProvider.scarceResource,10) + } + + onTestSignal2: { + // this signal will be invoked manually in the test. + // the scarce resource should be released automatically after evaluation + // but since we assign it to a property, the pixmap won't be detached. + scarceResourceCopy = scarceResourceProvider.scarceResource + } + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.variant.qml new file mode 100644 index 0000000000..1011c7e240 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceSignal.variant.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +QtObject { + id: root + + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + + property ScarceResourceSignalComponentVariant b; + b: ScarceResourceSignalComponentVariant { + objectName: "srsc" + + onTestSignal: { + // this signal will be invoked manually in the test. + // the scarce resource should be released automatically after evaluation + // and since we don't keep a copy of it, the pixmap will be detached. + width = (scarceResourceProvider.scarceResource,10) + } + + onTestSignal2: { + // this signal will be invoked manually in the test. + // the scarce resource should be released automatically after evaluation + // but since we assign it to a property, the pixmap won't be detached. + scarceResourceCopy = scarceResourceProvider.scarceResource + } + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.js new file mode 100644 index 0000000000..c904eb3564 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.js @@ -0,0 +1,48 @@ +.import Qt.test 1.0 as JsQtTest + +function importScarceResource(scarceResourceProvider) { + // the scarce resource should be automatically released + // after the binding is evaluated if preserve is not + // called. + return scarceResourceProvider.scarceResource; +} + +function importPreservedScarceResource(scarceResourceProvider) { + // the scarce resource is manually preserved + // during the evaluation of the binding. + // it should not be released. + var scarceResource = scarceResourceProvider.scarceResource; + scarceResource.preserve(); + return scarceResource; +} + +function importReleasedScarceResource(scarceResourceProvider) { + // release the scarce resource during the + // evaluation of the binding. The returned + // variant will therefore be invalid. + var scarceResource = scarceResourceProvider.scarceResource; + scarceResource.destroy(); + return scarceResource; +} + +function importPreservedScarceResourceFromMultiple(scarceResourceProvider) { + // some scarce resources are manually preserved, + // some of them are manually destroyed, + // and some are automatically managed. + // We return a preserved resource + var sr1 = scarceResourceProvider.scarceResource; // preserved/destroyed. + sr1.preserve(); + var sr2 = scarceResourceProvider.scarceResource; // preserved/destroyed + sr2.preserve(); + var sr3 = scarceResourceProvider.scarceResource; // automatic. + var sr4 = scarceResourceProvider.scarceResource; // automatic and returned. + var sr5 = scarceResourceProvider.scarceResource; // destroyed + sr5.destroy(); + sr2.destroy(); + var sr6 = scarceResourceProvider.scarceResource; // destroyed + var sr7 = scarceResourceProvider.scarceResource; // automatic + sr1.destroy(); + sr6.destroy(); + return sr4; +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.qml new file mode 100644 index 0000000000..1d4e67055e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.var.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +// Here we import a scarce resource directly, and use it in a binding. +// It is not preserved or released manually, so it should be +// automatically released once evaluation of the binding +// is complete. + +QtObject { + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + property int scarceResourceTest: scarceResourceProvider.scarceResource,100 // return 100, but include the scarceResource in the binding to be evaluated. +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.js new file mode 100644 index 0000000000..c904eb3564 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.js @@ -0,0 +1,48 @@ +.import Qt.test 1.0 as JsQtTest + +function importScarceResource(scarceResourceProvider) { + // the scarce resource should be automatically released + // after the binding is evaluated if preserve is not + // called. + return scarceResourceProvider.scarceResource; +} + +function importPreservedScarceResource(scarceResourceProvider) { + // the scarce resource is manually preserved + // during the evaluation of the binding. + // it should not be released. + var scarceResource = scarceResourceProvider.scarceResource; + scarceResource.preserve(); + return scarceResource; +} + +function importReleasedScarceResource(scarceResourceProvider) { + // release the scarce resource during the + // evaluation of the binding. The returned + // variant will therefore be invalid. + var scarceResource = scarceResourceProvider.scarceResource; + scarceResource.destroy(); + return scarceResource; +} + +function importPreservedScarceResourceFromMultiple(scarceResourceProvider) { + // some scarce resources are manually preserved, + // some of them are manually destroyed, + // and some are automatically managed. + // We return a preserved resource + var sr1 = scarceResourceProvider.scarceResource; // preserved/destroyed. + sr1.preserve(); + var sr2 = scarceResourceProvider.scarceResource; // preserved/destroyed + sr2.preserve(); + var sr3 = scarceResourceProvider.scarceResource; // automatic. + var sr4 = scarceResourceProvider.scarceResource; // automatic and returned. + var sr5 = scarceResourceProvider.scarceResource; // destroyed + sr5.destroy(); + sr2.destroy(); + var sr6 = scarceResourceProvider.scarceResource; // destroyed + var sr7 = scarceResourceProvider.scarceResource; // automatic + sr1.destroy(); + sr6.destroy(); + return sr4; +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.qml new file mode 100644 index 0000000000..1d4e67055e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTest.variant.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +// Here we import a scarce resource directly, and use it in a binding. +// It is not preserved or released manually, so it should be +// automatically released once evaluation of the binding +// is complete. + +QtObject { + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + property int scarceResourceTest: scarceResourceProvider.scarceResource,100 // return 100, but include the scarceResource in the binding to be evaluated. +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.var.qml new file mode 100644 index 0000000000..5e6c2d97f9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.var.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceTest.var.js" as ScarceResourceProviderJs + +// In this case, multiple scarce resource are explicity preserved +// and then explicitly destroyed, while others are automatically +// managed. Since none are manually preserved without subsequently +// being destroyed, after the evaluation of the binding the +// scarce resource should be detached. + +QtObject { + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + property int scarceResourceTest: ScarceResourceProviderJs.importPreservedScarceResourceFromMultiple(scarceResourceProvider), 100 +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.variant.qml new file mode 100644 index 0000000000..2970bcb26c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestMultiple.variant.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceTest.variant.js" as ScarceResourceProviderJs + +// In this case, multiple scarce resource are explicity preserved +// and then explicitly destroyed, while others are automatically +// managed. Since none are manually preserved without subsequently +// being destroyed, after the evaluation of the binding the +// scarce resource should be detached. + +QtObject { + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + property int scarceResourceTest: ScarceResourceProviderJs.importPreservedScarceResourceFromMultiple(scarceResourceProvider), 100 +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.var.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.var.qml new file mode 100644 index 0000000000..9e9495c0fa --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.var.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceTest.var.js" as ScarceResourceProviderJs + +// In this case, the scarce resource is explicity preserved. +// It should not be automatically released after the evaluation +// of the binding is complete, but instead will be kept in +// memory until the JS garbage collector runs. + +QtObject { + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + property int scarceResourceTest: ScarceResourceProviderJs.importPreservedScarceResource(scarceResourceProvider),100 // return 100, but the resource should be preserved. +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.variant.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.variant.qml new file mode 100644 index 0000000000..022067beca --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scarceResourceTestPreserve.variant.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 +import Qt.test 1.0 +import "scarceResourceTest.variant.js" as ScarceResourceProviderJs + +// In this case, the scarce resource is explicity preserved. +// It should not be automatically released after the evaluation +// of the binding is complete, but instead will be kept in +// memory until the JS garbage collector runs. + +QtObject { + property MyScarceResourceObject a; + a: MyScarceResourceObject { id: scarceResourceProvider } + property int scarceResourceTest: ScarceResourceProviderJs.importPreservedScarceResource(scarceResourceProvider),100 // return 100, but the resource should be preserved. +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/ScarceResourceSignalComponent.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/ScarceResourceSignalComponent.qml deleted file mode 100644 index e10fcfe36a..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/ScarceResourceSignalComponent.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 - -QtObject { - property variant scarceResourceCopy - property int width: 5 - signal testSignal - signal testSignal2 -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopy.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopy.qml deleted file mode 100644 index ee5b05b28a..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopy.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 - -// Here we import a scarce resource directly. -// The instance has a property which is a copy -// of the scarce resource, so it should not be -// detached (but we should automatically release -// the resource from our engine internal list). - -QtObject { - property MyScarceResourceObject a; - a: MyScarceResourceObject { id: scarceResourceProvider } - property variant scarceResourceCopy: scarceResourceProvider.scarceResource -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyFromJs.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyFromJs.qml deleted file mode 100644 index 40f6d7bbd6..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyFromJs.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 -import "scarceResourceTest.js" as ScarceResourceProviderJs - -// Here we import a scarce resource directly, from JS module. -// It is not preserved or released manually, so it should be -// automatically released once evaluation of the binding -// is complete. - -QtObject { - property MyScarceResourceObject a; - a: MyScarceResourceObject { id: scarceResourceProvider } - property variant scarceResourceCopy: ScarceResourceProviderJs.importScarceResource(scarceResourceProvider) -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.js deleted file mode 100644 index bacc50dcc9..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.js +++ /dev/null @@ -1,24 +0,0 @@ -.import Qt.test 1.0 as JsQtTest - -// In this case, the "retn" variable will be evaluated during import. -// Since the "importScarceResource()" function depends on this variable, -// we must explicitly preserve the "retn" variable or the scarce -// resource would automatically be released after import completes -// but before the binding is evaluated. - -var component = Qt.createComponent("scarceResourceCopy.qml"); -var scarceResourceElement = component.createObject(null); -var scarceResourceProvider = scarceResourceElement.a; -var retn = scarceResourceProvider.scarceResource; -retn.preserve(); // must preserve manually or it will be released! - -function importScarceResource() { - // if called prior to calling destroyScarceResource(), - // this function should return the preserved scarce resource. - // otherwise, it should return an invalid variant. - return retn; -} - -function destroyScarceResource() { - retn.destroy(); -} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.qml deleted file mode 100644 index 08acc1b694..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImport.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 -import "scarceResourceCopyImport.js" as ScarceResourceCopyImportJs - -QtObject { - // this binding is evaluated once, prior to the resource being released - property variant scarceResourceCopy: ScarceResourceCopyImportJs.importScarceResource() - - // this code is evaluated on completion, and so copy one should be valid, copy two invalid. - property variant scarceResourceAssignedCopyOne; - property variant scarceResourceAssignedCopyTwo; - Component.onCompleted: { - scarceResourceAssignedCopyOne = ScarceResourceCopyImportJs.importScarceResource(); - ScarceResourceCopyImportJs.destroyScarceResource(); - scarceResourceAssignedCopyTwo = ScarceResourceCopyImportJs.importScarceResource(); - } -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.js deleted file mode 100644 index 6c495863b5..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.js +++ /dev/null @@ -1,18 +0,0 @@ -.import Qt.test 1.0 as JsQtTest - -// In this case, the "retn" variable will be evaluated during import. -// Since the importScarceResource() function depends on this variable, -// because we DO NOT call "retn.preserve()", the scarce resource will -// be released after the import completes but prior to evaluation of -// any binding which calls "importScarceResource()". -// Thus, "importScarceResource()" will return a released (invalid) -// scarce resource. - -var component = Qt.createComponent("scarceResourceCopy.qml"); -var scarceResourceElement = component.createObject(null); -var scarceResourceProvider = scarceResourceElement.a; -var retn = scarceResourceProvider.scarceResource; - -function importScarceResource() { - return retn; // should return a released (invalid) scarce resource -} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.qml deleted file mode 100644 index 613d3a8ee8..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportFail.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 -import "scarceResourceCopyImportFail.js" as ScarceResourceCopyImportFailJs - -QtObject { - property variant scarceResourceCopy: ScarceResourceCopyImportFailJs.importScarceResource() -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.js deleted file mode 100644 index 4a5b6b4427..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.js +++ /dev/null @@ -1,14 +0,0 @@ -.import Qt.test 1.0 as JsQtTest - -// In this case, the "retn" variable will be evaluated during import. -// Since the importScarceResource() function depends on this variable, -// because we DO NOT call "retn.preserve()", the scarce resource will -// be released after the import completes but prior to evaluation of -// any binding which calls "importScarceResource()". -// Thus, "importScarceResource()" will return a released (invalid) -// scarce resource. - -var component = Qt.createComponent("scarceResourceCopyNoBinding.qml"); -var scarceResourceElement = component.createObject(null); -var scarceResourceProvider = scarceResourceElement.a; -var retn = scarceResourceProvider.scarceResource; diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.qml deleted file mode 100644 index 81deec0713..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyImportNoBinding.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 - -// the following js import doesn't manually preserve or destroy any resources -import "scarceResourceCopyImportNoBinding.js" as ScarceResourceCopyImportNoBindingJs - -QtObject { - // in this case, there is an import but no binding evaluated. - // nonetheless, any resources which are not preserved, should - // be automatically released by the engine. -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyNoBinding.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyNoBinding.qml deleted file mode 100644 index 4adef39980..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceCopyNoBinding.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 - -QtObject { - // this component doesn't bind any property to a scarce - // resource from the scarce resource provider, - // so the binding evaluation resource cleanup - // codepath shouldn't be activated; so if the resources - // are released, it will be due to the import evaluation - // resource cleanup codepath being activated correctly. - property MyScarceResourceObject a; - a: MyScarceResourceObject { id: scarceResourceProvider } -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceDestroyedCopy.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceDestroyedCopy.qml deleted file mode 100644 index e47c37aba3..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceDestroyedCopy.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 -import "scarceResourceTest.js" as ScarceResourceProviderJs - -// In this case, following the evaluation of the binding, -// the scarceResourceTest value should be an invalid variant, -// since the scarce resource will have been released. - -QtObject { - property MyScarceResourceObject a; - a: MyScarceResourceObject { id: scarceResourceProvider } - property variant scarceResourceCopy: ScarceResourceProviderJs.importReleasedScarceResource(scarceResourceProvider); -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunction.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunction.qml deleted file mode 100644 index fe3707b5d3..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunction.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 - -// Here we import a scarce resource directly. -// The copy is only assigned when retrieveScarceResource() -// is called, and so should be detached prior to that. -// The copy should be released when releaseScarceResource() -// is called, and so should be detached after that. - -QtObject { - id: root - property MyScarceResourceObject a: MyScarceResourceObject { id: scarceResourceProvider } - property variant scarceResourceCopy; - - function retrieveScarceResource() { - root.scarceResourceCopy = scarceResourceProvider.scarceResource; - } - - function releaseScarceResource() { - root.scarceResourceCopy = null; - } -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunctionFail.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunctionFail.qml deleted file mode 100644 index 38de0ae0aa..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceFunctionFail.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 - -// In this example, a common syntax error will only be "caught" -// when the function is called via: -// QDeclarativeVMEMetaObject::metaCall->invokeMetaMethod() -// We would like to ensure that a useful error message is printed, -// rather than having QScriptValue::call() function fail silently. - -QtObject { - id: root - property MyScarceResourceObject a: MyScarceResourceObject { id: scarceResourceProvider } - property variant scarceResourceCopy; - property string srp_name: a.toString(); - - function retrieveScarceResource() { - root.scarceResourceCopy = scarceResourceProvider.scarceResource(); // common syntax error, should throw exception - } - - function releaseScarceResource() { - root.scarceResourceCopy = null; - } -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceSignal.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceSignal.qml deleted file mode 100644 index 1d5a39c52d..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceSignal.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 - -QtObject { - id: root - - property MyScarceResourceObject a; - a: MyScarceResourceObject { id: scarceResourceProvider } - - property ScarceResourceSignalComponent b; - b: ScarceResourceSignalComponent { - objectName: "srsc" - - onTestSignal: { - // this signal will be invoked manually in the test. - // the scarce resource should be released automatically after evaluation - // and since we don't keep a copy of it, the pixmap will be detached. - width = (scarceResourceProvider.scarceResource,10) - } - - onTestSignal2: { - // this signal will be invoked manually in the test. - // the scarce resource should be released automatically after evaluation - // but since we assign it to a property, the pixmap won't be detached. - scarceResourceCopy = scarceResourceProvider.scarceResource - } - } -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.js b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.js deleted file mode 100644 index c904eb3564..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.js +++ /dev/null @@ -1,48 +0,0 @@ -.import Qt.test 1.0 as JsQtTest - -function importScarceResource(scarceResourceProvider) { - // the scarce resource should be automatically released - // after the binding is evaluated if preserve is not - // called. - return scarceResourceProvider.scarceResource; -} - -function importPreservedScarceResource(scarceResourceProvider) { - // the scarce resource is manually preserved - // during the evaluation of the binding. - // it should not be released. - var scarceResource = scarceResourceProvider.scarceResource; - scarceResource.preserve(); - return scarceResource; -} - -function importReleasedScarceResource(scarceResourceProvider) { - // release the scarce resource during the - // evaluation of the binding. The returned - // variant will therefore be invalid. - var scarceResource = scarceResourceProvider.scarceResource; - scarceResource.destroy(); - return scarceResource; -} - -function importPreservedScarceResourceFromMultiple(scarceResourceProvider) { - // some scarce resources are manually preserved, - // some of them are manually destroyed, - // and some are automatically managed. - // We return a preserved resource - var sr1 = scarceResourceProvider.scarceResource; // preserved/destroyed. - sr1.preserve(); - var sr2 = scarceResourceProvider.scarceResource; // preserved/destroyed - sr2.preserve(); - var sr3 = scarceResourceProvider.scarceResource; // automatic. - var sr4 = scarceResourceProvider.scarceResource; // automatic and returned. - var sr5 = scarceResourceProvider.scarceResource; // destroyed - sr5.destroy(); - sr2.destroy(); - var sr6 = scarceResourceProvider.scarceResource; // destroyed - var sr7 = scarceResourceProvider.scarceResource; // automatic - sr1.destroy(); - sr6.destroy(); - return sr4; -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.qml deleted file mode 100644 index 1d4e67055e..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTest.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 - -// Here we import a scarce resource directly, and use it in a binding. -// It is not preserved or released manually, so it should be -// automatically released once evaluation of the binding -// is complete. - -QtObject { - property MyScarceResourceObject a; - a: MyScarceResourceObject { id: scarceResourceProvider } - property int scarceResourceTest: scarceResourceProvider.scarceResource,100 // return 100, but include the scarceResource in the binding to be evaluated. -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestMultiple.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestMultiple.qml deleted file mode 100644 index 9a6ee30ff1..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestMultiple.qml +++ /dev/null @@ -1,16 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 -import "scarceResourceTest.js" as ScarceResourceProviderJs - -// In this case, multiple scarce resource are explicity preserved -// and then explicitly destroyed, while others are automatically -// managed. Since none are manually preserved without subsequently -// being destroyed, after the evaluation of the binding the -// scarce resource should be detached. - -QtObject { - property MyScarceResourceObject a; - a: MyScarceResourceObject { id: scarceResourceProvider } - property int scarceResourceTest: ScarceResourceProviderJs.importPreservedScarceResourceFromMultiple(scarceResourceProvider), 100 -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestPreserve.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestPreserve.qml deleted file mode 100644 index d7a40312ab..0000000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/scarceresources/scarceResourceTestPreserve.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 -import "scarceResourceTest.js" as ScarceResourceProviderJs - -// In this case, the scarce resource is explicity preserved. -// It should not be automatically released after the evaluation -// of the binding is complete, but instead will be kept in -// memory until the JS garbage collector runs. - -QtObject { - property MyScarceResourceObject a; - a: MyScarceResourceObject { id: scarceResourceProvider } - property int scarceResourceTest: ScarceResourceProviderJs.importPreservedScarceResource(scarceResourceProvider),100 // return 100, but the resource should be preserved. -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 3d50d6ee3d..5e62ec6508 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -152,6 +152,8 @@ private slots: void importScripts_data(); void importScripts(); void scarceResources(); + void scarceResources_data(); + void scarceResources_other(); void propertyChangeSlots(); void propertyVar_data(); void propertyVar(); @@ -1412,15 +1414,15 @@ void tst_qdeclarativeecmascript::functionErrors() delete object; // test that if an exception occurs while invoking js function from cpp, it is reported as expected. - QDeclarativeComponent componentTwo(&engine, TEST_FILE("scarceresources/scarceResourceFunctionFail.qml")); + QDeclarativeComponent componentTwo(&engine, TEST_FILE("scarceResourceFunctionFail.var.qml")); url = componentTwo.url().toString(); object = componentTwo.create(); QVERIFY(object != 0); QString srpname = object->property("srp_name").toString(); - warning = url + QLatin1String(":17: TypeError: Property 'scarceResource' of object ") + srpname + - QLatin1String(" is not a function"); + warning = url + QLatin1String(":16: TypeError: Property 'scarceResource' of object ") + srpname + + QLatin1String(" is not a function"); QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); // we expect a meaningful warning to be printed. QMetaObject::invokeMethod(object, "retrieveScarceResource"); delete object; @@ -3197,110 +3199,98 @@ void tst_qdeclarativeecmascript::importScripts() } } -void tst_qdeclarativeecmascript::scarceResources() +void tst_qdeclarativeecmascript::scarceResources_other() { + /* These tests require knowledge of state, since we test values after + performing signal or function invocation. */ + QPixmap origPixmap(100, 100); origPixmap.fill(Qt::blue); - + QString srp_name, expectedWarning; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(&engine); ScarceResourceObject *eo = 0; + QObject *srsc = 0; QObject *object = 0; - // in the following three cases, the instance created from the component - // has a property which is a copy of the scarce resource; hence, the - // resource should NOT be detached prior to deletion of the object instance, - // unless the resource is destroyed explicitly. - QDeclarativeComponent component(&engine, TEST_FILE("scarceresources/scarceResourceCopy.qml")); - object = component.create(); - QVERIFY(object != 0); - QVERIFY(object->property("scarceResourceCopy").isValid()); - QCOMPARE(object->property("scarceResourceCopy").value(), origPixmap); - QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point. + /* property var semantics */ + + // test that scarce resources are handled properly in signal invocation + QDeclarativeComponent varComponentTen(&engine, TEST_FILE("scarceResourceSignal.var.qml")); + object = varComponentTen.create(); + srsc = object->findChild("srsc"); + QVERIFY(srsc); + QVERIFY(!srsc->property("scarceResourceCopy").isValid()); // hasn't been instantiated yet. + QCOMPARE(srsc->property("width"), QVariant(5)); // default value is 5. + eo = qobject_cast(QDeclarativeProperty::read(object, "a").value()); + QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage. + QMetaObject::invokeMethod(srsc, "testSignal"); + QVERIFY(!srsc->property("scarceResourceCopy").isValid()); // still hasn't been instantiated + QCOMPARE(srsc->property("width"), QVariant(10)); // but width was assigned to 10. eo = qobject_cast(QDeclarativeProperty::read(object, "a").value()); - QVERIFY(!eo->scarceResourceIsDetached()); // there are two copies of it in existence: the property of object, and the property of eo. + QVERIFY(eo->scarceResourceIsDetached()); // should still be no other copies of it at this stage. + QMetaObject::invokeMethod(srsc, "testSignal2"); // assigns scarceResourceCopy to the scarce pixmap. + QVERIFY(srsc->property("scarceResourceCopy").isValid()); + QCOMPARE(srsc->property("scarceResourceCopy").value(), origPixmap); + eo = qobject_cast(QDeclarativeProperty::read(object, "a").value()); + QVERIFY(!(eo->scarceResourceIsDetached())); // should be another copy of the resource now. + QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point. delete object; - QDeclarativeComponent componentTwo(&engine, TEST_FILE("scarceresources/scarceResourceCopyFromJs.qml")); - object = componentTwo.create(); + // test that scarce resources are handled properly from js functions in qml files + QDeclarativeComponent varComponentEleven(&engine, TEST_FILE("scarceResourceFunction.var.qml")); + object = varComponentEleven.create(); QVERIFY(object != 0); - QVERIFY(object->property("scarceResourceCopy").isValid()); + QVERIFY(!object->property("scarceResourceCopy").isValid()); // not yet assigned, so should not be valid + eo = qobject_cast(QDeclarativeProperty::read(object, "a").value()); + QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage. + QMetaObject::invokeMethod(object, "retrieveScarceResource"); + QVERIFY(object->property("scarceResourceCopy").isValid()); // assigned, so should be valid. QCOMPARE(object->property("scarceResourceCopy").value(), origPixmap); - QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point. eo = qobject_cast(QDeclarativeProperty::read(object, "a").value()); - QVERIFY(!eo->scarceResourceIsDetached()); // there are two copies of it in existence: the property of object, and the property of eo. - delete object; - - QDeclarativeComponent componentThree(&engine, TEST_FILE("scarceresources/scarceResourceDestroyedCopy.qml")); - object = componentThree.create(); - QVERIFY(object != 0); - QVERIFY(!(object->property("scarceResourceCopy").isValid())); // was manually released prior to being returned. - QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point. + QVERIFY(!eo->scarceResourceIsDetached()); // should be a copy of the resource at this stage. + QMetaObject::invokeMethod(object, "releaseScarceResource"); + QVERIFY(!object->property("scarceResourceCopy").isValid()); // just released, so should not be valid eo = qobject_cast(QDeclarativeProperty::read(object, "a").value()); - QVERIFY(eo->scarceResourceIsDetached()); // should have explicitly been released during the evaluation of the binding. - delete object; - - // in the following three cases, no other copy should exist in memory, - // and so it should be detached (unless explicitly preserved). - QDeclarativeComponent componentFour(&engine, TEST_FILE("scarceresources/scarceResourceTest.qml")); - object = componentFour.create(); - QVERIFY(object != 0); - QVERIFY(object->property("scarceResourceTest").isValid()); - QCOMPARE(object->property("scarceResourceTest").toInt(), 100); + QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage. QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point. - eo = qobject_cast(QDeclarativeProperty::read(object, "a").value()); - QVERIFY(eo->scarceResourceIsDetached()); // the resource should have been released after the binding was evaluated. delete object; - QDeclarativeComponent componentFive(&engine, TEST_FILE("scarceresources/scarceResourceTestPreserve.qml")); - object = componentFive.create(); + // test that if an exception occurs while invoking js function from cpp, that the resources are released. + QDeclarativeComponent varComponentTwelve(&engine, TEST_FILE("scarceResourceFunctionFail.var.qml")); + object = varComponentTwelve.create(); QVERIFY(object != 0); - QVERIFY(object->property("scarceResourceTest").isValid()); - QCOMPARE(object->property("scarceResourceTest").toInt(), 100); - QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point. + QVERIFY(!object->property("scarceResourceCopy").isValid()); // not yet assigned, so should not be valid eo = qobject_cast(QDeclarativeProperty::read(object, "a").value()); - QVERIFY(!eo->scarceResourceIsDetached()); // this won't be detached since we explicitly preserved it. - delete object; - - QDeclarativeComponent componentSix(&engine, TEST_FILE("scarceresources/scarceResourceTestMultiple.qml")); - object = componentSix.create(); - QVERIFY(object != 0); - QVERIFY(object->property("scarceResourceTest").isValid()); - QCOMPARE(object->property("scarceResourceTest").toInt(), 100); - QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point. + QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage. + srp_name = object->property("srp_name").toString(); + expectedWarning = varComponentTwelve.url().toString() + QLatin1String(":16: TypeError: Property 'scarceResource' of object ") + srp_name + QLatin1String(" is not a function"); + QTest::ignoreMessage(QtWarningMsg, qPrintable(expectedWarning)); // we expect a meaningful warning to be printed. + QMetaObject::invokeMethod(object, "retrieveScarceResource"); + QVERIFY(!object->property("scarceResourceCopy").isValid()); // due to exception, assignment will NOT have occurred. eo = qobject_cast(QDeclarativeProperty::read(object, "a").value()); - QVERIFY(eo->scarceResourceIsDetached()); // all resources were released manually or automatically released. - delete object; - - // test that scarce resources are handled correctly for imports - QDeclarativeComponent componentSeven(&engine, TEST_FILE("scarceresources/scarceResourceCopyImportNoBinding.qml")); - object = componentSeven.create(); - QVERIFY(object != 0); // the import should have caused the addition of a resource to the ScarceResources list - QVERIFY(ep->scarceResources.isEmpty()); // but they should have been released by this point. - delete object; - - QDeclarativeComponent componentEight(&engine, TEST_FILE("scarceresources/scarceResourceCopyImportFail.qml")); - object = componentEight.create(); - QVERIFY(object != 0); - QVERIFY(!object->property("scarceResourceCopy").isValid()); // wasn't preserved, so shouldn't be valid. + QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage. QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point. delete object; - QDeclarativeComponent componentNine(&engine, TEST_FILE("scarceresources/scarceResourceCopyImport.qml")); - object = componentNine.create(); + // test that if an Item which has JS ownership but has a scarce resource property is garbage collected, + // that the scarce resource is removed from the engine's list of scarce resources to clean up. + QDeclarativeComponent varComponentThirteen(&engine, TEST_FILE("scarceResourceObjectGc.var.qml")); + object = varComponentThirteen.create(); QVERIFY(object != 0); - QVERIFY(object->property("scarceResourceCopy").isValid()); // preserved, so should be valid. - QCOMPARE(object->property("scarceResourceCopy").value(), origPixmap); - QVERIFY(object->property("scarceResourceAssignedCopyOne").isValid()); // assigned before destroy(), so should be valid. - QCOMPARE(object->property("scarceResourceAssignedCopyOne").value(), origPixmap); - QVERIFY(!object->property("scarceResourceAssignedCopyTwo").isValid()); // assigned after destroy(), so should be invalid. - QVERIFY(ep->scarceResources.isEmpty()); // this will still be zero, because "preserve()" REMOVES it from this list. + QVERIFY(!object->property("varProperty").isValid()); // not assigned yet + QMetaObject::invokeMethod(object, "assignVarProperty"); + QVERIFY(ep->scarceResources.isEmpty()); // the scarce resource is a VME property. + QMetaObject::invokeMethod(object, "deassignVarProperty"); + QVERIFY(ep->scarceResources.isEmpty()); // should still be empty; the resource should have been released on gc. delete object; + /* property variant semantics */ + // test that scarce resources are handled properly in signal invocation - QDeclarativeComponent componentTen(&engine, TEST_FILE("scarceresources/scarceResourceSignal.qml")); - object = componentTen.create(); + QDeclarativeComponent variantComponentTen(&engine, TEST_FILE("scarceResourceSignal.variant.qml")); + object = variantComponentTen.create(); QVERIFY(object != 0); - QObject *srsc = object->findChild("srsc"); + srsc = object->findChild("srsc"); QVERIFY(srsc); QVERIFY(!srsc->property("scarceResourceCopy").isValid()); // hasn't been instantiated yet. QCOMPARE(srsc->property("width"), QVariant(5)); // default value is 5. @@ -3320,8 +3310,8 @@ void tst_qdeclarativeecmascript::scarceResources() delete object; // test that scarce resources are handled properly from js functions in qml files - QDeclarativeComponent componentEleven(&engine, TEST_FILE("scarceresources/scarceResourceFunction.qml")); - object = componentEleven.create(); + QDeclarativeComponent variantComponentEleven(&engine, TEST_FILE("scarceResourceFunction.variant.qml")); + object = variantComponentEleven.create(); QVERIFY(object != 0); QVERIFY(!object->property("scarceResourceCopy").isValid()); // not yet assigned, so should not be valid eo = qobject_cast(QDeclarativeProperty::read(object, "a").value()); @@ -3339,14 +3329,14 @@ void tst_qdeclarativeecmascript::scarceResources() delete object; // test that if an exception occurs while invoking js function from cpp, that the resources are released. - QDeclarativeComponent componentTwelve(&engine, TEST_FILE("scarceresources/scarceResourceFunctionFail.qml")); - object = componentTwelve.create(); + QDeclarativeComponent variantComponentTwelve(&engine, TEST_FILE("scarceResourceFunctionFail.variant.qml")); + object = variantComponentTwelve.create(); QVERIFY(object != 0); QVERIFY(!object->property("scarceResourceCopy").isValid()); // not yet assigned, so should not be valid eo = qobject_cast(QDeclarativeProperty::read(object, "a").value()); QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage. - QString srp_name = object->property("srp_name").toString(); - QString expectedWarning = componentTwelve.url().toString() + QLatin1String(":17: TypeError: Property 'scarceResource' of object ") + srp_name + QLatin1String(" is not a function"); + srp_name = object->property("srp_name").toString(); + expectedWarning = variantComponentTwelve.url().toString() + QLatin1String(":16: TypeError: Property 'scarceResource' of object ") + srp_name + QLatin1String(" is not a function"); QTest::ignoreMessage(QtWarningMsg, qPrintable(expectedWarning)); // we expect a meaningful warning to be printed. QMetaObject::invokeMethod(object, "retrieveScarceResource"); QVERIFY(!object->property("scarceResourceCopy").isValid()); // due to exception, assignment will NOT have occurred. @@ -3356,6 +3346,266 @@ void tst_qdeclarativeecmascript::scarceResources() delete object; } +void tst_qdeclarativeecmascript::scarceResources_data() +{ + QTest::addColumn("qmlFile"); + QTest::addColumn("readDetachStatus"); + QTest::addColumn("expectedDetachStatus"); + QTest::addColumn("propertyNames"); + QTest::addColumn("expectedValidity"); + QTest::addColumn("expectedValues"); + QTest::addColumn("expectedErrors"); + + QPixmap origPixmap(100, 100); + origPixmap.fill(Qt::blue); + + /* property var semantics */ + + // in the following three cases, the instance created from the component + // has a property which is a copy of the scarce resource; hence, the + // resource should NOT be detached prior to deletion of the object instance, + // unless the resource is destroyed explicitly. + QTest::newRow("var: import scarce resource copy directly") + << TEST_FILE("scarceResourceCopy.var.qml") + << true + << false // won't be detached, because assigned to property and not explicitly released + << (QStringList() << QLatin1String("scarceResourceCopy")) + << (QList() << true) + << (QList() << origPixmap) + << QStringList(); + + QTest::newRow("var: import scarce resource copy from JS") + << TEST_FILE("scarceResourceCopyFromJs.var.qml") + << true + << false // won't be detached, because assigned to property and not explicitly released + << (QStringList() << QLatin1String("scarceResourceCopy")) + << (QList() << true) + << (QList() << origPixmap) + << QStringList(); + + QTest::newRow("var: import released scarce resource copy from JS") + << TEST_FILE("scarceResourceDestroyedCopy.var.qml") + << true + << true // explicitly released, so it will be detached + << (QStringList() << QLatin1String("scarceResourceCopy")) + << (QList() << false) + << (QList() << QVariant()) + << QStringList(); + + // in the following three cases, no other copy should exist in memory, + // and so it should be detached (unless explicitly preserved). + QTest::newRow("var: import auto-release SR from JS in binding side-effect") + << TEST_FILE("scarceResourceTest.var.qml") + << true + << true // auto released, so it will be detached + << (QStringList() << QLatin1String("scarceResourceTest")) + << (QList() << true) + << (QList() << QVariant(100)) + << QStringList(); + QTest::newRow("var: import explicit-preserve SR from JS in binding side-effect") + << TEST_FILE("scarceResourceTestPreserve.var.qml") + << true + << false // won't be detached because we explicitly preserve it + << (QStringList() << QLatin1String("scarceResourceTest")) + << (QList() << true) + << (QList() << QVariant(100)) + << QStringList(); + QTest::newRow("var: import explicit-preserve SR from JS in binding side-effect") + << TEST_FILE("scarceResourceTestMultiple.var.qml") + << true + << true // will be detached because all resources were released manually or automatically. + << (QStringList() << QLatin1String("scarceResourceTest")) + << (QList() << true) + << (QList() << QVariant(100)) + << QStringList(); + + // In the following three cases, test that scarce resources are handled + // correctly for imports. + QTest::newRow("var: import with no binding") + << TEST_FILE("scarceResourceCopyImportNoBinding.var.qml") + << false // cannot check detach status. + << false + << QStringList() + << QList() + << QList() + << QStringList(); + QTest::newRow("var: import with binding without explicit preserve") + << TEST_FILE("scarceResourceCopyImportNoBinding.var.qml") + << false + << false + << (QStringList() << QLatin1String("scarceResourceCopy")) + << (QList() << false) // will have been released prior to evaluation of binding. + << (QList() << QVariant()) + << QStringList(); + QTest::newRow("var: import with explicit release after binding evaluation") + << TEST_FILE("scarceResourceCopyImport.var.qml") + << false + << false + << (QStringList() << QLatin1String("scarceResourceImportedCopy") << QLatin1String("scarceResourceAssignedCopyOne") << QLatin1String("scarceResourceAssignedCopyTwo") << QLatin1String("arePropertiesEqual")) + << (QList() << false << false << false << true) // since property var = JS object reference, by releasing the provider's resource, all handles are invalidated. + << (QList() << QVariant() << QVariant() << QVariant() << QVariant(true)) + << QStringList(); + QTest::newRow("var: import with different js objects") + << TEST_FILE("scarceResourceCopyImportDifferent.var.qml") + << false + << false + << (QStringList() << QLatin1String("scarceResourceAssignedCopyOne") << QLatin1String("scarceResourceAssignedCopyTwo") << QLatin1String("arePropertiesEqual")) + << (QList() << false << true << true) // invalidating one shouldn't invalidate the other, because they're not references to the same JS object. + << (QList() << QVariant() << QVariant(origPixmap) << QVariant(false)) + << QStringList(); + QTest::newRow("var: import with different js objects and explicit release") + << TEST_FILE("scarceResourceMultipleDifferentNoBinding.var.qml") + << false + << false + << (QStringList() << QLatin1String("resourceOne") << QLatin1String("resourceTwo")) + << (QList() << true << false) // invalidating one shouldn't invalidate the other, because they're not references to the same JS object. + << (QList() << QVariant(origPixmap) << QVariant()) + << QStringList(); + QTest::newRow("var: import with same js objects and explicit release") + << TEST_FILE("scarceResourceMultipleSameNoBinding.var.qml") + << false + << false + << (QStringList() << QLatin1String("resourceOne") << QLatin1String("resourceTwo")) + << (QList() << false << false) // invalidating one should invalidate the other, because they're references to the same JS object. + << (QList() << QVariant() << QVariant()) + << QStringList(); + QTest::newRow("var: binding with same js objects and explicit release") + << TEST_FILE("scarceResourceMultipleSameWithBinding.var.qml") + << false + << false + << (QStringList() << QLatin1String("resourceOne") << QLatin1String("resourceTwo")) + << (QList() << false << false) // invalidating one should invalidate the other, because they're references to the same JS object. + << (QList() << QVariant() << QVariant()) + << QStringList(); + + + /* property variant semantics */ + + // in the following three cases, the instance created from the component + // has a property which is a copy of the scarce resource; hence, the + // resource should NOT be detached prior to deletion of the object instance, + // unless the resource is destroyed explicitly. + QTest::newRow("variant: import scarce resource copy directly") + << TEST_FILE("scarceResourceCopy.variant.qml") + << true + << false // won't be detached, because assigned to property and not explicitly released + << (QStringList() << QLatin1String("scarceResourceCopy")) + << (QList() << true) + << (QList() << origPixmap) + << QStringList(); + + QTest::newRow("variant: import scarce resource copy from JS") + << TEST_FILE("scarceResourceCopyFromJs.variant.qml") + << true + << false // won't be detached, because assigned to property and not explicitly released + << (QStringList() << QLatin1String("scarceResourceCopy")) + << (QList() << true) + << (QList() << origPixmap) + << QStringList(); + + QTest::newRow("variant: import released scarce resource copy from JS") + << TEST_FILE("scarceResourceDestroyedCopy.variant.qml") + << true + << true // explicitly released, so it will be detached + << (QStringList() << QLatin1String("scarceResourceCopy")) + << (QList() << false) + << (QList() << QVariant()) + << QStringList(); + + // in the following three cases, no other copy should exist in memory, + // and so it should be detached (unless explicitly preserved). + QTest::newRow("variant: import auto-release SR from JS in binding side-effect") + << TEST_FILE("scarceResourceTest.variant.qml") + << true + << true // auto released, so it will be detached + << (QStringList() << QLatin1String("scarceResourceTest")) + << (QList() << true) + << (QList() << QVariant(100)) + << QStringList(); + QTest::newRow("variant: import explicit-preserve SR from JS in binding side-effect") + << TEST_FILE("scarceResourceTestPreserve.variant.qml") + << true + << false // won't be detached because we explicitly preserve it + << (QStringList() << QLatin1String("scarceResourceTest")) + << (QList() << true) + << (QList() << QVariant(100)) + << QStringList(); + QTest::newRow("variant: import multiple scarce resources") + << TEST_FILE("scarceResourceTestMultiple.variant.qml") + << true + << true // will be detached because all resources were released manually or automatically. + << (QStringList() << QLatin1String("scarceResourceTest")) + << (QList() << true) + << (QList() << QVariant(100)) + << QStringList(); + + // In the following three cases, test that scarce resources are handled + // correctly for imports. + QTest::newRow("variant: import with no binding") + << TEST_FILE("scarceResourceCopyImportNoBinding.variant.qml") + << false // cannot check detach status. + << false + << QStringList() + << QList() + << QList() + << QStringList(); + QTest::newRow("variant: import with binding without explicit preserve") + << TEST_FILE("scarceResourceCopyImportNoBinding.variant.qml") + << false + << false + << (QStringList() << QLatin1String("scarceResourceCopy")) + << (QList() << false) // will have been released prior to evaluation of binding. + << (QList() << QVariant()) + << QStringList(); + QTest::newRow("variant: import with explicit release after binding evaluation") + << TEST_FILE("scarceResourceCopyImport.variant.qml") + << false + << false + << (QStringList() << QLatin1String("scarceResourceImportedCopy") << QLatin1String("scarceResourceAssignedCopyOne") << QLatin1String("scarceResourceAssignedCopyTwo")) + << (QList() << true << true << false) // since property variant = variant copy, releasing the provider's resource does not invalidate previously assigned copies. + << (QList() << origPixmap << origPixmap << QVariant()) + << QStringList(); +} + +void tst_qdeclarativeecmascript::scarceResources() +{ + QFETCH(QUrl, qmlFile); + QFETCH(bool, readDetachStatus); + QFETCH(bool, expectedDetachStatus); + QFETCH(QStringList, propertyNames); + QFETCH(QVariantList, expectedValidity); + QFETCH(QVariantList, expectedValues); + QFETCH(QStringList, expectedErrors); + + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(&engine); + ScarceResourceObject *eo = 0; + QObject *object = 0; + + QDeclarativeComponent c(&engine, qmlFile); + object = c.create(); + QVERIFY(object != 0); + for (int i = 0; i < propertyNames.size(); ++i) { + QString prop = propertyNames.at(i); + bool validity = expectedValidity.at(i).toBool(); + QVariant value = expectedValues.at(i); + + QCOMPARE(object->property(prop.toLatin1().constData()).isValid(), validity); + if (value.type() == QVariant::Int) { + QCOMPARE(object->property(prop.toLatin1().constData()).toInt(), value.toInt()); + } else if (value.type() == QVariant::Pixmap) { + QCOMPARE(object->property(prop.toLatin1().constData()).value(), value.value()); + } + } + + if (readDetachStatus) { + eo = qobject_cast(QDeclarativeProperty::read(object, "a").value()); + QCOMPARE(eo->scarceResourceIsDetached(), expectedDetachStatus); + } + + QVERIFY(ep->scarceResources.isEmpty()); + delete object; +} + void tst_qdeclarativeecmascript::propertyChangeSlots() { // ensure that allowable property names are allowed and onPropertyNameChanged slots are generated correctly. -- cgit v1.2.3