aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquickstates
diff options
context:
space:
mode:
authorMatthew Vogt <matthew.vogt@nokia.com>2012-02-16 14:43:03 +1000
committerQt by Nokia <qt-info@nokia.com>2012-02-24 04:51:31 +0100
commitb855240b782395f94315f43ea3e7e182299fac48 (patch)
treebc594c04449be8cd14cd0ab0bb72dafc2be0ffb2 /tests/auto/quick/qquickstates
parent6a42a6e0a9a1abdda0d07a5a20b4ac7e45348684 (diff)
Rename QDeclarative symbols to QQuick and QQml
Symbols beginning with QDeclarative are already exported by the quick1 module. Users can apply the bin/rename-qtdeclarative-symbols.sh script to modify client code using the previous names of the renamed symbols. Task-number: QTBUG-23737 Change-Id: Ifaa482663767634931e8711a8e9bf6e404859e66 Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'tests/auto/quick/qquickstates')
-rw-r--r--tests/auto/quick/qquickstates/data/ExtendedRectangle.qml19
-rw-r--r--tests/auto/quick/qquickstates/data/Implementation/MyType.qml32
-rw-r--r--tests/auto/quick/qquickstates/data/Implementation/images/qt-logo.pngbin0 -> 5149 bytes
-rw-r--r--tests/auto/quick/qquickstates/data/QTBUG-14830.qml29
-rw-r--r--tests/auto/quick/qquickstates/data/anchorChanges1.qml23
-rw-r--r--tests/auto/quick/qquickstates/data/anchorChanges2.qml21
-rw-r--r--tests/auto/quick/qquickstates/data/anchorChanges3.qml29
-rw-r--r--tests/auto/quick/qquickstates/data/anchorChanges4.qml22
-rw-r--r--tests/auto/quick/qquickstates/data/anchorChanges5.qml22
-rw-r--r--tests/auto/quick/qquickstates/data/anchorChangesCrash.qml14
-rw-r--r--tests/auto/quick/qquickstates/data/anchorRewindBug.qml37
-rw-r--r--tests/auto/quick/qquickstates/data/anchorRewindBug2.qml25
-rw-r--r--tests/auto/quick/qquickstates/data/attachedPropertyChanges.qml20
-rw-r--r--tests/auto/quick/qquickstates/data/autoStateAtStartupRestoreBug.qml18
-rw-r--r--tests/auto/quick/qquickstates/data/avoidFastForward.qml17
-rw-r--r--tests/auto/quick/qquickstates/data/basicBinding.qml12
-rw-r--r--tests/auto/quick/qquickstates/data/basicBinding2.qml12
-rw-r--r--tests/auto/quick/qquickstates/data/basicBinding3.qml13
-rw-r--r--tests/auto/quick/qquickstates/data/basicBinding4.qml17
-rw-r--r--tests/auto/quick/qquickstates/data/basicChanges.qml10
-rw-r--r--tests/auto/quick/qquickstates/data/basicChanges2.qml15
-rw-r--r--tests/auto/quick/qquickstates/data/basicChanges3.qml15
-rw-r--r--tests/auto/quick/qquickstates/data/basicChanges4.qml19
-rw-r--r--tests/auto/quick/qquickstates/data/basicExtension.qml16
-rw-r--r--tests/auto/quick/qquickstates/data/deleting.qml11
-rw-r--r--tests/auto/quick/qquickstates/data/deletingState.qml13
-rw-r--r--tests/auto/quick/qquickstates/data/editProperties.qml34
-rw-r--r--tests/auto/quick/qquickstates/data/explicit.qml15
-rw-r--r--tests/auto/quick/qquickstates/data/extendsBug.qml26
-rw-r--r--tests/auto/quick/qquickstates/data/fakeExtension.qml16
-rw-r--r--tests/auto/quick/qquickstates/data/illegalObj.qml12
-rw-r--r--tests/auto/quick/qquickstates/data/illegalTempState.qml21
-rw-r--r--tests/auto/quick/qquickstates/data/image.pngbin0 -> 173 bytes
-rw-r--r--tests/auto/quick/qquickstates/data/legalTempState.qml23
-rw-r--r--tests/auto/quick/qquickstates/data/nonExistantProp.qml11
-rw-r--r--tests/auto/quick/qquickstates/data/parentChange1.qml37
-rw-r--r--tests/auto/quick/qquickstates/data/parentChange2.qml31
-rw-r--r--tests/auto/quick/qquickstates/data/parentChange3.qml42
-rw-r--r--tests/auto/quick/qquickstates/data/parentChange4.qml30
-rw-r--r--tests/auto/quick/qquickstates/data/parentChange5.qml30
-rw-r--r--tests/auto/quick/qquickstates/data/parentChange6.qml30
-rw-r--r--tests/auto/quick/qquickstates/data/propertyErrors.qml10
-rw-r--r--tests/auto/quick/qquickstates/data/reset.qml19
-rw-r--r--tests/auto/quick/qquickstates/data/restoreEntryValues.qml14
-rw-r--r--tests/auto/quick/qquickstates/data/returnToBase.qml21
-rw-r--r--tests/auto/quick/qquickstates/data/revertListBug.qml47
-rw-r--r--tests/auto/quick/qquickstates/data/script.qml10
-rw-r--r--tests/auto/quick/qquickstates/data/signalOverride.qml18
-rw-r--r--tests/auto/quick/qquickstates/data/signalOverride2.qml9
-rw-r--r--tests/auto/quick/qquickstates/data/signalOverrideCrash.qml15
-rw-r--r--tests/auto/quick/qquickstates/data/signalOverrideCrash2.qml24
-rw-r--r--tests/auto/quick/qquickstates/data/signalOverrideCrash3.qml27
-rw-r--r--tests/auto/quick/qquickstates/data/unnamedWhen.qml14
-rw-r--r--tests/auto/quick/qquickstates/data/urlResolution.qml12
-rw-r--r--tests/auto/quick/qquickstates/data/whenOrdering.qml11
-rw-r--r--tests/auto/quick/qquickstates/qquickstates.pro14
-rw-r--r--tests/auto/quick/qquickstates/tst_qquickstates.cpp1608
57 files changed, 2712 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickstates/data/ExtendedRectangle.qml b/tests/auto/quick/qquickstates/data/ExtendedRectangle.qml
new file mode 100644
index 0000000000..1ea346b841
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/ExtendedRectangle.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+Rectangle {
+ id: extendedRect
+ objectName: "extendedRect"
+ property color extendedColor: "orange"
+
+ width: 100; height: 100
+ color: "red"
+ states: State {
+ name: "green"
+ PropertyChanges {
+ target: rect
+ onDidSomething: {
+ extendedRect.color = "green"
+ extendedColor = "green"
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/Implementation/MyType.qml b/tests/auto/quick/qquickstates/data/Implementation/MyType.qml
new file mode 100644
index 0000000000..01eb32cd4d
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/Implementation/MyType.qml
@@ -0,0 +1,32 @@
+import QtQuick 2.0
+
+Item {
+ Column {
+ anchors.centerIn: parent
+ Image { id: image1; objectName: "image1" }
+ Image { id: image2; objectName: "image2" }
+ Image { id: image3; objectName: "image3" }
+ }
+
+ states: State {
+ name: "SetImageState"
+ PropertyChanges {
+ target: image1
+ source: "images/qt-logo.png"
+ }
+ PropertyChanges {
+ target: image2
+ source: "images/" + "qt-logo.png"
+ }
+ PropertyChanges {
+ target: image3
+ source: "images/" + (true ? "qt-logo.png" : "")
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: parent.state = "SetImageState"
+ }
+
+}
diff --git a/tests/auto/quick/qquickstates/data/Implementation/images/qt-logo.png b/tests/auto/quick/qquickstates/data/Implementation/images/qt-logo.png
new file mode 100644
index 0000000000..14ddf2a028
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/Implementation/images/qt-logo.png
Binary files differ
diff --git a/tests/auto/quick/qquickstates/data/QTBUG-14830.qml b/tests/auto/quick/qquickstates/data/QTBUG-14830.qml
new file mode 100644
index 0000000000..5ba7c3ad6f
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/QTBUG-14830.qml
@@ -0,0 +1,29 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 1024
+ height: 768
+
+ Item {
+ id: area
+ objectName: "area"
+ property int numx: 6
+ property int cellwidth: 1024/numx
+
+ onWidthChanged: {
+ width = width>1024?1024:width;
+ }
+
+ state: 'minimal'
+ states: [
+ State {
+ name: 'minimal'
+ PropertyChanges {
+ target: area
+ width: cellwidth
+ }
+ }
+ ]
+
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/anchorChanges1.qml b/tests/auto/quick/qquickstates/data/anchorChanges1.qml
new file mode 100644
index 0000000000..378f5390f9
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/anchorChanges1.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: container
+ width: 200; height: 200
+ Rectangle {
+ id: myRect
+ objectName: "MyRect"
+ width: 50; height: 50
+ color: "green";
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+ }
+ states: State {
+ name: "right"
+ AnchorChanges {
+ id: ancCh
+ target: myRect;
+ anchors.left: undefined
+ anchors.right: container.right
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/anchorChanges2.qml b/tests/auto/quick/qquickstates/data/anchorChanges2.qml
new file mode 100644
index 0000000000..dc7f8ef0d1
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/anchorChanges2.qml
@@ -0,0 +1,21 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200; height: 200
+ Rectangle {
+ id: myRect
+ objectName: "MyRect"
+ width: 50; height: 50
+ color: "green";
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+ }
+ states: State {
+ name: "right"
+ AnchorChanges {
+ target: myRect;
+ anchors.left: undefined
+ anchors.right: parent.right
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/anchorChanges3.qml b/tests/auto/quick/qquickstates/data/anchorChanges3.qml
new file mode 100644
index 0000000000..af49575854
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/anchorChanges3.qml
@@ -0,0 +1,29 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: container
+ width: 200; height: 200
+ Rectangle {
+ id: myRect
+ objectName: "MyRect"
+ color: "green";
+ anchors.left: parent.left
+ anchors.right: rightGuideline.left
+ anchors.top: topGuideline.top
+ anchors.bottom: container.bottom
+ }
+ Item { objectName: "LeftGuideline"; id: leftGuideline; x: 10 }
+ Item { id: rightGuideline; x: 150 }
+ Item { id: topGuideline; y: 10 }
+ Item { objectName: "BottomGuideline"; id: bottomGuideline; y: 150 }
+ states: State {
+ name: "reanchored"
+ AnchorChanges {
+ target: myRect;
+ anchors.left: leftGuideline.left
+ anchors.right: container.right
+ anchors.top: container.top
+ anchors.bottom: bottomGuideline.bottom
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/anchorChanges4.qml b/tests/auto/quick/qquickstates/data/anchorChanges4.qml
new file mode 100644
index 0000000000..28b55818bd
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/anchorChanges4.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200; height: 200
+ Rectangle {
+ id: myRect
+ objectName: "MyRect"
+ color: "green";
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ Item { objectName: "LeftGuideline"; id: leftGuideline; x: 10 }
+ Item { objectName: "BottomGuideline"; id: bottomGuideline; y: 150 }
+ states: State {
+ name: "reanchored"
+ AnchorChanges {
+ target: myRect;
+ anchors.horizontalCenter: bottomGuideline.horizontalCenter
+ anchors.verticalCenter: leftGuideline.verticalCenter
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/anchorChanges5.qml b/tests/auto/quick/qquickstates/data/anchorChanges5.qml
new file mode 100644
index 0000000000..b1ca968fb9
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/anchorChanges5.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200; height: 200
+ Rectangle {
+ id: myRect
+ objectName: "MyRect"
+ color: "green";
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.baseline: parent.baseline
+ }
+ Item { objectName: "LeftGuideline"; id: leftGuideline; x: 10 }
+ Item { objectName: "BottomGuideline"; id: bottomGuideline; y: 150 }
+ states: State {
+ name: "reanchored"
+ AnchorChanges {
+ target: myRect;
+ anchors.horizontalCenter: bottomGuideline.horizontalCenter
+ anchors.baseline: leftGuideline.baseline
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/anchorChangesCrash.qml b/tests/auto/quick/qquickstates/data/anchorChangesCrash.qml
new file mode 100644
index 0000000000..9af0e4645a
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/anchorChangesCrash.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: container
+ width: 400
+ height: 400
+
+ states: State {
+ name: "reanchored"
+ AnchorChanges {
+ anchors.top: container.top
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/anchorRewindBug.qml b/tests/auto/quick/qquickstates/data/anchorRewindBug.qml
new file mode 100644
index 0000000000..60c537b1ed
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/anchorRewindBug.qml
@@ -0,0 +1,37 @@
+import QtQuick 2.0
+Rectangle {
+ id: container
+ color: "red"
+ height: 200
+ width: 200
+ Column {
+ id: column
+ objectName: "column"
+ anchors.left: container.right
+ anchors.bottom: container.bottom
+
+ Rectangle {
+ id: rectangle
+ color: "blue"
+ height: 100
+ width: 200
+ }
+ Rectangle {
+ color: "blue"
+ height: 100
+ width: 200
+ }
+ }
+ states: State {
+ name: "reanchored"
+ AnchorChanges {
+ target: column
+ anchors.left: undefined
+ anchors.right: container.right
+ }
+ PropertyChanges {
+ target: rectangle
+ visible: false
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/anchorRewindBug2.qml b/tests/auto/quick/qquickstates/data/anchorRewindBug2.qml
new file mode 100644
index 0000000000..574ef473ce
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/anchorRewindBug2.qml
@@ -0,0 +1,25 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ width:200; height:300
+
+ Rectangle {
+ id: rectangle
+ objectName: "mover"
+ color: "green"
+ width:50; height:50
+ }
+
+ states: [
+ State {
+ name: "anchored"
+ AnchorChanges {
+ target: rectangle
+ anchors.left: root.left
+ anchors.right: root.right
+ anchors.bottom: root.bottom
+ }
+ }
+ ]
+}
diff --git a/tests/auto/quick/qquickstates/data/attachedPropertyChanges.qml b/tests/auto/quick/qquickstates/data/attachedPropertyChanges.qml
new file mode 100644
index 0000000000..413af2ee42
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/attachedPropertyChanges.qml
@@ -0,0 +1,20 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+Item {
+ id: item
+ width: 100; height: 100
+ MyRectangle.foo: 0
+
+ states: State {
+ name: "foo1"
+ PropertyChanges {
+ target: item
+ MyRectangle.foo: 1
+ width: 50
+ }
+ }
+
+ Component.onCompleted: item.state = "foo1"
+}
+
diff --git a/tests/auto/quick/qquickstates/data/autoStateAtStartupRestoreBug.qml b/tests/auto/quick/qquickstates/data/autoStateAtStartupRestoreBug.qml
new file mode 100644
index 0000000000..6cbf524ec2
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/autoStateAtStartupRestoreBug.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ property int input: 1
+ property int test: 9
+
+ states: [
+ State {
+ name: "portrait"
+ when: root.input == 1
+ PropertyChanges {
+ target: root
+ test: 3
+ }
+ }
+ ]
+}
diff --git a/tests/auto/quick/qquickstates/data/avoidFastForward.qml b/tests/auto/quick/qquickstates/data/avoidFastForward.qml
new file mode 100644
index 0000000000..519befc31e
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/avoidFastForward.qml
@@ -0,0 +1,17 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: rect
+ width: 200
+ height: 200
+
+ property int updateCount: 0
+ onColorChanged: updateCount++
+
+ property color aColor: "green"
+
+ states: State {
+ name: "a"
+ PropertyChanges { target: rect; color: aColor }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/basicBinding.qml b/tests/auto/quick/qquickstates/data/basicBinding.qml
new file mode 100644
index 0000000000..59b67d0863
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/basicBinding.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+
+ property color sourceColor: "blue"
+ width: 100; height: 100
+ color: "red"
+ states: State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; color: sourceColor }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/basicBinding2.qml b/tests/auto/quick/qquickstates/data/basicBinding2.qml
new file mode 100644
index 0000000000..55f88120aa
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/basicBinding2.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+
+ property color sourceColor: "red"
+ width: 100; height: 100
+ color: sourceColor
+ states: State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; color: "blue" }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/basicBinding3.qml b/tests/auto/quick/qquickstates/data/basicBinding3.qml
new file mode 100644
index 0000000000..361ab0b091
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/basicBinding3.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+
+ property color sourceColor: "red"
+ property color sourceColor2: "blue"
+ width: 100; height: 100
+ color: sourceColor
+ states: State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; color: sourceColor2 }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/basicBinding4.qml b/tests/auto/quick/qquickstates/data/basicBinding4.qml
new file mode 100644
index 0000000000..b29f0fcf22
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/basicBinding4.qml
@@ -0,0 +1,17 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+
+ property color sourceColor: "blue"
+ width: 100; height: 100
+ color: "red"
+ states: [
+ State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; color: sourceColor }
+ },
+ State {
+ name: "green"
+ PropertyChanges { target: myRectangle; color: "green" }
+ }]
+}
diff --git a/tests/auto/quick/qquickstates/data/basicChanges.qml b/tests/auto/quick/qquickstates/data/basicChanges.qml
new file mode 100644
index 0000000000..3e2b73acde
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/basicChanges.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+ width: 100; height: 100
+ color: "red"
+ states: State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; color: "blue" }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/basicChanges2.qml b/tests/auto/quick/qquickstates/data/basicChanges2.qml
new file mode 100644
index 0000000000..5ff46cc60c
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/basicChanges2.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+ width: 100; height: 100
+ color: "red"
+ states: [
+ State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; color: "blue" }
+ },
+ State {
+ name: "green"
+ PropertyChanges { target: myRectangle; color: "green" }
+ }]
+}
diff --git a/tests/auto/quick/qquickstates/data/basicChanges3.qml b/tests/auto/quick/qquickstates/data/basicChanges3.qml
new file mode 100644
index 0000000000..e46e98f75e
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/basicChanges3.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+ width: 100; height: 100
+ color: "red"
+ states: [
+ State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; color: "blue" }
+ },
+ State {
+ name: "bordered"
+ PropertyChanges { target: myRectangle; border.width: 2 }
+ }]
+}
diff --git a/tests/auto/quick/qquickstates/data/basicChanges4.qml b/tests/auto/quick/qquickstates/data/basicChanges4.qml
new file mode 100644
index 0000000000..7da1e0fb2e
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/basicChanges4.qml
@@ -0,0 +1,19 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyRectangle {
+ id: rect
+ width: 100; height: 100
+ color: "red"
+
+ states: State {
+ name: "aBlueDay"
+ PropertyChanges {
+ target: rect
+ onPropertyWithNotifyChanged: { rect.color = "blue"; }
+ }
+ }
+
+ Component.onCompleted: rect.state = "aBlueDay"
+}
+
diff --git a/tests/auto/quick/qquickstates/data/basicExtension.qml b/tests/auto/quick/qquickstates/data/basicExtension.qml
new file mode 100644
index 0000000000..00f5fee287
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/basicExtension.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+ width: 100; height: 100
+ color: "red"
+ states: [
+ State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; color: "blue" }
+ },
+ State {
+ name: "bordered"
+ extend: "blue"
+ PropertyChanges { target: myRectangle; border.width: 2 }
+ }]
+}
diff --git a/tests/auto/quick/qquickstates/data/deleting.qml b/tests/auto/quick/qquickstates/data/deleting.qml
new file mode 100644
index 0000000000..b8e8d33c17
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/deleting.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+ width: 100; height: 100
+ color: "red"
+ states: State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; color: "blue"; objectName: "pc1" }
+ PropertyChanges { target: myRectangle; radius: 5; objectName: "pc2" }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/deletingState.qml b/tests/auto/quick/qquickstates/data/deletingState.qml
new file mode 100644
index 0000000000..68a9c2a24d
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/deletingState.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+ width: 100; height: 100
+ color: "red"
+ StateGroup {
+ id: stateGroup
+ states: State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; color: "blue" }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/editProperties.qml b/tests/auto/quick/qquickstates/data/editProperties.qml
new file mode 100644
index 0000000000..9bff3657ba
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/editProperties.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+
+ property color sourceColor: "blue"
+ width: 400; height: 400
+ color: "red"
+
+ Rectangle {
+ id: rect2
+ objectName: "rect2"
+ width: parent.width + 2
+ height: 200
+ color: "yellow"
+ }
+
+ states: [
+ State {
+ name: "blue"
+ PropertyChanges {
+ target: rect2
+ width:50
+ height: 40
+ }
+ },
+ State {
+ name: "green"
+ PropertyChanges {
+ target: rect2
+ width: myRectangle.width / 2
+ height: myRectangle.width / 4
+ }
+ }]
+}
diff --git a/tests/auto/quick/qquickstates/data/explicit.qml b/tests/auto/quick/qquickstates/data/explicit.qml
new file mode 100644
index 0000000000..d09893a1db
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/explicit.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+ property color sourceColor: "blue"
+ width: 100; height: 100
+ color: "red"
+ states: State {
+ name: "blue"
+ PropertyChanges {
+ objectName: "changes"
+ target: myRectangle; explicit: true
+ color: sourceColor
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/extendsBug.qml b/tests/auto/quick/qquickstates/data/extendsBug.qml
new file mode 100644
index 0000000000..573341520d
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/extendsBug.qml
@@ -0,0 +1,26 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200
+ height: 200
+
+ Rectangle {
+ id: rect
+ objectName: "greenRect"
+ width: 100
+ height: 100
+ color: "green"
+ }
+
+ states:[
+ State {
+ name: "a"
+ PropertyChanges { target: rect; x: 100 }
+ },
+ State {
+ name: "b"
+ extend:"a"
+ PropertyChanges { target: rect; y: 100 }
+ }
+ ]
+}
diff --git a/tests/auto/quick/qquickstates/data/fakeExtension.qml b/tests/auto/quick/qquickstates/data/fakeExtension.qml
new file mode 100644
index 0000000000..6a5c7003f6
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/fakeExtension.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+ width: 100; height: 100
+ color: "red"
+ states: [
+ State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; color: "blue" }
+ },
+ State {
+ name: "green"
+ extend: "blue"
+ PropertyChanges { target: myRectangle; color: "green" }
+ }]
+}
diff --git a/tests/auto/quick/qquickstates/data/illegalObj.qml b/tests/auto/quick/qquickstates/data/illegalObj.qml
new file mode 100644
index 0000000000..a2bbd5d32b
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/illegalObj.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: myItem
+
+ states : State {
+ PropertyChanges {
+ target: myItem
+ children: Item { id: newItem }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/illegalTempState.qml b/tests/auto/quick/qquickstates/data/illegalTempState.qml
new file mode 100644
index 0000000000..9cb39c0728
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/illegalTempState.qml
@@ -0,0 +1,21 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: card
+ width: 100; height: 100
+
+ states: [
+ State {
+ name: "placed"
+ PropertyChanges { target: card; state: "idle" }
+ },
+ State {
+ name: "idle"
+ }
+ ]
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: card.state = "placed"
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/image.png b/tests/auto/quick/qquickstates/data/image.png
new file mode 100644
index 0000000000..ed1833c95b
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/image.png
Binary files differ
diff --git a/tests/auto/quick/qquickstates/data/legalTempState.qml b/tests/auto/quick/qquickstates/data/legalTempState.qml
new file mode 100644
index 0000000000..a93860f5cc
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/legalTempState.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: card
+ width: 100; height: 100
+
+ states: [
+ State {
+ name: "placed"
+ onCompleted: card.state = "idle"
+ StateChangeScript { script: console.log("entering placed") }
+ },
+ State {
+ name: "idle"
+ StateChangeScript { script: console.log("entering idle") }
+ }
+ ]
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: card.state = "placed"
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/nonExistantProp.qml b/tests/auto/quick/qquickstates/data/nonExistantProp.qml
new file mode 100644
index 0000000000..ce502699bb
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/nonExistantProp.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+
+ width: 100; height: 100
+ color: "red"
+ states: State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; colr: "blue" }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/parentChange1.qml b/tests/auto/quick/qquickstates/data/parentChange1.qml
new file mode 100644
index 0000000000..663ad1a264
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/parentChange1.qml
@@ -0,0 +1,37 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 400; height: 400
+ Item {
+ x: 10; y: 10
+ Rectangle {
+ id: myRect
+ objectName: "MyRect"
+ x: 5
+ width: 100; height: 100
+ color: "red"
+ }
+ }
+ MouseArea {
+ id: clickable
+ anchors.fill: parent
+ }
+
+ Item {
+ x: -100; y: -50
+ Item {
+ id: newParent
+ objectName: "NewParent"
+ x: 248; y: 360
+ }
+ }
+
+ states: State {
+ name: "reparented"
+ when: clickable.pressed
+ ParentChange {
+ target: myRect
+ parent: newParent
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/parentChange2.qml b/tests/auto/quick/qquickstates/data/parentChange2.qml
new file mode 100644
index 0000000000..ae290e961e
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/parentChange2.qml
@@ -0,0 +1,31 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: newParent
+ width: 400; height: 400
+ Item {
+ scale: .5
+ rotation: 15
+ x: 10; y: 10
+ Rectangle {
+ id: myRect
+ objectName: "MyRect"
+ x: 5
+ width: 100; height: 100
+ color: "red"
+ }
+ }
+ MouseArea {
+ id: clickable
+ anchors.fill: parent
+ }
+
+ states: State {
+ name: "reparented"
+ when: clickable.pressed
+ ParentChange {
+ target: myRect
+ parent: newParent
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/parentChange3.qml b/tests/auto/quick/qquickstates/data/parentChange3.qml
new file mode 100644
index 0000000000..46665cb4c8
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/parentChange3.qml
@@ -0,0 +1,42 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 400; height: 400
+ Item {
+ scale: .5
+ rotation: 15
+ transformOrigin: "Center"
+ x: 10; y: 10
+ Rectangle {
+ id: myRect
+ objectName: "MyRect"
+ x: 5
+ width: 100; height: 100
+ transformOrigin: "BottomLeft"
+ color: "red"
+ }
+ }
+ MouseArea {
+ id: clickable
+ anchors.fill: parent
+ }
+
+ Item {
+ x: 200; y: 200
+ rotation: 52;
+ scale: 2
+ Item {
+ id: newParent
+ x: 100; y: 100
+ }
+ }
+
+ states: State {
+ name: "reparented"
+ when: clickable.pressed
+ ParentChange {
+ target: myRect
+ parent: newParent
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/parentChange4.qml b/tests/auto/quick/qquickstates/data/parentChange4.qml
new file mode 100644
index 0000000000..22de72f8c9
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/parentChange4.qml
@@ -0,0 +1,30 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 400; height: 400
+ Rectangle {
+ id: myRect
+ objectName: "MyRect"
+ x: 5; y: 5
+ width: 100; height: 100
+ color: "red"
+ }
+ MouseArea {
+ id: clickable
+ anchors.fill: parent
+ }
+
+ Item {
+ id: newParent
+ transform: Scale { xScale: .5; yScale: .7}
+ }
+
+ states: State {
+ name: "reparented"
+ when: clickable.pressed
+ ParentChange {
+ target: myRect
+ parent: newParent
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/parentChange5.qml b/tests/auto/quick/qquickstates/data/parentChange5.qml
new file mode 100644
index 0000000000..c353d2637f
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/parentChange5.qml
@@ -0,0 +1,30 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 400; height: 400
+ Rectangle {
+ id: myRect
+ objectName: "MyRect"
+ x: 5; y: 5
+ width: 100; height: 100
+ color: "red"
+ }
+ MouseArea {
+ id: clickable
+ anchors.fill: parent
+ }
+
+ Item {
+ id: newParent
+ transform: Rotation { angle: 30; axis { x: 0; y: 1; z: 0 } }
+ }
+
+ states: State {
+ name: "reparented"
+ when: clickable.pressed
+ ParentChange {
+ target: myRect
+ parent: newParent
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/parentChange6.qml b/tests/auto/quick/qquickstates/data/parentChange6.qml
new file mode 100644
index 0000000000..b373dbba20
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/parentChange6.qml
@@ -0,0 +1,30 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 400; height: 400
+ Rectangle {
+ id: myRect
+ objectName: "MyRect"
+ x: 5; y: 5
+ width: 100; height: 100
+ color: "red"
+ }
+ MouseArea {
+ id: clickable
+ anchors.fill: parent
+ }
+
+ Item {
+ id: newParent
+ rotation: 180
+ }
+
+ states: State {
+ name: "reparented"
+ when: clickable.pressed
+ ParentChange {
+ target: myRect
+ parent: newParent
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/propertyErrors.qml b/tests/auto/quick/qquickstates/data/propertyErrors.qml
new file mode 100644
index 0000000000..ddd636493d
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/propertyErrors.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+ width: 100; height: 100
+ color: "red"
+ states: State {
+ name: "blue"
+ PropertyChanges { target: myRectangle; colr: "blue"; activeFocus: true }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/reset.qml b/tests/auto/quick/qquickstates/data/reset.qml
new file mode 100644
index 0000000000..f0ecab0950
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/reset.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 640
+ height: 480
+ Image {
+ id: image
+ width: 40
+ source: "image.png"
+ }
+
+ states: State {
+ name: "state1"
+ PropertyChanges {
+ target: image
+ width: undefined
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/restoreEntryValues.qml b/tests/auto/quick/qquickstates/data/restoreEntryValues.qml
new file mode 100644
index 0000000000..950a522841
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/restoreEntryValues.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+ width: 100; height: 100
+ color: "red"
+ states: State {
+ name: "blue"
+ PropertyChanges {
+ target: myRectangle
+ restoreEntryValues: false
+ color: "blue"
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/returnToBase.qml b/tests/auto/quick/qquickstates/data/returnToBase.qml
new file mode 100644
index 0000000000..9a0ee82397
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/returnToBase.qml
@@ -0,0 +1,21 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: theRect
+ property bool triggerState: false
+ property string stateString: ""
+ states: [ State {
+ when: triggerState
+ PropertyChanges {
+ target: theRect
+ stateString: "inState"
+ }
+ },
+ State {
+ name: ""
+ PropertyChanges {
+ target: theRect
+ stateString: "originalState"
+ }
+ }]
+}
diff --git a/tests/auto/quick/qquickstates/data/revertListBug.qml b/tests/auto/quick/qquickstates/data/revertListBug.qml
new file mode 100644
index 0000000000..fbc4bc5ecc
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/revertListBug.qml
@@ -0,0 +1,47 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 400; height: 400
+
+ property Item targetItem: rect1
+
+ function switchTargetItem() {
+ if (targetItem === rect1)
+ targetItem = rect2;
+ else
+ targetItem = rect1;
+ }
+
+ states: State {
+ name: "reparented"
+ ParentChange {
+ target: targetItem
+ parent: newParent
+ x: 0; y: 0
+ }
+ }
+
+ Item {
+ objectName: "originalParent1"
+ Rectangle {
+ id: rect1; objectName: "rect1"
+ width: 50; height: 50
+ color: "green"
+ }
+ }
+
+ Item {
+ objectName: "originalParent2"
+ Rectangle {
+ id: rect2; objectName: "rect2"
+ x: 50; y: 50
+ width: 50; height: 50
+ color: "green"
+ }
+ }
+
+ Item {
+ id: newParent; objectName: "newParent"
+ x: 200; y: 100
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/script.qml b/tests/auto/quick/qquickstates/data/script.qml
new file mode 100644
index 0000000000..218f0fae74
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/script.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+Rectangle {
+ id: myRectangle
+ width: 100; height: 100
+ color: "red"
+ states: State {
+ name: "blue"
+ StateChangeScript { script: myRectangle.color = "blue"; }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/signalOverride.qml b/tests/auto/quick/qquickstates/data/signalOverride.qml
new file mode 100644
index 0000000000..9ab8037e51
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/signalOverride.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+MyRectangle {
+ id: rect
+
+ onDidSomething: color = "blue"
+
+ width: 100; height: 100
+ color: "red"
+ states: State {
+ name: "green"
+ PropertyChanges {
+ target: rect
+ onDidSomething: color = "green"
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/signalOverride2.qml b/tests/auto/quick/qquickstates/data/signalOverride2.qml
new file mode 100644
index 0000000000..4e5e335b8b
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/signalOverride2.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+MyRectangle {
+ id: rect
+ onDidSomething: color = "blue"
+ width: 100; height: 100
+ ExtendedRectangle {}
+}
diff --git a/tests/auto/quick/qquickstates/data/signalOverrideCrash.qml b/tests/auto/quick/qquickstates/data/signalOverrideCrash.qml
new file mode 100644
index 0000000000..3e2ae1e93d
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/signalOverrideCrash.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+MyRectangle {
+ id: rect
+
+ width: 100; height: 100
+ states: State {
+ name: "overridden"
+ PropertyChanges {
+ target: rect
+ onDidSomething: rect.state = ""
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/signalOverrideCrash2.qml b/tests/auto/quick/qquickstates/data/signalOverrideCrash2.qml
new file mode 100644
index 0000000000..3937874aa2
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/signalOverrideCrash2.qml
@@ -0,0 +1,24 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: myRect
+ width: 400
+ height: 400
+
+ states: [
+ State {
+ name: "state1"
+ PropertyChanges {
+ target: myRect
+ onHeightChanged: console.log("Hello World")
+ color: "green"
+ }
+ },
+ State {
+ name: "state2"; extend: "state1"
+ PropertyChanges {
+ target: myRect
+ color: "red"
+ }
+ }]
+}
diff --git a/tests/auto/quick/qquickstates/data/signalOverrideCrash3.qml b/tests/auto/quick/qquickstates/data/signalOverrideCrash3.qml
new file mode 100644
index 0000000000..98d4c57219
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/signalOverrideCrash3.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: myRect
+ width: 400
+ height: 400
+
+ onHeightChanged: console.log("base state")
+
+ states: [
+ State {
+ name: "state1"
+ PropertyChanges {
+ target: myRect
+ onHeightChanged: console.log("state1")
+ color: "green"
+ }
+ },
+ State {
+ name: "state2";
+ PropertyChanges {
+ target: myRect
+ onHeightChanged: console.log("state2")
+ color: "red"
+ }
+ }]
+}
diff --git a/tests/auto/quick/qquickstates/data/unnamedWhen.qml b/tests/auto/quick/qquickstates/data/unnamedWhen.qml
new file mode 100644
index 0000000000..35eacff07b
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/unnamedWhen.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: theRect
+ property bool triggerState: false
+ property string stateString: ""
+ states: State {
+ when: triggerState
+ PropertyChanges {
+ target: theRect
+ stateString: "inState"
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/urlResolution.qml b/tests/auto/quick/qquickstates/data/urlResolution.qml
new file mode 100644
index 0000000000..516ac034d6
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/urlResolution.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+import "Implementation"
+
+Rectangle {
+ width: 100
+ height: 200
+
+ MyType {
+ objectName: "MyType"
+ anchors.fill: parent
+ }
+}
diff --git a/tests/auto/quick/qquickstates/data/whenOrdering.qml b/tests/auto/quick/qquickstates/data/whenOrdering.qml
new file mode 100644
index 0000000000..92025a2054
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/whenOrdering.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+
+Rectangle {
+ property bool condition1: false
+ property bool condition2: false
+
+ states: [
+ State { name: "state1"; when: condition1 },
+ State { name: "state2"; when: condition2 }
+ ]
+}
diff --git a/tests/auto/quick/qquickstates/qquickstates.pro b/tests/auto/quick/qquickstates/qquickstates.pro
new file mode 100644
index 0000000000..ec881680ea
--- /dev/null
+++ b/tests/auto/quick/qquickstates/qquickstates.pro
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_qquickstates
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickstates.cpp
+
+include (../../shared/util.pri)
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+QT += core-private gui-private v8-private qml-private quick-private opengl-private testlib
diff --git a/tests/auto/quick/qquickstates/tst_qquickstates.cpp b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
new file mode 100644
index 0000000000..fc8194f6ca
--- /dev/null
+++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
@@ -0,0 +1,1608 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcomponent.h>
+#include <QtQuick/qquickview.h>
+#include <private/qquickstateoperations_p.h>
+#include <private/qquickanchors_p_p.h>
+#include <QtQuick/private/qquickrectangle_p.h>
+#include <private/qquickimage_p.h>
+#include <QtQuick/private/qquickpropertychanges_p.h>
+#include <QtQuick/private/qquickstategroup_p.h>
+#include <private/qquickitem_p.h>
+#include <private/qqmlproperty_p.h>
+#include "../../shared/util.h"
+
+class MyAttached : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int foo READ foo WRITE setFoo)
+public:
+ MyAttached(QObject *parent) : QObject(parent), m_foo(13) {}
+
+ int foo() const { return m_foo; }
+ void setFoo(int f) { m_foo = f; }
+
+private:
+ int m_foo;
+};
+
+class MyRect : public QQuickRectangle
+{
+ Q_OBJECT
+ Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal)
+public:
+ MyRect() {}
+
+ void doSomething() { emit didSomething(); }
+
+ int propertyWithNotify() const { return m_prop; }
+ void setPropertyWithNotify(int i) { m_prop = i; emit oddlyNamedNotifySignal(); }
+
+ static MyAttached *qmlAttachedProperties(QObject *o) {
+ return new MyAttached(o);
+ }
+Q_SIGNALS:
+ void didSomething();
+ void oddlyNamedNotifySignal();
+
+private:
+ int m_prop;
+};
+
+QML_DECLARE_TYPE(MyRect)
+QML_DECLARE_TYPEINFO(MyRect, QML_HAS_ATTACHED_PROPERTIES)
+
+class tst_qquickstates : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_qquickstates() {}
+
+private:
+ QByteArray fullDataPath(const QString &path) const;
+
+private slots:
+ void initTestCase();
+
+ void basicChanges();
+ void attachedPropertyChanges();
+ void basicExtension();
+ void basicBinding();
+ void signalOverride();
+ void signalOverrideCrash();
+ void signalOverrideCrash2();
+ void signalOverrideCrash3();
+ void parentChange();
+ void parentChangeErrors();
+ void anchorChanges();
+ void anchorChanges2();
+ void anchorChanges3();
+ void anchorChanges4();
+ void anchorChanges5();
+ void anchorChangesRTL();
+ void anchorChangesRTL2();
+ void anchorChangesRTL3();
+ void anchorChangesCrash();
+ void anchorRewindBug();
+ void anchorRewindBug2();
+ void script();
+ void restoreEntryValues();
+ void explicitChanges();
+ void propertyErrors();
+ void incorrectRestoreBug();
+ void autoStateAtStartupRestoreBug();
+ void deletingChange();
+ void deletingState();
+ void tempState();
+ void illegalTempState();
+ void nonExistantProperty();
+ void reset();
+ void illegalObjectCreation();
+ void whenOrdering();
+ void urlResolution();
+ void unnamedWhen();
+ void returnToBase();
+ void extendsBug();
+ void editProperties();
+ void QTBUG_14830();
+ void avoidFastForward();
+ void revertListBug();
+};
+
+void tst_qquickstates::initTestCase()
+{
+ QQmlDataTest::initTestCase();
+ qmlRegisterType<MyRect>("Qt.test", 1, 0, "MyRectangle");
+}
+
+QByteArray tst_qquickstates::fullDataPath(const QString &path) const
+{
+ return testFileUrl(path).toString().toUtf8();
+}
+
+void tst_qquickstates::basicChanges()
+{
+ QQmlEngine engine;
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("basicChanges.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QVERIFY(rect != 0);
+
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+ }
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("basicChanges2.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QVERIFY(rect != 0);
+
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("green");
+ QCOMPARE(rect->color(),QColor("green"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("green");
+ QCOMPARE(rect->color(),QColor("green"));
+ }
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("basicChanges3.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QVERIFY(rect != 0);
+
+ QCOMPARE(rect->color(),QColor("red"));
+ QCOMPARE(rect->border()->width(),1.0);
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+ QCOMPARE(rect->border()->width(),1.0);
+
+ rectPrivate->setState("bordered");
+ QCOMPARE(rect->color(),QColor("red"));
+ QCOMPARE(rect->border()->width(),2.0);
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+ QCOMPARE(rect->border()->width(),1.0);
+ //### we should be checking that this is an implicit rather than explicit 1 (which currently fails)
+
+ rectPrivate->setState("bordered");
+ QCOMPARE(rect->color(),QColor("red"));
+ QCOMPARE(rect->border()->width(),2.0);
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+ QCOMPARE(rect->border()->width(),1.0);
+
+ }
+
+ {
+ // Test basicChanges4.qml can magically connect to propertyWithNotify's notify
+ // signal using 'onPropertyWithNotifyChanged' even though the signal name is
+ // actually 'oddlyNamedNotifySignal'
+
+ QQmlComponent component(&engine, testFileUrl("basicChanges4.qml"));
+ QVERIFY(component.isReady());
+
+ MyRect *rect = qobject_cast<MyRect*>(component.create());
+ QVERIFY(rect != 0);
+
+ QMetaProperty prop = rect->metaObject()->property(rect->metaObject()->indexOfProperty("propertyWithNotify"));
+ QVERIFY(prop.hasNotifySignal());
+ QString notifySignal = QByteArray(prop.notifySignal().signature());
+ QVERIFY(!notifySignal.startsWith("propertyWithNotifyChanged("));
+
+ QCOMPARE(rect->color(), QColor(Qt::red));
+
+ rect->setPropertyWithNotify(100);
+ QCOMPARE(rect->color(), QColor(Qt::blue));
+ }
+}
+
+void tst_qquickstates::attachedPropertyChanges()
+{
+ QQmlEngine engine;
+
+ QQmlComponent component(&engine, testFileUrl("attachedPropertyChanges.qml"));
+ QVERIFY(component.isReady());
+
+ QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(item != 0);
+ QCOMPARE(item->width(), 50.0);
+
+ // Ensure attached property has been changed
+ QObject *attObj = qmlAttachedPropertiesObject<MyRect>(item, false);
+ QVERIFY(attObj);
+
+ MyAttached *att = qobject_cast<MyAttached*>(attObj);
+ QVERIFY(att);
+
+ QCOMPARE(att->foo(), 1);
+}
+
+void tst_qquickstates::basicExtension()
+{
+ QQmlEngine engine;
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("basicExtension.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QVERIFY(rect != 0);
+
+ QCOMPARE(rect->color(),QColor("red"));
+ QCOMPARE(rect->border()->width(),1.0);
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+ QCOMPARE(rect->border()->width(),1.0);
+
+ rectPrivate->setState("bordered");
+ QCOMPARE(rect->color(),QColor("blue"));
+ QCOMPARE(rect->border()->width(),2.0);
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+ QCOMPARE(rect->border()->width(),1.0);
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+ QCOMPARE(rect->border()->width(),1.0);
+
+ rectPrivate->setState("bordered");
+ QCOMPARE(rect->color(),QColor("blue"));
+ QCOMPARE(rect->border()->width(),2.0);
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+ QCOMPARE(rect->border()->width(),1.0);
+ }
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("fakeExtension.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QVERIFY(rect != 0);
+
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("green");
+ QCOMPARE(rect->color(),QColor("green"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("green");
+ QCOMPARE(rect->color(),QColor("green"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("green");
+ QCOMPARE(rect->color(),QColor("green"));
+ }
+}
+
+void tst_qquickstates::basicBinding()
+{
+ QQmlEngine engine;
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("basicBinding.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QVERIFY(rect != 0);
+
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+ rect->setProperty("sourceColor", QColor("green"));
+ QCOMPARE(rect->color(),QColor("green"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+ rect->setProperty("sourceColor", QColor("yellow"));
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("yellow"));
+ }
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("basicBinding2.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QVERIFY(rect != 0);
+
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+ rect->setProperty("sourceColor", QColor("green"));
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("green"));
+ rect->setProperty("sourceColor", QColor("yellow"));
+ QCOMPARE(rect->color(),QColor("yellow"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("yellow"));
+ }
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("basicBinding3.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QVERIFY(rect != 0);
+
+ QCOMPARE(rect->color(),QColor("red"));
+ rect->setProperty("sourceColor", QColor("green"));
+ QCOMPARE(rect->color(),QColor("green"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+ rect->setProperty("sourceColor", QColor("red"));
+ QCOMPARE(rect->color(),QColor("blue"));
+ rect->setProperty("sourceColor2", QColor("yellow"));
+ QCOMPARE(rect->color(),QColor("yellow"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+ rect->setProperty("sourceColor2", QColor("green"));
+ QCOMPARE(rect->color(),QColor("red"));
+ rect->setProperty("sourceColor", QColor("yellow"));
+ QCOMPARE(rect->color(),QColor("yellow"));
+ }
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("basicBinding4.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QVERIFY(rect != 0);
+
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+ rect->setProperty("sourceColor", QColor("yellow"));
+ QCOMPARE(rect->color(),QColor("yellow"));
+
+ rectPrivate->setState("green");
+ QCOMPARE(rect->color(),QColor("green"));
+ rect->setProperty("sourceColor", QColor("purple"));
+ QCOMPARE(rect->color(),QColor("green"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("purple"));
+
+ rectPrivate->setState("green");
+ QCOMPARE(rect->color(),QColor("green"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+ }
+}
+
+void tst_qquickstates::signalOverride()
+{
+ QQmlEngine engine;
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("signalOverride.qml"));
+ MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QCOMPARE(rect->color(),QColor("red"));
+ rect->doSomething();
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ QQuickItemPrivate::get(rect)->setState("green");
+ rect->doSomething();
+ QCOMPARE(rect->color(),QColor("green"));
+ }
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("signalOverride2.qml"));
+ MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QCOMPARE(rect->color(),QColor("white"));
+ rect->doSomething();
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("extendedRect"));
+ QQuickItemPrivate::get(innerRect)->setState("green");
+ rect->doSomething();
+ QCOMPARE(rect->color(),QColor("blue"));
+ QCOMPARE(innerRect->color(),QColor("green"));
+ QCOMPARE(innerRect->property("extendedColor").value<QColor>(),QColor("green"));
+ }
+}
+
+void tst_qquickstates::signalOverrideCrash()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("signalOverrideCrash.qml"));
+ MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickItemPrivate::get(rect)->setState("overridden");
+ rect->doSomething();
+}
+
+void tst_qquickstates::signalOverrideCrash2()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("signalOverrideCrash2.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickItemPrivate::get(rect)->setState("state1");
+ QQuickItemPrivate::get(rect)->setState("state2");
+ QQuickItemPrivate::get(rect)->setState("state1");
+
+ delete rect;
+}
+
+void tst_qquickstates::signalOverrideCrash3()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("signalOverrideCrash3.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickItemPrivate::get(rect)->setState("state1");
+ QQuickItemPrivate::get(rect)->setState("");
+ QQuickItemPrivate::get(rect)->setState("state2");
+ QQuickItemPrivate::get(rect)->setState("");
+
+ delete rect;
+}
+
+void tst_qquickstates::parentChange()
+{
+ QQmlEngine engine;
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("parentChange1.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+
+ QQmlListReference list(rect, "states");
+ QQuickState *state = qobject_cast<QQuickState*>(list.at(0));
+ QVERIFY(state != 0);
+
+ qmlExecuteDeferred(state);
+ QQuickParentChange *pChange = qobject_cast<QQuickParentChange*>(state->operationAt(0));
+ QVERIFY(pChange != 0);
+ QQuickItem *nParent = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("NewParent"));
+ QVERIFY(nParent != 0);
+
+ QCOMPARE(pChange->parent(), nParent);
+
+ QQuickItemPrivate::get(rect)->setState("reparented");
+ QCOMPARE(innerRect->rotation(), qreal(0));
+ QCOMPARE(innerRect->scale(), qreal(1));
+ QCOMPARE(innerRect->x(), qreal(-133));
+ QCOMPARE(innerRect->y(), qreal(-300));
+ }
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("parentChange2.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+
+ rectPrivate->setState("reparented");
+ QCOMPARE(innerRect->rotation(), qreal(15));
+ QCOMPARE(innerRect->scale(), qreal(.5));
+ QCOMPARE(QString("%1").arg(innerRect->x()), QString("%1").arg(-19.9075));
+ QCOMPARE(QString("%1").arg(innerRect->y()), QString("%1").arg(-8.73433));
+ }
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("parentChange3.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+
+ rectPrivate->setState("reparented");
+ QCOMPARE(innerRect->rotation(), qreal(-37));
+ QCOMPARE(innerRect->scale(), qreal(.25));
+ QCOMPARE(QString("%1").arg(innerRect->x()), QString("%1").arg(-217.305));
+ QCOMPARE(QString("%1").arg(innerRect->y()), QString("%1").arg(-164.413));
+
+ rectPrivate->setState("");
+ QCOMPARE(innerRect->rotation(), qreal(0));
+ QCOMPARE(innerRect->scale(), qreal(1));
+ QCOMPARE(innerRect->x(), qreal(5));
+ //do a non-qFuzzyCompare fuzzy compare
+ QVERIFY(innerRect->y() < qreal(0.00001) && innerRect->y() > qreal(-0.00001));
+ }
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("parentChange6.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+
+ QQuickItemPrivate::get(rect)->setState("reparented");
+ QCOMPARE(innerRect->rotation(), qreal(180));
+ QCOMPARE(innerRect->scale(), qreal(1));
+ QCOMPARE(innerRect->x(), qreal(-105));
+ QCOMPARE(innerRect->y(), qreal(-105));
+ }
+}
+
+void tst_qquickstates::parentChangeErrors()
+{
+ QQmlEngine engine;
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("parentChange4.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+
+ QTest::ignoreMessage(QtWarningMsg, fullDataPath("parentChange4.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under non-uniform scale");
+ QQuickItemPrivate::get(rect)->setState("reparented");
+ QCOMPARE(innerRect->rotation(), qreal(0));
+ QCOMPARE(innerRect->scale(), qreal(1));
+ QCOMPARE(innerRect->x(), qreal(5));
+ QCOMPARE(innerRect->y(), qreal(5));
+ }
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("parentChange5.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+
+ QTest::ignoreMessage(QtWarningMsg, fullDataPath("parentChange5.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under complex transform");
+ QQuickItemPrivate::get(rect)->setState("reparented");
+ QCOMPARE(innerRect->rotation(), qreal(0));
+ QCOMPARE(innerRect->scale(), qreal(1));
+ QCOMPARE(innerRect->x(), qreal(5));
+ QCOMPARE(innerRect->y(), qreal(5));
+ }
+}
+
+void tst_qquickstates::anchorChanges()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("anchorChanges1.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+
+ QQmlListReference list(rect, "states");
+ QQuickState *state = qobject_cast<QQuickState*>(list.at(0));
+ QVERIFY(state != 0);
+
+ qmlExecuteDeferred(state);
+ QQuickAnchorChanges *aChanges = qobject_cast<QQuickAnchorChanges*>(state->operationAt(0));
+ QVERIFY(aChanges != 0);
+
+ QCOMPARE(aChanges->anchors()->left().script(), QLatin1String("undefined"));
+ QCOMPARE(aChanges->anchors()->right().script(), QLatin1String("container.right"));
+
+ rectPrivate->setState("right");
+ QCOMPARE(innerRect->x(), qreal(150));
+ QCOMPARE(aChanges->object(), qobject_cast<QQuickItem*>(innerRect));
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickAnchorLine::Invalid); //### was reset (how do we distinguish from not set at all)
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
+
+ rectPrivate->setState("");
+ QCOMPARE(innerRect->x(), qreal(5));
+
+ delete rect;
+}
+
+void tst_qquickstates::anchorChanges2()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("anchorChanges2.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+
+ rectPrivate->setState("right");
+ QCOMPARE(innerRect->x(), qreal(150));
+
+ rectPrivate->setState("");
+ QCOMPARE(innerRect->x(), qreal(5));
+
+ delete rect;
+}
+
+void tst_qquickstates::anchorChanges3()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("anchorChanges3.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+
+ QQuickItem *leftGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("LeftGuideline"));
+ QVERIFY(leftGuideline != 0);
+
+ QQuickItem *bottomGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("BottomGuideline"));
+ QVERIFY(bottomGuideline != 0);
+
+ QQmlListReference list(rect, "states");
+ QQuickState *state = qobject_cast<QQuickState*>(list.at(0));
+ QVERIFY(state != 0);
+
+ qmlExecuteDeferred(state);
+ QQuickAnchorChanges *aChanges = qobject_cast<QQuickAnchorChanges*>(state->operationAt(0));
+ QVERIFY(aChanges != 0);
+
+ QCOMPARE(aChanges->anchors()->top().script(), QLatin1String("container.top"));
+ QCOMPARE(aChanges->anchors()->bottom().script(), QLatin1String("bottomGuideline.bottom"));
+
+ rectPrivate->setState("reanchored");
+ QCOMPARE(aChanges->object(), qobject_cast<QQuickItem*>(innerRect));
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().item, QQuickItemPrivate::get(leftGuideline)->left().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickItemPrivate::get(leftGuideline)->left().anchorLine);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().item, QQuickItemPrivate::get(bottomGuideline)->bottom().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QQuickItemPrivate::get(bottomGuideline)->bottom().anchorLine);
+
+ QCOMPARE(innerRect->x(), qreal(10));
+ QCOMPARE(innerRect->y(), qreal(0));
+ QCOMPARE(innerRect->width(), qreal(190));
+ QCOMPARE(innerRect->height(), qreal(150));
+
+ rectPrivate->setState("");
+ QCOMPARE(innerRect->x(), qreal(0));
+ QCOMPARE(innerRect->y(), qreal(10));
+ QCOMPARE(innerRect->width(), qreal(150));
+ QCOMPARE(innerRect->height(), qreal(190));
+
+ delete rect;
+}
+
+void tst_qquickstates::anchorChanges4()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("anchorChanges4.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+
+ QQuickItem *leftGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("LeftGuideline"));
+ QVERIFY(leftGuideline != 0);
+
+ QQuickItem *bottomGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("BottomGuideline"));
+ QVERIFY(bottomGuideline != 0);
+
+ QQmlListReference list(rect, "states");
+ QQuickState *state = qobject_cast<QQuickState*>(list.at(0));
+ QVERIFY(state != 0);
+
+ qmlExecuteDeferred(state);
+ QQuickAnchorChanges *aChanges = qobject_cast<QQuickAnchorChanges*>(state->operationAt(0));
+ QVERIFY(aChanges != 0);
+
+ QCOMPARE(aChanges->anchors()->horizontalCenter().script(), QLatin1String("bottomGuideline.horizontalCenter"));
+ QCOMPARE(aChanges->anchors()->verticalCenter().script(), QLatin1String("leftGuideline.verticalCenter"));
+
+ QQuickItemPrivate::get(rect)->setState("reanchored");
+ QCOMPARE(aChanges->object(), qobject_cast<QQuickItem*>(innerRect));
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().item, QQuickItemPrivate::get(bottomGuideline)->horizontalCenter().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().anchorLine, QQuickItemPrivate::get(bottomGuideline)->horizontalCenter().anchorLine);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->verticalCenter().item, QQuickItemPrivate::get(leftGuideline)->verticalCenter().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->verticalCenter().anchorLine, QQuickItemPrivate::get(leftGuideline)->verticalCenter().anchorLine);
+
+ delete rect;
+}
+
+void tst_qquickstates::anchorChanges5()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("anchorChanges5.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+
+ QQuickItem *leftGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("LeftGuideline"));
+ QVERIFY(leftGuideline != 0);
+
+ QQuickItem *bottomGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("BottomGuideline"));
+ QVERIFY(bottomGuideline != 0);
+
+ QQmlListReference list(rect, "states");
+ QQuickState *state = qobject_cast<QQuickState*>(list.at(0));
+ QVERIFY(state != 0);
+
+ qmlExecuteDeferred(state);
+ QQuickAnchorChanges *aChanges = qobject_cast<QQuickAnchorChanges*>(state->operationAt(0));
+ QVERIFY(aChanges != 0);
+
+ QCOMPARE(aChanges->anchors()->baseline().script(), QLatin1String("leftGuideline.baseline"));
+
+ QQuickItemPrivate::get(rect)->setState("reanchored");
+ QCOMPARE(aChanges->object(), qobject_cast<QQuickItem*>(innerRect));
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().item, QQuickItemPrivate::get(bottomGuideline)->horizontalCenter().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().anchorLine, QQuickItemPrivate::get(bottomGuideline)->horizontalCenter().anchorLine);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->baseline().item, QQuickItemPrivate::get(leftGuideline)->baseline().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->baseline().anchorLine, QQuickItemPrivate::get(leftGuideline)->baseline().anchorLine);
+
+ delete rect;
+}
+
+void mirrorAnchors(QQuickItem *item) {
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->setLayoutMirror(true);
+}
+
+qreal offsetRTL(QQuickItem *anchorItem, QQuickItem *item) {
+ return anchorItem->width()+2*anchorItem->x()-item->width();
+}
+
+void tst_qquickstates::anchorChangesRTL()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("anchorChanges1.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+ mirrorAnchors(innerRect);
+
+ QQmlListReference list(rect, "states");
+ QQuickState *state = qobject_cast<QQuickState*>(list.at(0));
+ QVERIFY(state != 0);
+
+ qmlExecuteDeferred(state);
+ QQuickAnchorChanges *aChanges = qobject_cast<QQuickAnchorChanges*>(state->operationAt(0));
+ QVERIFY(aChanges != 0);
+
+ rectPrivate->setState("right");
+ QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(150));
+ QCOMPARE(aChanges->object(), qobject_cast<QQuickItem*>(innerRect));
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickAnchorLine::Invalid); //### was reset (how do we distinguish from not set at all)
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
+
+ rectPrivate->setState("");
+ QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) -qreal(5));
+
+ delete rect;
+}
+
+void tst_qquickstates::anchorChangesRTL2()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("anchorChanges2.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+ mirrorAnchors(innerRect);
+
+ rectPrivate->setState("right");
+ QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(150));
+
+ rectPrivate->setState("");
+ QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(5));
+
+ delete rect;
+}
+
+void tst_qquickstates::anchorChangesRTL3()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("anchorChanges3.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+
+ QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
+ QVERIFY(innerRect != 0);
+ mirrorAnchors(innerRect);
+
+ QQuickItem *leftGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("LeftGuideline"));
+ QVERIFY(leftGuideline != 0);
+
+ QQuickItem *bottomGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("BottomGuideline"));
+ QVERIFY(bottomGuideline != 0);
+
+ QQmlListReference list(rect, "states");
+ QQuickState *state = qobject_cast<QQuickState*>(list.at(0));
+ QVERIFY(state != 0);
+
+ qmlExecuteDeferred(state);
+ QQuickAnchorChanges *aChanges = qobject_cast<QQuickAnchorChanges*>(state->operationAt(0));
+ QVERIFY(aChanges != 0);
+
+ rectPrivate->setState("reanchored");
+ QCOMPARE(aChanges->object(), qobject_cast<QQuickItem*>(innerRect));
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().item, QQuickItemPrivate::get(leftGuideline)->left().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickItemPrivate::get(leftGuideline)->left().anchorLine);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().item, QQuickItemPrivate::get(bottomGuideline)->bottom().item);
+ QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QQuickItemPrivate::get(bottomGuideline)->bottom().anchorLine);
+
+ QCOMPARE(innerRect->x(), offsetRTL(leftGuideline, innerRect) - qreal(10));
+ QCOMPARE(innerRect->y(), qreal(0));
+ // between left side of parent and leftGuideline.x: 10, which has width 0
+ QCOMPARE(innerRect->width(), qreal(10));
+ QCOMPARE(innerRect->height(), qreal(150));
+
+ rectPrivate->setState("");
+ QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(0));
+ QCOMPARE(innerRect->y(), qreal(10));
+ // between right side of parent and left side of rightGuideline.x: 150, which has width 0
+ QCOMPARE(innerRect->width(), qreal(50));
+ QCOMPARE(innerRect->height(), qreal(190));
+
+ delete rect;
+}
+
+//QTBUG-9609
+void tst_qquickstates::anchorChangesCrash()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("anchorChangesCrash.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickItemPrivate::get(rect)->setState("reanchored");
+
+ delete rect;
+}
+
+// QTBUG-12273
+void tst_qquickstates::anchorRewindBug()
+{
+ QQuickView *view = new QQuickView;
+ view->setSource(testFileUrl("anchorRewindBug.qml"));
+
+ view->show();
+ view->requestActivateWindow();
+
+ QTest::qWaitForWindowShown(view);
+
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(view->rootObject());
+ QVERIFY(rect != 0);
+
+ QQuickItem * column = rect->findChild<QQuickItem*>("column");
+
+ QVERIFY(column != 0);
+ QVERIFY(!QQuickItemPrivate::get(column)->heightValid);
+ QVERIFY(!QQuickItemPrivate::get(column)->widthValid);
+ QCOMPARE(column->height(), 200.0);
+ QQuickItemPrivate::get(rect)->setState("reanchored");
+
+ // column height and width should stay implicit
+ // and column's implicit resizing should still work
+ QVERIFY(!QQuickItemPrivate::get(column)->heightValid);
+ QVERIFY(!QQuickItemPrivate::get(column)->widthValid);
+ QTRY_COMPARE(column->height(), 100.0);
+
+ QQuickItemPrivate::get(rect)->setState("");
+
+ // column height and width should stay implicit
+ // and column's implicit resizing should still work
+ QVERIFY(!QQuickItemPrivate::get(column)->heightValid);
+ QVERIFY(!QQuickItemPrivate::get(column)->widthValid);
+ QTRY_COMPARE(column->height(), 200.0);
+
+ delete view;
+}
+
+// QTBUG-11834
+void tst_qquickstates::anchorRewindBug2()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("anchorRewindBug2.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickRectangle *mover = rect->findChild<QQuickRectangle*>("mover");
+
+ QVERIFY(mover != 0);
+ QCOMPARE(mover->y(), qreal(0.0));
+ QCOMPARE(mover->width(), qreal(50.0));
+
+ QQuickItemPrivate::get(rect)->setState("anchored");
+ QCOMPARE(mover->y(), qreal(250.0));
+ QCOMPARE(mover->width(), qreal(200.0));
+
+ QQuickItemPrivate::get(rect)->setState("");
+ QCOMPARE(mover->y(), qreal(0.0));
+ QCOMPARE(mover->width(), qreal(50.0));
+
+ delete rect;
+}
+
+void tst_qquickstates::script()
+{
+ QQmlEngine engine;
+
+ {
+ QQmlComponent rectComponent(&engine, testFileUrl("script.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("blue")); // a script isn't reverted
+ }
+}
+
+void tst_qquickstates::restoreEntryValues()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("restoreEntryValues.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("blue"));
+}
+
+void tst_qquickstates::explicitChanges()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("explicit.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QQmlListReference list(rect, "states");
+ QQuickState *state = qobject_cast<QQuickState*>(list.at(0));
+ QVERIFY(state != 0);
+
+ qmlExecuteDeferred(state);
+ QQuickPropertyChanges *changes = qobject_cast<QQuickPropertyChanges*>(rect->findChild<QQuickPropertyChanges*>("changes"));
+ QVERIFY(changes != 0);
+ QVERIFY(changes->isExplicit());
+
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rect->setProperty("sourceColor", QColor("green"));
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+ rect->setProperty("sourceColor", QColor("yellow"));
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("yellow"));
+}
+
+void tst_qquickstates::propertyErrors()
+{
+ QQmlEngine engine;
+ QQmlComponent rectComponent(&engine, testFileUrl("propertyErrors.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QCOMPARE(rect->color(),QColor("red"));
+
+ QTest::ignoreMessage(QtWarningMsg, fullDataPath("propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\"");
+ QTest::ignoreMessage(QtWarningMsg, fullDataPath("propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to read-only property \"activeFocus\"");
+ QQuickItemPrivate::get(rect)->setState("blue");
+}
+
+void tst_qquickstates::incorrectRestoreBug()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("basicChanges.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QCOMPARE(rect->color(),QColor("red"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+
+ // make sure if we change the base state value, we then restore to it correctly
+ rect->setColor(QColor("green"));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("green"));
+}
+
+void tst_qquickstates::autoStateAtStartupRestoreBug()
+{
+ QQmlEngine engine;
+
+ QQmlComponent component(&engine, testFileUrl("autoStateAtStartupRestoreBug.qml"));
+ QObject *obj = component.create();
+
+ QVERIFY(obj != 0);
+ QCOMPARE(obj->property("test").toInt(), 3);
+
+ obj->setProperty("input", 2);
+
+ QCOMPARE(obj->property("test").toInt(), 9);
+
+ delete obj;
+}
+
+void tst_qquickstates::deletingChange()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("deleting.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+ QCOMPARE(rect->radius(),qreal(5));
+
+ rectPrivate->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+ QCOMPARE(rect->radius(),qreal(0));
+
+ QQuickPropertyChanges *pc = rect->findChild<QQuickPropertyChanges*>("pc1");
+ QVERIFY(pc != 0);
+ delete pc;
+
+ QQuickState *state = rect->findChild<QQuickState*>();
+ QVERIFY(state != 0);
+ qmlExecuteDeferred(state);
+ QCOMPARE(state->operationCount(), 1);
+
+ rectPrivate->setState("blue");
+ QCOMPARE(rect->color(),QColor("red"));
+ QCOMPARE(rect->radius(),qreal(5));
+
+ delete rect;
+}
+
+void tst_qquickstates::deletingState()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("deletingState.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickStateGroup *sg = rect->findChild<QQuickStateGroup*>();
+ QVERIFY(sg != 0);
+ QVERIFY(sg->findState("blue") != 0);
+
+ sg->setState("blue");
+ QCOMPARE(rect->color(),QColor("blue"));
+
+ sg->setState("");
+ QCOMPARE(rect->color(),QColor("red"));
+
+ QQuickState *state = rect->findChild<QQuickState*>();
+ QVERIFY(state != 0);
+ delete state;
+
+ QVERIFY(sg->findState("blue") == 0);
+
+ //### should we warn that state doesn't exist
+ sg->setState("blue");
+ QCOMPARE(rect->color(),QColor("red"));
+
+ delete rect;
+}
+
+void tst_qquickstates::tempState()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("legalTempState.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QTest::ignoreMessage(QtDebugMsg, "entering placed");
+ QTest::ignoreMessage(QtDebugMsg, "entering idle");
+ rectPrivate->setState("placed");
+ QCOMPARE(rectPrivate->state(), QLatin1String("idle"));
+}
+
+void tst_qquickstates::illegalTempState()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("illegalTempState.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML StateGroup: Can't apply a state change as part of a state definition.");
+ rectPrivate->setState("placed");
+ QCOMPARE(rectPrivate->state(), QLatin1String("placed"));
+}
+
+void tst_qquickstates::nonExistantProperty()
+{
+ QQmlEngine engine;
+
+ QQmlComponent rectComponent(&engine, testFileUrl("nonExistantProp.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QTest::ignoreMessage(QtWarningMsg, fullDataPath("nonExistantProp.qml") + ":9:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\"");
+ rectPrivate->setState("blue");
+ QCOMPARE(rectPrivate->state(), QLatin1String("blue"));
+}
+
+void tst_qquickstates::reset()
+{
+ QQmlEngine engine;
+
+ QQmlComponent c(&engine, testFileUrl("reset.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QVERIFY(rect != 0);
+
+ QQuickImage *image = rect->findChild<QQuickImage*>();
+ QVERIFY(image != 0);
+ QCOMPARE(image->width(), qreal(40.));
+ QCOMPARE(image->height(), qreal(20.));
+
+ QQuickItemPrivate::get(rect)->setState("state1");
+
+ QCOMPARE(image->width(), 20.0);
+ QCOMPARE(image->height(), qreal(20.));
+
+ delete rect;
+}
+
+void tst_qquickstates::illegalObjectCreation()
+{
+ QQmlEngine engine;
+
+ QQmlComponent component(&engine, testFileUrl("illegalObj.qml"));
+ QList<QQmlError> errors = component.errors();
+ QVERIFY(errors.count() == 1);
+ const QQmlError &error = errors.at(0);
+ QCOMPARE(error.line(), 9);
+ QCOMPARE(error.column(), 23);
+ QCOMPARE(error.description().toUtf8().constData(), "PropertyChanges does not support creating state-specific objects.");
+}
+
+void tst_qquickstates::whenOrdering()
+{
+ QQmlEngine engine;
+
+ QQmlComponent c(&engine, testFileUrl("whenOrdering.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+
+ QCOMPARE(rectPrivate->state(), QLatin1String(""));
+ rect->setProperty("condition2", true);
+ QCOMPARE(rectPrivate->state(), QLatin1String("state2"));
+ rect->setProperty("condition1", true);
+ QCOMPARE(rectPrivate->state(), QLatin1String("state1"));
+ rect->setProperty("condition2", false);
+ QCOMPARE(rectPrivate->state(), QLatin1String("state1"));
+ rect->setProperty("condition2", true);
+ QCOMPARE(rectPrivate->state(), QLatin1String("state1"));
+ rect->setProperty("condition1", false);
+ rect->setProperty("condition2", false);
+ QCOMPARE(rectPrivate->state(), QLatin1String(""));
+}
+
+void tst_qquickstates::urlResolution()
+{
+ QQmlEngine engine;
+
+ QQmlComponent c(&engine, testFileUrl("urlResolution.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QVERIFY(rect != 0);
+
+ QQuickItem *myType = rect->findChild<QQuickItem*>("MyType");
+ QQuickImage *image1 = rect->findChild<QQuickImage*>("image1");
+ QQuickImage *image2 = rect->findChild<QQuickImage*>("image2");
+ QQuickImage *image3 = rect->findChild<QQuickImage*>("image3");
+ QVERIFY(myType != 0 && image1 != 0 && image2 != 0 && image3 != 0);
+
+ QQuickItemPrivate::get(myType)->setState("SetImageState");
+ QUrl resolved = testFileUrl("Implementation/images/qt-logo.png");
+ QCOMPARE(image1->source(), resolved);
+ QCOMPARE(image2->source(), resolved);
+ QCOMPARE(image3->source(), resolved);
+
+ delete rect;
+}
+
+void tst_qquickstates::unnamedWhen()
+{
+ QQmlEngine engine;
+
+ QQmlComponent c(&engine, testFileUrl("unnamedWhen.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+
+ QCOMPARE(rectPrivate->state(), QLatin1String(""));
+ QCOMPARE(rect->property("stateString").toString(), QLatin1String(""));
+ rect->setProperty("triggerState", true);
+ QCOMPARE(rectPrivate->state(), QLatin1String("anonymousState1"));
+ QCOMPARE(rect->property("stateString").toString(), QLatin1String("inState"));
+ rect->setProperty("triggerState", false);
+ QCOMPARE(rectPrivate->state(), QLatin1String(""));
+ QCOMPARE(rect->property("stateString").toString(), QLatin1String(""));
+}
+
+void tst_qquickstates::returnToBase()
+{
+ QQmlEngine engine;
+
+ QQmlComponent c(&engine, testFileUrl("returnToBase.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+
+ QCOMPARE(rectPrivate->state(), QLatin1String(""));
+ QCOMPARE(rect->property("stateString").toString(), QLatin1String(""));
+ rect->setProperty("triggerState", true);
+ QCOMPARE(rectPrivate->state(), QLatin1String("anonymousState1"));
+ QCOMPARE(rect->property("stateString").toString(), QLatin1String("inState"));
+ rect->setProperty("triggerState", false);
+ QCOMPARE(rectPrivate->state(), QLatin1String(""));
+ QCOMPARE(rect->property("stateString").toString(), QLatin1String("originalState"));
+}
+
+//QTBUG-12559
+void tst_qquickstates::extendsBug()
+{
+ QQmlEngine engine;
+
+ QQmlComponent c(&engine, testFileUrl("extendsBug.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QVERIFY(rect != 0);
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QQuickRectangle *greenRect = rect->findChild<QQuickRectangle*>("greenRect");
+
+ rectPrivate->setState("b");
+ QCOMPARE(greenRect->x(), qreal(100));
+ QCOMPARE(greenRect->y(), qreal(100));
+}
+
+void tst_qquickstates::editProperties()
+{
+ QQmlEngine engine;
+
+ QQmlComponent c(&engine, testFileUrl("editProperties.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QVERIFY(rect != 0);
+
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+
+ QQuickStateGroup *stateGroup = rectPrivate->_states();
+ QVERIFY(stateGroup != 0);
+ qmlExecuteDeferred(stateGroup);
+
+ QQuickState *blueState = stateGroup->findState("blue");
+ QVERIFY(blueState != 0);
+ qmlExecuteDeferred(blueState);
+
+ QQuickPropertyChanges *propertyChangesBlue = qobject_cast<QQuickPropertyChanges*>(blueState->operationAt(0));
+ QVERIFY(propertyChangesBlue != 0);
+
+ QQuickState *greenState = stateGroup->findState("green");
+ QVERIFY(greenState != 0);
+ qmlExecuteDeferred(greenState);
+
+ QQuickPropertyChanges *propertyChangesGreen = qobject_cast<QQuickPropertyChanges*>(greenState->operationAt(0));
+ QVERIFY(propertyChangesGreen != 0);
+
+ QQuickRectangle *childRect = rect->findChild<QQuickRectangle*>("rect2");
+ QVERIFY(childRect != 0);
+ QCOMPARE(childRect->width(), qreal(402));
+ QVERIFY(QQmlPropertyPrivate::binding(QQmlProperty(childRect, "width")));
+ QCOMPARE(childRect->height(), qreal(200));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(childRect->width(), qreal(50));
+ QCOMPARE(childRect->height(), qreal(40));
+ QVERIFY(!QQmlPropertyPrivate::binding(QQmlProperty(childRect, "width")));
+ QVERIFY(blueState->bindingInRevertList(childRect, "width"));
+
+
+ rectPrivate->setState("green");
+ QCOMPARE(childRect->width(), qreal(200));
+ QCOMPARE(childRect->height(), qreal(100));
+ QVERIFY(greenState->bindingInRevertList(childRect, "width"));
+
+
+ rectPrivate->setState("");
+
+
+ QCOMPARE(propertyChangesBlue->actions().length(), 2);
+ QVERIFY(propertyChangesBlue->containsValue("width"));
+ QVERIFY(!propertyChangesBlue->containsProperty("x"));
+ QCOMPARE(propertyChangesBlue->value("width").toInt(), 50);
+ QVERIFY(!propertyChangesBlue->value("x").isValid());
+
+ propertyChangesBlue->changeValue("width", 60);
+ QCOMPARE(propertyChangesBlue->value("width").toInt(), 60);
+ QCOMPARE(propertyChangesBlue->actions().length(), 2);
+
+
+ propertyChangesBlue->changeExpression("width", "myRectangle.width / 2");
+ QVERIFY(!propertyChangesBlue->containsValue("width"));
+ QVERIFY(propertyChangesBlue->containsExpression("width"));
+ QCOMPARE(propertyChangesBlue->value("width").toInt(), 0);
+ QCOMPARE(propertyChangesBlue->actions().length(), 2);
+
+ propertyChangesBlue->changeValue("width", 50);
+ QVERIFY(propertyChangesBlue->containsValue("width"));
+ QVERIFY(!propertyChangesBlue->containsExpression("width"));
+ QCOMPARE(propertyChangesBlue->value("width").toInt(), 50);
+ QCOMPARE(propertyChangesBlue->actions().length(), 2);
+
+ QVERIFY(QQmlPropertyPrivate::binding(QQmlProperty(childRect, "width")));
+ rectPrivate->setState("blue");
+ QCOMPARE(childRect->width(), qreal(50));
+ QCOMPARE(childRect->height(), qreal(40));
+
+ propertyChangesBlue->changeValue("width", 60);
+ QCOMPARE(propertyChangesBlue->value("width").toInt(), 60);
+ QCOMPARE(propertyChangesBlue->actions().length(), 2);
+ QCOMPARE(childRect->width(), qreal(60));
+ QVERIFY(!QQmlPropertyPrivate::binding(QQmlProperty(childRect, "width")));
+
+ propertyChangesBlue->changeExpression("width", "myRectangle.width / 2");
+ QVERIFY(!propertyChangesBlue->containsValue("width"));
+ QVERIFY(propertyChangesBlue->containsExpression("width"));
+ QCOMPARE(propertyChangesBlue->value("width").toInt(), 0);
+ QCOMPARE(propertyChangesBlue->actions().length(), 2);
+ QVERIFY(QQmlPropertyPrivate::binding(QQmlProperty(childRect, "width")));
+ QCOMPARE(childRect->width(), qreal(200));
+
+ propertyChangesBlue->changeValue("width", 50);
+ QCOMPARE(childRect->width(), qreal(50));
+
+ rectPrivate->setState("");
+ QCOMPARE(childRect->width(), qreal(402));
+ QVERIFY(QQmlPropertyPrivate::binding(QQmlProperty(childRect, "width")));
+
+ QCOMPARE(propertyChangesGreen->actions().length(), 2);
+ rectPrivate->setState("green");
+ QCOMPARE(childRect->width(), qreal(200));
+ QCOMPARE(childRect->height(), qreal(100));
+ QVERIFY(QQmlPropertyPrivate::binding(QQmlProperty(childRect, "width")));
+ QVERIFY(greenState->bindingInRevertList(childRect, "width"));
+ QCOMPARE(propertyChangesGreen->actions().length(), 2);
+
+
+ propertyChangesGreen->removeProperty("height");
+ QVERIFY(!QQmlPropertyPrivate::binding(QQmlProperty(childRect, "height")));
+ QCOMPARE(childRect->height(), qreal(200));
+
+ QVERIFY(greenState->bindingInRevertList(childRect, "width"));
+ QVERIFY(greenState->containsPropertyInRevertList(childRect, "width"));
+ propertyChangesGreen->removeProperty("width");
+ QVERIFY(QQmlPropertyPrivate::binding(QQmlProperty(childRect, "width")));
+ QCOMPARE(childRect->width(), qreal(402));
+ QVERIFY(!greenState->bindingInRevertList(childRect, "width"));
+ QVERIFY(!greenState->containsPropertyInRevertList(childRect, "width"));
+
+ propertyChangesBlue->removeProperty("width");
+ QCOMPARE(childRect->width(), qreal(402));
+
+ rectPrivate->setState("blue");
+ QCOMPARE(childRect->width(), qreal(402));
+ QCOMPARE(childRect->height(), qreal(40));
+}
+
+void tst_qquickstates::QTBUG_14830()
+{
+ QQmlEngine engine;
+
+ QQmlComponent c(&engine, testFileUrl("QTBUG-14830.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QVERIFY(rect != 0);
+ QQuickItem *item = rect->findChild<QQuickItem*>("area");
+
+ QCOMPARE(item->width(), qreal(171));
+}
+
+void tst_qquickstates::avoidFastForward()
+{
+ QQmlEngine engine;
+
+ //shouldn't fast forward if there isn't a transition
+ QQmlComponent c(&engine, testFileUrl("avoidFastForward.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QVERIFY(rect != 0);
+
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ rectPrivate->setState("a");
+ QCOMPARE(rect->property("updateCount").toInt(), 1);
+}
+
+//QTBUG-22583
+void tst_qquickstates::revertListBug()
+{
+ QQmlEngine engine;
+
+ QQmlComponent c(&engine, testFileUrl("revertListBug.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QVERIFY(rect != 0);
+
+ QQuickRectangle *rect1 = rect->findChild<QQuickRectangle*>("rect1");
+ QQuickRectangle *rect2 = rect->findChild<QQuickRectangle*>("rect2");
+ QQuickItem *origParent1 = rect->findChild<QQuickItem*>("originalParent1");
+ QQuickItem *origParent2 = rect->findChild<QQuickItem*>("originalParent2");
+ QQuickItem *newParent = rect->findChild<QQuickItem*>("newParent");
+
+ QCOMPARE(rect1->parentItem(), origParent1);
+ QCOMPARE(rect2->parentItem(), origParent2);
+
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ rectPrivate->setState("reparented");
+
+ QCOMPARE(rect1->parentItem(), newParent);
+ QCOMPARE(rect2->parentItem(), origParent2);
+
+ rectPrivate->setState("");
+
+ QCOMPARE(rect1->parentItem(), origParent1);
+ QCOMPARE(rect2->parentItem(), origParent2);
+
+ QMetaObject::invokeMethod(rect, "switchTargetItem");
+
+ rectPrivate->setState("reparented");
+
+ QCOMPARE(rect1->parentItem(), origParent1);
+ QCOMPARE(rect2->parentItem(), newParent);
+
+ rectPrivate->setState("");
+
+ QCOMPARE(rect1->parentItem(), origParent1);
+ QCOMPARE(rect2->parentItem(), origParent2); //QTBUG-22583 causes rect2's parent item to be origParent1
+}
+
+QTEST_MAIN(tst_qquickstates)
+
+#include "tst_qquickstates.moc"