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 | |
29 | //TESTED_COMPONENT=src/location |
30 | |
31 | #include <QTest> |
32 | #include <QMetaType> |
33 | #include <QSignalSpy> |
34 | #include <QDebug> |
35 | #include <QTimer> |
36 | |
37 | #include <limits.h> |
38 | |
39 | #include <qnumeric.h> |
40 | #include <QtPositioning/qgeopositioninfosource.h> |
41 | #include <QtPositioning/qgeopositioninfo.h> |
42 | |
43 | #include "testqgeopositioninfosource_p.h" |
44 | #include "../utils/qlocationtestutils_p.h" |
45 | |
46 | Q_DECLARE_METATYPE(QGeoPositionInfoSource::PositioningMethod) |
47 | Q_DECLARE_METATYPE(QGeoPositionInfoSource::PositioningMethods) |
48 | |
49 | #define MAX_WAITING_TIME 50000 |
50 | |
51 | // Must provide a valid source, unless testing the source |
52 | // returned by QGeoPositionInfoSource::createDefaultSource() on a system |
53 | // that has no default source |
54 | #define CHECK_SOURCE_VALID { \ |
55 | if (!m_source) { \ |
56 | if (m_testingDefaultSource && QGeoPositionInfoSource::createDefaultSource(0) == 0) \ |
57 | QSKIP("No default position source on this system"); \ |
58 | else \ |
59 | QFAIL("createTestSource() must return a valid source!"); \ |
60 | } \ |
61 | } |
62 | |
63 | class MyPositionSource : public QGeoPositionInfoSource |
64 | { |
65 | Q_OBJECT |
66 | public: |
67 | MyPositionSource(QObject *parent = 0) |
68 | : QGeoPositionInfoSource(parent) { |
69 | } |
70 | |
71 | QGeoPositionInfo lastKnownPosition(bool /*fromSatellitePositioningMethodsOnly = false*/) const { |
72 | return QGeoPositionInfo(); |
73 | } |
74 | |
75 | void setSupportedPositioningMethods(PositioningMethods methods) { |
76 | m_methods = methods; |
77 | } |
78 | |
79 | virtual PositioningMethods supportedPositioningMethods() const { |
80 | return m_methods; |
81 | } |
82 | virtual int minimumUpdateInterval() const { |
83 | return 0; |
84 | } |
85 | |
86 | virtual void startUpdates() {} |
87 | virtual void stopUpdates() {} |
88 | |
89 | virtual void requestUpdate(int) {} |
90 | |
91 | Error error() const { return QGeoPositionInfoSource::NoError; } |
92 | |
93 | private: |
94 | PositioningMethods m_methods; |
95 | }; |
96 | |
97 | class DefaultSourceTest : public TestQGeoPositionInfoSource |
98 | { |
99 | Q_OBJECT |
100 | protected: |
101 | QGeoPositionInfoSource *createTestSource() { |
102 | return QGeoPositionInfoSource::createSource(QStringLiteral("test.source" ), parent: 0); |
103 | } |
104 | }; |
105 | |
106 | |
107 | TestQGeoPositionInfoSource::TestQGeoPositionInfoSource(QObject *parent) |
108 | : QObject(parent) |
109 | { |
110 | m_testingDefaultSource = false; |
111 | #if QT_CONFIG(library) |
112 | /* |
113 | * Set custom path since CI doesn't install test plugins |
114 | */ |
115 | #ifdef Q_OS_WIN |
116 | QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + |
117 | QStringLiteral("/../../../../plugins" )); |
118 | #else |
119 | QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() |
120 | + QStringLiteral("/../../../plugins" )); |
121 | #endif |
122 | #endif |
123 | } |
124 | |
125 | TestQGeoPositionInfoSource *TestQGeoPositionInfoSource::createDefaultSourceTest() |
126 | { |
127 | DefaultSourceTest *test = new DefaultSourceTest; |
128 | test->m_testingDefaultSource = true; |
129 | return test; |
130 | } |
131 | |
132 | void TestQGeoPositionInfoSource::test_slot1() |
133 | { |
134 | } |
135 | |
136 | void TestQGeoPositionInfoSource::test_slot2() |
137 | { |
138 | m_testSlot2Called = true; |
139 | } |
140 | |
141 | void TestQGeoPositionInfoSource::base_initTestCase() |
142 | { |
143 | |
144 | } |
145 | |
146 | void TestQGeoPositionInfoSource::base_init() |
147 | { |
148 | m_source = createTestSource(); |
149 | m_testSlot2Called = false; |
150 | } |
151 | |
152 | void TestQGeoPositionInfoSource::base_cleanup() |
153 | { |
154 | delete m_source; |
155 | m_source = 0; |
156 | } |
157 | |
158 | void TestQGeoPositionInfoSource::base_cleanupTestCase() |
159 | { |
160 | } |
161 | |
162 | void TestQGeoPositionInfoSource::initTestCase() |
163 | { |
164 | base_initTestCase(); |
165 | } |
166 | |
167 | void TestQGeoPositionInfoSource::init() |
168 | { |
169 | base_init(); |
170 | } |
171 | |
172 | void TestQGeoPositionInfoSource::cleanup() |
173 | { |
174 | base_cleanup(); |
175 | } |
176 | |
177 | void TestQGeoPositionInfoSource::cleanupTestCase() |
178 | { |
179 | base_cleanupTestCase(); |
180 | } |
181 | |
182 | // TC_ID_3_x_1 |
183 | void TestQGeoPositionInfoSource::constructor_withParent() |
184 | { |
185 | QObject *parent = new QObject(); |
186 | new MyPositionSource(parent); |
187 | delete parent; |
188 | } |
189 | |
190 | // TC_ID_3_x_2 |
191 | void TestQGeoPositionInfoSource::constructor_noParent() |
192 | { |
193 | MyPositionSource *obj = new MyPositionSource(); |
194 | delete obj; |
195 | } |
196 | |
197 | void TestQGeoPositionInfoSource::updateInterval() |
198 | { |
199 | MyPositionSource s; |
200 | QCOMPARE(s.updateInterval(), 0); |
201 | } |
202 | |
203 | void TestQGeoPositionInfoSource::setPreferredPositioningMethods() |
204 | { |
205 | QFETCH(QGeoPositionInfoSource::PositioningMethod, supported); |
206 | QFETCH(QGeoPositionInfoSource::PositioningMethod, preferred); |
207 | QFETCH(QGeoPositionInfoSource::PositioningMethod, resulting); |
208 | |
209 | MyPositionSource s; |
210 | s.setSupportedPositioningMethods(supported); |
211 | s.setPreferredPositioningMethods(preferred); |
212 | QCOMPARE(s.preferredPositioningMethods(), resulting); |
213 | } |
214 | |
215 | void TestQGeoPositionInfoSource::setPreferredPositioningMethods_data() |
216 | { |
217 | QTest::addColumn<QGeoPositionInfoSource::PositioningMethod>(name: "supported" ); |
218 | QTest::addColumn<QGeoPositionInfoSource::PositioningMethod>(name: "preferred" ); |
219 | QTest::addColumn<QGeoPositionInfoSource::PositioningMethod>(name: "resulting" ); |
220 | |
221 | QTest::newRow(dataTag: "Sat supported, Sat preferred" ) |
222 | << QGeoPositionInfoSource::SatellitePositioningMethods |
223 | << QGeoPositionInfoSource::SatellitePositioningMethods |
224 | << QGeoPositionInfoSource::SatellitePositioningMethods; |
225 | QTest::newRow(dataTag: "Sat supported, Non-Sat preferred" ) |
226 | << QGeoPositionInfoSource::SatellitePositioningMethods |
227 | << QGeoPositionInfoSource::NonSatellitePositioningMethods |
228 | << QGeoPositionInfoSource::SatellitePositioningMethods; |
229 | QTest::newRow(dataTag: "Sat supported, All preferred" ) |
230 | << QGeoPositionInfoSource::SatellitePositioningMethods |
231 | << QGeoPositionInfoSource::AllPositioningMethods |
232 | << QGeoPositionInfoSource::SatellitePositioningMethods; |
233 | |
234 | QTest::newRow(dataTag: "Non-Sat supported, Sat preferred" ) |
235 | << QGeoPositionInfoSource::NonSatellitePositioningMethods |
236 | << QGeoPositionInfoSource::SatellitePositioningMethods |
237 | << QGeoPositionInfoSource::NonSatellitePositioningMethods; |
238 | QTest::newRow(dataTag: "Non-Sat supported, Non-Sat preferred" ) |
239 | << QGeoPositionInfoSource::NonSatellitePositioningMethods |
240 | << QGeoPositionInfoSource::NonSatellitePositioningMethods |
241 | << QGeoPositionInfoSource::NonSatellitePositioningMethods; |
242 | QTest::newRow(dataTag: "Non-Sat supported, All preferred" ) |
243 | << QGeoPositionInfoSource::NonSatellitePositioningMethods |
244 | << QGeoPositionInfoSource::AllPositioningMethods |
245 | << QGeoPositionInfoSource::NonSatellitePositioningMethods; |
246 | |
247 | QTest::newRow(dataTag: "All supported, Sat preferred" ) |
248 | << QGeoPositionInfoSource::AllPositioningMethods |
249 | << QGeoPositionInfoSource::SatellitePositioningMethods |
250 | << QGeoPositionInfoSource::SatellitePositioningMethods; |
251 | QTest::newRow(dataTag: "All supported, Non-Sat preferred" ) |
252 | << QGeoPositionInfoSource::AllPositioningMethods |
253 | << QGeoPositionInfoSource::NonSatellitePositioningMethods |
254 | << QGeoPositionInfoSource::NonSatellitePositioningMethods; |
255 | QTest::newRow(dataTag: "All supported, All preferred" ) |
256 | << QGeoPositionInfoSource::AllPositioningMethods |
257 | << QGeoPositionInfoSource::AllPositioningMethods |
258 | << QGeoPositionInfoSource::AllPositioningMethods; |
259 | } |
260 | |
261 | void TestQGeoPositionInfoSource::preferredPositioningMethods() |
262 | { |
263 | MyPositionSource s; |
264 | QCOMPARE(s.preferredPositioningMethods(), 0); |
265 | } |
266 | |
267 | //TC_ID_3_x_1 : Create a position source with the given parent that reads from the system's default |
268 | // sources of location data |
269 | void TestQGeoPositionInfoSource::createDefaultSource() |
270 | { |
271 | QObject *parent = new QObject; |
272 | |
273 | QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(parent); |
274 | // now all platforms have the dummy plugin at least |
275 | QVERIFY(source != 0); |
276 | delete parent; |
277 | } |
278 | |
279 | void TestQGeoPositionInfoSource::setUpdateInterval() |
280 | { |
281 | CHECK_SOURCE_VALID; |
282 | |
283 | QFETCH(int, interval); |
284 | QFETCH(int, expectedInterval); |
285 | |
286 | m_source->setUpdateInterval(interval); |
287 | QCOMPARE(m_source->updateInterval(), expectedInterval); |
288 | } |
289 | |
290 | void TestQGeoPositionInfoSource::setUpdateInterval_data() |
291 | { |
292 | QTest::addColumn<int>(name: "interval" ); |
293 | QTest::addColumn<int>(name: "expectedInterval" ); |
294 | QGeoPositionInfoSource *source = createTestSource(); |
295 | int minUpdateInterval = source ? source->minimumUpdateInterval() : -1; |
296 | if (source) |
297 | delete source; |
298 | |
299 | QTest::newRow(dataTag: "0" ) << 0 << 0; |
300 | |
301 | if (minUpdateInterval > -1) { |
302 | QTest::newRow(dataTag: "INT_MIN" ) << INT_MIN << minUpdateInterval; |
303 | QTest::newRow(dataTag: "-1" ) << -1 << minUpdateInterval; |
304 | } |
305 | |
306 | if (minUpdateInterval > 0) { |
307 | QTest::newRow(dataTag: "more than minInterval" ) << minUpdateInterval + 1 << minUpdateInterval + 1; |
308 | QTest::newRow(dataTag: "equal to minInterval" ) << minUpdateInterval << minUpdateInterval; |
309 | } |
310 | |
311 | if (minUpdateInterval > 1) { |
312 | QTest::newRow(dataTag: "less then minInterval" ) << minUpdateInterval - 1 << minUpdateInterval; |
313 | QTest::newRow(dataTag: "in btw zero and minInterval" ) << 1 << minUpdateInterval; |
314 | } |
315 | } |
316 | |
317 | void TestQGeoPositionInfoSource::lastKnownPosition() |
318 | { |
319 | CHECK_SOURCE_VALID; |
320 | QFETCH(QGeoPositionInfoSource::PositioningMethod, positioningMethod); |
321 | QFETCH(bool, lastKnownPositionArgument); |
322 | |
323 | if ((m_source->supportedPositioningMethods() & positioningMethod) == 0) |
324 | QSKIP("Not a supported positioning method for this position source" ); |
325 | |
326 | m_source->setPreferredPositioningMethods(positioningMethod); |
327 | |
328 | QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
329 | QSignalSpy timeout(m_source, SIGNAL(updateTimeout())); |
330 | int time_out = 7000; |
331 | m_source->setUpdateInterval(time_out); |
332 | m_source->startUpdates(); |
333 | |
334 | // Use QEventLoop instead of qWait() to ensure we stop as soon as a |
335 | // position is emitted (otherwise the lastKnownPosition() may have |
336 | // changed by the time it is checked) |
337 | QEventLoop loop; |
338 | QTimer timer; |
339 | //simulated CI tests will quickly return -> real GPS tests take 2 minutes for satellite systems |
340 | //use a 5 min timeout |
341 | timer.setInterval(300000); |
342 | connect(sender: m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), |
343 | receiver: &loop, SLOT(quit())); |
344 | connect(sender: &timer, SIGNAL(timeout()), receiver: &loop, SLOT(quit())); |
345 | timer.start(); |
346 | loop.exec(); |
347 | |
348 | QVERIFY((spy.count() > 0) && (timeout.count() == 0)); |
349 | |
350 | QList<QVariant> list = spy.takeFirst(); |
351 | QGeoPositionInfo info = list.at(i: 0).value<QGeoPositionInfo>(); |
352 | QGeoPositionInfo lastPositioninfo = m_source->lastKnownPosition(fromSatellitePositioningMethodsOnly: lastKnownPositionArgument); |
353 | |
354 | // lastPositioninfo is only gauranteed to be valid in all cases when only using satelite |
355 | // positioning methods or when lastKnownPositionArgument is false |
356 | if (!lastKnownPositionArgument || |
357 | positioningMethod == QGeoPositionInfoSource::SatellitePositioningMethods) { |
358 | QVERIFY(lastPositioninfo.isValid()); |
359 | } |
360 | |
361 | if (lastPositioninfo.isValid()) { |
362 | QCOMPARE(info.coordinate(), lastPositioninfo.coordinate()); |
363 | // On some CI machines the above evenloop code is not sufficient as positionUpdated |
364 | // still fires causing last know position and last update to be out of sync. |
365 | // To accommodate we check that the time stamps are no more than 1s apart |
366 | // ideally they should be the same |
367 | // doesn't work: QCOMPARE(info.timestamp(), lastPositioninfo.timestamp()); |
368 | const qint64 diff = qAbs(t: info.timestamp().msecsTo(lastPositioninfo.timestamp())); |
369 | QCOMPARE(diff < 1000, true); |
370 | |
371 | QCOMPARE(info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy), |
372 | lastPositioninfo.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)); |
373 | |
374 | if (info.hasAttribute(attribute: QGeoPositionInfo::HorizontalAccuracy)) { |
375 | bool isNaN1 = qIsNaN(d: info.attribute(attribute: QGeoPositionInfo::HorizontalAccuracy)); |
376 | bool isNaN2 = qIsNaN(d: lastPositioninfo.attribute(attribute: QGeoPositionInfo::HorizontalAccuracy)); |
377 | QCOMPARE(isNaN1, isNaN2); |
378 | if (!isNaN1) { |
379 | QCOMPARE(qFuzzyCompare(info.attribute(QGeoPositionInfo::HorizontalAccuracy), |
380 | lastPositioninfo.attribute(QGeoPositionInfo::HorizontalAccuracy)), true); |
381 | } |
382 | } |
383 | |
384 | QCOMPARE(info.hasAttribute(QGeoPositionInfo::VerticalAccuracy), |
385 | lastPositioninfo.hasAttribute(QGeoPositionInfo::VerticalAccuracy)); |
386 | |
387 | if (info.hasAttribute(attribute: QGeoPositionInfo::VerticalAccuracy)) { |
388 | bool isNaN1 = qIsNaN(d: info.attribute(attribute: QGeoPositionInfo::VerticalAccuracy)); |
389 | bool isNaN2 = qIsNaN(d: lastPositioninfo.attribute(attribute: QGeoPositionInfo::VerticalAccuracy)); |
390 | QCOMPARE(isNaN1, isNaN2); |
391 | if (!isNaN1) { |
392 | QCOMPARE(qFuzzyCompare(info.attribute(QGeoPositionInfo::VerticalAccuracy), |
393 | lastPositioninfo.attribute(QGeoPositionInfo::VerticalAccuracy)), true); |
394 | } |
395 | } |
396 | } |
397 | |
398 | m_source->stopUpdates(); |
399 | } |
400 | |
401 | void TestQGeoPositionInfoSource::lastKnownPosition_data() |
402 | { |
403 | QTest::addColumn<QGeoPositionInfoSource::PositioningMethod>(name: "positioningMethod" ); |
404 | QTest::addColumn<bool>(name: "lastKnownPositionArgument" ); |
405 | |
406 | // no good way to determine on MeeGo what are supported. If we ask for all or non-satellites, we |
407 | // typically get geoclue-example provider, which is not suitable for this test. |
408 | QTest::newRow(dataTag: "all - false" ) << QGeoPositionInfoSource::AllPositioningMethods << false; |
409 | QTest::newRow(dataTag: "all - true" ) << QGeoPositionInfoSource::AllPositioningMethods << true; |
410 | QTest::newRow(dataTag: "satellite - false" ) << QGeoPositionInfoSource::SatellitePositioningMethods << false; |
411 | QTest::newRow(dataTag: "satellite - true" ) << QGeoPositionInfoSource::SatellitePositioningMethods << true; |
412 | } |
413 | |
414 | void TestQGeoPositionInfoSource::minimumUpdateInterval() |
415 | { |
416 | CHECK_SOURCE_VALID; |
417 | |
418 | QVERIFY(m_source->minimumUpdateInterval() > 0); |
419 | } |
420 | |
421 | //TC_ID_3_x_1 |
422 | void TestQGeoPositionInfoSource::startUpdates_testIntervals() |
423 | { |
424 | CHECK_SOURCE_VALID; |
425 | QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
426 | QSignalSpy timeout(m_source, SIGNAL(updateTimeout())); |
427 | m_source->setUpdateInterval(7000); |
428 | int interval = m_source->updateInterval(); |
429 | |
430 | m_source->startUpdates(); |
431 | |
432 | QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 9500); |
433 | for (int i = 0; i < 6; i++) { |
434 | QTRY_VERIFY_WITH_TIMEOUT((spy.count() == 1) && (timeout.count() == 0), (interval*2)); |
435 | spy.clear(); |
436 | } |
437 | |
438 | m_source->stopUpdates(); |
439 | } |
440 | |
441 | |
442 | void TestQGeoPositionInfoSource::startUpdates_testIntervalChangesWhileRunning() |
443 | { |
444 | // There are two ways of dealing with an interval change, and we have left it system dependent. |
445 | // The interval can be changed will running or after the next update. |
446 | // WinCE uses the first method, S60 uses the second method. |
447 | |
448 | // The minimum interval on the symbian emulator is 5000 msecs, which is why the times in |
449 | // this test are as high as they are. |
450 | |
451 | CHECK_SOURCE_VALID; |
452 | |
453 | QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
454 | QSignalSpy timeout(m_source, SIGNAL(updateTimeout())); |
455 | m_source->setUpdateInterval(0); |
456 | m_source->startUpdates(); |
457 | m_source->setUpdateInterval(0); |
458 | |
459 | QTRY_VERIFY_WITH_TIMEOUT(spy.count() > 0, 7000); |
460 | QCOMPARE(timeout.count(), 0); |
461 | spy.clear(); |
462 | |
463 | m_source->setUpdateInterval(5000); |
464 | |
465 | QTRY_VERIFY_WITH_TIMEOUT((spy.count() == 2) && (timeout.count() == 0), 15000); |
466 | spy.clear(); |
467 | |
468 | m_source->setUpdateInterval(10000); |
469 | |
470 | QTRY_VERIFY_WITH_TIMEOUT((spy.count() == 2) && (timeout.count() == 0), 30000); |
471 | spy.clear(); |
472 | |
473 | m_source->setUpdateInterval(5000); |
474 | |
475 | QTRY_VERIFY_WITH_TIMEOUT((spy.count() == 2) && (timeout.count() == 0), 15000); |
476 | spy.clear(); |
477 | |
478 | m_source->setUpdateInterval(5000); |
479 | |
480 | QTRY_VERIFY_WITH_TIMEOUT((spy.count() == 2) && (timeout.count() == 0), 15000); |
481 | spy.clear(); |
482 | |
483 | m_source->setUpdateInterval(0); |
484 | |
485 | QTRY_VERIFY_WITH_TIMEOUT((spy.count() > 0) && (timeout.count() == 0), 7000); |
486 | spy.clear(); |
487 | |
488 | m_source->setUpdateInterval(0); |
489 | |
490 | QTRY_VERIFY_WITH_TIMEOUT((spy.count() > 0) && (timeout.count() == 0), 7000); |
491 | spy.clear(); |
492 | |
493 | m_source->stopUpdates(); |
494 | } |
495 | |
496 | //TC_ID_3_x_2 |
497 | void TestQGeoPositionInfoSource::startUpdates_testDefaultInterval() |
498 | { |
499 | CHECK_SOURCE_VALID; |
500 | |
501 | QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
502 | QSignalSpy timeout(m_source, SIGNAL(updateTimeout())); |
503 | m_source->startUpdates(); |
504 | for (int i = 0; i < 3; i++) { |
505 | |
506 | QTRY_VERIFY_WITH_TIMEOUT((spy.count() > 0) && (timeout.count() == 0), 7000); |
507 | spy.clear(); |
508 | } |
509 | m_source->stopUpdates(); |
510 | } |
511 | |
512 | //TC_ID_3_x_3 |
513 | void TestQGeoPositionInfoSource::startUpdates_testZeroInterval() |
514 | { |
515 | CHECK_SOURCE_VALID; |
516 | |
517 | QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
518 | QSignalSpy timeout(m_source, SIGNAL(updateTimeout())); |
519 | m_source->setUpdateInterval(0); |
520 | m_source->startUpdates(); |
521 | for (int i = 0; i < 3; i++) { |
522 | QTRY_VERIFY_WITH_TIMEOUT((spy.count() > 0) && (timeout.count() == 0), 7000); |
523 | spy.clear(); |
524 | } |
525 | m_source->stopUpdates(); |
526 | } |
527 | |
528 | void TestQGeoPositionInfoSource::startUpdates_moreThanOnce() |
529 | { |
530 | CHECK_SOURCE_VALID; |
531 | |
532 | QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
533 | QSignalSpy timeout(m_source, SIGNAL(updateTimeout())); |
534 | m_source->setUpdateInterval(0); |
535 | m_source->startUpdates(); |
536 | |
537 | m_source->startUpdates(); // check there is no crash |
538 | |
539 | QTRY_VERIFY_WITH_TIMEOUT((spy.count() > 0) && (timeout.count() == 0), 7000); |
540 | |
541 | m_source->startUpdates(); // check there is no crash |
542 | |
543 | m_source->stopUpdates(); |
544 | } |
545 | |
546 | //TC_ID_3_x_1 |
547 | void TestQGeoPositionInfoSource::stopUpdates() |
548 | { |
549 | CHECK_SOURCE_VALID; |
550 | |
551 | QSignalSpy spy(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
552 | QSignalSpy timeout(m_source, SIGNAL(updateTimeout())); |
553 | m_source->setUpdateInterval(7000); |
554 | m_source->startUpdates(); |
555 | for (int i = 0; i < 2; i++) { |
556 | QTRY_VERIFY_WITH_TIMEOUT((spy.count() > 0) && (timeout.count() == 0), 9500); |
557 | spy.clear(); |
558 | } |
559 | m_source->stopUpdates(); |
560 | QTest::qWait(ms: 9500); |
561 | QCOMPARE(spy.count(), 0); |
562 | spy.clear(); |
563 | |
564 | m_source->setUpdateInterval(0); |
565 | m_source->startUpdates(); |
566 | m_source->stopUpdates(); |
567 | QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 0, 9500); |
568 | } |
569 | |
570 | //TC_ID_3_x_2 |
571 | void TestQGeoPositionInfoSource::stopUpdates_withoutStart() |
572 | { |
573 | CHECK_SOURCE_VALID; |
574 | m_source->stopUpdates(); // check there is no crash |
575 | } |
576 | |
577 | void TestQGeoPositionInfoSource::requestUpdate() |
578 | { |
579 | CHECK_SOURCE_VALID; |
580 | QFETCH(int, timeout); |
581 | QSignalSpy spy(m_source, SIGNAL(updateTimeout())); |
582 | m_source->requestUpdate(timeout); |
583 | QTRY_COMPARE(spy.count(), 1); |
584 | } |
585 | |
586 | void TestQGeoPositionInfoSource::requestUpdate_data() |
587 | { |
588 | QTest::addColumn<int>(name: "timeout" ); |
589 | QTest::newRow(dataTag: "less than zero" ) << -1; //TC_ID_3_x_7 |
590 | } |
591 | |
592 | // TC_ID_3_x_1 : Create position source and call requestUpdate with valid timeout value |
593 | void TestQGeoPositionInfoSource::requestUpdate_validTimeout() |
594 | { |
595 | CHECK_SOURCE_VALID; |
596 | |
597 | QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
598 | QSignalSpy spyTimeout(m_source, SIGNAL(updateTimeout())); |
599 | |
600 | m_source->requestUpdate(timeout: 7000); |
601 | |
602 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), 7000); |
603 | } |
604 | |
605 | void TestQGeoPositionInfoSource::requestUpdate_defaultTimeout() |
606 | { |
607 | CHECK_SOURCE_VALID; |
608 | QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
609 | QSignalSpy spyTimeout(m_source, SIGNAL(updateTimeout())); |
610 | |
611 | m_source->requestUpdate(timeout: 0); |
612 | |
613 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), 7000); |
614 | } |
615 | |
616 | // TC_ID_3_x_2 : Create position source and call requestUpdate with a timeout less than |
617 | // minimumupdateInterval |
618 | void TestQGeoPositionInfoSource::requestUpdate_timeoutLessThanMinimumInterval() |
619 | { |
620 | CHECK_SOURCE_VALID; |
621 | |
622 | QSignalSpy spyTimeout(m_source, SIGNAL(updateTimeout())); |
623 | m_source->requestUpdate(timeout: 1); |
624 | |
625 | QTRY_COMPARE_WITH_TIMEOUT(spyTimeout.count(), 1, 1000); |
626 | } |
627 | |
628 | // TC_ID_3_x_3 : Call requestUpdate() with same value repeatedly |
629 | void TestQGeoPositionInfoSource::requestUpdate_repeatedCalls() |
630 | { |
631 | CHECK_SOURCE_VALID; |
632 | |
633 | QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
634 | QSignalSpy spyTimeout(m_source, SIGNAL(updateTimeout())); |
635 | |
636 | m_source->requestUpdate(timeout: 7000); |
637 | |
638 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), 7000); |
639 | spyUpdate.clear(); |
640 | m_source->requestUpdate(timeout: 7000); |
641 | |
642 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), 7000); |
643 | } |
644 | |
645 | void TestQGeoPositionInfoSource::requestUpdate_overlappingCalls() |
646 | { |
647 | CHECK_SOURCE_VALID; |
648 | |
649 | QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
650 | QSignalSpy spyTimeout(m_source, SIGNAL(updateTimeout())); |
651 | |
652 | m_source->requestUpdate(timeout: 7000); |
653 | m_source->requestUpdate(timeout: 7000); |
654 | |
655 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), 7000); |
656 | } |
657 | |
658 | //TC_ID_3_x_4 |
659 | void TestQGeoPositionInfoSource::requestUpdateAfterStartUpdates_ZeroInterval() |
660 | { |
661 | CHECK_SOURCE_VALID; |
662 | |
663 | QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
664 | QSignalSpy spyTimeout(m_source, SIGNAL(updateTimeout())); |
665 | |
666 | m_source->setUpdateInterval(0); |
667 | m_source->startUpdates(); |
668 | |
669 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), 7000); |
670 | spyUpdate.clear(); |
671 | |
672 | m_source->requestUpdate(timeout: 7000); |
673 | QTest::qWait(ms: 7000); |
674 | |
675 | QVERIFY((spyUpdate.count() > 0) && (spyTimeout.count() == 0)); |
676 | spyUpdate.clear(); |
677 | |
678 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), MAX_WAITING_TIME); |
679 | |
680 | m_source->stopUpdates(); |
681 | } |
682 | |
683 | void TestQGeoPositionInfoSource::requestUpdateAfterStartUpdates_SmallInterval() |
684 | { |
685 | CHECK_SOURCE_VALID; |
686 | |
687 | QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
688 | QSignalSpy spyTimeout(m_source, SIGNAL(updateTimeout())); |
689 | |
690 | m_source->setUpdateInterval(10000); |
691 | m_source->startUpdates(); |
692 | |
693 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() == 1) && (spyTimeout.count() == 0), 20000); |
694 | spyUpdate.clear(); |
695 | |
696 | m_source->requestUpdate(timeout: 7000); |
697 | |
698 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() == 1) && (spyTimeout.count() == 0), 7000); |
699 | spyUpdate.clear(); |
700 | |
701 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() == 1) && (spyTimeout.count() == 0), 20000); |
702 | |
703 | m_source->stopUpdates(); |
704 | } |
705 | |
706 | void TestQGeoPositionInfoSource::requestUpdateBeforeStartUpdates_ZeroInterval() |
707 | { |
708 | CHECK_SOURCE_VALID; |
709 | |
710 | QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
711 | QSignalSpy spyTimeout(m_source, SIGNAL(updateTimeout())); |
712 | |
713 | m_source->requestUpdate(timeout: 7000); |
714 | |
715 | m_source->setUpdateInterval(0); |
716 | m_source->startUpdates(); |
717 | |
718 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() >= 2) && (spyTimeout.count() == 0), 14000); |
719 | spyUpdate.clear(); |
720 | |
721 | QTest::qWait(ms: 7000); |
722 | |
723 | QCOMPARE(spyTimeout.count(), 0); |
724 | |
725 | m_source->stopUpdates(); |
726 | } |
727 | |
728 | void TestQGeoPositionInfoSource::requestUpdateBeforeStartUpdates_SmallInterval() |
729 | { |
730 | CHECK_SOURCE_VALID; |
731 | QSignalSpy spyUpdate(m_source, SIGNAL(positionUpdated(QGeoPositionInfo))); |
732 | QSignalSpy spyTimeout(m_source, SIGNAL(updateTimeout())); |
733 | |
734 | m_source->requestUpdate(timeout: 7000); |
735 | |
736 | m_source->setUpdateInterval(10000); |
737 | m_source->startUpdates(); |
738 | |
739 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), 7000); |
740 | spyUpdate.clear(); |
741 | |
742 | QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), 20000); |
743 | |
744 | m_source->stopUpdates(); |
745 | } |
746 | |
747 | void TestQGeoPositionInfoSource::removeSlotForRequestTimeout() |
748 | { |
749 | CHECK_SOURCE_VALID; |
750 | |
751 | bool i = connect(sender: m_source, SIGNAL(updateTimeout()), receiver: this, SLOT(test_slot1())); |
752 | QVERIFY(i == true); |
753 | i = connect(sender: m_source, SIGNAL(updateTimeout()), receiver: this, SLOT(test_slot2())); |
754 | QVERIFY(i == true); |
755 | i = disconnect(sender: m_source, SIGNAL(updateTimeout()), receiver: this, SLOT(test_slot1())); |
756 | QVERIFY(i == true); |
757 | |
758 | m_source->requestUpdate(timeout: -1); |
759 | QTRY_VERIFY_WITH_TIMEOUT((m_testSlot2Called == true), 1000); |
760 | } |
761 | |
762 | void TestQGeoPositionInfoSource::removeSlotForPositionUpdated() |
763 | { |
764 | CHECK_SOURCE_VALID; |
765 | |
766 | bool i = connect(sender: m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), receiver: this, SLOT(test_slot1())); |
767 | QVERIFY(i == true); |
768 | i = connect(sender: m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), receiver: this, SLOT(test_slot2())); |
769 | QVERIFY(i == true); |
770 | i = disconnect(sender: m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), receiver: this, SLOT(test_slot1())); |
771 | QVERIFY(i == true); |
772 | |
773 | m_source->requestUpdate(timeout: 7000); |
774 | |
775 | QTRY_VERIFY_WITH_TIMEOUT((m_testSlot2Called == true), 7000); |
776 | } |
777 | |
778 | #include "testqgeopositioninfosource.moc" |
779 | |