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 | |
44 | QT_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. |
48 | Q_SENSORS_EXPORT void sensors_unit_test_hook(int index); |
49 | bool 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 | |
56 | namespace 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 | |
78 | class MyFilter : public TestSensorFilter { bool filter(TestSensorReading *) override { return false; } }; |
79 | |
80 | class ModFilter : public TestSensorFilter |
81 | { |
82 | bool filter(TestSensorReading *reading) override |
83 | { |
84 | reading->setTest(3); |
85 | return true; |
86 | } |
87 | }; |
88 | |
89 | class 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 | */ |
100 | class tst_QSensor : public QObject |
101 | { |
102 | Q_OBJECT |
103 | |
104 | public: |
105 | tst_QSensor() |
106 | { |
107 | qputenv(varName: "QT_SENSORS_LOAD_PLUGINS" , value: "0" ); // Do not load plugins |
108 | } |
109 | |
110 | private 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 | |
980 | QT_END_NAMESPACE |
981 | |
982 | QTEST_MAIN(tst_QSensor) |
983 | |
984 | #include "tst_qsensor.moc" |
985 | |