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:
MyPositionSource(QObject * parent=0)67     MyPositionSource(QObject *parent = 0)
68             : QGeoPositionInfoSource(parent) {
69     }
70 
lastKnownPosition(bool) const71     QGeoPositionInfo lastKnownPosition(bool /*fromSatellitePositioningMethodsOnly = false*/) const {
72         return QGeoPositionInfo();
73     }
74 
setSupportedPositioningMethods(PositioningMethods methods)75     void setSupportedPositioningMethods(PositioningMethods methods) {
76         m_methods = methods;
77     }
78 
supportedPositioningMethods() const79     virtual PositioningMethods supportedPositioningMethods() const {
80         return m_methods;
81     }
minimumUpdateInterval() const82     virtual int minimumUpdateInterval() const {
83         return 0;
84     }
85 
startUpdates()86     virtual void startUpdates() {}
stopUpdates()87     virtual void stopUpdates() {}
88 
requestUpdate(int)89     virtual void requestUpdate(int) {}
90 
error() const91     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:
createTestSource()101     QGeoPositionInfoSource *createTestSource() {
102         return QGeoPositionInfoSource::createSource(QStringLiteral("test.source"), 0);
103     }
104 };
105 
106 
TestQGeoPositionInfoSource(QObject * parent)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 
createDefaultSourceTest()125 TestQGeoPositionInfoSource *TestQGeoPositionInfoSource::createDefaultSourceTest()
126 {
127     DefaultSourceTest *test = new DefaultSourceTest;
128     test->m_testingDefaultSource = true;
129     return test;
130 }
131 
test_slot1()132 void TestQGeoPositionInfoSource::test_slot1()
133 {
134 }
135 
test_slot2()136 void TestQGeoPositionInfoSource::test_slot2()
137 {
138     m_testSlot2Called = true;
139 }
140 
base_initTestCase()141 void TestQGeoPositionInfoSource::base_initTestCase()
142 {
143 
144 }
145 
base_init()146 void TestQGeoPositionInfoSource::base_init()
147 {
148     m_source = createTestSource();
149     m_testSlot2Called = false;
150 }
151 
base_cleanup()152 void TestQGeoPositionInfoSource::base_cleanup()
153 {
154     delete m_source;
155     m_source = 0;
156 }
157 
base_cleanupTestCase()158 void TestQGeoPositionInfoSource::base_cleanupTestCase()
159 {
160 }
161 
initTestCase()162 void TestQGeoPositionInfoSource::initTestCase()
163 {
164     base_initTestCase();
165 }
166 
init()167 void TestQGeoPositionInfoSource::init()
168 {
169     base_init();
170 }
171 
cleanup()172 void TestQGeoPositionInfoSource::cleanup()
173 {
174     base_cleanup();
175 }
176 
cleanupTestCase()177 void TestQGeoPositionInfoSource::cleanupTestCase()
178 {
179     base_cleanupTestCase();
180 }
181 
182 // TC_ID_3_x_1
constructor_withParent()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
constructor_noParent()191 void TestQGeoPositionInfoSource::constructor_noParent()
192 {
193     MyPositionSource *obj = new MyPositionSource();
194     delete obj;
195 }
196 
updateInterval()197 void TestQGeoPositionInfoSource::updateInterval()
198 {
199     MyPositionSource s;
200     QCOMPARE(s.updateInterval(), 0);
201 }
202 
setPreferredPositioningMethods()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 
setPreferredPositioningMethods_data()215 void TestQGeoPositionInfoSource::setPreferredPositioningMethods_data()
216 {
217     QTest::addColumn<QGeoPositionInfoSource::PositioningMethod>("supported");
218     QTest::addColumn<QGeoPositionInfoSource::PositioningMethod>("preferred");
219     QTest::addColumn<QGeoPositionInfoSource::PositioningMethod>("resulting");
220 
221     QTest::newRow("Sat supported, Sat preferred")
222         << QGeoPositionInfoSource::SatellitePositioningMethods
223         << QGeoPositionInfoSource::SatellitePositioningMethods
224         << QGeoPositionInfoSource::SatellitePositioningMethods;
225     QTest::newRow("Sat supported, Non-Sat preferred")
226         << QGeoPositionInfoSource::SatellitePositioningMethods
227         << QGeoPositionInfoSource::NonSatellitePositioningMethods
228         << QGeoPositionInfoSource::SatellitePositioningMethods;
229     QTest::newRow("Sat supported, All preferred")
230         << QGeoPositionInfoSource::SatellitePositioningMethods
231         << QGeoPositionInfoSource::AllPositioningMethods
232         << QGeoPositionInfoSource::SatellitePositioningMethods;
233 
234     QTest::newRow("Non-Sat supported, Sat preferred")
235         << QGeoPositionInfoSource::NonSatellitePositioningMethods
236         << QGeoPositionInfoSource::SatellitePositioningMethods
237         << QGeoPositionInfoSource::NonSatellitePositioningMethods;
238     QTest::newRow("Non-Sat supported, Non-Sat preferred")
239         << QGeoPositionInfoSource::NonSatellitePositioningMethods
240         << QGeoPositionInfoSource::NonSatellitePositioningMethods
241         << QGeoPositionInfoSource::NonSatellitePositioningMethods;
242     QTest::newRow("Non-Sat supported, All preferred")
243         << QGeoPositionInfoSource::NonSatellitePositioningMethods
244         << QGeoPositionInfoSource::AllPositioningMethods
245         << QGeoPositionInfoSource::NonSatellitePositioningMethods;
246 
247     QTest::newRow("All supported, Sat preferred")
248         << QGeoPositionInfoSource::AllPositioningMethods
249         << QGeoPositionInfoSource::SatellitePositioningMethods
250         << QGeoPositionInfoSource::SatellitePositioningMethods;
251     QTest::newRow("All supported, Non-Sat preferred")
252         << QGeoPositionInfoSource::AllPositioningMethods
253         << QGeoPositionInfoSource::NonSatellitePositioningMethods
254         << QGeoPositionInfoSource::NonSatellitePositioningMethods;
255     QTest::newRow("All supported, All preferred")
256         << QGeoPositionInfoSource::AllPositioningMethods
257         << QGeoPositionInfoSource::AllPositioningMethods
258         << QGeoPositionInfoSource::AllPositioningMethods;
259 }
260 
preferredPositioningMethods()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
createDefaultSource()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 
setUpdateInterval()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 
setUpdateInterval_data()290 void TestQGeoPositionInfoSource::setUpdateInterval_data()
291 {
292     QTest::addColumn<int>("interval");
293     QTest::addColumn<int>("expectedInterval");
294     QGeoPositionInfoSource *source = createTestSource();
295     int minUpdateInterval = source ? source->minimumUpdateInterval() : -1;
296     if (source)
297         delete source;
298 
299     QTest::newRow("0") << 0 << 0;
300 
301     if (minUpdateInterval > -1) {
302         QTest::newRow("INT_MIN") << INT_MIN << minUpdateInterval;
303         QTest::newRow("-1") << -1 << minUpdateInterval;
304     }
305 
306     if (minUpdateInterval > 0) {
307         QTest::newRow("more than minInterval") << minUpdateInterval + 1 << minUpdateInterval + 1;
308         QTest::newRow("equal to minInterval") << minUpdateInterval << minUpdateInterval;
309     }
310 
311     if (minUpdateInterval > 1) {
312         QTest::newRow("less then minInterval") << minUpdateInterval - 1 << minUpdateInterval;
313         QTest::newRow("in btw zero and minInterval") << 1 << minUpdateInterval;
314     }
315 }
316 
lastKnownPosition()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(m_source, SIGNAL(positionUpdated(QGeoPositionInfo)),
343             &loop, SLOT(quit()));
344     connect(&timer, SIGNAL(timeout()), &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(0).value<QGeoPositionInfo>();
352     QGeoPositionInfo lastPositioninfo = m_source->lastKnownPosition(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(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(QGeoPositionInfo::HorizontalAccuracy)) {
375             bool isNaN1 =  qIsNaN(info.attribute(QGeoPositionInfo::HorizontalAccuracy));
376             bool isNaN2 =  qIsNaN(lastPositioninfo.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(QGeoPositionInfo::VerticalAccuracy)) {
388             bool isNaN1 =  qIsNaN(info.attribute(QGeoPositionInfo::VerticalAccuracy));
389             bool isNaN2 =  qIsNaN(lastPositioninfo.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 
lastKnownPosition_data()401 void TestQGeoPositionInfoSource::lastKnownPosition_data()
402 {
403     QTest::addColumn<QGeoPositionInfoSource::PositioningMethod>("positioningMethod");
404     QTest::addColumn<bool>("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("all - false") << QGeoPositionInfoSource::AllPositioningMethods << false;
409     QTest::newRow("all - true") << QGeoPositionInfoSource::AllPositioningMethods << true;
410     QTest::newRow("satellite - false") << QGeoPositionInfoSource::SatellitePositioningMethods << false;
411     QTest::newRow("satellite - true") << QGeoPositionInfoSource::SatellitePositioningMethods << true;
412 }
413 
minimumUpdateInterval()414 void TestQGeoPositionInfoSource::minimumUpdateInterval()
415 {
416     CHECK_SOURCE_VALID;
417 
418     QVERIFY(m_source->minimumUpdateInterval() > 0);
419 }
420 
421 //TC_ID_3_x_1
startUpdates_testIntervals()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 
startUpdates_testIntervalChangesWhileRunning()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
startUpdates_testDefaultInterval()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
startUpdates_testZeroInterval()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 
startUpdates_moreThanOnce()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
stopUpdates()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(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
stopUpdates_withoutStart()571 void TestQGeoPositionInfoSource::stopUpdates_withoutStart()
572 {
573     CHECK_SOURCE_VALID;
574     m_source->stopUpdates(); // check there is no crash
575 }
576 
requestUpdate()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 
requestUpdate_data()586 void TestQGeoPositionInfoSource::requestUpdate_data()
587 {
588     QTest::addColumn<int>("timeout");
589     QTest::newRow("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
requestUpdate_validTimeout()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(7000);
601 
602     QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), 7000);
603 }
604 
requestUpdate_defaultTimeout()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(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
requestUpdate_timeoutLessThanMinimumInterval()618 void TestQGeoPositionInfoSource::requestUpdate_timeoutLessThanMinimumInterval()
619 {
620     CHECK_SOURCE_VALID;
621 
622     QSignalSpy spyTimeout(m_source, SIGNAL(updateTimeout()));
623     m_source->requestUpdate(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
requestUpdate_repeatedCalls()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(7000);
637 
638     QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), 7000);
639     spyUpdate.clear();
640     m_source->requestUpdate(7000);
641 
642     QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), 7000);
643 }
644 
requestUpdate_overlappingCalls()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(7000);
653     m_source->requestUpdate(7000);
654 
655     QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() > 0) && (spyTimeout.count() == 0), 7000);
656 }
657 
658 //TC_ID_3_x_4
requestUpdateAfterStartUpdates_ZeroInterval()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(7000);
673     QTest::qWait(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 
requestUpdateAfterStartUpdates_SmallInterval()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(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 
requestUpdateBeforeStartUpdates_ZeroInterval()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(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(7000);
722 
723     QCOMPARE(spyTimeout.count(), 0);
724 
725     m_source->stopUpdates();
726 }
727 
requestUpdateBeforeStartUpdates_SmallInterval()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(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 
removeSlotForRequestTimeout()747 void TestQGeoPositionInfoSource::removeSlotForRequestTimeout()
748 {
749     CHECK_SOURCE_VALID;
750 
751     bool i = connect(m_source, SIGNAL(updateTimeout()), this, SLOT(test_slot1()));
752     QVERIFY(i == true);
753     i = connect(m_source, SIGNAL(updateTimeout()), this, SLOT(test_slot2()));
754     QVERIFY(i == true);
755     i = disconnect(m_source, SIGNAL(updateTimeout()), this, SLOT(test_slot1()));
756     QVERIFY(i == true);
757 
758     m_source->requestUpdate(-1);
759     QTRY_VERIFY_WITH_TIMEOUT((m_testSlot2Called == true), 1000);
760 }
761 
removeSlotForPositionUpdated()762 void TestQGeoPositionInfoSource::removeSlotForPositionUpdated()
763 {
764     CHECK_SOURCE_VALID;
765 
766     bool i = connect(m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(test_slot1()));
767     QVERIFY(i == true);
768     i = connect(m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(test_slot2()));
769     QVERIFY(i == true);
770     i = disconnect(m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(test_slot1()));
771     QVERIFY(i == true);
772 
773     m_source->requestUpdate(7000);
774 
775     QTRY_VERIFY_WITH_TIMEOUT((m_testSlot2Called == true), 7000);
776 }
777 
778 #include "testqgeopositioninfosource.moc"
779