1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29import QtQuick 2.0
30import QtTest 1.0
31import QtPositioning 5.2
32import QtLocation 5.5
33
34Item {
35    id: testCase
36
37    property variant coordinate1: QtPositioning.coordinate(1, 1)
38    property variant coordinate2: QtPositioning.coordinate(2, 2)
39    property variant coordinate3: QtPositioning.coordinate(80, 80)
40
41    property variant emptyCircle: QtPositioning.circle()
42    property variant circle1: QtPositioning.circle(coordinate1, 200000)
43
44    SignalSpy { id: circleChangedSpy; target: testCase; signalName: "emptyCircleChanged" }
45
46    TestCase {
47        name: "Bounding circle"
48        function test_circle_defaults_and_setters() {
49            circleChangedSpy.clear();
50            compare (emptyCircle.radius, -1)
51            compare (circle1.radius, 200000)
52
53            emptyCircle.radius = 200
54            compare(circleChangedSpy.count, 1);
55            emptyCircle.radius = 200;
56            compare(circleChangedSpy.count, 1);
57
58            emptyCircle.center = coordinate1;
59            compare(circleChangedSpy.count, 2);
60            emptyCircle.center = coordinate1
61            compare(circleChangedSpy.count, 2);
62            emptyCircle.center = coordinate2
63            compare(circleChangedSpy.count, 3);
64
65            emptyCircle.center = coordinate1
66            emptyCircle.radius = 200000
67
68            compare(emptyCircle.contains(coordinate1), true);
69            compare(emptyCircle.contains(coordinate2), true);
70            compare(emptyCircle.contains(coordinate3), false);
71        }
72    }
73
74    property variant trace1 : [     QtPositioning.coordinate(43.773175, 11.255386),
75                                    QtPositioning.coordinate(43.773546 , 11.255372) ]
76    property variant trace2 : [     QtPositioning.coordinate(43.773175, 11.255386),
77                                    QtPositioning.coordinate(43.773546 , 11.255372),
78                                    QtPositioning.coordinate(43.77453 , 11.255734)]
79
80
81    // coordinate unit square
82    property variant bl: QtPositioning.coordinate(0, 0)
83    property variant tl: QtPositioning.coordinate(1, 0)
84    property variant tr: QtPositioning.coordinate(1, 1)
85    property variant br: QtPositioning.coordinate(0, 1)
86    property variant ntr: QtPositioning.coordinate(3, 3)
87
88    property variant invalid: QtPositioning.coordinate(100, 190)
89    property variant inside: QtPositioning.coordinate(0.5, 0.5)
90    property variant outside: QtPositioning.coordinate(2, 2)
91
92    property variant box: QtPositioning.rectangle(tl, br)
93
94    property variant coordinates: [bl, tl, tr, br]
95    property variant coordinates2: [bl, tl, tr, br, ntr]
96    property variant coordinates3: [tr]
97    property variant coordinates4: [invalid]
98    property variant coordinates5: []
99
100    property variant listBox: QtPositioning.rectangle(coordinates)
101    property variant listBox2: QtPositioning.rectangle(coordinates2)
102    property variant listBox3: QtPositioning.rectangle(coordinates3)
103    property variant listBox4: QtPositioning.rectangle(coordinates4)
104    property variant listBox5: QtPositioning.rectangle(coordinates5)
105
106    property variant widthBox: QtPositioning.rectangle(inside, 1, 1);
107
108    // C++ auto test exists for basics of bounding box, testing here
109    // only added functionality
110    TestCase {
111        name: "Bounding box"
112        function test_box_defaults_and_setters() {
113            compare (box.bottomRight.longitude, br.longitude) // sanity
114            compare (box.contains(bl), true)
115            compare (box.contains(inside), true)
116            compare (box.contains(outside), false)
117            box.topRight = ntr
118            compare (box.contains(outside), true)
119
120            compare (listBox.isValid, true)
121            compare (listBox.contains(outside), false)
122            compare (listBox2.contains(outside), true)
123            compare (listBox3.isValid, true)
124            compare (listBox3.isEmpty, true)
125            compare (listBox4.isValid, false)
126            compare (listBox5.isValid, false)
127
128            compare (widthBox.contains(inside), true)
129            compare (widthBox.contains(outside), false)
130        }
131    }
132
133    TestCase {
134        name: "Shape"
135
136        function test_shape_comparison_data() {
137            return [
138                { tag: "invalid shape", shape1: QtPositioning.shape(), shape2: QtPositioning.shape(), result: true },
139                { tag: "box equal", shape1: box, shape2: QtPositioning.rectangle(tl, br), result: true },
140                { tag: "box not equal", shape1: box, shape2: QtPositioning.rectangle([inside, outside]), result: false },
141                { tag: "box invalid shape", rect1: box, shape2: QtPositioning.shape(), result: false },
142                { tag: "invalid rectangle", shape1: QtPositioning.rectangle(), shape2: QtPositioning.rectangle(), result: true },
143                { tag: "invalid rectangle2", shape1: QtPositioning.rectangle(), shape2: QtPositioning.shape(), result: false },
144                { tag: "circle1 equal", shape1: circle1, shape2: QtPositioning.circle(coordinate1, 200000), result: true },
145                { tag: "circle1 not equal", shape1: circle1, shape2: QtPositioning.circle(coordinate2, 2000), result: false },
146                { tag: "circle1 invalid shape", shape1: circle1, shape2: QtPositioning.shape(), result: false },
147                { tag: "invalid circle", shape1: QtPositioning.circle(), shape2: QtPositioning.circle(), result: true },
148                { tag: "invalid circle2", shape1: QtPositioning.circle(), shape2: QtPositioning.shape(), result: false }
149            ]
150        }
151
152        function test_shape_comparison(data) {
153            compare(data.shape1 === data.shape2, data.result)
154            compare(data.shape1 !== data.shape2, !data.result)
155            compare(data.shape1 == data.shape2, data.result)
156            compare(data.shape1 != data.shape2, !data.result)
157        }
158    }
159
160    TestCase {
161        name: "Conversions"
162
163        function test_shape_circle_conversions() {
164            var circle = QtPositioning.shapeToCircle(QtPositioning.shape())
165            verify(!circle.isValid)
166            circle = QtPositioning.shapeToCircle(QtPositioning.circle())
167            verify(!circle.isValid)
168            circle = QtPositioning.shapeToCircle(QtPositioning.circle(tl, 10000))
169            verify(circle.isValid)
170            compare(circle.center, tl)
171            compare(circle.radius, 10000)
172            circle = QtPositioning.shapeToCircle(QtPositioning.rectangle())
173            verify(!circle.isValid)
174            circle = QtPositioning.shapeToCircle(QtPositioning.rectangle(tl, br))
175            verify(!circle.isValid)
176            circle = QtPositioning.shapeToCircle(listBox)
177            verify(!circle.isValid)
178        }
179
180        function test_shape_rectangle_conversions() {
181            var rectangle = QtPositioning.shapeToRectangle(QtPositioning.shape())
182            verify(!rectangle.isValid)
183            rectangle = QtPositioning.shapeToRectangle(QtPositioning.circle())
184            verify(!rectangle.isValid)
185            rectangle = QtPositioning.shapeToRectangle(QtPositioning.circle(tl, 10000))
186            verify(!rectangle.isValid)
187            rectangle = QtPositioning.shapeToRectangle(QtPositioning.rectangle())
188            verify(!rectangle.isValid)
189            rectangle = QtPositioning.shapeToRectangle(QtPositioning.rectangle(tl, br))
190            verify(rectangle.isValid)
191            compare(rectangle.topLeft, tl)
192            compare(rectangle.bottomRight, br)
193            rectangle = QtPositioning.shapeToRectangle(listBox)
194            verify(rectangle.isValid)
195        }
196
197        function test_shape_path_conversions() {
198            var path = QtPositioning.shapeToPath(QtPositioning.shape())
199            verify(!path.isValid)
200            path = QtPositioning.shapeToPath(QtPositioning.circle())
201            verify(!path.isValid)
202            path = QtPositioning.shapeToPath(QtPositioning.circle(tl, 10000))
203            verify(!path.isValid)
204            path = QtPositioning.shapeToPath(QtPositioning.rectangle())
205            verify(!path.isValid)
206            path = QtPositioning.shapeToPath(QtPositioning.rectangle(tl, br))
207            verify(!path.isValid)
208
209            path = QtPositioning.shapeToPath(QtPositioning.path())
210            verify(!path.isValid)
211            path = QtPositioning.shapeToPath(QtPositioning.path(trace1, 1))
212            verify(path.isValid)
213            path = QtPositioning.shapeToPath(QtPositioning.path(trace2, 2))
214            verify(path.isValid)
215            verify(path !== QtPositioning.shapeToPath(QtPositioning.path(trace1, 1)))
216            compare(path, QtPositioning.shapeToPath(QtPositioning.path(trace2, 2)))
217        }
218
219        function test_shape_polygon_conversions() {
220            var polygon = QtPositioning.shapeToPolygon(QtPositioning.shape())
221            verify(!polygon.isValid)
222            polygon = QtPositioning.shapeToPolygon(QtPositioning.circle())
223            verify(!polygon.isValid)
224            polygon = QtPositioning.shapeToPolygon(QtPositioning.circle(tl, 10000))
225            verify(polygon.isValid) // fixed, polygon copy constructor can now initialize from a circle.
226            polygon = QtPositioning.shapeToPolygon(QtPositioning.rectangle())
227            verify(!polygon.isValid)
228            polygon = QtPositioning.shapeToPolygon(QtPositioning.rectangle(tl, br))
229            verify(polygon.isValid) // fixed, polygon copy constructor can now initialize from a rectangle.
230
231            polygon = QtPositioning.shapeToPolygon(QtPositioning.polygon())
232            verify(!polygon.isValid)
233            polygon = QtPositioning.shapeToPolygon(QtPositioning.polygon(trace1))
234            verify(!polygon.isValid) // polygon needs 3 coords at least
235            polygon = QtPositioning.shapeToPolygon(QtPositioning.polygon(trace2))
236            verify(polygon.isValid)
237            verify(polygon !== QtPositioning.shapeToPolygon(QtPositioning.polygon(trace1)))
238            compare(polygon, QtPositioning.shapeToPolygon(QtPositioning.polygon(trace2)))
239        }
240    }
241
242
243    MapPolyline {
244        id: mapPolyline
245        path: [
246                { latitude: -27, longitude: 153.0 },
247                { latitude: -27, longitude: 154.1 },
248                { latitude: -28, longitude: 153.5 },
249                { latitude: -29, longitude: 153.5 }
250            ]
251    }
252
253    MapPolyline {
254        id: mapPolylineGeopath
255    }
256
257    TestCase {
258        name: "MapPolyline path"
259        function test_path_operations() {
260            compare(mapPolyline.path[1].latitude, -27)
261            compare(mapPolyline.path[1].longitude, 154.1)
262            compare(mapPolyline.coordinateAt(1), QtPositioning.coordinate(-27, 154.1))
263            compare(mapPolyline.path.length, mapPolyline.pathLength())
264
265            mapPolyline.removeCoordinate(1);
266            compare(mapPolyline.path[1].latitude, -28)
267            compare(mapPolyline.path[1].longitude, 153.5)
268            compare(mapPolyline.coordinateAt(1), QtPositioning.coordinate(-28, 153.5))
269            compare(mapPolyline.path.length, mapPolyline.pathLength())
270
271            mapPolyline.addCoordinate(QtPositioning.coordinate(30, 153.1))
272            compare(mapPolyline.path[mapPolyline.path.length-1].latitude, 30)
273            compare(mapPolyline.path[mapPolyline.path.length-1].longitude, 153.1)
274            compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(30, 153.1)), true)
275            compare(mapPolyline.path.length, mapPolyline.pathLength())
276
277            mapPolyline.removeCoordinate(QtPositioning.coordinate(30, 153.1))
278            compare(mapPolyline.path[mapPolyline.path.length-1].latitude, -29)
279            compare(mapPolyline.path[mapPolyline.path.length-1].longitude, 153.5)
280            compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(30, 153.1)), false)
281            compare(mapPolyline.path.length, mapPolyline.pathLength())
282
283            mapPolyline.insertCoordinate(2, QtPositioning.coordinate(35, 153.1))
284            compare(mapPolyline.path[2].latitude, 35)
285            compare(mapPolyline.path[2].longitude, 153.1)
286            compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(35, 153.1)), true)
287            compare(mapPolyline.path.length, mapPolyline.pathLength())
288
289            mapPolyline.replaceCoordinate(2, QtPositioning.coordinate(45, 150.1))
290            compare(mapPolyline.path[2].latitude, 45)
291            compare(mapPolyline.path[2].longitude, 150.1)
292            compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(35, 153.1)), false)
293            compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(45, 150.1)), true)
294            compare(mapPolyline.path.length, mapPolyline.pathLength())
295
296            mapPolyline.insertCoordinate(2, QtPositioning.coordinate(35, 153.1))
297            compare(mapPolyline.coordinateAt(2).latitude, 35)
298            compare(mapPolyline.coordinateAt(2).longitude, 153.1)
299            compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(35, 153.1)), true)
300            compare(mapPolyline.path.length, mapPolyline.pathLength())
301        }
302    }
303
304    TestCase {
305        name: "GeoPath path"
306        function test_qgeopath_path_operations() {
307            var geopath = QtPositioning.path()
308
309            geopath.path = trace2
310            compare(geopath.path.length, trace2.length)
311
312            geopath.path = mapPolyline.path
313            compare(geopath.path.length, mapPolyline.pathLength())
314            compare(geopath.boundingGeoRectangle(), mapPolyline.geoShape.boundingGeoRectangle())
315
316            mapPolylineGeopath.geoShape = geopath
317            compare(mapPolylineGeopath.pathLength(), mapPolyline.pathLength())
318            compare(mapPolylineGeopath.geoShape.boundingGeoRectangle(), mapPolyline.geoShape.boundingGeoRectangle())
319
320            geopath.path = trace2
321            geopath.path[0].longitude = 11.0
322            compare(geopath.path.length, trace2.length)
323            compare(geopath.coordinateAt(0).latitude, trace2[0].latitude)
324            expectFail("", "Longitude comparison fails")
325            compare(geopath.coordinateAt(0).longitude, 11)
326        }
327    }
328
329    TestCase {
330        name: "GeoPolygon path"
331        function test_qgeopolygon_path_operations() {
332            var geopolygon = QtPositioning.polygon()
333
334            geopolygon.perimeter = trace2
335            compare(geopolygon.perimeter.length, trace2.length)
336
337            geopolygon.perimeter = mapPolyline.path
338            compare(geopolygon.perimeter.length, mapPolyline.pathLength())
339            compare(geopolygon.boundingGeoRectangle(), mapPolyline.geoShape.boundingGeoRectangle())
340
341            geopolygon.perimeter = trace2
342            compare(geopolygon.perimeter.length, trace2.length)
343            compare(geopolygon.coordinateAt(0).latitude, trace2[0].latitude)
344            compare(geopolygon.coordinateAt(0).longitude, trace2[0].longitude)
345        }
346    }
347}
348