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 QtSensors module 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#include <QtTest/QtTest>
30#include <QtTest/QSignalSpy>
31#include <QtCore/QDebug>
32
33#include "../../../src/imports/sensors/qmlsensor.h"
34#include "../../../src/imports/sensors/qmlsensorgesture.h"
35
36#include "qtemplategestureplugin.h"
37#include "qtemplaterecognizer.h"
38#include <qsensorgesturemanager.h>
39#include <qsensorbackend.h>
40#include "qsensormanager.h"
41
42QT_USE_NAMESPACE
43
44QT_BEGIN_NAMESPACE
45
46class tst_Sensors2QMLAPI : public QObject
47{
48 Q_OBJECT
49
50private slots:
51 void initTestCase();
52 void testGesture();
53 void testSensorRanges();
54};
55
56void tst_Sensors2QMLAPI::initTestCase()
57{
58 qputenv(varName: "QT_SENSORS_LOAD_PLUGINS", value: "0"); // Do not load plugins
59}
60
61void tst_Sensors2QMLAPI::testGesture()
62{
63 QTemplateGesturePlugin* plugin = new QTemplateGesturePlugin();
64 QList <QSensorGestureRecognizer *> recognizers = plugin->createRecognizers();
65 QSensorGestureManager manager;
66
67 QmlSensorGesture* gs = new QmlSensorGesture(this);
68 gs->componentComplete();
69 QSignalSpy spy_availableGesturesChanged(gs, SIGNAL(availableGesturesChanged()));
70 QSignalSpy spy_detected(gs, SIGNAL(detected(QString)));
71 QSignalSpy spy_gesturesChanged(gs, SIGNAL(gesturesChanged()));
72 QSignalSpy spy_validGesturesChanged(gs, SIGNAL(validGesturesChanged()));
73 QSignalSpy spy_invalidGesturesChanged(gs, SIGNAL(invalidGesturesChanged()));
74 QSignalSpy spy_enabledChanged(gs, SIGNAL(enabledChanged()));
75
76 //This flag is needed if you run this unit test with an alread installed template plugin
77 bool registered = false;
78 for (int i = 0; i < recognizers.count(); i++){
79 registered = manager.registerSensorGestureRecognizer(recognizer: recognizers[i]);
80 }
81 if (registered) {
82 QCOMPARE(spy_availableGesturesChanged.count(), 2);
83 }
84
85 //check creation of a not known plugin
86 QCOMPARE(spy_invalidGesturesChanged.count(), 0);
87 QCOMPARE(spy_gesturesChanged.count(), 0);
88 gs->setGestures(QStringList() << "lollipop");
89 QCOMPARE(spy_gesturesChanged.count(), 1);
90 QCOMPARE(spy_invalidGesturesChanged.count(), 1);
91
92 //check creation of a known plugin
93 QCOMPARE(spy_validGesturesChanged.count(), 0);
94 QCOMPARE(spy_gesturesChanged.count(), 1);
95 spy_invalidGesturesChanged.clear();
96 spy_validGesturesChanged.clear();
97 gs->setGestures(QStringList() << "QtSensors.template");
98 QCOMPARE(spy_gesturesChanged.count(), 2);
99 QCOMPARE(spy_invalidGesturesChanged.count(), 1);
100 QCOMPARE(spy_validGesturesChanged.count(), 1);
101
102 //enable "QtSensors.template"
103 QCOMPARE(spy_enabledChanged.count(), 0);
104 QCOMPARE(spy_detected.count(), 0);
105 gs->setEnabled(true);
106 QCOMPARE(spy_enabledChanged.count(), 1);
107 QCOMPARE(spy_detected.count(), 1);
108
109 //set gesture during running sensor should not emit gesture changed
110 spy_gesturesChanged.clear();
111 gs->setGestures(QStringList() << "QtSensors.template2");
112 QCOMPARE(spy_gesturesChanged.count(), 0);
113
114 gs->setEnabled(false);
115
116 QmlSensorGesture* gs1 = new QmlSensorGesture(this);
117 QSignalSpy spy1_detected(gs1, SIGNAL(detected(QString)));
118 QSignalSpy spy1_gesturesChanged(gs1, SIGNAL(gesturesChanged()));
119 QSignalSpy spy1_validGesturesChanged(gs1, SIGNAL(validGesturesChanged()));
120 QSignalSpy spy1_invalidGesturesChanged(gs1, SIGNAL(invalidGesturesChanged()));
121 QSignalSpy spy1_enabledChanged(gs1, SIGNAL(enabledChanged()));
122 gs1->componentComplete();
123
124 //set enable = true without gesture should
125 gs1->setEnabled(true);
126 QCOMPARE(spy1_enabledChanged.count(), 1);
127 gs1->setEnabled(false);
128 spy1_enabledChanged.clear();
129
130 //reding gestures check if we get back an empty string list
131 QStringList gestures = gs1->gestures();
132 QCOMPARE(gestures.count(), 0);
133 QStringList validgestures = gs1->validGestures();
134 QCOMPARE(validgestures.count(), 0);
135 QStringList invalidgestures = gs1->invalidGestures();
136 QCOMPARE(invalidgestures.count(), 0);
137
138 //check types "QtSensors.template" "QtSensors.template1" "lollipop"
139 //expect valid 2 not available 1
140 gestures << "QtSensors.template" << "QtSensors.template1" << "lollipop";
141 gs1->setGestures(gestures);
142 gestures = gs1->gestures();
143 QCOMPARE(gestures.count(), 3);
144 QCOMPARE(spy1_validGesturesChanged.count(), 1);
145 QCOMPARE(spy1_invalidGesturesChanged.count(), 1);
146 QCOMPARE(spy1_gesturesChanged.count(), 1);
147 //set same gesture again should not emit gesture changed
148 gs1->setGestures(gestures);
149 QCOMPARE(spy1_gesturesChanged.count(), 1);
150
151 spy1_gesturesChanged.clear();
152 gestures.clear();
153 gs1->setGestures(gestures);
154 QCOMPARE(spy1_gesturesChanged.count(), 1);
155
156 //enable "QtSensors.template" and "QtSensors.template1"
157 gestures << "QtSensors.template" << "QtSensors.template1";
158 gs1->setEnabled(false);
159 gs1->setGestures(gestures);
160 spy1_enabledChanged.clear();
161 spy1_detected.clear();
162 gs1->setEnabled(true);
163 QCOMPARE(spy1_enabledChanged.count(), 1);
164 QCOMPARE(spy1_detected.count(), 2);
165 gs1->setEnabled(false);
166
167 //check sensor shouldn't run until the componentComplete gets called
168 QmlSensorGesture* gs2 = new QmlSensorGesture(this);
169 QSignalSpy spy2_detected(gs2, SIGNAL(detected(QString)));
170 gs2->setGestures(QStringList() << "QtSensors.template");
171 gs2->setEnabled(true);
172 QCOMPARE(spy2_detected.count(), 0);
173 gs2->componentComplete();
174 QCOMPARE(spy2_detected.count(), 1);
175}
176
177class QDummySensorBackend : public QSensorBackend
178{
179 Q_OBJECT
180public:
181 QDummySensorBackend(QSensor *sensor) : QSensorBackend(sensor)
182 {
183 addDataRate(min: 2, max: 3);
184 addDataRate(min: 5, max: 7);
185 addOutputRange(min: 100, max: 200, accuracy: 1);
186 addOutputRange(min: 600, max: 700, accuracy: 10);
187 addOutputRange(min: 0, max: 1, accuracy: 2);
188 }
189
190 void start() override {}
191 void stop() override {}
192};
193
194class QDummySensorReading : public QSensorReading
195{
196 Q_OBJECT
197public:
198 QDummySensorReading(QObject *parent) : QSensorReading(parent, nullptr) {}
199};
200
201class QmlDummySensorReading : public QmlSensorReading
202{
203 Q_OBJECT
204public:
205 QmlDummySensorReading(QSensor *sensor) :
206 QmlSensorReading(sensor),
207 m_reading(new QDummySensorReading(this))
208 {}
209
210 QSensorReading *reading() const override { return m_reading; }
211 void readingUpdate() override {}
212
213private:
214 QSensorReading *m_reading = nullptr;
215};
216
217class QmlDummySensor : public QmlSensor
218{
219 Q_OBJECT
220public:
221 QmlDummySensor(QObject *parent = nullptr) :
222 QmlSensor(parent),
223 m_sensor(new QSensor("dummy", this))
224 {
225 QDummySensorBackend b(m_sensor);
226 Q_UNUSED(b);
227 }
228
229 QSensor *sensor() const override { return m_sensor; }
230 QmlSensorReading *createReading() const override { return new QmlDummySensorReading(m_sensor); }
231
232 void componentComplete() override { QmlSensor::componentComplete(); }
233
234private:
235 QSensor *m_sensor = nullptr;
236};
237
238void tst_Sensors2QMLAPI::testSensorRanges()
239{
240 QScopedPointer<QmlDummySensor> qmlSensor(new QmlDummySensor);
241 qmlSensor->componentComplete();
242
243 auto ranges = qmlSensor->availableDataRates();
244 QCOMPARE(ranges.count(&ranges), 2);
245
246 const auto range0 = ranges.at(&ranges, 0);
247 QCOMPARE(range0->minimum(), 2);
248 QCOMPARE(range0->maximum(), 3);
249 QSignalSpy range0Spy(range0, SIGNAL(destroyed()));
250
251 const auto range1 = ranges.at(&ranges, 1);
252 QCOMPARE(range1->minimum(), 5);
253 QCOMPARE(range1->maximum(), 7);
254 QSignalSpy range1Spy(range1, SIGNAL(destroyed()));
255
256 auto outputs = qmlSensor->outputRanges();
257 QCOMPARE(outputs.count(&outputs), 3);
258
259 const auto output0 = outputs.at(&outputs, 0);
260 QCOMPARE(output0->minimum(), 100);
261 QCOMPARE(output0->maximum(), 200);
262 QCOMPARE(output0->accuracy(), 1);
263 QSignalSpy output0Spy(output0, SIGNAL(destroyed()));
264
265 const auto output1 = outputs.at(&outputs, 1);
266 QCOMPARE(output1->minimum(), 600);
267 QCOMPARE(output1->maximum(), 700);
268 QCOMPARE(output1->accuracy(), 10);
269 QSignalSpy output1Spy(output1, SIGNAL(destroyed()));
270
271 const auto output2 = outputs.at(&outputs, 2);
272 QCOMPARE(output2->minimum(), 0);
273 QCOMPARE(output2->maximum(), 1);
274 QCOMPARE(output2->accuracy(), 2);
275 QSignalSpy output2Spy(output2, SIGNAL(destroyed()));
276
277 qmlSensor.reset();
278 QCOMPARE(range0Spy.count(), 1);
279 QCOMPARE(range1Spy.count(), 1);
280 QCOMPARE(output0Spy.count(), 1);
281 QCOMPARE(output1Spy.count(), 1);
282 QCOMPARE(output2Spy.count(), 1);
283}
284
285QT_END_NAMESPACE
286
287QTEST_MAIN(tst_Sensors2QMLAPI)
288#include "tst_sensors2qmlapi.moc"
289

source code of qtsensors/tests/auto/sensors2qmlapi/tst_sensors2qmlapi.cpp