void tst_QNmeaPositionInfoSource::startUpdates() { QFETCH(QList<QDateTime>, dateTimes); QNmeaPositionInfoSource source(m_mode); QNmeaPositionInfoSourceProxyFactory factory; QNmeaPositionInfoSourceProxy *proxy = static_cast<QNmeaPositionInfoSourceProxy*>(factory.createProxy(&source)); QSignalSpy spyUpdate(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); proxy->source()->startUpdates(); for (int i=0; i<dateTimes.count(); i++) proxy->feedUpdate(dateTimes[i]); QTRY_COMPARE(spyUpdate.count(), dateTimes.count()); }
void tst_QNmeaPositionInfoSource::requestUpdate_waitForValidDateTime() { QFETCH(QByteArray, bytes); QFETCH(QList<QDateTime>, dateTimes); QNmeaPositionInfoSource source(m_mode); QNmeaPositionInfoSourceProxyFactory factory; QNmeaPositionInfoSourceProxy *proxy = static_cast<QNmeaPositionInfoSourceProxy*>(factory.createProxy(&source)); QSignalSpy spy(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); proxy->source()->requestUpdate(); proxy->feedBytes(bytes); QTRY_COMPARE(spy.count(), 1); QCOMPARE(spy[0][0].value<QGeoPositionInfo>().timestamp(), dateTimes[0]); }
QNmeaPositionInfoSourceProxy *QNmeaPositionInfoSourceProxyFactory::createProxy(QNmeaPositionInfoSource *source) { QTcpSocket *client = new QTcpSocket; client->connectToHost(m_server->serverAddress(), m_server->serverPort()); //qDebug() << "listening on" << m_server->serverAddress() << m_server->serverPort(); bool b = m_server->waitForNewConnection(5000); Q_ASSERT(b); b = client->waitForConnected(); Q_ASSERT(b); //QNmeaPositionInfoSource *source = new QNmeaPositionInfoSource(m_mode); source->setDevice(m_server->nextPendingConnection()); Q_ASSERT(source->device() != 0); QNmeaPositionInfoSourceProxy *proxy = new QNmeaPositionInfoSourceProxy(source, client); proxy->setParent(source); return proxy; }
void tst_QNmeaPositionInfoSource::requestUpdate_after_start() { QNmeaPositionInfoSource source(m_mode); QNmeaPositionInfoSourceProxyFactory factory; QNmeaPositionInfoSourceProxy *proxy = static_cast<QNmeaPositionInfoSourceProxy*>(factory.createProxy(&source)); QSignalSpy spyUpdate(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); QSignalSpy spyTimeout(proxy->source(), SIGNAL(updateTimeout())); // Start updates with 500ms interval and requestUpdate() with 100ms // timeout. Feed an update, and it should be emitted immediately due to // the requestUpdate(). The update should not be emitted again after that // (i.e. the startUpdates() interval should not cause it to be re-emitted). QDateTime dt = QDateTime::currentDateTime().toUTC(); proxy->source()->setUpdateInterval(500); proxy->source()->startUpdates(); proxy->source()->requestUpdate(100); proxy->feedUpdate(dt); QTRY_COMPARE(spyUpdate.count(), 1); QCOMPARE(spyUpdate[0][0].value<QGeoPositionInfo>().timestamp(), dt); QCOMPARE(spyTimeout.count(), 0); spyUpdate.clear(); // Update has been emitted for requestUpdate(), shouldn't be emitted for startUpdates() QTRY_COMPARE_WITH_TIMEOUT(spyUpdate.count(), 0, 1000); }
void tst_QNmeaPositionInfoSource::startUpdates_waitForValidDateTime() { // Tests that the class does not emit an update until it receives a // sentences with a valid date *and* time. All sentences before this // should be ignored, and any sentences received after this that do // not have a date should use the known date. QFETCH(QByteArray, bytes); QFETCH(QList<QDateTime>, dateTimes); QFETCH(QList<bool>, expectHorizontalAccuracy); QFETCH(QList<bool>, expectVerticalAccuracy); QNmeaPositionInfoSource source(m_mode); source.setUserEquivalentRangeError(5.1); QNmeaPositionInfoSourceProxyFactory factory; QNmeaPositionInfoSourceProxy *proxy = static_cast<QNmeaPositionInfoSourceProxy*>(factory.createProxy(&source)); QSignalSpy spy(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); proxy->source()->startUpdates(); proxy->feedBytes(bytes); QTRY_COMPARE(spy.count(), dateTimes.count()); for (int i=0; i<spy.count(); i++) { QGeoPositionInfo pInfo = spy[i][0].value<QGeoPositionInfo>(); QCOMPARE(pInfo.timestamp(), dateTimes[i]); // Generated GGA/GSA sentences have hard coded HDOP of 3.5, which corrisponds to a // horizontal accuracy of 35.7, for the user equivalent range error of 5.1 set above. QCOMPARE(pInfo.hasAttribute(QGeoPositionInfo::HorizontalAccuracy), expectHorizontalAccuracy[i]); if (pInfo.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) QVERIFY(qFuzzyCompare(pInfo.attribute(QGeoPositionInfo::HorizontalAccuracy), 35.7)); // Generate GSA sentences have hard coded VDOP of 4.0, which corrisponds to a vertical // accuracy of 40.8, for the user equivalent range error of 5.1 set above. QCOMPARE(pInfo.hasAttribute(QGeoPositionInfo::VerticalAccuracy), expectVerticalAccuracy[i]); if (pInfo.hasAttribute(QGeoPositionInfo::VerticalAccuracy)) QVERIFY(qFuzzyCompare(pInfo.attribute(QGeoPositionInfo::VerticalAccuracy), 40.8)); } }
void tst_QNmeaPositionInfoSource::startUpdates_expectLatestUpdateOnly() { // If startUpdates() is called and an interval has been set, if multiple' // updates are in the buffer, only the latest update should be emitted QNmeaPositionInfoSource source(m_mode); QNmeaPositionInfoSourceProxyFactory factory; QNmeaPositionInfoSourceProxy *proxy = static_cast<QNmeaPositionInfoSourceProxy*>(factory.createProxy(&source)); QSignalSpy spyUpdate(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); proxy->source()->setUpdateInterval(500); proxy->source()->startUpdates(); QList<QDateTime> dateTimes = createDateTimes(3); for (int i=0; i<dateTimes.count(); i++) proxy->feedUpdate(dateTimes[i]); QTRY_COMPARE(spyUpdate.count(), 1); QCOMPARE(spyUpdate[0][0].value<QGeoPositionInfo>().timestamp(), dateTimes.last()); }
void tst_QNmeaPositionInfoSource::requestUpdate() { QNmeaPositionInfoSource source(m_mode); QNmeaPositionInfoSourceProxyFactory factory; QNmeaPositionInfoSourceProxy *proxy = static_cast<QNmeaPositionInfoSourceProxy*>(factory.createProxy(&source)); QSignalSpy spyUpdate(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); QSignalSpy spyTimeout(proxy->source(), SIGNAL(updateTimeout())); QDateTime dt; proxy->source()->requestUpdate(100); QTRY_COMPARE(spyTimeout.count(), 1); spyTimeout.clear(); dt = QDateTime::currentDateTime().toUTC(); proxy->feedUpdate(dt); proxy->source()->requestUpdate(); QTRY_COMPARE(spyUpdate.count(), 1); QCOMPARE(spyUpdate[0][0].value<QGeoPositionInfo>().timestamp(), dt); QCOMPARE(spyTimeout.count(), 0); spyUpdate.clear(); // delay the update and expect it to be emitted after 300ms dt = QDateTime::currentDateTime().toUTC(); proxy->source()->requestUpdate(1000); QTest::qWait(300); proxy->feedUpdate(dt); QTRY_COMPARE(spyUpdate.count(), 1); QCOMPARE(spyUpdate[0][0].value<QGeoPositionInfo>().timestamp(), dt); QCOMPARE(spyTimeout.count(), 0); spyUpdate.clear(); // delay the update and expect updateTimeout() to be emitted dt = QDateTime::currentDateTime().toUTC(); proxy->source()->requestUpdate(500); QTest::qWait(1000); proxy->feedUpdate(dt); QCOMPARE(spyTimeout.count(), 1); QCOMPARE(spyUpdate.count(), 0); spyUpdate.clear(); }
void tst_QNmeaPositionInfoSource::testWithBadNmea() { QFETCH(QByteArray, bytes); QFETCH(QList<QDateTime>, dateTimes); QFETCH(UpdateTriggerMethod, trigger); QNmeaPositionInfoSource source(m_mode); QNmeaPositionInfoSourceProxyFactory factory; QNmeaPositionInfoSourceProxy *proxy = static_cast<QNmeaPositionInfoSourceProxy*>(factory.createProxy(&source)); QSignalSpy spy(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); if (trigger == StartUpdatesMethod) proxy->source()->startUpdates(); else proxy->source()->requestUpdate(); proxy->feedBytes(bytes); QTRY_COMPARE(spy.count(), dateTimes.count()); for (int i=0; i<dateTimes.count(); i++) QCOMPARE(spy[i][0].value<QGeoPositionInfo>().timestamp(), dateTimes[i]); }
void tst_QNmeaPositionInfoSource::setUpdateInterval_delayedUpdate() { // If an update interval is set, and an update is not available at a // particular interval, the source should emit the next update as soon // as it becomes available QNmeaPositionInfoSource source(m_mode); QNmeaPositionInfoSourceProxyFactory factory; QNmeaPositionInfoSourceProxy *proxy = static_cast<QNmeaPositionInfoSourceProxy*>(factory.createProxy(&source)); QSignalSpy spyUpdate(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); proxy->source()->setUpdateInterval(500); proxy->source()->startUpdates(); QTest::qWait(600); QDateTime now = QDateTime::currentDateTime(); proxy->feedUpdate(now); QTRY_COMPARE(spyUpdate.count(), 1); // should have gotten the update immediately, and not have needed to // wait until the next interval QVERIFY(now.time().msecsTo(QDateTime::currentDateTime().time()) < 200); }
void tst_QNmeaPositionInfoSource::startUpdates_waitForValidDateTime() { // Tests that the class does not emit an update until it receives a // sentences with a valid date *and* time. All sentences before this // should be ignored, and any sentences received after this that do // not have a date should use the known date. QFETCH(QByteArray, bytes); QFETCH(QList<QDateTime>, dateTimes); QNmeaPositionInfoSource source(m_mode); QNmeaPositionInfoSourceProxyFactory factory; QNmeaPositionInfoSourceProxy *proxy = static_cast<QNmeaPositionInfoSourceProxy*>(factory.createProxy(&source)); QSignalSpy spy(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); proxy->source()->startUpdates(); proxy->feedBytes(bytes); QTRY_COMPARE(spy.count(), dateTimes.count()); for (int i=0; i<spy.count(); i++) QCOMPARE(spy[i][0].value<QGeoPositionInfo>().timestamp(), dateTimes[i]); }
void tst_QNmeaPositionInfoSource::startUpdates_withTimeout() { QNmeaPositionInfoSource source(m_mode); QNmeaPositionInfoSourceProxyFactory factory; QNmeaPositionInfoSourceProxy *proxy = static_cast<QNmeaPositionInfoSourceProxy*>(factory.createProxy(&source)); QSignalSpy spyUpdate(proxy->source(), SIGNAL(positionUpdated(QGeoPositionInfo))); QSignalSpy spyTimeout(proxy->source(), SIGNAL(updateTimeout())); proxy->source()->setUpdateInterval(1000); proxy->source()->startUpdates(); QDateTime dt = QDateTime::currentDateTime().toUTC(); if (m_mode == QNmeaPositionInfoSource::SimulationMode) { // the first sentence primes the simulation proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt).toLatin1()); proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addMSecs(10)).toLatin1()); proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addMSecs(1100)).toLatin1()); proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addMSecs(2200)).toLatin1()); proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addSecs(9)).toLatin1()); QTime t; t.start(); for (int j = 1; j < 4; ++j) { QTRY_COMPARE(spyUpdate.count(), j); QCOMPARE(spyTimeout.count(), 0); int time = t.elapsed(); QVERIFY((time > j*1000 - 300) && (time < j*1000 + 300)); } spyUpdate.clear(); QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() == 0) && (spyTimeout.count() == 1), 7500); spyTimeout.clear(); QTRY_VERIFY_WITH_TIMEOUT((spyUpdate.count() == 1) && (spyTimeout.count() == 0), 7500); } else { // dt + 900 QTRY_VERIFY(spyUpdate.count() == 0 && spyTimeout.count() == 0); proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addSecs(1)).toLatin1()); // dt + 1200 QTRY_VERIFY(spyUpdate.count() == 1 && spyTimeout.count() == 0); spyUpdate.clear(); // dt + 1900 QTRY_VERIFY(spyUpdate.count() == 0 && spyTimeout.count() == 0); proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addSecs(2)).toLatin1()); // dt + 2200 QTRY_VERIFY(spyUpdate.count() == 1 && spyTimeout.count() == 0); spyUpdate.clear(); // dt + 2900 QTRY_VERIFY(spyUpdate.count() == 0 && spyTimeout.count() == 0); proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addSecs(3)).toLatin1()); // dt + 3200 QTRY_VERIFY(spyUpdate.count() == 1 && spyTimeout.count() == 0); spyUpdate.clear(); // dt + 6900 QTRY_VERIFY(spyUpdate.count() == 0 && spyTimeout.count() == 1); spyTimeout.clear(); proxy->feedBytes(QLocationTestUtils::createRmcSentence(dt.addSecs(7)).toLatin1()); // dt + 7200 QTRY_VERIFY(spyUpdate.count() == 1 && spyTimeout.count() == 0); spyUpdate.clear(); } }
void tst_QNmeaPositionInfoSource::lastKnownPosition() { QNmeaPositionInfoSource source(m_mode); QNmeaPositionInfoSourceProxyFactory factory; QNmeaPositionInfoSourceProxy *proxy = static_cast<QNmeaPositionInfoSourceProxy*>(factory.createProxy(&source)); QCOMPARE(proxy->source()->lastKnownPosition(), QGeoPositionInfo()); // source may need requestUpdate() or startUpdates() to be called to // trigger reading of data channel QSignalSpy spyTimeout(proxy->source(), SIGNAL(updateTimeout())); proxy->source()->requestUpdate(proxy->source()->minimumUpdateInterval()); QTRY_COMPARE(spyTimeout.count(), 1); // If an update is received and startUpdates() or requestUpdate() hasn't // been called, it should still be available through lastKnownPosition() QDateTime dt = QDateTime::currentDateTime().toUTC(); proxy->feedUpdate(dt); QTRY_COMPARE(proxy->source()->lastKnownPosition().timestamp(), dt); QList<QDateTime> dateTimes = createDateTimes(5); for (int i=0; i<dateTimes.count(); i++) { proxy->source()->requestUpdate(); proxy->feedUpdate(dateTimes[i]); QTRY_COMPARE(proxy->source()->lastKnownPosition().timestamp(), dateTimes[i]); } proxy->source()->startUpdates(); dateTimes = createDateTimes(5); for (int i=0; i<dateTimes.count(); i++) { proxy->feedUpdate(dateTimes[i]); QTRY_COMPARE(proxy->source()->lastKnownPosition().timestamp(), dateTimes[i]); } }