1b5d78ae15ee02d6f9ad8f02b2d2418c72dea98c
[situare] / tests / map / mapengine / testmapengine.cpp
1 /*
2     Situare - A location system for Facebook
3     Copyright (C) 2010  Ixonos Plc. Authors:
4
5         Sami Rämö - sami.ramo@ixonos.com
6
7     Situare is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     version 2 as published by the Free Software Foundation.
10
11     Situare is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with Situare; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
19     USA.
20 */
21
22 #include <QGraphicsScene>
23 #include <QGraphicsView>
24 #include <QtTest/QtTest>
25
26 #include "common.h"
27 #include "coordinates/scenecoordinate.h"
28 #include "map/mapcommon.h"
29 #include "map/maptile.h"
30
31 #include "map/mapengine.h"
32
33 const int ZOOM_LEVEL = 14;
34 const SceneCoordinate DEFAULT_TEST_SCENECOORDINATE = SceneCoordinate(12345, 54321);
35 const SceneCoordinate NEW_TEST_SCENECOORDINATE = SceneCoordinate(50000, 40000);
36 const int MAP_FETCH_DELAY = 1000;
37
38 class TestMapEngine: public QObject
39 {
40     Q_OBJECT
41
42 private slots:
43     void convertTileNumberToSceneCoordinate();
44     void convertTileNumberToSceneCoordinate_data();
45     void setLocationNewTilesCount();
46     void setLocationRemovedTilesCount();
47     void usingLastLocation();
48     void zoomInRemovedTilesCount();
49     void zoomOutRemovedTilesCount();
50
51 signals:
52     void setCenterPosition(SceneCoordinate); // a way to call a private slot
53 };
54
55 /**
56 * @brief Test converting tile numbers to scene coordinates
57 *
58 * Different zoom levels are also tested
59 */
60 void TestMapEngine::convertTileNumberToSceneCoordinate()
61 {
62     QFETCH(int, zoomLevel);
63     QFETCH(QPoint, tileNumber);
64     QFETCH(SceneCoordinate, expected);
65
66     SceneCoordinate result = MapTile::convertTileNumberToSceneCoordinate(zoomLevel, tileNumber);
67     QCOMPARE(result.x(), expected.x());
68     QCOMPARE(result.y(), expected.y());
69 }
70
71 void TestMapEngine::convertTileNumberToSceneCoordinate_data()
72 {
73     QTest::addColumn<int>("zoomLevel");
74     QTest::addColumn<QPoint>("tileNumber");
75     QTest::addColumn<SceneCoordinate>("expected");
76
77     QTest::newRow("data1") << 18 << QPoint(0, 0) << SceneCoordinate(0, 0);
78     QTest::newRow("data2") << 18 << QPoint(1, 2) << SceneCoordinate(256, 512);
79     QTest::newRow("data3") << 16 << QPoint(3, 4) << SceneCoordinate(3072, 4096);
80 }
81
82 void TestMapEngine::setLocationNewTilesCount()
83 {
84     MapEngine engine;
85     QGraphicsView view;
86     view.setScene(engine.scene());
87     engine.viewResized(QSize(800, 480));
88     connect(this, SIGNAL(setCenterPosition(SceneCoordinate)),
89             &engine, SLOT(setCenterPosition(SceneCoordinate)));
90
91     // set initial state for map engine
92     engine.setZoomLevel(ZOOM_LEVEL);
93     emit setCenterPosition(SceneCoordinate(0, 0));
94     QTest::qWait(MAP_FETCH_DELAY);
95
96     QSignalSpy fetchImageSpy(&engine, SIGNAL(fetchImage(int,int,int)));
97
98     // first test, target location in the scene is empty so all tiles should be downloaded
99     emit setCenterPosition(SceneCoordinate(1220*16, 1220*16));
100     QTest::qWait(MAP_FETCH_DELAY);
101     QCOMPARE(fetchImageSpy.count(), 5*4);
102     fetchImageSpy.clear();
103
104     // move one tile to east and south, only most right one column and most bottom one row tiles
105     // should be downloaded
106     emit setCenterPosition(SceneCoordinate((1220+OSM_TILE_SIZE_X)*16, (1220+OSM_TILE_SIZE_Y)*16));
107     QTest::qWait(MAP_FETCH_DELAY);
108     QCOMPARE(fetchImageSpy.count(), 4 + 4);
109     fetchImageSpy.clear();
110 }
111
112 void TestMapEngine::setLocationRemovedTilesCount()
113 {
114     MapEngine engine;
115     QGraphicsView view;
116     view.setScene(engine.scene());
117     engine.viewResized(QSize(800, 480));
118     connect(this, SIGNAL(setCenterPosition(SceneCoordinate)),
119             &engine, SLOT(setCenterPosition(SceneCoordinate)));
120
121     engine.setZoomLevel(OSM_MAX_ZOOM_LEVEL);
122
123     const int maxItemsCount = 40;
124
125     emit setCenterPosition(SceneCoordinate(1220*16, 1220*16));
126     QTest::qWait(MAP_FETCH_DELAY);
127     emit setCenterPosition(SceneCoordinate(2220*16, 2220*16));
128     QTest::qWait(MAP_FETCH_DELAY);
129     QVERIFY(engine.scene()->items().count() <= maxItemsCount);
130
131     emit setCenterPosition(SceneCoordinate(520*16, 2220*16));
132     QTest::qWait(MAP_FETCH_DELAY);
133     emit setCenterPosition(SceneCoordinate(2220*16, 520*16));
134     QTest::qWait(MAP_FETCH_DELAY);
135     QVERIFY(engine.scene()->items().count() <= maxItemsCount);
136 }
137
138 void TestMapEngine::zoomInRemovedTilesCount()
139 {
140     MapEngine engine;
141     QGraphicsView view;
142     view.setScene(engine.scene());
143     engine.viewResized(QSize(800, 480));
144     connect(this, SIGNAL(setCenterPosition(SceneCoordinate)),
145             &engine, SLOT(setCenterPosition(SceneCoordinate)));
146
147     engine.setZoomLevel(OSM_MAX_ZOOM_LEVEL);
148
149     const int maxItemsCount = 40;
150
151     emit setCenterPosition(SceneCoordinate(1220*16, 1220*16));
152     QTest::qWait(MAP_FETCH_DELAY);
153     QTest::qWait(MAP_FETCH_DELAY);
154     QVERIFY(engine.scene()->items().count() <= maxItemsCount);
155
156     emit setCenterPosition(SceneCoordinate(520*16, 2220*16));
157     QTest::qWait(MAP_FETCH_DELAY);
158     emit setCenterPosition(SceneCoordinate(2220*16, 520*16));
159     QTest::qWait(MAP_FETCH_DELAY);
160     QVERIFY(engine.scene()->items().count() <= maxItemsCount);
161 }
162
163 void TestMapEngine::zoomOutRemovedTilesCount()
164 {
165     MapEngine engine;
166     QGraphicsView view;
167     view.setScene(engine.scene());
168     engine.viewResized(QSize(800, 480));
169     connect(this, SIGNAL(setCenterPosition(SceneCoordinate)),
170             &engine, SLOT(setCenterPosition(SceneCoordinate)));
171
172     engine.setZoomLevel(OSM_MAX_ZOOM_LEVEL);
173
174     const int maxItemsCount = 40;
175
176     emit setCenterPosition(SceneCoordinate(1220*16, 1220.23*16));
177     QTest::qWait(MAP_FETCH_DELAY);
178     emit setCenterPosition(SceneCoordinate(2220*16, 2220.23*16));
179     QTest::qWait(MAP_FETCH_DELAY);
180     QVERIFY(engine.scene()->items().count() <= maxItemsCount);
181
182     emit setCenterPosition(SceneCoordinate(520*16, 2220*16));
183     QTest::qWait(MAP_FETCH_DELAY);
184     emit setCenterPosition(SceneCoordinate(2220*16, 520*16));
185     QTest::qWait(MAP_FETCH_DELAY);
186     QVERIFY(engine.scene()->items().count() <= maxItemsCount);
187 }
188
189 void TestMapEngine::usingLastLocation()
190 {
191     // Create mapengine and start monitoring zoomLevelChanged-signal
192     MapEngine *mapengine = new MapEngine;
193     QGraphicsView view;
194     view.setScene(mapengine->scene());
195     QSignalSpy mapEngineSpy(mapengine, SIGNAL(zoomLevelChanged(int)));
196     connect(this, SIGNAL(setCenterPosition(SceneCoordinate)),
197             mapengine, SLOT(setCenterPosition(SceneCoordinate)));
198     QVERIFY (mapEngineSpy.isValid());
199     QCOMPARE (mapEngineSpy.count(), 0);
200
201     // Write new zoomlevel and location to settings
202     QSettings settings(DIRECTORY_NAME, FILE_NAME);
203     settings.setValue(MAP_LAST_ZOOMLEVEL, ZOOM_LEVEL);
204     settings.setValue(MAP_LAST_POSITION,
205                       QVariant::fromValue(GeoCoordinate(DEFAULT_TEST_SCENECOORDINATE)));
206
207     // Call mapengines init() and verify that signal will be send
208     mapengine->init();
209     QCOMPARE (mapEngineSpy.count(), 1);
210
211     // Remove zoomlevel and location from settings, call init() again and check that
212     // signals are sent again
213     settings.remove(MAP_LAST_ZOOMLEVEL);
214     settings.remove(MAP_LAST_POSITION);
215     mapengine->init();
216     QCOMPARE(mapEngineSpy.count(), 2);
217
218     // Check parameters of sended signals
219     QList<QVariant> parameters = mapEngineSpy.takeFirst();
220     QVERIFY(parameters.at(0).toInt() == ZOOM_LEVEL);
221
222     // Call set location with know parameter to get location changed
223     // Store new location and zoomlevel to settings
224     emit setCenterPosition(NEW_TEST_SCENECOORDINATE);
225     delete mapengine;
226
227     // Read settings and verify that zoomlevel is correct
228     GeoCoordinate location =
229         settings.value(MAP_LAST_POSITION, ERROR_VALUE_NOT_FOUND_ON_SETTINGS).value<GeoCoordinate>();
230     QCOMPARE(location.latitude(), GeoCoordinate(NEW_TEST_SCENECOORDINATE).latitude());
231     QCOMPARE(location.longitude(), GeoCoordinate(NEW_TEST_SCENECOORDINATE).longitude());
232 }
233
234 QTEST_MAIN(TestMapEngine)
235 #include "testmapengine.moc"