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 <QtCore/QString>
30#include <QtTest/QtTest>
31#include <QDebug>
32#include <QVariant>
33#include <QSignalSpy>
34
35#include <qsensorgesture.h>
36#include <qsensorgesturemanager.h>
37
38#include <qsensorgesturerecognizer.h>
39#include <qsensorgestureplugininterface.h>
40
41Q_IMPORT_PLUGIN(QTestSensorGesturePlugin)
42Q_IMPORT_PLUGIN(QTestSensorGestureDupPlugin)
43
44static QString removeParens(const QString &arg)
45{
46 return arg.left(n: arg.indexOf(s: "("));
47}
48
49class QSensorGestureWithSlots : public QObject
50{
51 Q_OBJECT
52public:
53 QSensorGestureWithSlots(const QStringList &ids)
54 : gesture(new QSensorGesture(ids, this))
55 {
56 }
57
58 QSensorGesture *gesture;
59
60public slots:
61 void startDetection()
62 {
63 gesture->startDetection();
64 }
65
66 void stopDetection()
67 {
68 gesture->stopDetection();
69 }
70};
71
72class QTest3Recognizer : public QSensorGestureRecognizer
73{
74 Q_OBJECT
75
76public:
77
78 QTest3Recognizer(QObject *parent = 0);
79
80 void create() override;
81
82 QString id() const override;
83 bool start() override;
84 bool stop() override;
85 bool isActive() override;
86 void changeId(const QString &);
87
88 QString recognizerId;
89};
90
91QTest3Recognizer::QTest3Recognizer(QObject *parent) : QSensorGestureRecognizer(parent),
92 recognizerId("QtSensors/test3"){}
93
94void QTest3Recognizer::create(){}
95
96QString QTest3Recognizer::id() const{ return recognizerId; }
97bool QTest3Recognizer::start(){return true;}
98bool QTest3Recognizer::stop() { return true;}
99bool QTest3Recognizer::isActive() { return true; }
100void QTest3Recognizer::changeId(const QString &id)
101{
102 recognizerId = id;
103}
104
105
106class Tst_qsensorgestureTest : public QObject
107{
108 Q_OBJECT
109
110public:
111 Tst_qsensorgestureTest();
112
113private Q_SLOTS:
114 void tst_sensor_gesture_notinitialized();
115
116 void tst_recognizer_dup(); //comes first to weed out messages
117
118 void tst_manager();
119 void tst_manager_gestureids();
120 void tst_manager_recognizerSignals();
121 void tst_manager_registerSensorGestureRecognizer();
122 void tst_manager__newSensorAvailable();
123
124 void tst_sensor_gesture_signals();
125 void tst_sensor_gesture_threaded();
126
127 void tst_sensor_gesture();
128
129 void tst_recognizer();
130
131 void tst_sensorgesture_noid();
132
133 void tst_sensor_gesture_multi();
134
135 void shakeDetected(const QString &);
136
137
138private:
139 QString currentSignal;
140};
141
142Tst_qsensorgestureTest::Tst_qsensorgestureTest()
143{
144}
145
146void Tst_qsensorgestureTest::tst_recognizer_dup()
147{
148 QStringList idList;
149 {
150// QTest::ignoreMessage(QtWarningMsg, "\"QtSensors.test.dup\" from the plugin \"TestGesturesDup\" is already known.");
151 QSensorGestureManager manager;
152 idList = manager.gestureIds();
153
154 for (int i = 0; i < idList.count(); i++) {
155 if (idList.at(i) == "QtSensors.test.dup")
156 QTest::ignoreMessage(type: QtWarningMsg, message: "Ignoring recognizer \"QtSensors.test.dup\" from plugin \"TestGesturesDup\" because it is already registered");
157 QStringList recognizerSignalsList = manager.recognizerSignals(recognizerId: idList.at(i));
158
159 QVERIFY(!recognizerSignalsList.contains("QtSensors.test2"));
160 }
161
162 QScopedPointer<QSensorGesture> sensorGesture(new QSensorGesture(idList));
163 QVERIFY(sensorGesture->validIds().contains("QtSensors.test2"));
164 QVERIFY(sensorGesture->validIds().contains("QtSensors.test"));
165 QVERIFY(sensorGesture->validIds().contains("QtSensors.test.dup"));
166 }
167
168 QScopedPointer<QSensorGesture> thisGesture;
169 QString plugin;
170 plugin = "QtSensors.test2";
171 thisGesture.reset(other: new QSensorGesture(QStringList() << plugin));
172 QVERIFY(thisGesture->validIds().contains("QtSensors.test2"));
173
174 plugin = "QtSensors.test.dup";
175 thisGesture.reset(other: new QSensorGesture(QStringList() << plugin));
176 QVERIFY(!thisGesture->validIds().contains("QtSensors.test2"));
177}
178
179void Tst_qsensorgestureTest::tst_manager()
180{
181 QSensorGestureManager *manager2;
182 manager2 = new QSensorGestureManager(this);
183 QVERIFY(manager2 != 0);
184 delete manager2;
185}
186
187void Tst_qsensorgestureTest::tst_manager_gestureids()
188{
189 QStringList idList;
190 QSensorGestureManager manager;
191 idList = manager.gestureIds();
192
193 QVERIFY(idList.count() > 0);
194
195 QVERIFY(idList.contains("QtSensors.test"));
196 QVERIFY(idList.contains("QtSensors.test2"));
197 QVERIFY(idList.contains("QtSensors.test.dup"));
198}
199
200void Tst_qsensorgestureTest::tst_manager_recognizerSignals()
201{
202 QStringList idList;
203
204 QSensorGestureManager manager;
205 idList = manager.gestureIds();
206
207 idList.removeOne(t: "QtSensors.test.dup");
208
209 for (int i = 0; i < idList.count(); i++) {
210
211 QStringList recognizerSignalsList = manager.recognizerSignals(recognizerId: idList.at(i));
212
213 if (idList.at(i) == "QtSensors.test") {
214 QStringList signalList;
215 signalList << "detected(QString)";
216 signalList << "tested()";
217 QCOMPARE(recognizerSignalsList.count(), 2);
218
219 QCOMPARE(recognizerSignalsList, signalList);
220
221 } else if (idList.at(i) == "QtSensors.test2") {
222 QStringList signalList;
223 signalList << "detected(QString)";
224 signalList << "test2()";
225 signalList << "test3(bool)";
226
227 QCOMPARE(recognizerSignalsList.count(), 3);
228 QCOMPARE(recognizerSignalsList, signalList);
229 }
230 }
231}
232
233void Tst_qsensorgestureTest::tst_manager_registerSensorGestureRecognizer()
234{
235 QSensorGestureManager manager;
236 int num = manager.gestureIds().count();
237 QSensorGestureRecognizer *recognizer = new QTest3Recognizer;
238 bool ok = manager.registerSensorGestureRecognizer(recognizer);
239 QCOMPARE(ok, true);
240 QCOMPARE(num+1, manager.gestureIds().count());
241
242 recognizer = new QTest3Recognizer;
243// QTest::ignoreMessage(QtWarningMsg, "\"QtSensors/test3\" is already known");
244 ok = manager.registerSensorGestureRecognizer(recognizer);
245 QCOMPARE(ok, false);
246 QCOMPARE(num+1, manager.gestureIds().count());
247}
248
249void Tst_qsensorgestureTest::tst_manager__newSensorAvailable()
250{
251 QSensorGestureManager manager;
252 QSensorGestureManager manager2;
253
254 QSignalSpy spy_manager_available(&manager, SIGNAL(newSensorGestureAvailable()));
255 QSignalSpy spy_manager2_available(&manager2, SIGNAL(newSensorGestureAvailable()));
256
257 manager.gestureIds();
258 QCOMPARE(spy_manager_available.count(),0);
259 QCOMPARE(spy_manager2_available.count(),0);
260
261 QTest3Recognizer *recognizer = new QTest3Recognizer;
262 recognizer->changeId(id: "QtSensors.test4");
263
264 bool ok = manager.registerSensorGestureRecognizer(recognizer);
265 QCOMPARE(ok, true);
266 QCOMPARE(spy_manager_available.count(),1);
267
268 recognizer = new QTest3Recognizer;
269 recognizer->changeId(id: "QtSensors.test4");
270// QTest::ignoreMessage(QtWarningMsg, "\"QtSensors.test4\" is already known");
271 ok = manager.registerSensorGestureRecognizer(recognizer);
272 QCOMPARE(ok, false);
273 QCOMPARE(spy_manager_available.count(),1);
274 QCOMPARE(spy_manager2_available.count(),1);
275
276 QScopedPointer<QSensorGesture> test4sg;
277 test4sg.reset(other: new QSensorGesture(QStringList() << "QtSensors.test4"));
278 QVERIFY(!test4sg->validIds().isEmpty());
279 QVERIFY(test4sg->invalidIds().isEmpty());
280}
281
282
283void Tst_qsensorgestureTest::tst_sensor_gesture_signals()
284{
285 QStringList testidList;
286 testidList << "QtSensors.test";
287 testidList << "QtSensors.test2";
288
289 Q_FOREACH (const QString &plugin, testidList) {
290
291 QScopedPointer<QSensorGesture> thisGesture(new QSensorGesture(QStringList() << plugin));
292
293 QSignalSpy spy_gesture_detected(thisGesture.data(), SIGNAL(detected(QString)));
294 QScopedPointer<QSignalSpy> spy_gesture_tested(0);
295
296 if (plugin == "QtSensors.test") {
297 QStringList signalList;
298 signalList << "detected(QString)";
299 signalList << "tested()";
300
301 QCOMPARE(thisGesture->gestureSignals().count(), 2);
302 QCOMPARE(thisGesture->gestureSignals(), signalList);
303
304 QCOMPARE(thisGesture->gestureSignals().at(1), QString("tested()"));
305
306 spy_gesture_tested.reset(other: new QSignalSpy(thisGesture.data(), SIGNAL(tested())));
307 } else if (plugin == "QtSensors.test2") {
308 QStringList signalList;
309 signalList << "detected(QString)";
310 signalList << "test2()";
311 signalList << "test3(bool)";
312 QCOMPARE(thisGesture->gestureSignals().count(), 3);
313 QCOMPARE(thisGesture->gestureSignals(), signalList);
314
315 QCOMPARE(thisGesture->gestureSignals().at(1), QString("test2()"));
316 spy_gesture_tested.reset(other: new QSignalSpy(thisGesture.data(), SIGNAL(test2())));
317 }
318
319 QVERIFY(!thisGesture->validIds().isEmpty());
320 thisGesture->startDetection();
321
322 QCOMPARE(spy_gesture_detected.count(),1);
323
324 if (plugin == "QtSensors.test") {
325 QCOMPARE(spy_gesture_tested->count(),1);
326 QList<QVariant> arguments ;
327 arguments = spy_gesture_detected.takeFirst(); // take the first signal
328 QCOMPARE(arguments.at(0).toString(), QString("tested"));
329 } else if (plugin == "QtSensors.test2") {
330 QCOMPARE(spy_gesture_tested->count(),1);
331 }
332 }
333
334}
335
336
337void Tst_qsensorgestureTest::tst_sensor_gesture_threaded()
338{
339
340 QScopedPointer<QSensorGesture> gesture(new QSensorGesture(QStringList() << "QtSensors.test"));
341
342 QScopedPointer<QThread> thread(new QThread);
343 QScopedPointer<QSensorGestureWithSlots> t_gesture(new QSensorGestureWithSlots(QStringList() << "QtSensors.test"));
344 t_gesture->moveToThread(thread: thread.data());
345
346 currentSignal = removeParens(arg: gesture->gestureSignals().at(i: 0));
347
348 QSignalSpy thread_gesture(t_gesture->gesture, SIGNAL(detected(QString)));
349 QSignalSpy spy_gesture2(gesture.data(), SIGNAL(detected(QString)));
350
351 QCOMPARE(gesture->isActive(),false);
352 gesture->startDetection();
353
354 QCOMPARE(thread_gesture.count(),0);
355 QCOMPARE(spy_gesture2.count(),1);
356
357 QCOMPARE(gesture->isActive(),true);
358
359 thread->start();
360 QTimer::singleShot(msec: 0, receiver: t_gesture.data(), SLOT(startDetection())); // Delivered on the thread
361
362 QTRY_COMPARE(t_gesture->gesture->isActive(),true);
363
364 QTRY_VERIFY(thread_gesture.count() > 0);
365 spy_gesture2.clear();
366 QTRY_VERIFY(spy_gesture2.count() > 0);
367
368 QTimer::singleShot(msec: 0, receiver: t_gesture.data(), SLOT(stopDetection())); // Delivered on the thread
369
370 QTRY_COMPARE(t_gesture->gesture->isActive(),false);
371 QCOMPARE(gesture->isActive(),true);
372
373 thread->quit();
374 thread->wait();
375}
376
377void Tst_qsensorgestureTest::tst_sensor_gesture()
378{
379 QScopedPointer<QSensorGesture> gesture(new QSensorGesture(QStringList() << "QtSensors.test"));
380
381 QScopedPointer<QSensorGesture> gesture2(new QSensorGesture(QStringList() << "QtSensors.test2"));
382 QScopedPointer<QSensorGesture> gesture3(new QSensorGesture(QStringList() << "QtSensors.test2"));
383
384 QCOMPARE(gesture->validIds(),QStringList() << "QtSensors.test");
385
386 QCOMPARE(gesture->gestureSignals().at(1), QString("tested()"));
387
388 QVERIFY(gesture->invalidIds().isEmpty());
389 QVERIFY(gesture2->invalidIds().isEmpty());
390 QVERIFY(gesture3->invalidIds().isEmpty());
391
392 currentSignal = removeParens(arg: gesture->gestureSignals().at(i: 1));
393
394 QSignalSpy spy_gesture(gesture.data(), SIGNAL(detected(QString)));
395
396 QSignalSpy spy_gesture2(gesture2.data(), SIGNAL(detected(QString)));
397
398 QSignalSpy spy_gesture3_detected(gesture3.data(), SIGNAL(detected(QString)));
399
400 QSignalSpy spy_gesture4_test2(gesture3.data(), SIGNAL(test2()));
401 QSignalSpy spy_gesture5_test3(gesture3.data(), SIGNAL(test3(bool)));
402
403
404 QCOMPARE(gesture->isActive(),false);
405 gesture->startDetection();
406
407 QCOMPARE(spy_gesture.count(),1);
408
409 QCOMPARE(gesture->isActive(),true);
410 QCOMPARE(gesture2->validIds(),QStringList() <<"QtSensors.test2");
411 QCOMPARE(gesture2->gestureSignals().at(1), QString("test2()"));
412 currentSignal = removeParens(arg: gesture2->gestureSignals().at(i: 1));
413
414 connect(sender: gesture2.data(),SIGNAL(detected(QString)),
415 receiver: this,SLOT(shakeDetected(QString)));
416
417 QCOMPARE(gesture2->isActive(),false);
418
419 gesture2->startDetection();
420
421 QCOMPARE(gesture2->isActive(),true);
422
423 QCOMPARE(spy_gesture2.count(),1);
424
425 QCOMPARE(spy_gesture3_detected.count(),0);
426
427 gesture2->stopDetection();
428
429 QCOMPARE(gesture2->isActive(),false);
430 QCOMPARE(gesture3->isActive(),false);
431
432 gesture3->startDetection();
433
434 QCOMPARE(gesture3->isActive(),true);
435 QCOMPARE(gesture2->isActive(),false);
436
437 QCOMPARE(spy_gesture.count(),1);
438
439 QCOMPARE(spy_gesture2.count(),1);
440
441
442 QCOMPARE(spy_gesture3_detected.count(),1);
443
444 QCOMPARE(spy_gesture4_test2.count(),1);
445
446 QCOMPARE(spy_gesture5_test3.count(),1);
447
448 QList<QVariant> arguments2 = spy_gesture5_test3.takeFirst();
449 QCOMPARE(arguments2.at(0).toBool(), true);
450}
451
452void Tst_qsensorgestureTest::tst_recognizer()
453{
454 QScopedPointer<QSensorGesture> gesture(new QSensorGesture(QStringList() << "QtSensors.test"));
455 QScopedPointer<QSensorGesture> gesture2(new QSensorGesture(QStringList() << "QtSensors.test"));
456
457 QSignalSpy spy_gesture(gesture.data(), SIGNAL(detected(QString)));
458 QSignalSpy spy_gesture2(gesture2.data(), SIGNAL(detected(QString)));
459
460 QCOMPARE(gesture->isActive(),false);
461 QCOMPARE(gesture2->isActive(),false);
462
463 currentSignal = removeParens(arg: gesture2->gestureSignals().at(i: 0));
464
465 gesture2->startDetection();//activate 2
466
467 QCOMPARE(gesture->isActive(),false);
468 QCOMPARE(gesture2->isActive(),true);
469
470 QCOMPARE(spy_gesture.count(),0);
471
472 QCOMPARE(spy_gesture2.count(),1);
473
474 QList<QVariant> arguments = spy_gesture2.takeFirst();
475 QCOMPARE(arguments.at(0).toString(), QString("tested"));
476
477 QCOMPARE(spy_gesture2.count(),0);
478
479 gesture->startDetection(); //activate 1
480
481 QCOMPARE(gesture->isActive(),true);
482 QCOMPARE(gesture2->isActive(),true);
483
484 QTRY_COMPARE(spy_gesture.count(),1);
485
486 QCOMPARE(spy_gesture2.count(),1);
487
488 arguments = spy_gesture.takeFirst(); // take the first signal
489 QCOMPARE(arguments.at(0).toString(), QString("tested"));
490 spy_gesture2.removeFirst();
491
492 gesture->stopDetection(); //stop 1 gesture object
493
494 QCOMPARE(gesture->isActive(),false);
495 QCOMPARE(gesture2->isActive(),true);
496
497 spy_gesture2.clear();
498 gesture2->startDetection();
499
500 QCOMPARE(gesture->isActive(),false);
501 QCOMPARE(spy_gesture.count(),0);
502
503 QCOMPARE(gesture2->isActive(),true);
504
505 QTRY_COMPARE(spy_gesture2.count(), 1);
506}
507
508
509void Tst_qsensorgestureTest::tst_sensorgesture_noid()
510{
511 QScopedPointer<QSensorGesture> gesture(new QSensorGesture(QStringList() << "QtSensors.noid"));
512 QVERIFY(gesture->validIds().isEmpty());
513 QCOMPARE(gesture->invalidIds(), QStringList() << "QtSensors.noid");
514
515 QTest::ignoreMessage(type: QtWarningMsg, message: "QSignalSpy: No such signal: 'detected(QString)'");
516 QSignalSpy spy_gesture(gesture.data(), SIGNAL(detected(QString)));
517
518 QCOMPARE(spy_gesture.count(),0);
519
520 gesture->startDetection();
521 QCOMPARE(gesture->isActive(),false);
522 QCOMPARE(spy_gesture.count(),0);
523
524 gesture->stopDetection();
525 QCOMPARE(gesture->isActive(),false);
526 QCOMPARE(spy_gesture.count(),0);
527
528 QVERIFY(gesture->gestureSignals().isEmpty());
529
530 QCOMPARE(gesture->invalidIds() ,QStringList() << "QtSensors.noid");
531
532 QSensorGestureManager manager;
533 QStringList recognizerSignalsList = manager.recognizerSignals( recognizerId: "QtSensors.noid");
534 QVERIFY(recognizerSignalsList.isEmpty());
535
536 QVERIFY(!recognizerSignalsList.contains("QtSensors.noid"));
537
538 QSensorGestureRecognizer *fakeRecognizer = manager.sensorGestureRecognizer(id: "QtSensors.noid");
539 QVERIFY(!fakeRecognizer);
540}
541
542void Tst_qsensorgestureTest::tst_sensor_gesture_multi()
543{
544
545 QStringList ids;
546 ids << "QtSensors.test";
547 ids <<"QtSensors.test2";
548 ids << "QtSensors.bogus";
549
550 QScopedPointer<QSensorGesture> gesture(new QSensorGesture(ids));
551 QStringList gestureSignals = gesture->gestureSignals();
552
553 gestureSignals.removeDuplicates() ;
554 QCOMPARE(gestureSignals, gesture->gestureSignals());
555
556 QCOMPARE(gesture->gestureSignals().count(), 4);
557 QCOMPARE(gesture->invalidIds(), QStringList() << "QtSensors.bogus");
558
559 QCOMPARE(gesture->isActive(),false);
560
561 QSignalSpy spy_gesture_detected(gesture.data(), SIGNAL(detected(QString)));
562 gesture->startDetection();
563 QCOMPARE(gesture->isActive(),true);
564 QCOMPARE(spy_gesture_detected.count(),2);
565
566 QList<QVariant> arguments ;
567 arguments = spy_gesture_detected.takeAt(i: 0);
568 QCOMPARE(arguments.at(0).toString(), QString("tested"));
569
570 arguments = spy_gesture_detected.takeAt(i: 0);
571 QCOMPARE(arguments.at(0).toString(), QString("test2"));
572
573 QTRY_COMPARE(spy_gesture_detected.count(),1);
574
575 gesture->stopDetection();
576
577 QCOMPARE(gesture->isActive(),false);
578
579 {
580 QSensorGestureManager manager;
581 QVERIFY(!manager.gestureIds().contains("QtSensors.bogus"));
582 QSensorGestureRecognizer *recognizer = manager.sensorGestureRecognizer(id: "QtSensors.bogus");
583 QVERIFY(recognizer == 0);
584 }
585
586}
587
588void Tst_qsensorgestureTest::shakeDetected(const QString &type)
589{
590 QCOMPARE(type,currentSignal);
591}
592
593void Tst_qsensorgestureTest::tst_sensor_gesture_notinitialized()
594{
595 QTest::ignoreMessage(type: QtWarningMsg, message: "\"QtSensors.test.dup\" from the plugin \"TestGesturesDup\" is already known.");
596 QSensorGestureManager manager;
597 QSensorGestureRecognizer *recognizer = manager.sensorGestureRecognizer(id: "QtSensors.test");
598
599 QTest::ignoreMessage(type: QtWarningMsg, message: "Not starting. Gesture Recognizer not initialized");
600 recognizer->startBackend();
601 QVERIFY(recognizer->isActive() == false);
602
603 QTest::ignoreMessage(type: QtWarningMsg, message: "Not stopping. Gesture Recognizer not initialized");
604 recognizer->stopBackend();
605 QVERIFY(recognizer->isActive() == false);
606
607 recognizer->createBackend();
608 QVERIFY(recognizer->isActive() == false);
609
610}
611
612
613QTEST_MAIN(Tst_qsensorgestureTest);
614
615#include "tst_qsensorgesturetest.moc"
616

source code of qtsensors/tests/auto/qsensorgestures/tst_qsensorgesturetest.cpp