diff options
author | Matthew Vogt <matthew.vogt@nokia.com> | 2012-02-16 14:43:03 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-24 04:51:31 +0100 |
commit | b855240b782395f94315f43ea3e7e182299fac48 (patch) | |
tree | bc594c04449be8cd14cd0ab0bb72dafc2be0ffb2 /tests/auto/quick/qquickanimations | |
parent | 6a42a6e0a9a1abdda0d07a5a20b4ac7e45348684 (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/qquickanimations')
49 files changed, 2394 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickanimations/data/Double.qml b/tests/auto/quick/qquickanimations/data/Double.qml new file mode 100644 index 0000000000..99ffca1d62 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/Double.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + id: container + property bool on: false + border.color: "#ffffff" + color: "green" + width: 50 + height: 50 + NumberAnimation on x { + objectName: "animation" + running: container.on; from: 0; to: 600; loops: Animation.Infinite; duration: 2000 + } +} diff --git a/tests/auto/quick/qquickanimations/data/attached.qml b/tests/auto/quick/qquickanimations/data/attached.qml new file mode 100644 index 0000000000..9dcfcd8752 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/attached.qml @@ -0,0 +1,34 @@ +import QtQuick 2.0 + +Rectangle { + width: 180; height: 200; + + Component { + id: delegate + Rectangle { + id: wrapper + width: 180; height: 200 + color: "blue" + + states: State { + name: "otherState" + PropertyChanges { target: wrapper; color: "green" } + } + + transitions: Transition { + PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true } + ScriptAction { script: console.log(wrapper.ListView.delayRemove ? "on" : "off") } + } + + Component.onCompleted: { + console.log(ListView.delayRemove ? "on" : "off"); + wrapper.state = "otherState" + } + } + } + + ListView { + model: 1 + delegate: delegate + } +} diff --git a/tests/auto/quick/qquickanimations/data/badproperty1.qml b/tests/auto/quick/qquickanimations/data/badproperty1.qml new file mode 100644 index 0000000000..9634c2c169 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/badproperty1.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 240 + height: 320 + Rectangle { + id: myRect + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + states: State { + name: "state1" + PropertyChanges { target: myRect; border.color: "blue" } + } + transitions: Transition { + ColorAnimation { target: myRect; to: "red"; property: "border.colr"; duration: 1000 } + } + Component.onCompleted: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; +} diff --git a/tests/auto/quick/qquickanimations/data/badproperty2.qml b/tests/auto/quick/qquickanimations/data/badproperty2.qml new file mode 100644 index 0000000000..c121172a99 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/badproperty2.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 240 + height: 320 + Rectangle { + id: myRect + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + states: State { + name: "state1" + PropertyChanges { target: myRect; border.color: "blue" } + } + transitions: Transition { + ColorAnimation { target: myRect; to: "red"; property: "border"; duration: 1000 } + } + Component.onCompleted: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; +} diff --git a/tests/auto/quick/qquickanimations/data/badtype1.qml b/tests/auto/quick/qquickanimations/data/badtype1.qml new file mode 100644 index 0000000000..43e1ec8572 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/badtype1.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + Rectangle { + color: "red" + width: 50; height: 50 + x: 100; y: 100 + PropertyAnimation on x { from: "blue"; to: "green"; } + } +} diff --git a/tests/auto/quick/qquickanimations/data/badtype2.qml b/tests/auto/quick/qquickanimations/data/badtype2.qml new file mode 100644 index 0000000000..5341cb3d1c --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/badtype2.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + Rectangle { + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { from: "blue"; to: "green"; } + } +} diff --git a/tests/auto/quick/qquickanimations/data/badtype3.qml b/tests/auto/quick/qquickanimations/data/badtype3.qml new file mode 100644 index 0000000000..182efa0840 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/badtype3.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + Rectangle { + color: "red" + ColorAnimation on color { from: 10; to: 15; } + width: 50; height: 50 + x: 100; y: 100 + } +} diff --git a/tests/auto/quick/qquickanimations/data/badtype4.qml b/tests/auto/quick/qquickanimations/data/badtype4.qml new file mode 100644 index 0000000000..f091e2430f --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/badtype4.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 240 + height: 320 + Rectangle { + id: myRect + objectName: "MyRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + MouseArea { + anchors.fill: parent + onClicked: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; + } + } + states: State { + name: "state1" + PropertyChanges { target: myRect; x: 200; color: "blue" } + } + transitions: Transition { + //comment out each in turn to make sure each only animates the relevant property + ColorAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color + NumberAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color + } +} diff --git a/tests/auto/quick/qquickanimations/data/disabledTransition.qml b/tests/auto/quick/qquickanimations/data/disabledTransition.qml new file mode 100644 index 0000000000..0fbafead8b --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/disabledTransition.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + enabled: false + NumberAnimation { targets: theRect; properties: "x" } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/quick/qquickanimations/data/dontAutoStart.qml b/tests/auto/quick/qquickanimations/data/dontAutoStart.qml new file mode 100644 index 0000000000..c0c0c65e3f --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/dontAutoStart.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 600 + height: 400 + + Rectangle { + id: redRect + width: 100; height: 100 + color: Qt.rgba(1,0,0) + Behavior on x { + NumberAnimation { id: myAnim; objectName: "MyAnim"; target: redRect; property: "y"; to: 300; loops: Animation.Infinite} + } + + } + +} diff --git a/tests/auto/quick/qquickanimations/data/dontStart.qml b/tests/auto/quick/qquickanimations/data/dontStart.qml new file mode 100644 index 0000000000..3eee0cfd35 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/dontStart.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 600 + height: 400 + + Rectangle { + id: redRect + width: 100; height: 100 + color: Qt.rgba(1,0,0) + SequentialAnimation on x { + running: false + NumberAnimation { objectName: "MyAnim"; running: true } + } + + } + +} diff --git a/tests/auto/quick/qquickanimations/data/dontStart2.qml b/tests/auto/quick/qquickanimations/data/dontStart2.qml new file mode 100644 index 0000000000..e7b4164e4e --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/dontStart2.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 600 + height: 400 + + Rectangle { + id: redRect + width: 100; height: 100 + color: Qt.rgba(1,0,0) + + transitions: Transition { + SequentialAnimation { + NumberAnimation { id: myAnim; objectName: "MyAnim"; running: true } + } + } + } +} diff --git a/tests/auto/quick/qquickanimations/data/dotproperty.qml b/tests/auto/quick/qquickanimations/data/dotproperty.qml new file mode 100644 index 0000000000..e0e46dcef5 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/dotproperty.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 240 + height: 320 + Rectangle { + id: myRect + color: "red" + width: 50; height: 50 + x: 100; y: 100 + MouseArea { + anchors.fill: parent + onClicked: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; + } + } + states: State { + name: "state1" + PropertyChanges { target: myRect; border.color: "blue" } + } + transitions: Transition { + ColorAnimation { properties: "border.color"; duration: 1000 } + } +} diff --git a/tests/auto/quick/qquickanimations/data/doubleRegistrationBug.qml b/tests/auto/quick/qquickanimations/data/doubleRegistrationBug.qml new file mode 100644 index 0000000000..9ef3da20c0 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/doubleRegistrationBug.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400 + + Double { id: dub; on: parent.width < 800 } + Component.onCompleted: dub.on = false +} diff --git a/tests/auto/quick/qquickanimations/data/looping.qml b/tests/auto/quick/qquickanimations/data/looping.qml new file mode 100644 index 0000000000..a3d40ae837 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/looping.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 + +Item { + width: 200; height: 200 + + Rectangle { + x: 50; y: 50; width: 50; height: 50; color: "red" + + SequentialAnimation on rotation { + NumberAnimation { + from: 0; to: 90; duration: 100 + loops: 3 + } + } + } +} diff --git a/tests/auto/quick/qquickanimations/data/mixedtype1.qml b/tests/auto/quick/qquickanimations/data/mixedtype1.qml new file mode 100644 index 0000000000..76129dd15e --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/mixedtype1.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 240 + height: 320 + Rectangle { + id: myRect + objectName: "MyRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + MouseArea { + anchors.fill: parent + onClicked: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; + } + } + states: State { + name: "state1" + PropertyChanges { target: myRect; x: 200; border.width: 10 } + } + transitions: Transition { + PropertyAnimation { properties: "x,border.width"; duration: 1000 } //x is real, border.width is int + } +} diff --git a/tests/auto/quick/qquickanimations/data/mixedtype2.qml b/tests/auto/quick/qquickanimations/data/mixedtype2.qml new file mode 100644 index 0000000000..1a7166e3f3 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/mixedtype2.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 240 + height: 320 + Rectangle { + id: myRect + objectName: "MyRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + MouseArea { + anchors.fill: parent + onClicked: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; + } + } + states: State { + name: "state1" + PropertyChanges { target: myRect; x: 200; color: "blue" } + } + transitions: Transition { + PropertyAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color + } +} diff --git a/tests/auto/quick/qquickanimations/data/nonTransitionBug.qml b/tests/auto/quick/qquickanimations/data/nonTransitionBug.qml new file mode 100644 index 0000000000..909c533e7b --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/nonTransitionBug.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 200 + height: 200 + + Rectangle { + id: mover + objectName: "mover" + } + + states: [ + State { + name: "free" + }, + State { + name: "left" + PropertyChanges { + restoreEntryValues: false + target: mover + x: 0 + } + } + ] + + transitions: Transition { + PropertyAnimation { properties: "x"; duration: 50 } + } +} diff --git a/tests/auto/quick/qquickanimations/data/pathAnimation.qml b/tests/auto/quick/qquickanimations/data/pathAnimation.qml new file mode 100644 index 0000000000..d2006a1c6a --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/pathAnimation.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + Rectangle { + id: redRect + color: "red" + width: 100; height: 100 + x: 50; y: 50 + } + + PathAnimation { + target: redRect + duration: 100; + path: Path { + startX: 50; startY: 50 + PathCubic { + x: 300; y: 300 + + control1X: 300; control1Y: 50 + control2X: 50; control2Y: 300 + } + } + } +} diff --git a/tests/auto/quick/qquickanimations/data/pathAnimation2.qml b/tests/auto/quick/qquickanimations/data/pathAnimation2.qml new file mode 100644 index 0000000000..2f64dac2cc --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/pathAnimation2.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + Rectangle { + id: redRect + color: "red" + width: 100; height: 100 + x: 50; y: 50 + } + + PathAnimation { + target: redRect + duration: 100; + endRotation: 0 + orientationEntryDuration: 10 + orientationExitDuration: 10 + orientation: PathAnimation.RightFirst + path: Path { + startX: 50; startY: 50 + PathLine { x: 300; y: 300 } + } + } +} diff --git a/tests/auto/quick/qquickanimations/data/pathAnimationNoStart.qml b/tests/auto/quick/qquickanimations/data/pathAnimationNoStart.qml new file mode 100644 index 0000000000..be3501fabb --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/pathAnimationNoStart.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + Rectangle { + id: redRect + color: "red" + width: 100; height: 100 + x: 50; y: 50 + } + + PathAnimation { + target: redRect + duration: 100; + path: Path { + //no startX/Y defined (should automatically start from redRects pos) + PathCubic { + x: 300; y: 300 + + control1X: 300; control1Y: 50 + control2X: 50; control2Y: 300 + } + } + } +} diff --git a/tests/auto/quick/qquickanimations/data/pathInterpolator.qml b/tests/auto/quick/qquickanimations/data/pathInterpolator.qml new file mode 100644 index 0000000000..0104412d7c --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/pathInterpolator.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +PathInterpolator { + path: Path { + startX: 50; startY: 50 + PathCubic { + x: 300; y: 300 + + control1X: 300; control1Y: 50 + control2X: 50; control2Y: 300 + } + } +} diff --git a/tests/auto/quick/qquickanimations/data/pathInterpolatorBack.qml b/tests/auto/quick/qquickanimations/data/pathInterpolatorBack.qml new file mode 100644 index 0000000000..41366ef798 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/pathInterpolatorBack.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +PathInterpolator { + path: Path { + startX: 50; startY: 50 + PathLine { x: 50; y: 100 } + PathLine { x: 100; y: 100 } + PathLine { x: 100; y: 50 } + PathLine { x: 200; y: 50 } + } +} diff --git a/tests/auto/quick/qquickanimations/data/pathInterpolatorBack2.qml b/tests/auto/quick/qquickanimations/data/pathInterpolatorBack2.qml new file mode 100644 index 0000000000..eb3d4c3f86 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/pathInterpolatorBack2.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +PathInterpolator { + path: Path { + startX: 200; startY: 280 + PathCurve { x: 150; y: 280 } + PathCurve { x: 150; y: 80 } + PathCurve { x: 0; y: 80 } + } +} diff --git a/tests/auto/quick/qquickanimations/data/pathTransition.qml b/tests/auto/quick/qquickanimations/data/pathTransition.qml new file mode 100644 index 0000000000..55ffc33f95 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/pathTransition.qml @@ -0,0 +1,41 @@ +import QtQuick 2.0 + +Rectangle { + width: 800 + height: 800 + + Rectangle { + id: redRect; objectName: "redRect" + color: "red" + width: 50; height: 50 + x: 500; y: 50 + } + + states: State { + name: "moved" + PropertyChanges { + target: redRect + x: 100; y: 700 + } + } + + transitions: Transition { + to: "moved"; reversible: true + PathAnimation { + id: pathAnim + target: redRect + duration: 300 + path: Path { + PathCurve { x: 100; y: 100 } + PathCurve { x: 200; y: 350 } + PathCurve { x: 600; y: 500 } + PathCurve {} + } + } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = parent.state == "moved" ? "" : "moved" + } +} diff --git a/tests/auto/quick/qquickanimations/data/pauseBindingBug.qml b/tests/auto/quick/qquickanimations/data/pauseBindingBug.qml new file mode 100644 index 0000000000..359cda166f --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/pauseBindingBug.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 + +Rectangle { + id: rect + width: 200 + height: 200 + + property bool animating: false + property int value: 0 + + NumberAnimation on value { + objectName: "animation" + paused: !rect.animating + to: 100 + duration: 50 + } +} diff --git a/tests/auto/quick/qquickanimations/data/pauseBug.qml b/tests/auto/quick/qquickanimations/data/pauseBug.qml new file mode 100644 index 0000000000..fa2c4be4ba --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/pauseBug.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +SequentialAnimation { + id: animation + running: true + ScriptAction { script: animation.paused = true } +} diff --git a/tests/auto/quick/qquickanimations/data/properties.qml b/tests/auto/quick/qquickanimations/data/properties.qml new file mode 100644 index 0000000000..f0f730967c --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/properties.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { to: 200 } + } +} diff --git a/tests/auto/quick/qquickanimations/data/properties2.qml b/tests/auto/quick/qquickanimations/data/properties2.qml new file mode 100644 index 0000000000..6b7f026e0b --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/properties2.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { targets: theRect; properties: "x"; to: 200; } + } +} diff --git a/tests/auto/quick/qquickanimations/data/properties3.qml b/tests/auto/quick/qquickanimations/data/properties3.qml new file mode 100644 index 0000000000..5eb65496d4 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/properties3.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { target: theRect; property: "x"; to: 300; } + } +} diff --git a/tests/auto/quick/qquickanimations/data/properties4.qml b/tests/auto/quick/qquickanimations/data/properties4.qml new file mode 100644 index 0000000000..dfe8ad17e7 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/properties4.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { target: theRect; property: "y"; to: 200; } + } +} diff --git a/tests/auto/quick/qquickanimations/data/properties5.qml b/tests/auto/quick/qquickanimations/data/properties5.qml new file mode 100644 index 0000000000..075fc9bc5a --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/properties5.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { targets: theRect; properties: "y"; to: 200; } + } +} diff --git a/tests/auto/quick/qquickanimations/data/propertiesTransition.qml b/tests/auto/quick/qquickanimations/data/propertiesTransition.qml new file mode 100644 index 0000000000..968c5f6285 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/propertiesTransition.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + NumberAnimation { targets: theRect; properties: "x" } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/quick/qquickanimations/data/propertiesTransition2.qml b/tests/auto/quick/qquickanimations/data/propertiesTransition2.qml new file mode 100644 index 0000000000..f06165604a --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/propertiesTransition2.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + NumberAnimation { target: theRect; property: "y"; to: 200 } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/quick/qquickanimations/data/propertiesTransition3.qml b/tests/auto/quick/qquickanimations/data/propertiesTransition3.qml new file mode 100644 index 0000000000..7d3b3b9c6d --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/propertiesTransition3.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + NumberAnimation { targets: theRect; properties: "y" } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/quick/qquickanimations/data/propertiesTransition4.qml b/tests/auto/quick/qquickanimations/data/propertiesTransition4.qml new file mode 100644 index 0000000000..1c31a79634 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/propertiesTransition4.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + NumberAnimation { target: theRect; properties: "x" } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/quick/qquickanimations/data/propertiesTransition5.qml b/tests/auto/quick/qquickanimations/data/propertiesTransition5.qml new file mode 100644 index 0000000000..a2ff746900 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/propertiesTransition5.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + NumberAnimation { targets: theRect; property: "x" } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/quick/qquickanimations/data/propertiesTransition6.qml b/tests/auto/quick/qquickanimations/data/propertiesTransition6.qml new file mode 100644 index 0000000000..d3db01efb0 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/propertiesTransition6.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + NumberAnimation { targets: theItem; properties: "x" } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/quick/qquickanimations/data/propertiesTransition7.qml b/tests/auto/quick/qquickanimations/data/propertiesTransition7.qml new file mode 100644 index 0000000000..98898de8ef --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/propertiesTransition7.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + SpringAnimation { targets: theRect; properties: "x"; velocity: 10000 } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/quick/qquickanimations/data/reanchor.qml b/tests/auto/quick/qquickanimations/data/reanchor.qml new file mode 100644 index 0000000000..241cc81a96 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/reanchor.qml @@ -0,0 +1,46 @@ +import QtQuick 2.0 + +Rectangle { + id: container + width: 200; height: 200 + Rectangle { + id: myRect + color: "green"; + anchors.left: parent.left + anchors.right: rightGuideline.left + anchors.top: topGuideline.top + anchors.bottom: container.bottom + } + Item { id: leftGuideline; x: 10 } + Item { id: rightGuideline; x: 150 } + Item { id: topGuideline; y: 10 } + Item { id: bottomGuideline; y: 150 } + Item { id: topGuideline2; y: 50 } + Item { id: bottomGuideline2; y: 175 } + + states: [ State { + name: "reanchored" + AnchorChanges { + target: myRect; + anchors.left: leftGuideline.left + anchors.right: container.right + anchors.top: container.top + anchors.bottom: bottomGuideline.bottom + } + }, State { + name: "reanchored2" + AnchorChanges { + target: myRect; + anchors.left: undefined + anchors.right: undefined + anchors.top: topGuideline2.top + anchors.bottom: bottomGuideline2.bottom + } + }] + + transitions: Transition { + AnchorAnimation { } + } + + state: "reanchored" +} diff --git a/tests/auto/quick/qquickanimations/data/registrationBug.qml b/tests/auto/quick/qquickanimations/data/registrationBug.qml new file mode 100644 index 0000000000..633da4e17f --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/registrationBug.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { + id: rect + width: 200 + height: 200 + + property bool animating: true + property int value: 0 + + NumberAnimation { + target: rect + property: "value" + running: rect.animating + to: 100 + duration: 50 + } +} diff --git a/tests/auto/quick/qquickanimations/data/reparent.qml b/tests/auto/quick/qquickanimations/data/reparent.qml new file mode 100644 index 0000000000..39f1e7a6d2 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/reparent.qml @@ -0,0 +1,56 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; + height: 240; + color: "black"; + + Rectangle { + id: gr + objectName: "target" + color: "green" + width: 50; height: 50 + } + + Rectangle { + id: np + objectName: "newParent" + x: 150 + width: 150; height: 150 + color: "yellow" + clip: true + Rectangle { + color: "red" + x: 50; y: 50; height: 50; width: 50 + } + + } + + Rectangle { + id: vp + objectName: "viaParent" + x: 100; y: 100 + width: 50; height: 50 + color: "blue" + rotation: 45 + scale: 2 + } + + states: State { + name: "state1" + ParentChange { + target: gr + parent: np + x: 50; y: 50; width: 100; + } + } + + transitions: Transition { + reversible: true + to: "state1" + ParentAnimation { + target: gr; via: vp; + NumberAnimation { properties: "x,y,rotation,scale,width" } + } + } +} diff --git a/tests/auto/quick/qquickanimations/data/rotation.qml b/tests/auto/quick/qquickanimations/data/rotation.qml new file mode 100644 index 0000000000..4dc42a1bd2 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/rotation.qml @@ -0,0 +1,48 @@ +import QtQuick 2.0 + +Rectangle { + width: 600; height: 200 + + Row { + spacing: 5 + Rectangle { + id: rr + objectName: "rr" + color: "red" + width: 100; height: 100 + } + Rectangle { + id: rr2 + objectName: "rr2" + color: "red" + width: 100; height: 100 + } + Rectangle { + id: rr3 + objectName: "rr3" + color: "red" + width: 100; height: 100 + } + Rectangle { + id: rr4 + objectName: "rr4" + color: "red" + width: 100; height: 100 + } + } + + states: State { + name: "state1" + PropertyChanges { target: rr; rotation: 370 } + PropertyChanges { target: rr2; rotation: 370 } + PropertyChanges { target: rr3; rotation: 370 } + PropertyChanges { target: rr4; rotation: 370 } + } + + transitions: Transition { + RotationAnimation { target: rr; direction: RotationAnimation.Numerical; duration: 1000 } + RotationAnimation { target: rr2; direction: RotationAnimation.Clockwise; duration: 1000 } + RotationAnimation { target: rr3; direction: RotationAnimation.Counterclockwise; duration: 1000 } + RotationAnimation { target: rr4; direction: RotationAnimation.Shortest; duration: 1000 } + } +} diff --git a/tests/auto/quick/qquickanimations/data/runningTrueBug.qml b/tests/auto/quick/qquickanimations/data/runningTrueBug.qml new file mode 100644 index 0000000000..bec6fab368 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/runningTrueBug.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 +Rectangle { + color: "skyblue" + width: 500 + height: 200 + Rectangle { + objectName: "cloud" + color: "white" + y: 50 + width: 100 + height: 100 + + SequentialAnimation on x { + loops: Animation.Infinite + running: true + NumberAnimation { + id: firstAnimation + from: 0 + to: 500 + duration: 5000 + } + NumberAnimation { + id: secondAnimation + from: -100 + to: 0 + duration: 1000 + } + } + } +} diff --git a/tests/auto/quick/qquickanimations/data/transitionAssignmentBug.qml b/tests/auto/quick/qquickanimations/data/transitionAssignmentBug.qml new file mode 100644 index 0000000000..508693e0fc --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/transitionAssignmentBug.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + property bool nullObject + Component.onCompleted: nullObject = transitions.length > 0 && transitions[0] === null + + property list<Transition> myTransitions: [Transition {}, Transition {}] + transitions: myTransitions +} diff --git a/tests/auto/quick/qquickanimations/data/valuesource.qml b/tests/auto/quick/qquickanimations/data/valuesource.qml new file mode 100644 index 0000000000..7a636b4003 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/valuesource.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { id: anim; objectName: "MyAnim"; to: 200 } + } +} diff --git a/tests/auto/quick/qquickanimations/data/valuesource2.qml b/tests/auto/quick/qquickanimations/data/valuesource2.qml new file mode 100644 index 0000000000..9788761ee8 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/valuesource2.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { id: anim; objectName: "MyAnim"; running: false; to: 200 } + } +} diff --git a/tests/auto/quick/qquickanimations/qquickanimations.pro b/tests/auto/quick/qquickanimations/qquickanimations.pro new file mode 100644 index 0000000000..0e432ab9f1 --- /dev/null +++ b/tests/auto/quick/qquickanimations/qquickanimations.pro @@ -0,0 +1,18 @@ +CONFIG += testcase +TARGET = tst_qquickanimations +SOURCES += tst_qquickanimations.cpp + +include (../../shared/util.pri) + +macx:CONFIG -= app_bundle + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private v8-private qml-private quick-private opengl-private testlib + +# QTBUG-23385 - color mixing tests failing on Ubuntu 11.10 x64 +linux-*:system(". /etc/lsb-release && [ $DISTRIB_CODENAME = oneiric ]"):DEFINES+=UBUNTU_ONEIRIC diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp new file mode 100644 index 0000000000..108bce64f9 --- /dev/null +++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp @@ -0,0 +1,1319 @@ +/**************************************************************************** +** +** 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 <QtTest/QtTest> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQuick/qquickview.h> +#include <QtQml/private/qanimationgroupjob_p.h> +#include <QtQuick/private/qquickrectangle_p.h> +#include <QtQuick/private/qquickanimation_p.h> +#include <QtQuick/private/qquicktransition_p.h> +#include <QtQuick/private/qquickitemanimation_p.h> +#include <QtQuick/private/qquickpathinterpolator_p.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QEasingCurve> + +#include <limits.h> +#include <math.h> + +#include "../../shared/util.h" + +class tst_qquickanimations : public QQmlDataTest +{ + Q_OBJECT +public: + tst_qquickanimations() {} + +private slots: + void initTestCase() + { + QQmlEngine engine; // ensure types are registered + QQmlDataTest::initTestCase(); + } + + void simpleProperty(); + void simpleNumber(); + void simpleColor(); + void simpleRotation(); + void simplePath(); + void simpleAnchor(); + void reparent(); + void pathInterpolator(); + void pathInterpolatorBackwardJump(); + void pathWithNoStart(); + void alwaysRunToEnd(); + void complete(); + void resume(); + void dotProperty(); + void badTypes(); + void badProperties(); + void mixedTypes(); + void properties(); + void propertiesTransition(); + void pathTransition(); + void disabledTransition(); + void invalidDuration(); + void attached(); + void propertyValueSourceDefaultStart(); + void dontStart(); + void easingProperties(); + void rotation(); + void runningTrueBug(); + void nonTransitionBug(); + void registrationBug(); + void doubleRegistrationBug(); + void alwaysRunToEndRestartBug(); + void transitionAssignmentBug(); + void pauseBindingBug(); + void pauseBug(); + void loopingBug(); +}; + +#define QTIMED_COMPARE(lhs, rhs) do { \ + for (int ii = 0; ii < 5; ++ii) { \ + if (lhs == rhs) \ + break; \ + QTest::qWait(50); \ + } \ + QCOMPARE(lhs, rhs); \ +} while (false) + +void tst_qquickanimations::simpleProperty() +{ + QQuickRectangle rect; + QQuickPropertyAnimation animation; + animation.setTargetObject(&rect); + animation.setProperty("x"); + animation.setTo(200); + QVERIFY(animation.target() == &rect); + QVERIFY(animation.property() == "x"); + QVERIFY(animation.to().toReal() == 200.0); + animation.start(); + QVERIFY(animation.isRunning()); + QTest::qWait(animation.duration()); + QTIMED_COMPARE(rect.x(), 200.0); + + rect.setPos(QPointF(0,0)); + animation.start(); + QVERIFY(animation.isRunning()); + animation.pause(); + QVERIFY(animation.isPaused()); + animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); + QCOMPARE(rect.x(),100.0); +} + +void tst_qquickanimations::simpleNumber() +{ + QQuickRectangle rect; + QQuickNumberAnimation animation; + animation.setTargetObject(&rect); + animation.setProperty("x"); + animation.setTo(200); + QVERIFY(animation.target() == &rect); + QVERIFY(animation.property() == "x"); + QVERIFY(animation.to() == 200); + animation.start(); + QVERIFY(animation.isRunning()); + QTest::qWait(animation.duration()); + QTIMED_COMPARE(rect.x(), qreal(200)); + + rect.setX(0); + animation.start(); + animation.pause(); + QVERIFY(animation.isRunning()); + QVERIFY(animation.isPaused()); + animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); + QCOMPARE(rect.x(), qreal(100)); +} + +void tst_qquickanimations::simpleColor() +{ + QQuickRectangle rect; + QQuickColorAnimation animation; + animation.setTargetObject(&rect); + animation.setProperty("color"); + animation.setTo(QColor("red")); + QVERIFY(animation.target() == &rect); + QVERIFY(animation.property() == "color"); + QVERIFY(animation.to() == QColor("red")); + animation.start(); + QVERIFY(animation.isRunning()); + QTest::qWait(animation.duration()); + QTIMED_COMPARE(rect.color(), QColor("red")); + + rect.setColor(QColor("blue")); + animation.start(); + animation.pause(); + QVERIFY(animation.isRunning()); + QVERIFY(animation.isPaused()); + animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); +#if defined(UBUNTU_ONEIRIC) && defined(__x86_64__) + QEXPECT_FAIL("", "Fails on this platform - QTBUG-23385", Abort); +#endif + QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1)); + + rect.setColor(QColor("green")); + animation.setFrom(QColor("blue")); + QVERIFY(animation.from() == QColor("blue")); + animation.restart(); + QCOMPARE(rect.color(), QColor("blue")); + QVERIFY(animation.isRunning()); + animation.setCurrentTime(125); + QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1)); +} + +void tst_qquickanimations::simpleRotation() +{ + QQuickRectangle rect; + QQuickRotationAnimation animation; + animation.setTargetObject(&rect); + animation.setProperty("rotation"); + animation.setTo(270); + QVERIFY(animation.target() == &rect); + QVERIFY(animation.property() == "rotation"); + QVERIFY(animation.to() == 270); + QVERIFY(animation.direction() == QQuickRotationAnimation::Numerical); + animation.start(); + QVERIFY(animation.isRunning()); + QTest::qWait(animation.duration()); + QTIMED_COMPARE(rect.rotation(), qreal(270)); + + rect.setRotation(0); + animation.start(); + animation.pause(); + QVERIFY(animation.isRunning()); + QVERIFY(animation.isPaused()); + animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); + QCOMPARE(rect.rotation(), qreal(135)); +} + +void tst_qquickanimations::simplePath() +{ + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("pathAnimation.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>(); + QVERIFY(redRect); + QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>(); + QVERIFY(pathAnim); + + QCOMPARE(pathAnim->duration(), 100); + QCOMPARE(pathAnim->target(), redRect); + + pathAnim->start(); + pathAnim->pause(); + + pathAnim->setCurrentTime(30); + QCOMPARE(redRect->x(), qreal(167)); + QCOMPARE(redRect->y(), qreal(104)); + + pathAnim->setCurrentTime(100); + QCOMPARE(redRect->x(), qreal(300)); + QCOMPARE(redRect->y(), qreal(300)); + + //verify animation runs to end + pathAnim->start(); + QCOMPARE(redRect->x(), qreal(50)); + QCOMPARE(redRect->y(), qreal(50)); + QTRY_COMPARE(redRect->x(), qreal(300)); + QCOMPARE(redRect->y(), qreal(300)); + + pathAnim->setOrientation(QQuickPathAnimation::RightFirst); + QCOMPARE(pathAnim->orientation(), QQuickPathAnimation::RightFirst); + pathAnim->start(); + QTRY_VERIFY(redRect->rotation() != 0); + pathAnim->stop(); + + delete rect; + } + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("pathAnimation2.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>(); + QVERIFY(redRect); + QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>(); + QVERIFY(pathAnim); + + QCOMPARE(pathAnim->orientation(), QQuickPathAnimation::RightFirst); + QCOMPARE(pathAnim->endRotation(), qreal(0)); + QCOMPARE(pathAnim->orientationEntryDuration(), 10); + QCOMPARE(pathAnim->orientationExitDuration(), 10); + + pathAnim->start(); + pathAnim->pause(); + QCOMPARE(redRect->x(), qreal(50)); + QCOMPARE(redRect->y(), qreal(50)); + QCOMPARE(redRect->rotation(), qreal(-360)); + + pathAnim->setCurrentTime(50); + QCOMPARE(redRect->x(), qreal(175)); + QCOMPARE(redRect->y(), qreal(175)); + QCOMPARE(redRect->rotation(), qreal(-315)); + + pathAnim->setCurrentTime(100); + QCOMPARE(redRect->x(), qreal(300)); + QCOMPARE(redRect->y(), qreal(300)); + QCOMPARE(redRect->rotation(), qreal(0)); + + delete rect; + } +} + +void tst_qquickanimations::simpleAnchor() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("reanchor.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *greenRect = rect->findChild<QQuickRectangle*>(); + QVERIFY(greenRect); + + QCOMPARE(rect->state(), QLatin1String("reanchored")); + QCOMPARE(greenRect->x(), qreal(10)); + QCOMPARE(greenRect->y(), qreal(0)); + QCOMPARE(greenRect->width(), qreal(190)); + QCOMPARE(greenRect->height(), qreal(150)); + + rect->setState(""); + + //verify animation in progress + QTRY_VERIFY(greenRect->x() < 10 && greenRect->x() > 0); + QVERIFY(greenRect->y() > 0 && greenRect->y() < 10); + QVERIFY(greenRect->width() < 190 && greenRect->width() > 150); + QVERIFY(greenRect->height() > 150 && greenRect->height() < 190); + + //verify end state ("") + QTRY_COMPARE(greenRect->x(), qreal(0)); + QCOMPARE(greenRect->y(), qreal(10)); + QCOMPARE(greenRect->width(), qreal(150)); + QCOMPARE(greenRect->height(), qreal(190)); + + rect->setState("reanchored2"); + + //verify animation in progress + QTRY_VERIFY(greenRect->y() > 10 && greenRect->y() < 50); + QVERIFY(greenRect->height() > 125 && greenRect->height() < 190); + //NOTE: setting left/right anchors to undefined removes the anchors, but does not resize. + QCOMPARE(greenRect->x(), qreal(0)); + QCOMPARE(greenRect->width(), qreal(150)); + + //verify end state ("reanchored2") + QTRY_COMPARE(greenRect->y(), qreal(50)); + QCOMPARE(greenRect->height(), qreal(125)); + QCOMPARE(greenRect->x(), qreal(0)); + QCOMPARE(greenRect->width(), qreal(150)); + + rect->setState("reanchored"); + + //verify animation in progress + QTRY_VERIFY(greenRect->x() < 10 && greenRect->x() > 0); + QVERIFY(greenRect->y() > 0 && greenRect->y() < 50); + QVERIFY(greenRect->width() < 190 && greenRect->width() > 150); + QVERIFY(greenRect->height() > 125 && greenRect->height() < 150); + + //verify end state ("reanchored") + QTRY_COMPARE(greenRect->x(), qreal(10)); + QCOMPARE(greenRect->y(), qreal(0)); + QCOMPARE(greenRect->width(), qreal(190)); + QCOMPARE(greenRect->height(), qreal(150)); + + rect->setState("reanchored2"); + + //verify animation in progress + QTRY_VERIFY(greenRect->x() < 10 && greenRect->x() > 0); + QVERIFY(greenRect->y() > 0 && greenRect->y() < 50); + QVERIFY(greenRect->width() < 190 && greenRect->width() > 150); + QVERIFY(greenRect->height() > 125 && greenRect->height() < 150); + + //verify end state ("reanchored2") + QTRY_COMPARE(greenRect->x(), qreal(0)); + QCOMPARE(greenRect->y(), qreal(50)); + QCOMPARE(greenRect->width(), qreal(150)); + QCOMPARE(greenRect->height(), qreal(125)); + + delete rect; +} + +void tst_qquickanimations::reparent() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("reparent.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *target = rect->findChild<QQuickRectangle*>("target"); + QVERIFY(target); + + QCOMPARE(target->parentItem(), rect); + QCOMPARE(target->x(), qreal(0)); + QCOMPARE(target->y(), qreal(0)); + QCOMPARE(target->width(), qreal(50)); + QCOMPARE(target->height(), qreal(50)); + QCOMPARE(target->rotation(), qreal(0)); + QCOMPARE(target->scale(), qreal(1)); + + rect->setState("state1"); + + QQuickRectangle *viaParent = rect->findChild<QQuickRectangle*>("viaParent"); + QVERIFY(viaParent); + + QQuickRectangle *newParent = rect->findChild<QQuickRectangle*>("newParent"); + QVERIFY(newParent); + + QTest::qWait(100); + + //animation in progress + QTRY_COMPARE(target->parentItem(), viaParent); + QVERIFY(target->x() > -100 && target->x() < 50); + QVERIFY(target->y() > -100 && target->y() < 50); + QVERIFY(target->width() > 50 && target->width() < 100); + QCOMPARE(target->height(), qreal(50)); + QCOMPARE(target->rotation(), qreal(-45)); + QCOMPARE(target->scale(), qreal(.5)); + + //end state + QTRY_COMPARE(target->parentItem(), newParent); + QCOMPARE(target->x(), qreal(50)); + QCOMPARE(target->y(), qreal(50)); + QCOMPARE(target->width(), qreal(100)); + QCOMPARE(target->height(), qreal(50)); + QCOMPARE(target->rotation(), qreal(0)); + QCOMPARE(target->scale(), qreal(1)); + + delete rect; +} + +void tst_qquickanimations::pathInterpolator() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("pathInterpolator.qml")); + QQuickPathInterpolator *interpolator = qobject_cast<QQuickPathInterpolator*>(c.create()); + QVERIFY(interpolator); + + QCOMPARE(interpolator->progress(), qreal(0)); + QCOMPARE(interpolator->x(), qreal(50)); + QCOMPARE(interpolator->y(), qreal(50)); + QCOMPARE(interpolator->angle(), qreal(0)); + + interpolator->setProgress(.5); + QCOMPARE(interpolator->progress(), qreal(.5)); + QCOMPARE(interpolator->x(), qreal(175)); + QCOMPARE(interpolator->y(), qreal(175)); + QCOMPARE(interpolator->angle(), qreal(90)); + + interpolator->setProgress(1); + QCOMPARE(interpolator->progress(), qreal(1)); + QCOMPARE(interpolator->x(), qreal(300)); + QCOMPARE(interpolator->y(), qreal(300)); + QCOMPARE(interpolator->angle(), qreal(0)); +} + +void tst_qquickanimations::pathInterpolatorBackwardJump() +{ + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("pathInterpolatorBack.qml")); + QQuickPathInterpolator *interpolator = qobject_cast<QQuickPathInterpolator*>(c.create()); + QVERIFY(interpolator); + + QCOMPARE(interpolator->progress(), qreal(0)); + QCOMPARE(interpolator->x(), qreal(50)); + QCOMPARE(interpolator->y(), qreal(50)); + QCOMPARE(interpolator->angle(), qreal(90)); + + interpolator->setProgress(.5); + QCOMPARE(interpolator->progress(), qreal(.5)); + QCOMPARE(interpolator->x(), qreal(100)); + QCOMPARE(interpolator->y(), qreal(75)); + QCOMPARE(interpolator->angle(), qreal(270)); + + interpolator->setProgress(1); + QCOMPARE(interpolator->progress(), qreal(1)); + QCOMPARE(interpolator->x(), qreal(200)); + QCOMPARE(interpolator->y(), qreal(50)); + QCOMPARE(interpolator->angle(), qreal(0)); + + //make sure we don't get caught in infinite loop here + interpolator->setProgress(0); + QCOMPARE(interpolator->progress(), qreal(0)); + QCOMPARE(interpolator->x(), qreal(50)); + QCOMPARE(interpolator->y(), qreal(50)); + QCOMPARE(interpolator->angle(), qreal(90)); + } + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("pathInterpolatorBack2.qml")); + QQuickPathInterpolator *interpolator = qobject_cast<QQuickPathInterpolator*>(c.create()); + QVERIFY(interpolator); + + QCOMPARE(interpolator->progress(), qreal(0)); + QCOMPARE(interpolator->x(), qreal(200)); + QCOMPARE(interpolator->y(), qreal(280)); + QCOMPARE(interpolator->angle(), qreal(180)); + + interpolator->setProgress(1); + QCOMPARE(interpolator->progress(), qreal(1)); + QCOMPARE(interpolator->x(), qreal(0)); + QCOMPARE(interpolator->y(), qreal(80)); + QCOMPARE(interpolator->angle(), qreal(180)); + + //make sure we don't get caught in infinite loop here + interpolator->setProgress(0); + QCOMPARE(interpolator->progress(), qreal(0)); + QCOMPARE(interpolator->x(), qreal(200)); + QCOMPARE(interpolator->y(), qreal(280)); + QCOMPARE(interpolator->angle(), qreal(180)); + } +} + +void tst_qquickanimations::pathWithNoStart() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("pathAnimationNoStart.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>(); + QVERIFY(redRect); + QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>(); + QVERIFY(pathAnim); + + pathAnim->start(); + pathAnim->pause(); + QCOMPARE(redRect->x(), qreal(50)); + QCOMPARE(redRect->y(), qreal(50)); + + pathAnim->setCurrentTime(50); + QCOMPARE(redRect->x(), qreal(175)); + QCOMPARE(redRect->y(), qreal(175)); + + pathAnim->setCurrentTime(100); + QCOMPARE(redRect->x(), qreal(300)); + QCOMPARE(redRect->y(), qreal(300)); + + redRect->setX(100); + redRect->setY(100); + pathAnim->start(); + QCOMPARE(redRect->x(), qreal(100)); + QCOMPARE(redRect->y(), qreal(100)); + QTRY_COMPARE(redRect->x(), qreal(300)); + QCOMPARE(redRect->y(), qreal(300)); +} + +void tst_qquickanimations::alwaysRunToEnd() +{ + QQuickRectangle rect; + QQuickPropertyAnimation animation; + animation.setTargetObject(&rect); + animation.setProperty("x"); + animation.setTo(200); + animation.setDuration(1000); + animation.setLoops(-1); + animation.setAlwaysRunToEnd(true); + QVERIFY(animation.loops() == -1); + QVERIFY(animation.alwaysRunToEnd() == true); + animation.start(); + QTest::qWait(1500); + animation.stop(); + QVERIFY(rect.x() != qreal(200)); + QTest::qWait(500); + QTIMED_COMPARE(rect.x(), qreal(200)); +} + +void tst_qquickanimations::complete() +{ + QQuickRectangle rect; + QQuickPropertyAnimation animation; + animation.setTargetObject(&rect); + animation.setProperty("x"); + animation.setFrom(1); + animation.setTo(200); + animation.setDuration(500); + QVERIFY(animation.from() == 1); + animation.start(); + QTest::qWait(50); + animation.stop(); + QVERIFY(rect.x() != qreal(200)); + animation.start(); + QTest::qWait(50); + QVERIFY(animation.isRunning()); + animation.complete(); + QCOMPARE(rect.x(), qreal(200)); +} + +void tst_qquickanimations::resume() +{ + QQuickRectangle rect; + QQuickPropertyAnimation animation; + animation.setTargetObject(&rect); + animation.setProperty("x"); + animation.setFrom(10); + animation.setTo(200); + animation.setDuration(1000); + QVERIFY(animation.from() == 10); + + animation.start(); + QTest::qWait(400); + animation.pause(); + qreal x = rect.x(); + QVERIFY(x != qreal(200) && x != qreal(10)); + QVERIFY(animation.isRunning()); + QVERIFY(animation.isPaused()); + + animation.resume(); + QVERIFY(animation.isRunning()); + QVERIFY(!animation.isPaused()); + QTest::qWait(400); + animation.stop(); + QVERIFY(rect.x() > x); +} + +void tst_qquickanimations::dotProperty() +{ + QQuickRectangle rect; + QQuickNumberAnimation animation; + animation.setTargetObject(&rect); + animation.setProperty("border.width"); + animation.setTo(10); + animation.start(); + QTest::qWait(animation.duration()+50); + QTIMED_COMPARE(rect.border()->width(), 10.0); + + rect.border()->setWidth(0); + animation.start(); + animation.pause(); + animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); + QCOMPARE(rect.border()->width(), 5.0); +} + +void tst_qquickanimations::badTypes() +{ + //don't crash + { + QQuickView *view = new QQuickView; + view->setSource(testFileUrl("badtype1.qml")); + + qApp->processEvents(); + + delete view; + } + + //make sure we get a compiler error + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("badtype2.qml")); + QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready"); + c.create(); + + QVERIFY(c.errors().count() == 1); + QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: number expected")); + } + + //make sure we get a compiler error + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("badtype3.qml")); + QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready"); + c.create(); + + QVERIFY(c.errors().count() == 1); + QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: color expected")); + } + + //don't crash + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("badtype4.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("state1"); + QTest::qWait(1000 + 50); + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("MyRect"); + QVERIFY(myRect); + QCOMPARE(myRect->x(),qreal(200)); + } +} + +void tst_qquickanimations::badProperties() +{ + //make sure we get a runtime error + { + QQmlEngine engine; + + QQmlComponent c1(&engine, testFileUrl("badproperty1.qml")); + QByteArray message = testFileUrl("badproperty1.qml").toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate non-existent property \"border.colr\""; + QTest::ignoreMessage(QtWarningMsg, message); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c1.create()); + QVERIFY(rect); + + QQmlComponent c2(&engine, testFileUrl("badproperty2.qml")); + message = testFileUrl("badproperty2.qml").toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate read-only property \"border\""; + QTest::ignoreMessage(QtWarningMsg, message); + rect = qobject_cast<QQuickRectangle*>(c2.create()); + QVERIFY(rect); + + //### should we warn here are well? + //rect->setState("state1"); + } +} + +//test animating mixed types with property animation in a transition +//for example, int + real; color + real; etc +void tst_qquickanimations::mixedTypes() +{ + //assumes border.width stays a real -- not real robust + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("mixedtype1.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("state1"); + QTest::qWait(500); + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("MyRect"); + QVERIFY(myRect); + + //rather inexact -- is there a better way? + QVERIFY(myRect->x() > 100 && myRect->x() < 200); + QVERIFY(myRect->border()->width() > 1 && myRect->border()->width() < 10); + } + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("mixedtype2.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("state1"); + QTest::qWait(500); + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("MyRect"); + QVERIFY(myRect); + + //rather inexact -- is there a better way? + QVERIFY(myRect->x() > 100 && myRect->x() < 200); +#if defined(UBUNTU_ONEIRIC) && defined(__x86_64__) + QEXPECT_FAIL("", "Fails on this platform - QTBUG-23385", Continue); +#endif + QVERIFY(myRect->color() != QColor("red") && myRect->color() != QColor("blue")); + } +} + +void tst_qquickanimations::properties() +{ + const int waitDuration = 300; + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("properties.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(200)); + } + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("properties2.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(200)); + } + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("properties3.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(300)); + } + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("properties4.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->y(),qreal(200)); + QTIMED_COMPARE(myRect->x(),qreal(100)); + } + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("properties5.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(100)); + QTIMED_COMPARE(myRect->y(),qreal(200)); + } +} + +void tst_qquickanimations::propertiesTransition() +{ + const int waitDuration = 300; + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("propertiesTransition.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("moved"); + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(200)); + } + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("propertiesTransition2.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + QQuickItemPrivate::get(rect)->setState("moved"); + QCOMPARE(myRect->x(),qreal(200)); + QCOMPARE(myRect->y(),qreal(100)); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->y(),qreal(200)); + } + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("propertiesTransition3.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + QQuickItemPrivate::get(rect)->setState("moved"); + QCOMPARE(myRect->x(),qreal(200)); + QCOMPARE(myRect->y(),qreal(100)); + } + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("propertiesTransition4.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + QQuickItemPrivate::get(rect)->setState("moved"); + QCOMPARE(myRect->x(),qreal(100)); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(200)); + } + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("propertiesTransition5.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + QQuickItemPrivate::get(rect)->setState("moved"); + QCOMPARE(myRect->x(),qreal(100)); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(200)); + } + + /*{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("propertiesTransition6.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + QQuickItemPrivate::get(rect)->setState("moved"); + QCOMPARE(myRect->x(),qreal(100)); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(100)); + }*/ + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("propertiesTransition7.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("moved"); + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(200)); + } + +} + +void tst_qquickanimations::pathTransition() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("pathTransition.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("redRect"); + QVERIFY(myRect); + + QQuickItemPrivate::get(rect)->setState("moved"); + QTRY_VERIFY(myRect->x() < 500 && myRect->x() > 100 && myRect->y() > 50 && myRect->y() < 700 ); //animation started + QTRY_VERIFY(qFuzzyCompare(myRect->x(), qreal(100)) && qFuzzyCompare(myRect->y(), qreal(700))); + QTest::qWait(100); + + QQuickItemPrivate::get(rect)->setState(""); + QTRY_VERIFY(myRect->x() < 500 && myRect->x() > 100 && myRect->y() > 50 && myRect->y() < 700 ); //animation started + QTRY_VERIFY(qFuzzyCompare(myRect->x(), qreal(500)) && qFuzzyCompare(myRect->y(), qreal(50))); +} + +void tst_qquickanimations::disabledTransition() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("disabledTransition.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect"); + QVERIFY(myRect); + + QQuickTransition *trans = rect->findChild<QQuickTransition*>(); + QVERIFY(trans); + + QCOMPARE(trans->enabled(), false); + + QQuickItemPrivate::get(rect)->setState("moved"); + QCOMPARE(myRect->x(),qreal(200)); + + trans->setEnabled(true); + + QQuickItemPrivate::get(rect)->setState(""); + QCOMPARE(myRect->x(),qreal(200)); + QTest::qWait(300); + QTIMED_COMPARE(myRect->x(),qreal(100)); +} + +void tst_qquickanimations::invalidDuration() +{ + QQuickPropertyAnimation *animation = new QQuickPropertyAnimation; + QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML PropertyAnimation: Cannot set a duration of < 0"); + animation->setDuration(-1); + QCOMPARE(animation->duration(), 250); + + QQuickPauseAnimation *pauseAnimation = new QQuickPauseAnimation; + QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML PauseAnimation: Cannot set a duration of < 0"); + pauseAnimation->setDuration(-1); + QCOMPARE(pauseAnimation->duration(), 250); +} + +void tst_qquickanimations::attached() +{ + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("attached.qml")); + QTest::ignoreMessage(QtDebugMsg, "off"); + QTest::ignoreMessage(QtDebugMsg, "on"); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); +} + +void tst_qquickanimations::propertyValueSourceDefaultStart() +{ + { + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("valuesource.qml")); + + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim"); + QVERIFY(myAnim); + QVERIFY(myAnim->isRunning()); + } + + { + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("valuesource2.qml")); + + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim"); + QVERIFY(myAnim); + QVERIFY(myAnim->isRunning() == false); + } + + { + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("dontAutoStart.qml")); + + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim"); + QVERIFY(myAnim && !myAnim->qtAnimation()); + //QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimationJob::Stopped); + } +} + + +void tst_qquickanimations::dontStart() +{ + { + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("dontStart.qml")); + + QString warning = c.url().toString() + ":14:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes."; + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim"); + QVERIFY(myAnim && !myAnim->qtAnimation()); + //QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimationJob::Stopped); + } + + { + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("dontStart2.qml")); + + QString warning = c.url().toString() + ":15:17: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes."; + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim"); + QVERIFY(myAnim && !myAnim->qtAnimation()); + //QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimationJob::Stopped); + } +} + +void tst_qquickanimations::easingProperties() +{ + { + QQmlEngine engine; + QString componentStr = "import QtQuick 2.0\nNumberAnimation { easing.type: \"InOutQuad\" }"; + QQmlComponent animationComponent(&engine); + animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickPropertyAnimation *animObject = qobject_cast<QQuickPropertyAnimation*>(animationComponent.create()); + + QVERIFY(animObject != 0); + QCOMPARE(animObject->easing().type(), QEasingCurve::InOutQuad); + } + + { + QQmlEngine engine; + QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"OutBounce\"; easing.amplitude: 5.0 }"; + QQmlComponent animationComponent(&engine); + animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickPropertyAnimation *animObject = qobject_cast<QQuickPropertyAnimation*>(animationComponent.create()); + + QVERIFY(animObject != 0); + QCOMPARE(animObject->easing().type(), QEasingCurve::OutBounce); + QCOMPARE(animObject->easing().amplitude(), 5.0); + } + + { + QQmlEngine engine; + QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"OutElastic\"; easing.amplitude: 5.0; easing.period: 3.0}"; + QQmlComponent animationComponent(&engine); + animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickPropertyAnimation *animObject = qobject_cast<QQuickPropertyAnimation*>(animationComponent.create()); + + QVERIFY(animObject != 0); + QCOMPARE(animObject->easing().type(), QEasingCurve::OutElastic); + QCOMPARE(animObject->easing().amplitude(), 5.0); + QCOMPARE(animObject->easing().period(), 3.0); + } + + { + QQmlEngine engine; + QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"InOutBack\"; easing.overshoot: 2 }"; + QQmlComponent animationComponent(&engine); + animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickPropertyAnimation *animObject = qobject_cast<QQuickPropertyAnimation*>(animationComponent.create()); + + QVERIFY(animObject != 0); + QCOMPARE(animObject->easing().type(), QEasingCurve::InOutBack); + QCOMPARE(animObject->easing().overshoot(), 2.0); + } + + { + QQmlEngine engine; + QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"Bezier\"; easing.bezierCurve: [0.5, 0.2, 0.13, 0.65, 1.0, 1.0] }"; + QQmlComponent animationComponent(&engine); + animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickPropertyAnimation *animObject = qobject_cast<QQuickPropertyAnimation*>(animationComponent.create()); + + QVERIFY(animObject != 0); + QCOMPARE(animObject->easing().type(), QEasingCurve::BezierSpline); + QList<QPointF> points = animObject->easing().cubicBezierSpline(); + QCOMPARE(points.count(), 3); + QCOMPARE(points.at(0), QPointF(0.5, 0.2)); + QCOMPARE(points.at(1), QPointF(0.13, 0.65)); + QCOMPARE(points.at(2), QPointF(1.0, 1.0)); + } +} + +void tst_qquickanimations::rotation() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("rotation.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *rr = rect->findChild<QQuickRectangle*>("rr"); + QQuickRectangle *rr2 = rect->findChild<QQuickRectangle*>("rr2"); + QQuickRectangle *rr3 = rect->findChild<QQuickRectangle*>("rr3"); + QQuickRectangle *rr4 = rect->findChild<QQuickRectangle*>("rr4"); + + QQuickItemPrivate::get(rect)->setState("state1"); + QTest::qWait(800); + qreal r1 = rr->rotation(); + qreal r2 = rr2->rotation(); + qreal r3 = rr3->rotation(); + qreal r4 = rr4->rotation(); + + QVERIFY(r1 > qreal(0) && r1 < qreal(370)); + QVERIFY(r2 > qreal(0) && r2 < qreal(370)); + QVERIFY(r3 < qreal(0) && r3 > qreal(-350)); + QVERIFY(r4 > qreal(0) && r4 < qreal(10)); + QCOMPARE(r1,r2); + QVERIFY(r4 < r2); + + QTest::qWait(800); + QTIMED_COMPARE(rr->rotation() + rr2->rotation() + rr3->rotation() + rr4->rotation(), qreal(370*4)); +} + +void tst_qquickanimations::runningTrueBug() +{ + //ensure we start correctly when "running: true" is explicitly set + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("runningTrueBug.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect); + + QQuickRectangle *cloud = rect->findChild<QQuickRectangle*>("cloud"); + QVERIFY(cloud); + QTest::qWait(1000); + QVERIFY(cloud->x() > qreal(0)); +} + +//QTBUG-12805 +void tst_qquickanimations::nonTransitionBug() +{ + //tests that the animation values from the previous transition are properly cleared + //in the case where an animation in the transition doesn't match anything (but previously did) + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("nonTransitionBug.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QQuickRectangle *mover = rect->findChild<QQuickRectangle*>("mover"); + + mover->setX(100); + QCOMPARE(mover->x(), qreal(100)); + + rectPrivate->setState("left"); + QTRY_COMPARE(mover->x(), qreal(0)); + + mover->setX(100); + QCOMPARE(mover->x(), qreal(100)); + + //make sure we don't try to animate back to 0 + rectPrivate->setState("free"); + QTest::qWait(300); + QCOMPARE(mover->x(), qreal(100)); +} + +//QTBUG-14042 +void tst_qquickanimations::registrationBug() +{ + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("registrationBug.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect != 0); + QTRY_COMPARE(rect->property("value"), QVariant(int(100))); +} + +void tst_qquickanimations::doubleRegistrationBug() +{ + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("doubleRegistrationBug.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect != 0); + + QQuickAbstractAnimation *anim = rect->findChild<QQuickAbstractAnimation*>("animation"); + QVERIFY(anim != 0); + QTRY_COMPARE(anim->qtAnimation()->state(), QAbstractAnimationJob::Stopped); +} + +//QTBUG-16736 +void tst_qquickanimations::alwaysRunToEndRestartBug() +{ + QQuickRectangle rect; + QQuickPropertyAnimation animation; + animation.setTargetObject(&rect); + animation.setProperty("x"); + animation.setTo(200); + animation.setDuration(1000); + animation.setLoops(-1); + animation.setAlwaysRunToEnd(true); + QVERIFY(animation.loops() == -1); + QVERIFY(animation.alwaysRunToEnd() == true); + animation.start(); + animation.stop(); + animation.start(); + animation.stop(); + QTest::qWait(500); + QVERIFY(rect.x() != qreal(200)); + QTest::qWait(800); + QTIMED_COMPARE(rect.x(), qreal(200)); + QCOMPARE(static_cast<QQuickAbstractAnimation*>(&animation)->qtAnimation()->state(), QAbstractAnimationJob::Stopped); +} + +//QTBUG-20227 +void tst_qquickanimations::transitionAssignmentBug() +{ + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("transitionAssignmentBug.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->property("nullObject").toBool(), false); +} + +//QTBUG-19080 +void tst_qquickanimations::pauseBindingBug() +{ + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("pauseBindingBug.qml")); + QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QVERIFY(rect != 0); + QQuickAbstractAnimation *anim = rect->findChild<QQuickAbstractAnimation*>("animation"); + QVERIFY(anim->qtAnimation()->state() == QAbstractAnimationJob::Paused); + + delete rect; +} + +//QTBUG-13598 +void tst_qquickanimations::pauseBug() +{ + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("pauseBug.qml")); + QQuickAbstractAnimation *anim = qobject_cast<QQuickAbstractAnimation*>(c.create()); + QVERIFY(anim != 0); + QCOMPARE(anim->qtAnimation()->state(), QAbstractAnimationJob::Paused); + QCOMPARE(anim->isPaused(), true); + QCOMPARE(anim->isRunning(), true); + + delete anim; +} + +//QTBUG-23092 +void tst_qquickanimations::loopingBug() +{ + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl("looping.qml")); + QObject *obj = c.create(); + + QQuickAbstractAnimation *anim = obj->findChild<QQuickAbstractAnimation*>(); + QVERIFY(anim != 0); + QCOMPARE(anim->qtAnimation()->totalDuration(), 300); + QCOMPARE(anim->isRunning(), true); + QTRY_COMPARE(static_cast<QAnimationGroupJob*>(anim->qtAnimation())->firstChild()->currentLoop(), 2); + QTRY_COMPARE(anim->isRunning(), false); + + QQuickRectangle *rect = obj->findChild<QQuickRectangle*>(); + QVERIFY(rect != 0); + QCOMPARE(rect->rotation(), qreal(90)); + + delete obj; +} + +QTEST_MAIN(tst_qquickanimations) + +#include "tst_qquickanimations.moc" |