From 3e38a836dcdeaa98a53aab96131eedd2bab348ab Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Tue, 30 Mar 2021 15:50:04 +0200 Subject: QDeclarativePositionSource: extend tests Extend the QML tests to check the bindings. Required to make sure that we do not break the behavior during migrating to new property binding system. Task-number: QTBUG-89874 Change-Id: I140b07a05944a30d5dbca910b015e3c00bc9e587 Reviewed-by: Juha Vuolle --- tests/auto/CMakeLists.txt | 1 + tests/auto/auto.pro | 3 +- .../tst_positionsource.qml | 200 ++++++++++++++++++++- tests/auto/dummypositionplugin/CMakeLists.txt | 20 +++ .../dummypositionplugin/dummypositionplugin.pro | 12 ++ tests/auto/dummypositionplugin/plugin.cpp | 155 ++++++++++++++++ tests/auto/dummypositionplugin/plugin.json | 9 + 7 files changed, 398 insertions(+), 2 deletions(-) create mode 100644 tests/auto/dummypositionplugin/CMakeLists.txt create mode 100644 tests/auto/dummypositionplugin/dummypositionplugin.pro create mode 100644 tests/auto/dummypositionplugin/plugin.cpp create mode 100644 tests/auto/dummypositionplugin/plugin.json diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt index dd361a5c..b6495691 100644 --- a/tests/auto/CMakeLists.txt +++ b/tests/auto/CMakeLists.txt @@ -74,6 +74,7 @@ add_subdirectory(qgeosatelliteinfo) # add_subdirectory(declarative_ui) # endif() if(TARGET Qt::Quick AND NOT ANDROID) + add_subdirectory(dummypositionplugin) add_subdirectory(declarative_positioning_core) add_subdirectory(declarative_geolocation) endif() diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index c94ec618..789c769d 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -82,7 +82,8 @@ qtHaveModule(location) { } qtHaveModule(quick):!android { - SUBDIRS += declarative_positioning_core + SUBDIRS += declarative_positioning_core \ + dummypositionplugin } SUBDIRS += \ diff --git a/tests/auto/declarative_positioning_core/tst_positionsource.qml b/tests/auto/declarative_positioning_core/tst_positionsource.qml index 7b787a0c..858ff699 100644 --- a/tests/auto/declarative_positioning_core/tst_positionsource.qml +++ b/tests/auto/declarative_positioning_core/tst_positionsource.qml @@ -121,7 +121,7 @@ TestCase { SignalSpy { id: directionValidSpyWParams; target: testingSourceWParams.position; signalName: "directionValidChanged" } SignalSpy { id: directionSpyWParams; target: testingSourceWParams.position; signalName: "directionChanged" } - PositionSource { id: testingSourceV1; name: "test.source.v1"; updateInterval: 1000 } + PositionSource { id: testingSourceV1; name: "test.source"; updateInterval: 1000 } SignalSpy { id: updateSpyV1; target: testingSourceV1; signalName: "positionChanged" } SignalSpy { id: directionValidSpyV1; target: testingSourceV1.position; signalName: "directionValidChanged" } SignalSpy { id: directionSpyV1; target: testingSourceV1.position; signalName: "directionChanged" } @@ -224,4 +224,202 @@ TestCase { verify(testingSourceWParams.position.speedValid) verify(testingSourceWParams.position.speed > 10000) } + + // tests for bindings + PositionSource { + id: testSourceForBindings + name: "test.source" + } + + property var positionObserver: testSourceForBindings.position + SignalSpy { + id: positionObserverSpy; target: testSourceForBindings; signalName: "positionChanged" + } + + property bool activeObserver: testSourceForBindings.active + SignalSpy { + id: activeObserverSpy; target: testSourceForBindings; signalName: "activeChanged" + } + + property bool validObserver: testSourceForBindings.valid + SignalSpy { + id: validObserverSpy; target: testSourceForBindings; signalName: "validityChanged" + } + + property int updateIntervalObserver: testSourceForBindings.updateInterval + SignalSpy { + id: updateIntervalObserverSpy; target: testSourceForBindings; signalName: "updateIntervalChanged" + } + + property int supportedMethodsObserver: testSourceForBindings.supportedPositioningMethods + SignalSpy { + id: supportedMethodsObserverSpy; target: testSourceForBindings; signalName: "supportedPositioningMethodsChanged" + } + + property int preferredMethodsObserver: testSourceForBindings.preferredPositioningMethods + SignalSpy { + id: preferredMethodsObserverSpy; + target: testSourceForBindings; + signalName: "preferredPositioningMethodsChanged" + } + + property int errorObserver: testSourceForBindings.sourceError + SignalSpy { + id: errorObserverSpy; target: testSourceForBindings; signalName: "sourceErrorChanged" + } + + property string nameObserver: testSourceForBindings.name + SignalSpy { + id: nameObserverSpy; target: testSourceForBindings; signalName: "nameChanged" + } + + function test_bindingsToPositionSource() { + positionObserverSpy.clear() + activeObserverSpy.clear() + validObserverSpy.clear() + updateIntervalObserverSpy.clear() + supportedMethodsObserverSpy.clear() + preferredMethodsObserverSpy.clear() + errorObserverSpy.clear() + nameObserverSpy.clear() + + verify(testSourceForBindings.valid) + compare(testSourceForBindings.supportedPositioningMethods, PositionSource.AllPositioningMethods) + + testSourceForBindings.preferredPositioningMethods = PositionSource.SatellitePositioningMethods + compare(preferredMethodsObserver, PositionSource.SatellitePositioningMethods) + compare(preferredMethodsObserverSpy.count, 1) + + testSourceForBindings.updateInterval = 1100; + compare(updateIntervalObserver, 1100) + compare(updateIntervalObserverSpy.count, 1) + + testSourceForBindings.start(); + compare(activeObserver, true) + compare(activeObserverSpy.count, 1) + + tryCompare(positionObserverSpy, "count", 1, 1500); + verify(testSourceForBindings.position.coordinate !== QtPositioning.coordinate()) + + testSourceForBindings.update(100) // small timeout will result in an error + tryCompare(errorObserverSpy, "count", 1, 200) + compare(errorObserver, PositionSource.UpdateTimeoutError) + + var newSourceName = "some invalid name" + testSourceForBindings.name = newSourceName + + compare(validObserver, false) + compare(validObserverSpy.count, 1) + + compare(nameObserver, newSourceName) + compare(nameObserverSpy.count, 1) + + compare(supportedMethodsObserver, PositionSource.NoPositioningMethods) + compare(supportedMethodsObserverSpy.count, 1) + } + + property bool activeSetter: false + property string nameSetter: "test.source" + property int updateIntervalSetter: 1000 + property int preferredMethodsSetter: PositionSource.NonSatellitePositioningMethods + + PositionSource { + id: sourceWithBindings + name: nameSetter + active: activeSetter + updateInterval: updateIntervalSetter + preferredPositioningMethods: preferredMethodsSetter + } + + function test_bindPositionSourceProperties() { + compare(sourceWithBindings.name, "test.source") + compare(sourceWithBindings.active, false) + compare(sourceWithBindings.updateInterval, 1000) + compare(sourceWithBindings.preferredPositioningMethods, PositionSource.NonSatellitePositioningMethods) + + updateIntervalSetter = 1100; + preferredMethodsSetter = PositionSource.AllPositioningMethods + activeSetter = true + + wait(0) // to trigger event processing + + compare(sourceWithBindings.active, true) + compare(sourceWithBindings.updateInterval, 1100) + compare(sourceWithBindings.preferredPositioningMethods, PositionSource.AllPositioningMethods) + + activeSetter = false; + + compare(sourceWithBindings.active, false) + + // check how call to update() effects the binding + sourceWithBindings.update(updateIntervalSetter) + compare(sourceWithBindings.active, true) + + wait(1500) + compare(sourceWithBindings.active, false) + + activeSetter = true; + wait(0) // to trigger event processing + // the binding is *not* broken by calling update() + compare(sourceWithBindings.active, true) + } + + function test_updateIntervalBindings() { + var updateIntervalSpy = Qt.createQmlObject('import QtTest; SignalSpy { }', testCase) + updateIntervalSpy.target = sourceWithBindings + updateIntervalSpy.signalName = "updateIntervalChanged" + verify(updateIntervalSpy.valid) + + nameSetter = "invalid name" + updateIntervalSetter = 800; + compare(sourceWithBindings.updateInterval, 800) + compare(updateIntervalSpy.count, 1) + + nameSetter = "test.source" + // "test.source" has a minimum update interval of 1000 + compare(sourceWithBindings.updateInterval, 1000) + compare(updateIntervalSpy.count, 2) + + nameSetter = "dummy.source" + // "dummy.source" has a minimum udpate interval of 100, so we expect + // the updateInterval to be set to 800 + compare(sourceWithBindings.updateInterval, 800) + compare(updateIntervalSpy.count, 3) + + // The binding still works + updateIntervalSetter = 1100 + compare(sourceWithBindings.updateInterval, 1100) + compare(updateIntervalSpy.count, 4) + } + + function test_preferredPositioningMethodsBindings() { + var preferredMethodsSpy = Qt.createQmlObject('import QtTest; SignalSpy { }', testCase) + preferredMethodsSpy.target = sourceWithBindings + preferredMethodsSpy.signalName = "preferredPositioningMethodsChanged" + verify(preferredMethodsSpy.valid) + + nameSetter = "invalid name" + preferredMethodsSetter = PositionSource.SatellitePositioningMethods + compare(sourceWithBindings.preferredPositioningMethods, PositionSource.SatellitePositioningMethods) + compare(preferredMethodsSpy.count, 1) + + nameSetter = "dummy.source" + // "dummy.source" has only NonSatellitePositioningMethods, so we expect + // the value to be set to NonSatellitePositioningMethods (see + // QGeoPositionInfoSource::setPreferredPositioningMethods for details) + compare(sourceWithBindings.preferredPositioningMethods, PositionSource.NonSatellitePositioningMethods) + compare(preferredMethodsSpy.count, 2) + + nameSetter = "test.source" + // "test.source" has all positioning methods, so we expect the value to + // be set to the desired SatellitePositioningMethods + compare(sourceWithBindings.preferredPositioningMethods, PositionSource.SatellitePositioningMethods) + compare(preferredMethodsSpy.count, 3) + + // The binding still works + preferredMethodsSetter = PositionSource.AllPositioningMethods + compare(sourceWithBindings.preferredPositioningMethods, PositionSource.AllPositioningMethods) + compare(preferredMethodsSpy.count, 4) + } + } diff --git a/tests/auto/dummypositionplugin/CMakeLists.txt b/tests/auto/dummypositionplugin/CMakeLists.txt new file mode 100644 index 00000000..aba6f092 --- /dev/null +++ b/tests/auto/dummypositionplugin/CMakeLists.txt @@ -0,0 +1,20 @@ +# Generated from positionplugin.pro. + +##################################################################### +## QGeoPositionInfoSourceFactoryTest Plugin: +##################################################################### + +qt_internal_add_plugin(DummyPluginForTests + OUTPUT_NAME qtposition_testplugin2 + TYPE position + DEFAULT_IF FALSE + SOURCES + plugin.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::Positioning +) + +#### Keys ignored in scope 1:.:.:positionplugin.pro:: +# OTHER_FILES = "plugin.json" +# PLUGIN_EXTENDS = "-" diff --git a/tests/auto/dummypositionplugin/dummypositionplugin.pro b/tests/auto/dummypositionplugin/dummypositionplugin.pro new file mode 100644 index 00000000..bdf4f7a2 --- /dev/null +++ b/tests/auto/dummypositionplugin/dummypositionplugin.pro @@ -0,0 +1,12 @@ +TARGET = qtposition_testplugin2 +QT += positioning-private + +PLUGIN_TYPE = position +PLUGIN_CLASS_NAME = DummyPluginForTests +PLUGIN_EXTENDS = - +load(qt_plugin) + +SOURCES += plugin.cpp + +OTHER_FILES += \ + plugin.json diff --git a/tests/auto/dummypositionplugin/plugin.cpp b/tests/auto/dummypositionplugin/plugin.cpp new file mode 100644 index 00000000..a0a8f475 --- /dev/null +++ b/tests/auto/dummypositionplugin/plugin.cpp @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +QT_USE_NAMESPACE + +// This is a dummy plugin that is created mostly to test some features of +// QDeclarativePositionSource. It does not provide any position updates. +// Use plugin from positionplugin subdirectory, if you need to simulate some +// positioning updates. + +class DummyPluginSource : public QGeoPositionInfoSource +{ + Q_OBJECT + +public: + DummyPluginSource(const QVariantMap ¶meters, QObject *parent = 0); + ~DummyPluginSource(); + + void startUpdates() override; + void stopUpdates() override; + void requestUpdate(int timeout = 5000) override; + + QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const override; + PositioningMethods supportedPositioningMethods() const override; + + void setUpdateInterval(int msec) override; + int minimumUpdateInterval() const override; + Error error() const override; + +private: + Error lastError = QGeoPositionInfoSource::NoError; +}; + +DummyPluginSource::DummyPluginSource(const QVariantMap ¶meters, QObject *parent) + : QGeoPositionInfoSource(parent) +{ + Q_UNUSED(parameters) +} + +QGeoPositionInfoSource::Error DummyPluginSource::error() const +{ + return lastError; +} + +void DummyPluginSource::setUpdateInterval(int msec) +{ + if (msec < minimumUpdateInterval()) + msec = minimumUpdateInterval(); + + QGeoPositionInfoSource::setUpdateInterval(msec); +} + +int DummyPluginSource::minimumUpdateInterval() const +{ + return 100; +} + +QGeoPositionInfo +DummyPluginSource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const +{ + Q_UNUSED(fromSatellitePositioningMethodsOnly); + return QGeoPositionInfo(); +} + +QGeoPositionInfoSource::PositioningMethods DummyPluginSource::supportedPositioningMethods() const +{ + return QGeoPositionInfoSource::NonSatellitePositioningMethods; +} + +void DummyPluginSource::startUpdates() +{ + lastError = QGeoPositionInfoSource::NoError; +} + +void DummyPluginSource::stopUpdates() { } + +void DummyPluginSource::requestUpdate(int timeout) +{ + lastError = QGeoPositionInfoSource::NoError; + if (timeout < minimumUpdateInterval()) { + lastError = QGeoPositionInfoSource::UpdateTimeoutError; + emit QGeoPositionInfoSource::errorOccurred(lastError); + } +} + +DummyPluginSource::~DummyPluginSource() { } + +class DummyPluginForTestsFactory : public QObject, public QGeoPositionInfoSourceFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" FILE "plugin.json") + Q_INTERFACES(QGeoPositionInfoSourceFactory) + +public: + QGeoPositionInfoSource *positionInfoSource(QObject *parent, + const QVariantMap ¶meters) override; + QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, + const QVariantMap ¶meters) override; + QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; +}; + +QGeoPositionInfoSource * +DummyPluginForTestsFactory::positionInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + return new DummyPluginSource(parameters, parent); +} + +QGeoSatelliteInfoSource * +DummyPluginForTestsFactory::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) +{ + Q_UNUSED(parent); + Q_UNUSED(parameters); + return nullptr; +} + +QGeoAreaMonitorSource *DummyPluginForTestsFactory::areaMonitor(QObject *parent, + const QVariantMap ¶meters) +{ + Q_UNUSED(parent); + Q_UNUSED(parameters); + return nullptr; +} + +#include "plugin.moc" diff --git a/tests/auto/dummypositionplugin/plugin.json b/tests/auto/dummypositionplugin/plugin.json new file mode 100644 index 00000000..61f2657b --- /dev/null +++ b/tests/auto/dummypositionplugin/plugin.json @@ -0,0 +1,9 @@ +{ + "Keys": ["dummy.source"], + "Provider": "dummy.source", + "Position": true, + "Satellite": false, + "Monitor": false, + "Priority": 1, + "Testable": true +} -- cgit v1.2.1