2
* Copyright 2013 Canonical Ltd.
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.
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.
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/>.
20
import "../../../Components"
21
import Ubuntu.Components.ListItems 0.1 as ListItem
22
import Ubuntu.Components 0.1
23
import Unity.Test 0.1 as UT
32
ListElement { name: "Parrot"; size: "Small" }
33
ListElement { name: "Guinea pig"; size: "Small" }
34
ListElement { name: "Mouse"; size: "Small" }
35
ListElement { name: "Sparrow"; size: "Small" }
36
ListElement { name: "Dog"; size: "Medium" }
37
ListElement { name: "Cat"; size: "Medium" }
38
ListElement { name: "Dolphin"; size: "Medium" }
39
ListElement { name: "Seal"; size: "Medium" }
40
ListElement { name: "Elephant"; size: "Large" }
41
ListElement { name: "Blue whale"; size: "Large" }
42
ListElement { name: "Rhino"; size: "Large" }
43
ListElement { name: "Ostrich"; size: "Large" }
44
ListElement { name: "Sperm whale"; size: "Large" }
45
ListElement { name: "Giraffe"; size: "Large" }
46
ListElement { name: "Parrot"; size: "Small" }
47
ListElement { name: "Guinea pig"; size: "Small" }
48
ListElement { name: "Mouse"; size: "Small" }
49
ListElement { name: "Sparrow"; size: "Small" }
50
ListElement { name: "Dog"; size: "Medium" }
51
ListElement { name: "Cat"; size: "Medium" }
52
ListElement { name: "Dolphin"; size: "Medium" }
53
ListElement { name: "Seal"; size: "Medium" }
54
ListElement { name: "Elephant"; size: "Large" }
55
ListElement { name: "Blue whale"; size: "Large" }
56
ListElement { name: "Rhino"; size: "Large" }
57
ListElement { name: "Ostrich"; size: "Large" }
58
ListElement { name: "Sperm whale"; size: "Large" }
59
ListElement { name: "Giraffe"; size: "Large" }
60
ListElement { name: "Parrot"; size: "Small" }
61
ListElement { name: "Guinea pig"; size: "Small" }
62
ListElement { name: "Mouse"; size: "Small" }
63
ListElement { name: "Sparrow"; size: "Small" }
64
ListElement { name: "Dog"; size: "Medium" }
65
ListElement { name: "Cat"; size: "Medium" }
66
ListElement { name: "Dolphin"; size: "Medium" }
67
ListElement { name: "Seal"; size: "Medium" }
68
ListElement { name: "Elephant"; size: "Large" }
69
ListElement { name: "Blue whale"; size: "Large" }
70
ListElement { name: "Rhino"; size: "Large" }
71
ListElement { name: "Ostrich"; size: "Large" }
72
ListElement { name: "Sperm whale"; size: "Large" }
73
ListElement { name: "Giraffe"; size: "Large" }
74
ListElement { name: "Parrot"; size: "Small" }
75
ListElement { name: "Guinea pig"; size: "Small" }
76
ListElement { name: "Mouse"; size: "Small" }
77
ListElement { name: "Sparrow"; size: "Small" }
78
ListElement { name: "Dog"; size: "Medium" }
79
ListElement { name: "Cat"; size: "Medium" }
80
ListElement { name: "Dolphin"; size: "Medium" }
81
ListElement { name: "Seal"; size: "Medium" }
82
ListElement { name: "Elephant"; size: "Large" }
83
ListElement { name: "Blue whale"; size: "Large" }
84
ListElement { name: "Rhino"; size: "Large" }
85
ListElement { name: "Ostrich"; size: "Large" }
86
ListElement { name: "Sperm whale"; size: "Large" }
87
ListElement { name: "Giraffe"; size: "Large" }
90
ListViewWithPageHeader {
106
verticalAlignment: Text.AlignVCenter
110
sectionProperty: "size"
111
sectionDelegate: Rectangle {
113
left: (parent) ? parent.left : undefined
114
right: (parent) ? parent.right : undefined
117
color: "lightsteelblue"
123
verticalAlignment: Text.AlignVCenter
127
pageHeader: PageHeader {
141
name: "ListViewWithPageHeader"
144
readonly property real xPos: listView.width / 2
145
readonly property real headerHeight: pageHeader.height
147
/**************************** Helper functions ****************************/
148
function listViewFirstSectionHeaderYPosition() {
149
return Math.round(listView.pageHeader.mapToItem(listView).y); //round as using floats
152
function firstSectionHeaderYPosition() {
153
return Math.round(listView.view.children[0].mapToItem(listView).y);
157
listView.positionAtBeginning();
158
// wait for list position to reset
159
tryCompareFunction(listViewFirstSectionHeaderYPosition, 0);
160
tryCompare(listView.view.contentY, 0);
163
// these functions are hand-crafted to move the Flickable down/up one pixel
164
function swipeDown1Pixel(item) {
165
mousePress(item, xPos, 15);
166
mouseMove(item, xPos, 14, 100);
167
mouseMove(item, xPos, 10, 100);
168
mouseMove(item, xPos, 6, 100);
169
mouseMove(item, xPos, 3, 100);
170
mouseMove(item, xPos, 1, 100);
171
mouseMove(item, xPos, 0, 100);
172
mouseRelease(item, xPos, 0);
175
function swipeUp1Pixel(item) {
176
mousePress(item, xPos, 0);
177
mouseMove(item, xPos, 1, 100);
178
mouseMove(item, xPos, 5, 100);
179
mouseMove(item, xPos, 9, 100);
180
mouseMove(item, xPos, 12, 100);
181
mouseMove(item, xPos, 14, 100);
182
mouseMove(item, xPos, 15, 100);
183
mouseRelease(item, xPos, 15);
186
/******************************* Test cases *******************************/
188
/* Check the initial positions of components are correct */
189
function test_initialState() {
190
compare(listViewFirstSectionHeaderYPosition(), 0);
191
compare(listView.view.contentY, 0);
193
// Check that the section delegate is positioned underneath the header
194
// First section delegate is the first child of the view
195
tryCompareFunction(firstSectionHeaderYPosition, headerHeight);
198
/* Check the header moves up one pixel when the view is moved up by one pixel */
199
function test_headerPositionAfterDownMoveByOnePixel() {
200
swipeDown1Pixel(listView)
202
tryCompareFunction(listViewFirstSectionHeaderYPosition, -1);
203
tryCompareFunction(firstSectionHeaderYPosition, headerHeight - 1);
204
tryCompare(listView.view.contentY, -1);
207
/* Check the header position is y=0 when view moved up and then down by one pixel */
208
function test_headerPositionAfterDownAndThenUpMoveByOne() {
209
swipeDown1Pixel(listView)
211
tryCompareFunction(listViewFirstSectionHeaderYPosition, -1);
212
tryCompare(listView.view.contentY, -1);
214
// these operations move the Flickabe up one pixel
215
swipeUp1Pixel(listView);
217
tryCompare(listView.view.contentY, 0);
218
// tryCompareFunction(listViewFirstSectionHeaderYPosition, 0) //FIXME - this fails due to bug in LVWPH
219
tryCompareFunction(firstSectionHeaderYPosition, headerHeight)
222
/* Check after a big flick the header is moved off-screen, with the header bottom
223
placed just above the view */
224
function test_headerPositionAfterDownMove() {
225
// move the Flickabe up to hide header
226
listView.flick(0, -10000);
228
// wait for flick to finish
229
tryCompare(listView.moving, false);
231
tryCompareFunction(listViewFirstSectionHeaderYPosition, -headerHeight);
234
/* Check when header off-screen, moving down the view by one pixel moves the header
236
function test_hiddenHeaderPositionAfterUpMoveByOnePixel() {
237
// move the Flickabe up to hide header
238
listView.flick(0, -10000);
240
// wait for flick to fully hide header
241
tryCompareFunction(listViewFirstSectionHeaderYPosition, -headerHeight);
243
swipeUp1Pixel(listView);
245
tryCompareFunction( function() {
246
return Math.floor( listViewFirstSectionHeaderYPosition() ); // need to round to make test more robust
247
}, -headerHeight + 1);
250
/* Check if up swipe causes list to bounces at the bottom, header stays hidden */
251
function test_upSwipeCausingBounceKeepsHeaderHidden() {
252
// move list to the bottom (will bounce)
253
listView.flick(0, -1000000);
255
// wait for bounce to complete
256
tryCompare(listView.moving, false);
257
tryCompare(listView.view.atYEnd, true);
259
tryCompareFunction(listViewFirstSectionHeaderYPosition, -headerHeight);
262
/* Check if up swipe causes list to bounces at the bottom, header stays hidden */
263
function test_downSwipeCausingBounceKeepsHeaderVisible() {
264
// move list to the bottom (will bounce)
265
listView.flick(0, -1000000);
267
// wait for bounce to complete
268
tryCompare(listView.moving, false);
269
tryCompare(listView.view.atYBeginning, true);
271
tryCompareFunction(listViewFirstSectionHeaderYPosition, 0);
274
/* Check if list at top is pulled down further, that the list contents move but the
275
header remains at the top of the view */
276
function test_topDragOverBoundsKeepsHeaderVisible() {
277
// drag list up - but don't release yet
282
100, true, false, 0.2);
284
// wait for gesture to occur
285
tryCompareFunction(function() { return listView.view.contentY < 20; }, true);
286
tryCompareFunction(listViewFirstSectionHeaderYPosition, 0);
288
mouseRelease(listView, xPos, 400);
290
// ensure list moving to recover from over-bound drag keeps header unchanged
291
tryCompare(listView.view.contentY, 0);
292
tryCompareFunction(listViewFirstSectionHeaderYPosition, 0);
295
/* Check if list at top is pulled down further, that the list contents move but the
296
header remains at the top of the view */
297
function test_bottomDragOverBoundsKeepsHeaderHidden() {
298
// move list to the bottom (will bounce)
299
listView.flick(0, -1000000);
301
// wait for bounce to complete
302
tryCompare(listView.moving, false);
303
tryCompare(listView.view.atYEnd, true);
305
// drag list up but don't release
310
-listView.height, true, false);
312
tryCompareFunction(listViewFirstSectionHeaderYPosition, -headerHeight);
314
mouseRelease(listView, xPos, -listView.height);
315
// wait for list to reset position
316
tryCompare(listView.moving, false);
317
tryCompare(listView.view.atYEnd, true);
319
// ensure list moving to recover from over-bound drag keeps header unchanged
320
tryCompareFunction(listViewFirstSectionHeaderYPosition, -headerHeight);
323
/* Check positionAtBeginning() works resets list and header position */
324
function test_positionAtBeginning() {
325
// move the Flickabe up to hide header
326
listView.flick(0, -10000);
328
// wait for gesture to complete
329
tryCompare(listView.moving, false);
331
listView.positionAtBeginning();
332
tryCompareFunction(listViewFirstSectionHeaderYPosition, 0);
333
tryCompare(listView.view.contentY, 0);
336
/* Check showHeader forces header to appear but list position remains unchanged */
337
function test_showHeader() {
338
// move the Flickabe up to hide header
339
listView.flick(0, -10000);
341
// wait for gesture to complete
342
tryCompare(listView.moving, false);
344
var listContentY = listView.view.contentY;
346
listView.showHeader();
347
tryCompareFunction(listViewFirstSectionHeaderYPosition, 0);
348
tryCompare(listView.view.contentY, listContentY);