on xenial help sign in
Add tests for LazyImage.
85be725Michał Sawicz
Components/LazyImage.qml+28−11
@@ -6,10 +6,10 @@ Item {
6
6
7 property url source
7 property url source
8
8
9− property real initialWidth: units.gu(5)
9+ property real initialWidth: sourceSize.width > -1 ? sourceSize.width : units.gu(10)
10− property real initialHeight: units.gu(5)
10+ property real initialHeight: sourceSize.height > -1 ? sourceSize.height : units.gu(10)
11+ property size sourceSize
11
12
12− property alias sourceSize: image.sourceSize
13 property alias fillMode: image.fillMode
13 property alias fillMode: image.fillMode
14 property alias asynchronous: image.asynchronous
14 property alias asynchronous: image.asynchronous
15 property alias cache: image.cache
15 property alias cache: image.cache
@@ -29,12 +29,13 @@ Item {
29
29
30 UbuntuShape {
30 UbuntuShape {
31 id: placeholder
31 id: placeholder
32− color: "#22000000"
32+ objectName: "placeholder"
33+ color: "#22FFFFFF"
33 anchors.fill: parent
34 anchors.fill: parent
35+ visible: opacity != 0
34
36
35 ActivityIndicator {
37 ActivityIndicator {
36 id: activity
38 id: activity
37− objectName: "activity"
38 anchors.centerIn: parent
39 anchors.centerIn: parent
39 opacity: 0
40 opacity: 0
40 visible: opacity != 0
41 visible: opacity != 0
@@ -63,14 +64,27 @@ Item {
63
64
64 image: Image {
65 image: Image {
65 id: image
66 id: image
67+ objectName: "image"
66
68
67 property url nextSource
69 property url nextSource
68
70
71+ width: {
72+ if (root.sourceSize.width > -1) return root.sourceSize.width;
73+ if (root.sourceSize.height > -1) return implicitWidth * root.sourceSize.height / implicitHeight
74+ return implicitWidth
75+ }
76+ height: {
77+ if (root.sourceSize.height > -1) return root.sourceSize.height;
78+ if (root.sourceSize.width > -1) return implicitHeight* root.sourceSize.width / implicitWidth
79+ return implicitHeight
80+ }
69− fillMode: Image.PreserveAspectFit
81+ fillMode: Image.PreserveAspectCrop
70 asynchronous: true
82 asynchronous: true
71 cache: false
83 cache: false
72 horizontalAlignment: Image.AlignHCenter
84 horizontalAlignment: Image.AlignHCenter
73 verticalAlignment: Image.AlignVCenter
85 verticalAlignment: Image.AlignVCenter
86+ sourceSize.width: root.sourceSize.width
87+ sourceSize.height: root.sourceSize.height
74 }
88 }
75 }
89 }
76
90
@@ -85,7 +99,6 @@ Item {
85 name: "loading"
99 name: "loading"
86 extend: "default"
100 extend: "default"
87 when: image.status === Image.Loading
101 when: image.status === Image.Loading
88− PropertyChanges { target: root; implicitWidth: root.initialWidth; implicitHeight: root.initialHeight }
89 PropertyChanges { target: activity; opacity: 1 }
102 PropertyChanges { target: activity; opacity: 1 }
90 },
103 },
91 State {
104 State {
@@ -93,7 +106,7 @@ Item {
93 when: image.status === Image.Ready && image.source != ""
106 when: image.status === Image.Ready && image.source != ""
94 PropertyChanges { target: root; implicitWidth: image.width; implicitHeight: image.height }
107 PropertyChanges { target: root; implicitWidth: image.width; implicitHeight: image.height }
95 PropertyChanges { target: shape; opacity: 1 }
108 PropertyChanges { target: shape; opacity: 1 }
96− PropertyChanges { target: placeholder; visible: false }
109+ PropertyChanges { target: placeholder; opacity: 0 }
97 },
110 },
98 State {
111 State {
99 name: "error"
112 name: "error"
@@ -106,24 +119,28 @@ Item {
106 transitions: [
119 transitions: [
107 Transition {
120 Transition {
108 to: "ready"
121 to: "ready"
122+ objectName: "readyTransition"
109 SequentialAnimation {
123 SequentialAnimation {
110 PropertyAction { target: shape; property: "visible" }
124 PropertyAction { target: shape; property: "visible" }
111 ParallelAnimation {
125 ParallelAnimation {
112 NumberAnimation { target: shape; property: "opacity"; easing.type: Easing.Linear }
126 NumberAnimation { target: shape; property: "opacity"; easing.type: Easing.Linear }
113 UbuntuNumberAnimation { target: root; properties: "implicitWidth,implicitHeight" }
127 UbuntuNumberAnimation { target: root; properties: "implicitWidth,implicitHeight" }
128+ NumberAnimation {
129+ targets: [placeholder, activity, errorImage]; property: "opacity";
130+ easing.type: Easing.Linear; duration: UbuntuAnimation.SnapDuration
131+ }
114 }
132 }
115− PropertyAction { target: placeholder; property: "visible" }
116 }
133 }
117 },
134 },
118
135
119 Transition {
136 Transition {
120 to: "*"
137 to: "*"
138+ objectName: "genericTransition"
121 SequentialAnimation {
139 SequentialAnimation {
122− PropertyAction { target: placeholder; property: "visible" }
123 ParallelAnimation {
140 ParallelAnimation {
124 NumberAnimation { target: shape; property: "opacity"; easing.type: Easing.Linear }
141 NumberAnimation { target: shape; property: "opacity"; easing.type: Easing.Linear }
125 NumberAnimation {
142 NumberAnimation {
126− targets: [activity, errorImage]; property: "opacity";
143+ targets: [placeholder, activity, errorImage]; property: "opacity";
127 easing.type: Easing.Linear; duration: UbuntuAnimation.SnapDuration
144 easing.type: Easing.Linear; duration: UbuntuAnimation.SnapDuration
128 }
145 }
129 UbuntuNumberAnimation { target: root; properties: "implicitWidth,implicitHeight" }
146 UbuntuNumberAnimation { target: root; properties: "implicitWidth,implicitHeight" }
tests/qmltests/CMakeLists.txt+1
@@ -31,6 +31,7 @@ add_manual_qml_test(Components DragHandle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugi
31add_qml_test(Components DraggingArea)
31add_qml_test(Components DraggingArea)
32add_qml_test(Components EdgeDemoOverlay)
32add_qml_test(Components EdgeDemoOverlay)
33add_qml_test(Components FilterGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
33add_qml_test(Components FilterGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
34+add_qml_test(Components LazyImage)
34add_qml_test(Components ResponsiveFlowView)
35add_qml_test(Components ResponsiveFlowView)
35add_qml_test(Components ResponsiveGridView)
36add_qml_test(Components ResponsiveGridView)
36add_qml_test(Components Revealer)
37add_qml_test(Components Revealer)
tests/qmltests/Components/tst_LazyImage.qmlnew file+154
@@ -0,0 +1,154 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtTest 1.0
19+import "../../../Components"
20+import Ubuntu.Components 0.1
21+import Unity.Test 0.1 as UT
22+import "tst_LazyImage"
23+
24+Rectangle {
25+ width: units.gu(120)
26+ height: units.gu(70)
27+
28+ Rectangle {
29+ id: baseRect
30+ anchors {
31+ fill: parent
32+ rightMargin: 2 * parent.width / 3
33+ }
34+
35+ color: "grey"
36+
37+ Column {
38+ anchors { fill: parent; margins: units.gu(5) }
39+
40+ Label {
41+ height: units.gu(4)
42+ text: "Unbound"
43+ color: "white"
44+ verticalAlignment: Text.AlignBottom
45+ }
46+
47+ LazyImage {
48+ id: lazy1
49+ }
50+
51+ Label {
52+ height: units.gu(4)
53+ text: "Width-bound"
54+ color: "white"
55+ verticalAlignment: Text.AlignBottom
56+ }
57+
58+ LazyImage {
59+ id: lazy2
60+ sourceSize.width: units.gu(30)
61+ }
62+
63+ Label {
64+ height: units.gu(4)
65+ text: "Height-bound"
66+ color: "white"
67+ verticalAlignment: Text.AlignBottom
68+ }
69+
70+ LazyImage {
71+ id: lazy3
72+ sourceSize.height: units.gu(10)
73+ }
74+ }
75+ }
76+
77+ Rectangle {
78+ id: controlsRect
79+ anchors {
80+ fill: parent
81+ leftMargin: parent.width / 3
82+ }
83+
84+ color: "lightgrey"
85+
86+ Column {
87+ id: controls
88+ spacing: units.gu(1)
89+
90+ anchors { fill: parent; margins: units.gu(3) }
91+
92+ ImageControls { id: controls1; image: lazy1 }
93+ ImageControls { id: controls2; image: lazy2 }
94+ ImageControls { id: controls3; image: lazy3 }
95+ }
96+ }
97+
98+ UT.UnityTestCase {
99+ name: "Stage"
100+ when: windowShown
101+
102+ function cleanup() {
103+ controls1.blank();
104+ tryCompare(lazy1, "width", units.gu(10));
105+ controls2.blank();
106+ tryCompare(lazy2, "height", units.gu(10));
107+ controls3.blank();
108+ tryCompare(lazy3, "width", units.gu(10));
109+ }
110+
111+ function test_lazyimage_data() {
112+ return [
113+ {tag: "Unbound Blank", image: lazy1, func: controls1.blank, width: units.gu(10), height: units.gu(10), placeholder: true},
114+ {tag: "Unbound Wide", image: lazy1, func: controls1.wide, transition: "readyTransition", width: 160, height: 80},
115+ {tag: "Unbound Square", image: lazy1, func: controls1.square, transition: "readyTransition", width: 160, height: 160},
116+ {tag: "Unbound Portrait", image: lazy1, func: controls1.portrait, transition: "readyTransition", width: 80, height: 160},
117+ {tag: "Unbound Bad path", image: lazy1, func: controls1.badpath, transition: "genericTransition", width: units.gu(10), height: units.gu(10), placeholder: true, error: true},
118+ {tag: "Width-bound Blank", image: lazy2, func: controls2.blank, width: units.gu(30), height: units.gu(10), placeholder: true},
119+ {tag: "Width-bound Wide", image: lazy2, func: controls2.wide, transition: "readyTransition", width: units.gu(30), height: units.gu(15)},
120+ {tag: "Width-bound Square", image: lazy2, func: controls2.square, transition: "readyTransition", width: units.gu(30), height: units.gu(30)},
121+ {tag: "Width-bound Portrait", image: lazy2, func: controls2.portrait, transition: "readyTransition", width: units.gu(30), height: units.gu(60)},
122+ {tag: "Width-bound Bad path", image: lazy2, func: controls2.badpath, transition: "genericTransition", width: units.gu(30), height: units.gu(10), placeholder: true, error: true},
123+ {tag: "Height-bound Blank", image: lazy3, func: controls3.blank, width: units.gu(10), height: units.gu(10), placeholder: true},
124+ {tag: "Height-bound Wide", image: lazy3, func: controls3.wide, transition: "readyTransition", width: units.gu(20), height: units.gu(10)},
125+ {tag: "Height-bound Square", image: lazy3, func: controls3.square, transition: "readyTransition", width: units.gu(10), height: units.gu(10)},
126+ {tag: "Height-bound Portrait", image: lazy3, func: controls3.portrait, transition: "readyTransition", width: units.gu(5), height: units.gu(10)},
127+ {tag: "Height-bound Bad path", image: lazy3, func: controls3.badpath, transition: "genericTransition", width: units.gu(10), height: units.gu(10), placeholder: true, error: true},
128+ ]
129+ }
130+
131+ function test_lazyimage(data) {
132+ data.func();
133+
134+ if (data.transition) {
135+ // wait for the transition to complete
136+ var transition = findInvisibleChild(data.image, data.transition);
137+ tryCompare(transition, "running", true);
138+ tryCompare(transition, "running", false);
139+ }
140+
141+ // check the dimensions
142+ compare(data.image.width, data.width);
143+ compare(data.image.height, data.height);
144+
145+ // check the placeholder
146+ var placeholder = findChild(data.image, "placeholder");
147+ compare(placeholder.visible, data.placeholder ? true : false);
148+
149+ // check the error image
150+ var error = findChild(data.image, "errorImage");
151+ compare(error.visible, data.error ? true : false);
152+ }
153+ }
154+}
tests/qmltests/Components/tst_LazyImage/ImageControls.qmlnew file+51
@@ -0,0 +1,51 @@
1+import QtQuick 2.0
2+import Ubuntu.Components 0.1
3+import "../../../../Components"
4+
5+Row {
6+ property LazyImage image
7+
8+ anchors { left: parent.left; right: parent.right }
9+ spacing: units.gu(1)
10+
11+ function blank() { blankButton.clicked() }
12+ function wide() { wideButton.clicked() }
13+ function square() { squareButton.clicked() }
14+ function portrait() { portraitButton.clicked() }
15+ function badpath() { badpathButton.clicked() }
16+
17+ Button {
18+ id: blankButton
19+ width: parent / 5
20+ text: "Blank"
21+ onClicked: image.source = ""
22+ }
23+
24+ Button {
25+ id: wideButton
26+ width: parent / 5
27+ text: "Wide"
28+ onClicked: image.source = "wide.png"
29+ }
30+
31+ Button {
32+ id: squareButton
33+ width: parent / 5
34+ text: "Square"
35+ onClicked: image.source = "square.png"
36+ }
37+
38+ Button {
39+ id: portraitButton
40+ width: parent / 5
41+ text: "Portrait"
42+ onClicked: image.source = "portrait.png"
43+ }
44+
45+ Button {
46+ id: badpathButton
47+ width: parent / 5
48+ text: "Bad path"
49+ onClicked: image.source = "bad/path"
50+ }
51+}
tests/qmltests/Components/tst_LazyImage/portrait.pngnew file

Binary file not shown.

tests/qmltests/Components/tst_LazyImage/square.pngnew file

Binary file not shown.

tests/qmltests/Components/tst_LazyImage/wide.pngnew file

Binary file not shown.