QQuickItemView/QQuickPathView: Fix creation of delegates
[qt:qtdeclarative.git] / tests / auto / qmltest / listview / tst_listview.qml
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 **   * Redistributions of source code must retain the above copyright
15 **     notice, this list of conditions and the following disclaimer.
16 **   * Redistributions in binary form must reproduce the above copyright
17 **     notice, this list of conditions and the following disclaimer in
18 **     the documentation and/or other materials provided with the
19 **     distribution.
20 **   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 **     of its contributors may be used to endorse or promote products derived
22 **     from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 import QtQuick 2.1
42 import QtTest 1.0
43
44 Item {
45     id: top
46
47     ListView {
48         id: emptylist
49         height: 20
50         width: 50
51     }
52
53     ListView {
54         id: viewmanyitems
55         model: manyitems
56         delegate: Text { text: model.name }
57     }
58
59     ListView {
60         id: modelchange
61         model: firstmodel
62         delegate: Text { text: model.name }
63     }
64
65     ListView {
66         id: modelalter
67         model: altermodel
68         delegate: Text { text: model.name }
69     }
70
71     ListView {
72         id: asyncLoaderCurrentIndexListView
73         width: 360
74         height: 360
75         model: asyncLoaderCurrentIndexListModel
76
77         currentIndex: 0
78
79         delegate: Loader {
80             width: asyncLoaderCurrentIndexListView.width
81             height: asyncLoaderCurrentIndexListView.height
82
83             source: component
84             asynchronous: true
85         }
86     }
87
88     ListView {
89         id: asyncListViewLoaderView
90         width: 360
91         height: 360
92         model: asyncListViewLoaderModel
93
94         currentIndex: 0
95
96         delegate: Loader {
97             width: asyncListViewLoaderView.width
98             height: asyncListViewLoaderView.height
99
100             source: component
101             asynchronous: true
102         }
103     }
104
105     ListView {
106         id: listViewDelegateModelAfterCreate
107         anchors.fill: parent
108         property int createdDelegates: 0
109     }
110
111     Component {
112         id: delegateModelAfterCreateComponent
113         Rectangle {
114             width: 140
115             height: 140
116             border.color: "black"
117             color: "red"
118             Component.onCompleted: listViewDelegateModelAfterCreate.createdDelegates++;
119         }
120     }
121
122     ListModel { id: emptymodel }
123     ListModel { id: manyitems }
124     ListModel { id: firstmodel; ListElement { name: "FirstModelElement0" } }
125     ListModel { id: secondmodel; ListElement { name: "SecondModelElement0" } ListElement { name: "SecondModelElement1" } }
126     ListModel { id: altermodel; ListElement { name: "AlterModelElement0" } ListElement { name: "AlterModelElement1" } }
127     ListModel {
128         id: asyncLoaderCurrentIndexListModel
129         ListElement { component: "data/asyncloadercurrentindex.qml" }
130         ListElement { component: "data/asyncloadercurrentindex.qml" }
131         ListElement { component: "data/asyncloadercurrentindex.qml" }
132         ListElement { component: "data/asyncloadercurrentindex.qml" }
133         ListElement { component: "data/asyncloadercurrentindex.qml" }
134         ListElement { component: "data/asyncloadercurrentindex.qml" }
135     }
136     ListModel {
137         id: asyncListViewLoaderModel
138         ListElement { component: "data/asynclistviewloader.qml" }
139         ListElement { component: "data/asynclistviewloader.qml" }
140         ListElement { component: "data/asynclistviewloader.qml" }
141         ListElement { component: "data/asynclistviewloader.qml" }
142         ListElement { component: "data/asynclistviewloader.qml" }
143     }
144
145     TestCase {
146         name: "ListView"
147         when: windowShown
148
149         function test_empty() {
150             compare(emptylist.count, 0)
151             emptylist.model = emptymodel;
152             compare(emptylist.count, 0)
153         }
154
155         function test_multipleitems_data() {
156             return [
157                 {
158                     tag: "10items",
159                     numitems: 10
160                 },
161                 {
162                     tag: "100items",
163                     numitems: 100
164                 },
165                 {
166                     tag: "10000items",
167                     numitems: 10000
168                 }
169             ]
170         }
171
172         function test_multipleitems(row) {
173             var i;
174             manyitems.clear();
175             compare(manyitems.count, 0)
176             for (i = 0; i < row.numitems; ++i) {
177                 manyitems.append({"name":"Item"+i})
178             }
179             compare(manyitems.count, row.numitems)
180             tryCompare(viewmanyitems, 'count', row.numitems)
181
182         }
183
184         function test_modelchange() {
185             tryCompare(modelchange, 'count', 1)
186             modelchange.currentIndex = 0;
187             compare(modelchange.currentItem.text, "FirstModelElement0")
188             modelchange.model = secondmodel;
189             tryCompare(modelchange, 'count', 2)
190             modelchange.currentIndex = 0;
191             compare(modelchange.currentItem.text, "SecondModelElement0")
192             modelchange.currentIndex = 1;
193             compare(modelchange.currentItem.text, "SecondModelElement1")
194         }
195
196         function test_modelaltered() {
197             tryCompare(modelalter, 'count', 2)
198             modelalter.currentIndex = 0;
199             compare(modelalter.currentItem.text, "AlterModelElement0")
200             modelalter.currentIndex = 1;
201             compare(modelalter.currentItem.text, "AlterModelElement1")
202             altermodel.append({"name":"AlterModelElement2"})
203             tryCompare(modelalter, 'count', 3)
204             modelalter.currentIndex = 0;
205             compare(modelalter.currentItem.text, "AlterModelElement0")
206             modelalter.currentIndex = 1;
207             compare(modelalter.currentItem.text, "AlterModelElement1")
208             modelalter.currentIndex = 2;
209             compare(modelalter.currentItem.text, "AlterModelElement2")
210             altermodel.insert(2,{"name":"AlterModelElement1.5"})
211             tryCompare(modelalter, 'count', 4)
212             modelalter.currentIndex = 0;
213             compare(modelalter.currentItem.text, "AlterModelElement0")
214             modelalter.currentIndex = 1;
215             compare(modelalter.currentItem.text, "AlterModelElement1")
216             modelalter.currentIndex = 2;
217             compare(modelalter.currentItem.text, "AlterModelElement1.5")
218             modelalter.currentIndex = 3;
219             compare(modelalter.currentItem.text, "AlterModelElement2")
220             altermodel.move(2,1,1);
221             tryCompare(modelalter, 'count', 4)
222             modelalter.currentIndex = 0;
223             compare(modelalter.currentItem.text, "AlterModelElement0")
224             modelalter.currentIndex = 1;
225             compare(modelalter.currentItem.text, "AlterModelElement1.5")
226             modelalter.currentIndex = 2;
227             compare(modelalter.currentItem.text, "AlterModelElement1")
228             modelalter.currentIndex = 3;
229             compare(modelalter.currentItem.text, "AlterModelElement2")
230             altermodel.remove(1,2)
231             tryCompare(modelalter, 'count', 2)
232             modelalter.currentIndex = 0;
233             compare(modelalter.currentItem.text, "AlterModelElement0")
234             modelalter.currentIndex = 1;
235             compare(modelalter.currentItem.text, "AlterModelElement2")
236             altermodel.set(1,{"name":"AlterModelElement1"})
237             modelalter.currentIndex = 0;
238             compare(modelalter.currentItem.text, "AlterModelElement0")
239             modelalter.currentIndex = 1;
240             compare(modelalter.currentItem.text, "AlterModelElement1")
241             altermodel.clear()
242             modelalter.forceLayout()
243             tryCompare(modelalter, 'count', 0)
244             compare(modelalter.currentItem, null)
245         }
246
247         function test_asyncLoaderCurrentIndexChange() {
248             for (var i = 0; i < 500; i++) {
249                 asyncLoaderCurrentIndexListView.currentIndex = 0;
250                 asyncLoaderCurrentIndexListView.currentIndex = 1;
251                 asyncLoaderCurrentIndexListView.currentIndex = 2;
252                 asyncLoaderCurrentIndexListView.currentIndex = 3;
253                 asyncLoaderCurrentIndexListView.currentIndex = 4;
254                 asyncLoaderCurrentIndexListView.currentIndex = 5;
255             }
256             wait(1000)
257         }
258
259         function test_asyncListViewLoader() {
260             for (var i = 0; i < 50; i++) {
261                 wait(10);
262                 asyncListViewLoaderView.currentIndex = 0;
263                 asyncListViewLoaderView.currentIndex = 1;
264                 asyncListViewLoaderView.currentIndex = 2;
265                 asyncListViewLoaderView.currentIndex = 3;
266                 asyncListViewLoaderView.currentIndex = 4;
267             }
268         }
269
270         function test_set_delegate_model_after_list_creation() {
271             listViewDelegateModelAfterCreate.delegate = delegateModelAfterCreateComponent;
272             listViewDelegateModelAfterCreate.model = 40;
273             verify(listViewDelegateModelAfterCreate.createdDelegates > 0);
274         }
275     }
276 }