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//TESTED_COMPONENT=src/sensors
30
31#include <QtCore/QObject>
32#include <QTest>
33#include <QtCore/QDebug>
34#include <QtCore/QFile>
35#include <QSignalSpy>
36#include <QtSensors/QSensorManager>
37
38#include "qsensor.h"
39#include "test_sensor.h"
40#include "test_sensor2.h"
41#include "test_sensorimpl.h"
42#include "test_backends.h"
43
44QT_BEGIN_NAMESPACE
45
46// The unit test needs to change the behaviour of the library. It does this
47// through an exported but undocumented function.
48Q_SENSORS_EXPORT void sensors_unit_test_hook(int index);
49bool operator==(const qoutputrange &orl1, const qoutputrange &orl2)
50{
51 return (orl1.minimum == orl2.minimum &&
52 orl1.maximum == orl2.maximum &&
53 orl1.accuracy == orl2.accuracy);
54}
55
56namespace QTest {
57 template<> char *toString(const qoutputrangelist &orl)
58 {
59 QStringList list;
60 foreach (const qoutputrange &item, orl) {
61 list << QString("%1-%2%3%4").arg(a: item.minimum).arg(a: item.maximum).arg(a: QString::fromWCharArray(string: L"\u00B1")).arg(a: item.accuracy);
62 }
63 QString ret = QString("qoutputrangelist: (%1)").arg(a: list.join(sep: "), ("));
64 return qstrdup(ret.toLatin1().data());
65 }
66 template<> char *toString(const QList<QByteArray> &data)
67 {
68 QStringList list;
69 foreach (const QByteArray &str, data) {
70 list << QString::fromLatin1(str);
71 }
72 QString ret = QString("QList<QByteArray>: (%1)").arg(a: list.join(sep: "), ("));
73 return qstrdup(ret.toLatin1().data());
74 }
75}
76
77
78class MyFilter : public TestSensorFilter { bool filter(TestSensorReading *) override { return false; } };
79
80class ModFilter : public TestSensorFilter
81{
82 bool filter(TestSensorReading *reading) override
83 {
84 reading->setTest(3);
85 return true;
86 }
87};
88
89class MyFactory : public QSensorBackendFactory
90{
91 QSensorBackend *createBackend(QSensor * /*sensor*/) override
92 {
93 return 0;
94 }
95};
96
97/*
98 Unit test for QSensor class.
99*/
100class tst_QSensor : public QObject
101{
102 Q_OBJECT
103
104public:
105 tst_QSensor()
106 {
107 qputenv(varName: "QT_SENSORS_LOAD_PLUGINS", value: "0"); // Do not load plugins
108 }
109
110private slots:
111 void initTestCase()
112 {
113 }
114
115 void cleanupTestCase()
116 {
117
118#ifdef WAIT_AT_END
119 QFile _stdin;
120 _stdin.open(1, QIODevice::ReadOnly);
121 _stdin.readLine();
122#endif
123 }
124
125 // This test MUST be first
126 void testRecursiveLoadPlugins()
127 {
128 TestSensor sensor;
129
130 // The logic for the test is in test_sensorplugin.cpp (which warns and aborts if the test fails)
131 (void)QSensor::sensorTypes();
132
133 // Checking that the availableSensorsChanged() signal was not emitted too many times while loading plugins.
134 QCOMPARE(sensor.sensorsChangedEmitted, 1);
135 }
136
137 void testTypeRegistered()
138 {
139 QList<QByteArray> expected;
140 expected << TestSensor::type << TestSensor2::type;
141 QList<QByteArray> actual = QSensor::sensorTypes();
142 std::sort(first: actual.begin(), last: actual.end()); // The actual list is not in a defined order
143 QCOMPARE(actual, expected);
144 }
145
146 void testSensorRegistered()
147 {
148 QList<QByteArray> expected;
149 expected << "test sensor 2" << "test sensor 3" << testsensorimpl::id;
150 QList<QByteArray> actual = QSensor::sensorsForType(type: TestSensor::type);
151 std::sort(first: actual.begin(), last: actual.end()); // The actual list is not in a defined order
152 QCOMPARE(actual, expected);
153 }
154
155 void testSensorDefault()
156 {
157 QByteArray expected = testsensorimpl::id;
158 QByteArray actual = QSensor::defaultSensorForType(type: TestSensor::type);
159 QCOMPARE(actual, expected);
160 }
161
162 void testBadDefaultFromConfig()
163 {
164 QSensorManager::setDefaultBackend(type: QByteArray(TestSensor::type), identifier: QByteArray("bogus id"));
165 QByteArray expected = testsensorimpl::id;
166 QByteArray actual = QSensor::defaultSensorForType(type: TestSensor::type);
167 QCOMPARE(actual, expected);
168 }
169
170 void testGoodDefaultFromConfig()
171 {
172 QSensorManager::setDefaultBackend(type: QByteArray(TestSensor::type), identifier: QByteArray(testsensorimpl::id));
173 QByteArray expected = testsensorimpl::id;
174 QByteArray actual = QSensor::defaultSensorForType(type: TestSensor::type);
175 QCOMPARE(actual, expected);
176 }
177
178 void testNoSensorsForType()
179 {
180 QList<QByteArray> expected;
181 QList<QByteArray> actual = QSensor::sensorsForType(type: "bogus type");
182 QCOMPARE(actual, expected);
183 }
184
185 void testNoDefaultForType()
186 {
187 QByteArray expected;
188 QByteArray actual = QSensor::defaultSensorForType(type: "bogus type");
189 QCOMPARE(actual, expected);
190 }
191
192 void testCreation()
193 {
194 TestSensor sensor;
195 sensor.connectToBackend();
196 QByteArray expected = testsensorimpl::id;
197 QByteArray actual = sensor.identifier();
198 QCOMPARE(actual, expected);
199 }
200
201 void testSetIdentifierFail()
202 {
203 TestSensor sensor;
204 sensor.setIdentifier(testsensorimpl::id);
205 sensor.connectToBackend();
206 QVERIFY(sensor.isConnectedToBackend());
207 QByteArray expected = testsensorimpl::id;
208 QByteArray actual = sensor.identifier();
209 QCOMPARE(actual, expected);
210
211 QTest::ignoreMessage(type: QtWarningMsg, message: "ERROR: Cannot call QSensor::setIdentifier while connected to a backend!");
212 sensor.setIdentifier("dummy.accelerometer");
213 expected = testsensorimpl::id;
214 actual = sensor.identifier();
215 QCOMPARE(actual, expected);
216 }
217
218 void testBadDefaultCreation()
219 {
220 QSensorManager::setDefaultBackend(type: QByteArray(TestSensor::type), identifier: QByteArray("test sensor 2"));
221 TestSensor sensor;
222 QTest::ignoreMessage(type: QtWarningMsg, message: "Can't create backend \"test sensor 2\"");
223 sensor.connectToBackend();
224 QByteArray expected = testsensorimpl::id;
225 QByteArray actual = sensor.identifier();
226 QCOMPARE(actual, expected);
227 }
228
229 void testBadCreation()
230 {
231 QSensor sensor("bogus type");
232 sensor.connectToBackend();
233 QByteArray expected; // should be null
234 QByteArray actual = sensor.identifier();
235 QCOMPARE(actual, expected);
236 }
237
238 void testTimestamp()
239 {
240 TestSensor sensor;
241 sensor.connectToBackend();
242 QVERIFY(sensor.reading() != 0);
243 quint64 timestamp = sensor.reading()->timestamp();
244 qtimestamp timestamp2 = sensor.reading()->timestamp();
245 QVERIFY(timestamp == quint64());
246 QVERIFY(timestamp2 == qtimestamp());
247 sensor.setProperty(name: "doThis", value: "setOne");
248 sensor.start();
249 timestamp = sensor.reading()->timestamp();
250 timestamp2 = sensor.reading()->timestamp();
251 QVERIFY(timestamp == 1);
252 QVERIFY(timestamp2 == 1);
253 }
254
255 void testStart()
256 {
257 TestSensor sensor;
258 sensor.start();
259 QVERIFY(sensor.isActive());
260 sensor.start();
261 QVERIFY(sensor.isActive());
262 }
263
264 void testBadStart()
265 {
266 QSensor sensor("bogus type");
267 sensor.start();
268 QVERIFY(!sensor.isActive());
269 }
270
271 void testStop()
272 {
273 TestSensor sensor;
274 sensor.stop();
275 QVERIFY(!sensor.isActive());
276 sensor.start();
277 QVERIFY(sensor.isActive());
278 sensor.stop();
279 QVERIFY(!sensor.isActive());
280 }
281
282 void testMetaData()
283 {
284 TestSensor sensor;
285
286 {
287 bool actual = sensor.isConnectedToBackend();
288 bool expected = false;
289 QCOMPARE(actual, expected);
290 }
291
292 sensor.connectToBackend();
293
294 {
295 bool actual = sensor.isConnectedToBackend();
296 bool expected = true;
297 QCOMPARE(actual, expected);
298 }
299
300 {
301 QString actual = sensor.description();
302 QString expected = "sensor description";
303 QCOMPARE(actual, expected);
304 }
305
306 {
307 qoutputrangelist actual = sensor.outputRanges();
308 qoutputrangelist expected;
309 qoutputrange r; r.minimum = 0; r.maximum = 1; r.accuracy = 0.5;
310 expected << r;
311 r.minimum = 0; r.maximum = 2; r.accuracy = 1;
312 expected << r;
313 QCOMPARE(actual, expected);
314 }
315
316 {
317 int actual = sensor.outputRange();
318 int expected = -1;
319 QCOMPARE(actual, expected);
320
321 sensor.setOutputRange(0);
322
323 actual = sensor.outputRange();
324 expected = 0;
325 QCOMPARE(actual, expected);
326 }
327
328 {
329 qrangelist actual = sensor.availableDataRates();
330 qrangelist expected = qrangelist() << qrange(100,100);
331 QCOMPARE(actual, expected);
332 }
333
334 {
335 TestSensor sensor;
336 sensor.setProperty(name: "doThis", value: "rates");
337 sensor.connectToBackend();
338 qrangelist actual = sensor.availableDataRates();
339 qrangelist expected = qrangelist() << qrange(100,100);
340 QCOMPARE(actual, expected);
341 }
342
343 // Test that a previously-set, valid data rate is retained
344 {
345 TestSensor sensor;
346 sensor.setDataRate(100);
347 sensor.setProperty(name: "doThis", value: "rates");
348 sensor.connectToBackend();
349 int actual = sensor.dataRate();
350 int expected = 100;
351 QCOMPARE(actual, expected);
352 }
353
354 // Test that a previously-set, invalid data rate is retained
355 {
356 TestSensor sensor;
357 sensor.setDataRate(50);
358 sensor.setProperty(name: "doThis", value: "rates");
359 sensor.connectToBackend();
360 int actual = sensor.dataRate();
361 int expected = 50;
362 QCOMPARE(actual, expected);
363 }
364
365 {
366 TestSensor sensor;
367 sensor.setProperty(name: "doThis", value: "rates(0)");
368 QTest::ignoreMessage(type: QtWarningMsg, message: "ERROR: Cannot call QSensorBackend::setDataRates with 0");
369 sensor.connectToBackend();
370 }
371
372 {
373 TestSensor sensor;
374 sensor.setProperty(name: "doThis", value: "rates(nodef)");
375 QTest::ignoreMessage(type: QtWarningMsg, message: "ERROR: Cannot call QSensorBackend::setDataRates with an invalid sensor");
376 sensor.connectToBackend();
377 }
378
379 {
380 int actual = sensor.dataRate();
381 int expected = 0;
382 QCOMPARE(actual, expected);
383
384 sensor.setDataRate(100);
385
386 actual = sensor.dataRate();
387 expected = 100;
388 QCOMPARE(actual, expected);
389 }
390
391 // Test the generic accessor functions
392 TestSensorReading *reading = sensor.reading();
393 QCOMPARE(reading->valueCount(), 1);
394 reading->setTest(1);
395 QCOMPARE(reading->test(), reading->value(0).toInt());
396 }
397
398 void testFilter()
399 {
400 TestSensor sensor;
401 sensor.connectToBackend();
402
403 QList<QSensorFilter*> actual = sensor.filters();
404 QList<QSensorFilter*> expected = QList<QSensorFilter*>();
405 QCOMPARE(actual, expected);
406
407 QTest::ignoreMessage(type: QtWarningMsg, message: "addFilter: passed a null filter!");
408 sensor.addFilter(filter: 0);
409
410 QTest::ignoreMessage(type: QtWarningMsg, message: "removeFilter: passed a null filter!");
411 sensor.removeFilter(filter: 0);
412
413 MyFilter *filter = new MyFilter;
414 sensor.addFilter(filter);
415
416 actual = sensor.filters();
417 expected = QList<QSensorFilter*>() << filter;
418 QCOMPARE(actual, expected);
419
420 MyFilter *filter2 = new MyFilter;
421 sensor.addFilter(filter: filter2);
422
423 actual = sensor.filters();
424 expected = QList<QSensorFilter*>() << filter << filter2;
425 QCOMPARE(actual, expected);
426
427 delete filter2;
428
429 actual = sensor.filters();
430 expected = QList<QSensorFilter*>() << filter;
431 QCOMPARE(actual, expected);
432
433 sensor.removeFilter(filter);
434
435 actual = sensor.filters();
436 expected = QList<QSensorFilter*>();
437 QCOMPARE(actual, expected);
438
439 delete filter;
440 }
441
442 void testFilter2()
443 {
444 TestSensor sensor;
445 sensor.setProperty(name: "doThis", value: "setOne");
446 TestSensorFilter *filter1 = new ModFilter;
447 TestSensorFilter *filter2 = new MyFilter;
448 sensor.addFilter(filter: filter1);
449 sensor.start();
450 QCOMPARE(sensor.reading()->test(), 3);
451 sensor.stop();
452 sensor.reading()->setTest(1);
453 sensor.addFilter(filter: filter2);
454 sensor.start();
455 QCOMPARE(sensor.reading()->test(), 1);
456 sensor.stop();
457 delete filter1;
458 delete filter2;
459 }
460
461 void testFilter3()
462 {
463 TestSensor sensor;
464 sensor.setProperty(name: "doThis", value: "setOne");
465 QSignalSpy spy(&sensor, SIGNAL(readingChanged()));
466 sensor.start();
467 QCOMPARE(spy.count(), 1); // reading changes
468 sensor.stop();
469
470 TestSensorFilter *filter2 = new MyFilter;
471 sensor.addFilter(filter: filter2);
472 sensor.start();
473 QCOMPARE(spy.count(), 1); // filter suppresses reading so it does not change
474 sensor.stop();
475 delete filter2;
476
477 TestSensorFilter *filter1 = new ModFilter;
478 sensor.addFilter(filter: filter1);
479 sensor.start();
480 QCOMPARE(spy.count(), 2); // filter does not suppress reading
481 sensor.stop();
482 delete filter1;
483 }
484
485 void testStart2()
486 {
487 TestSensor sensor;
488 sensor.connectToBackend();
489
490 sensor.setProperty(name: "doThis", value: "stop");
491 sensor.start();
492 QVERIFY(!sensor.isActive());
493 sensor.stop();
494
495 sensor.setProperty(name: "doThis", value: "error");
496 sensor.start();
497 QVERIFY(sensor.error() == 1);
498 // Yes, this is non-intuitive but the sensor
499 // decides if an error is fatal or not.
500 // In this case our test sensor is reporting a
501 // non-fatal error so the sensor will start.
502 QVERIFY(sensor.isActive());
503 sensor.stop();
504
505 sensor.setProperty(name: "doThis", value: "setOne");
506 sensor.start();
507 QCOMPARE(sensor.reading()->timestamp(), quint64(1));
508 QCOMPARE(sensor.reading()->test(), 1);
509 sensor.stop();
510
511 sensor.setProperty(name: "doThis", value: "setTwo");
512 sensor.start();
513 QCOMPARE(sensor.reading()->timestamp(), quint64(2));
514 QCOMPARE(sensor.reading()->test(), 2);
515 sensor.stop();
516 }
517
518 void testSetBadDataRate()
519 {
520 TestSensor sensor;
521 sensor.connectToBackend();
522
523 sensor.setDataRate(1);
524 QCOMPARE(sensor.dataRate(), 1);
525
526 sensor.setDataRate(1000);
527 QCOMPARE(sensor.dataRate(), 1000);
528 }
529
530 void testSetBadDataRateWhenNotConnected()
531 {
532 TestSensor sensor;
533 sensor.setDataRate(0);
534 QCOMPARE(sensor.dataRate(), 0);
535 sensor.setDataRate(300);
536 QCOMPARE(sensor.dataRate(), 300);
537 sensor.setDataRate(350);
538 sensor.connectToBackend();
539 QCOMPARE(sensor.dataRate(), 350);
540 }
541
542 void testSetBadOutputRange()
543 {
544 TestSensor sensor;
545 sensor.connectToBackend();
546
547 sensor.setOutputRange(-1);
548 QCOMPARE(sensor.outputRange(), -1);
549 QTest::ignoreMessage(type: QtWarningMsg, message: "setOutputRange: 300 is not supported by the sensor.");
550 sensor.setOutputRange(300);
551 QCOMPARE(sensor.outputRange(), -1);
552 }
553
554 void testSetBadOutputRangeWhenNotConnected()
555 {
556 TestSensor sensor;
557 sensor.setOutputRange(300);
558 QCOMPARE(sensor.outputRange(), 300);
559 sensor.setOutputRange(350);
560 QTest::ignoreMessage(type: QtWarningMsg, message: "setOutputRange: 350 is not supported by the sensor.");
561 sensor.connectToBackend();
562 QCOMPARE(sensor.outputRange(), -1);
563 QTest::ignoreMessage(type: QtWarningMsg, message: "setOutputRange: -2 is not supported by the sensor.");
564 sensor.setOutputRange(-2);
565 QCOMPARE(sensor.outputRange(), -1);
566 }
567
568 void testEnumHandling()
569 {
570 {
571 QAmbientLightReading reading;
572 for (int i = 0; i <= 6; i++) {
573 QAmbientLightReading::LightLevel setting = static_cast<QAmbientLightReading::LightLevel>(i);
574 QAmbientLightReading::LightLevel expected = setting;
575 if (i == 6)
576 expected = QAmbientLightReading::Undefined;
577 reading.setLightLevel(setting);
578 QCOMPARE(reading.lightLevel(), expected);
579 }
580 }
581
582 {
583 QOrientationReading reading;
584 for (int i = 0; i <= 7; i++) {
585 QOrientationReading::Orientation setting = static_cast<QOrientationReading::Orientation>(i);
586 QOrientationReading::Orientation expected = setting;
587 if (i == 7)
588 expected = QOrientationReading::Undefined;
589 reading.setOrientation(setting);
590 QCOMPARE(reading.orientation(), expected);
591 }
592 }
593
594 {
595 QTapReading reading;
596 reading.setTapDirection(QTapReading::Undefined);
597 QCOMPARE(reading.tapDirection(), QTapReading::Undefined);
598 reading.setTapDirection(QTapReading::X_Pos);
599 QCOMPARE(reading.tapDirection(), QTapReading::X_Pos);
600 reading.setTapDirection(QTapReading::X_Neg);
601 QCOMPARE(reading.tapDirection(), QTapReading::X_Neg);
602 reading.setTapDirection(QTapReading::Y_Pos);
603 QCOMPARE(reading.tapDirection(), QTapReading::Y_Pos);
604 reading.setTapDirection(QTapReading::Y_Neg);
605 QCOMPARE(reading.tapDirection(), QTapReading::Y_Neg);
606 reading.setTapDirection(QTapReading::Z_Pos);
607 QCOMPARE(reading.tapDirection(), QTapReading::Z_Pos);
608 reading.setTapDirection(QTapReading::Z_Neg);
609 QCOMPARE(reading.tapDirection(), QTapReading::Z_Neg);
610 // Directions can be ORed together
611 reading.setTapDirection(QTapReading::X_Both);
612 QCOMPARE(reading.tapDirection(), QTapReading::X_Both);
613 reading.setTapDirection(QTapReading::Y_Both);
614 QCOMPARE(reading.tapDirection(), QTapReading::Y_Both);
615 reading.setTapDirection(QTapReading::Z_Both);
616 QCOMPARE(reading.tapDirection(), QTapReading::Z_Both);
617 // You can't set just the Axis
618 reading.setTapDirection(QTapReading::X);
619 QCOMPARE(reading.tapDirection(), QTapReading::Undefined);
620 reading.setTapDirection(QTapReading::Y);
621 QCOMPARE(reading.tapDirection(), QTapReading::Undefined);
622 reading.setTapDirection(QTapReading::Z);
623 QCOMPARE(reading.tapDirection(), QTapReading::Undefined);
624 reading.setTapDirection(static_cast<QTapReading::TapDirection>(0x1000));
625 QCOMPARE(reading.tapDirection(), QTapReading::Undefined);
626 }
627 }
628
629 void testDynamicDefaultsAndGenericHandling()
630 {
631 QByteArray expected;
632 QByteArray actual;
633 MyFactory factory;
634
635 // The default for this type is null
636 expected = QByteArray();
637 actual = QSensor::defaultSensorForType(type: "random");
638 QCOMPARE(expected, actual);
639
640 // Register a bogus backend
641 QSensorManager::registerBackend(type: "random", identifier: "generic.random", factory: &factory);
642
643 // The default for this type is the newly-registered backend
644 expected = "generic.random";
645 actual = QSensor::defaultSensorForType(type: "random");
646 QCOMPARE(expected, actual);
647
648 // Register a non-generic bogus backend
649 QSensorManager::registerBackend(type: "random", identifier: "not.generic.random", factory: &factory);
650
651 // The default for this type is the newly-registered backend
652 expected = "not.generic.random";
653 actual = QSensor::defaultSensorForType(type: "random");
654 QCOMPARE(expected, actual);
655
656 // Unregister the non-generic bogus backend
657 QSensorManager::unregisterBackend(type: "random", identifier: "not.generic.random");
658
659 // The default for this type is the generic backend
660 expected = "generic.random";
661 actual = QSensor::defaultSensorForType(type: "random");
662 QCOMPARE(expected, actual);
663
664 // Unregister a bogus backend
665 QSensorManager::unregisterBackend(type: "random", identifier: "generic.random");
666
667 // The default for this type is null again
668 expected = QByteArray();
669 actual = QSensor::defaultSensorForType(type: "random");
670 QCOMPARE(expected, actual);
671
672
673 // Now test out some more of the logic
674 // Register 2 backends and unregister the first.
675 QSensorManager::registerBackend(type: "random", identifier: "random.1", factory: &factory);
676 expected = "random.1";
677 actual = QSensor::defaultSensorForType(type: "random");
678 QCOMPARE(expected, actual);
679 QSensorManager::registerBackend(type: "random", identifier: "random.2", factory: &factory);
680 expected = "random.1";
681 actual = QSensor::defaultSensorForType(type: "random");
682 QCOMPARE(expected, actual);
683 QSensorManager::unregisterBackend(type: "random", identifier: "random.1");
684 expected = "random.2";
685 actual = QSensor::defaultSensorForType(type: "random");
686 QCOMPARE(expected, actual);
687 QSensorManager::unregisterBackend(type: "random", identifier: "random.2");
688 expected = QByteArray();
689 actual = QSensor::defaultSensorForType(type: "random");
690 QCOMPARE(expected, actual);
691
692 // Now stick a generic backend into the mix and ensure the correct thing happens
693 QSensorManager::registerBackend(type: "random", identifier: "random.1", factory: &factory);
694 expected = "random.1";
695 actual = QSensor::defaultSensorForType(type: "random");
696 QCOMPARE(expected, actual);
697 QSensorManager::registerBackend(type: "random", identifier: "generic.random.2", factory: &factory);
698 expected = "random.1";
699 actual = QSensor::defaultSensorForType(type: "random");
700 QCOMPARE(expected, actual);
701 QSensorManager::registerBackend(type: "random", identifier: "random.2", factory: &factory);
702 expected = "random.1";
703 actual = QSensor::defaultSensorForType(type: "random");
704 QCOMPARE(expected, actual);
705 QSensorManager::unregisterBackend(type: "random", identifier: "random.1");
706 expected = "random.2";
707 actual = QSensor::defaultSensorForType(type: "random");
708 QCOMPARE(expected, actual);
709 QSensorManager::unregisterBackend(type: "random", identifier: "generic.random.2");
710 expected = "random.2";
711 actual = QSensor::defaultSensorForType(type: "random");
712 QCOMPARE(expected, actual);
713 QSensorManager::unregisterBackend(type: "random", identifier: "random.2");
714 expected = QByteArray();
715 actual = QSensor::defaultSensorForType(type: "random");
716 QCOMPARE(expected, actual);
717 }
718
719 void testCreation2()
720 {
721 MyFactory factory;
722
723 QSensorManager::registerBackend(type: "random", identifier: "random.1", factory: &factory);
724 QSensorManager::registerBackend(type: "random", identifier: "random.2", factory: &factory);
725 QSensor random("random");
726 // This is a sensorlog, not a warning
727 //QTest::ignoreMessage(QtWarningMsg, "no suitable backend found for requested identifier \"\" and type \"random\"");
728 random.connectToBackend();
729 QVERIFY(!random.isConnectedToBackend());
730 random.setIdentifier("random.3");
731 // This is a sensorlog, not a warning
732 //QTest::ignoreMessage(QtWarningMsg, "no backend with identifier \"random.3\" for type \"random\"");
733 random.connectToBackend();
734 QVERIFY(!random.isConnectedToBackend());
735 random.setIdentifier("random.1");
736 random.connectToBackend();
737 QVERIFY(!random.isConnectedToBackend());
738 QSensorManager::unregisterBackend(type: "random", identifier: "random.1");
739 QSensorManager::unregisterBackend(type: "random", identifier: "random.2");
740 }
741
742 void testSensorsChangedSignal()
743 {
744 TestSensor sensor;
745 MyFactory factory;
746
747 // Register a bogus backend
748 sensor.sensorsChangedEmitted = 0;
749 QSensorManager::registerBackend(type: "a random type", identifier: "a random id", factory: &factory);
750 QCOMPARE(sensor.sensorsChangedEmitted, 1);
751
752 // Register it again (creates a warning)
753 sensor.sensorsChangedEmitted = 0;
754 QTest::ignoreMessage(type: QtWarningMsg, message: "A backend with type \"a random type\" and identifier \"a random id\" has already been registered!");
755 QSensorManager::registerBackend(type: "a random type", identifier: "a random id", factory: &factory);
756 QCOMPARE(sensor.sensorsChangedEmitted, 0);
757
758 // Unregister a bogus backend
759 sensor.sensorsChangedEmitted = 0;
760 QSensorManager::unregisterBackend(type: "a random type", identifier: "a random id");
761 QCOMPARE(sensor.sensorsChangedEmitted, 1);
762
763 // Unregister an unknown identifier
764 sensor.sensorsChangedEmitted = 0;
765 QTest::ignoreMessage(type: QtWarningMsg, message: "Identifier \"a random id\" is not registered");
766 QSensorManager::unregisterBackend(type: TestSensor::type, identifier: "a random id");
767 QCOMPARE(sensor.sensorsChangedEmitted, 0);
768
769 // Unregister for an unknown type
770 sensor.sensorsChangedEmitted = 0;
771 QTest::ignoreMessage(type: QtWarningMsg, message: "No backends of type \"foo\" are registered");
772 QSensorManager::unregisterBackend(type: "foo", identifier: "bar");
773 QCOMPARE(sensor.sensorsChangedEmitted, 0);
774
775 // Make sure we've cleaned up the list of available types
776 QList<QByteArray> expected;
777 expected << TestSensor::type << TestSensor2::type;
778 QList<QByteArray> actual = QSensor::sensorTypes();
779 std::sort(first: actual.begin(), last: actual.end()); // The actual list is not in a defined order
780 QCOMPARE(actual, expected);
781 }
782
783 void testSetActive()
784 {
785 TestSensor sensor;
786 sensor.setActive(true);
787 // doesn't start till the event loop is hit
788 QVERIFY(!sensor.isActive());
789 // hit the event loop
790 QTest::qWait(ms: 0);
791 QVERIFY(sensor.isActive());
792 sensor.setActive(true);
793 QVERIFY(sensor.isActive());
794 // it does stop immediately
795 sensor.setActive(false);
796 QVERIFY(!sensor.isActive());
797 }
798
799 void testAlwaysOn()
800 {
801 TestSensor sensor;
802 QCOMPARE(sensor.isAlwaysOn(), false);
803 sensor.setAlwaysOn(true);
804 QCOMPARE(sensor.isAlwaysOn(), true);
805 sensor.setAlwaysOn(false);
806 QCOMPARE(sensor.isAlwaysOn(), false);
807 }
808
809 void testIsRegistered()
810 {
811 bool expected;
812 bool actual;
813
814 expected = true;
815 actual = QSensorManager::isBackendRegistered(type: TestSensor::type, identifier: testsensorimpl::id);
816 QCOMPARE(expected, actual);
817
818 expected = false;
819 actual = QSensorManager::isBackendRegistered(type: TestSensor::type, identifier: "random");
820 QCOMPARE(expected, actual);
821
822 expected = false;
823 actual = QSensorManager::isBackendRegistered(type: "random", identifier: "random");
824 QCOMPARE(expected, actual);
825 }
826
827 void testAllTheInterfaces()
828 {
829 register_test_backends();
830
831 TEST_SENSORINTERFACE(QAccelerometer, QAccelerometerReading, {
832 QCOMPARE(reading->x(), 1.0);
833 QCOMPARE(reading->y(), 1.0);
834 QCOMPARE(reading->z(), 1.0);
835 })
836
837 TEST_SENSORINTERFACE(QAltimeter, QAltimeterReading, {
838 QCOMPARE(reading->altitude(), 8848.0);
839 })
840
841 TEST_SENSORINTERFACE(QAmbientLightSensor, QAmbientLightReading, {
842 QCOMPARE(reading->lightLevel(), QAmbientLightReading::Twilight);
843 })
844
845 TEST_SENSORINTERFACE(QAmbientTemperatureSensor, QAmbientTemperatureReading, {
846 QCOMPARE(reading->temperature(), 30.0);
847 })
848
849 TEST_SENSORINTERFACE(QCompass, QCompassReading, {
850 QCOMPARE(reading->azimuth(), 1.0);
851 QCOMPARE(reading->calibrationLevel(), 1.0);
852 })
853
854 TEST_SENSORINTERFACE(QGyroscope, QGyroscopeReading, {
855 QCOMPARE(reading->x(), 1.0);
856 QCOMPARE(reading->y(), 1.0);
857 QCOMPARE(reading->z(), 1.0);
858 })
859
860 TEST_SENSORINTERFACE(QHolsterSensor, QHolsterReading, {
861 QCOMPARE(reading->holstered(), true);
862 })
863
864 TEST_SENSORINTERFACE(QLightSensor, QLightReading, {
865 QCOMPARE(reading->lux(), 1.0);
866 })
867
868 TEST_SENSORINTERFACE(QMagnetometer, QMagnetometerReading, {
869 QCOMPARE(reading->x(), 1.0);
870 QCOMPARE(reading->y(), 1.0);
871 QCOMPARE(reading->z(), 1.0);
872 QCOMPARE(reading->calibrationLevel(), 1.0);
873 })
874
875 TEST_SENSORINTERFACE(QOrientationSensor, QOrientationReading, {
876 QCOMPARE(reading->orientation(), QOrientationReading::LeftUp);
877 })
878
879 TEST_SENSORINTERFACE(QPressureSensor, QPressureReading, {
880 QCOMPARE(reading->pressure(), 1.0);
881 QCOMPARE(reading->temperature(), 1.0);
882 })
883
884 TEST_SENSORINTERFACE(QProximitySensor, QProximityReading, {
885 QCOMPARE(reading->close(), true);
886 })
887
888 TEST_SENSORINTERFACE(QRotationSensor, QRotationReading, {
889 QCOMPARE(reading->x(), 1.0);
890 QCOMPARE(reading->y(), 1.0);
891 QCOMPARE(reading->z(), 1.0);
892 })
893
894 TEST_SENSORINTERFACE(QTapSensor, QTapReading, {
895 QCOMPARE(reading->tapDirection(), QTapReading::Z_Both);
896 QCOMPARE(reading->isDoubleTap(), true);
897 })
898
899 TEST_SENSORINTERFACE(QTiltSensor, QTiltReading, {
900 QCOMPARE(reading->yRotation(), 1.0);
901 QCOMPARE(reading->xRotation(), 1.0);
902 })
903
904 TEST_SENSORINTERFACE(QIRProximitySensor, QIRProximityReading, {
905 QCOMPARE(reading->reflectance(), 0.5);
906 })
907
908 unregister_test_backends();
909 }
910
911 void testReadingBC()
912 {
913 // QSensorReading changed in 1.0.1 due to QTMOBILITY-226
914 // This test verifies that a backend built against the 1.0.0
915 // version of qsensor.h still runs.
916 TestSensor2 sensor;
917
918 sensor.setProperty(name: "doThis", value: "setOne");
919 sensor.start();
920 QCOMPARE(sensor.reading()->timestamp(), quint64(1));
921 QCOMPARE(sensor.reading()->test(), 1);
922 sensor.stop();
923
924 sensor.setProperty(name: "doThis", value: "setTwo");
925 sensor.start();
926 QCOMPARE(sensor.reading()->timestamp(), quint64(2));
927 QCOMPARE(sensor.reading()->test(), 2);
928 sensor.stop();
929 }
930
931 void testBusyChanged()
932 {
933 // Start an exclusive sensor
934 TestSensor sensor1;
935 sensor1.setProperty(name: "exclusive", value: true);
936 sensor1.start();
937 QVERIFY(sensor1.isActive());
938
939 // Try to start another one, sensor reports busy
940 TestSensor sensor2;
941 sensor2.setProperty(name: "exclusive", value: true);
942 sensor2.start();
943 QVERIFY(sensor2.isBusy());
944 QVERIFY(!sensor2.isActive());
945
946 // Stopping the first instance causes the busyChanged signal to be emitted from the second instance
947 QSignalSpy spy(&sensor2, SIGNAL(busyChanged()));
948 sensor1.stop();
949 QCOMPARE(spy.count(), 1);
950
951 // Now we can start the second instance
952 sensor2.start();
953 QVERIFY(sensor2.isActive());
954 }
955
956 void testSupportedFeatures()
957 {
958 TestSensor sensor;
959
960 // Not connected to backend - should report false for any feature
961 QVERIFY(!sensor.isConnectedToBackend());
962 QVERIFY(!sensor.isFeatureSupported(QSensor::AlwaysOn));
963 QVERIFY(!sensor.isFeatureSupported(QSensor::Buffering));
964 QVERIFY(!sensor.isFeatureSupported(QSensor::GeoValues));
965 QVERIFY(!sensor.isFeatureSupported(QSensor::FieldOfView));
966 QVERIFY(!sensor.isFeatureSupported(QSensor::AccelerationMode));
967
968 // Connect to backend - according to the testsensorimpl implementation, AlwaysOn and
969 // GeoValues should be supported afterwards
970 QVERIFY(sensor.connectToBackend());
971
972 QVERIFY(sensor.isFeatureSupported(QSensor::AlwaysOn));
973 QVERIFY(!sensor.isFeatureSupported(QSensor::Buffering));
974 QVERIFY(sensor.isFeatureSupported(QSensor::GeoValues));
975 QVERIFY(!sensor.isFeatureSupported(QSensor::FieldOfView));
976 QVERIFY(!sensor.isFeatureSupported(QSensor::AccelerationMode));
977 }
978};
979
980QT_END_NAMESPACE
981
982QTEST_MAIN(tst_QSensor)
983
984#include "tst_qsensor.moc"
985

source code of qtsensors/tests/auto/qsensor/tst_qsensor.cpp