1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the QtTest module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
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 Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "QtTest/qtestcase.h"
43#include "QtTest/qtestassert.h"
44
45#include <QtCore/qbytearray.h>
46#include <QtCore/qmetaobject.h>
47#include <QtCore/qobject.h>
48#include <QtCore/qstringlist.h>
49#include <QtCore/qvector.h>
50#include <QtCore/qvarlengtharray.h>
51#include <QtCore/qcoreapplication.h>
52#include <QtCore/qfile.h>
53#include <QtCore/qfileinfo.h>
54#include <QtCore/qdir.h>
55#include <QtCore/qprocess.h>
56#include <QtCore/qdebug.h>
57
58#include "QtTest/private/qtestlog_p.h"
59#include "QtTest/private/qtesttable_p.h"
60#include "QtTest/qtestdata.h"
61#include "QtTest/private/qtestresult_p.h"
62#include "QtTest/private/qsignaldumper_p.h"
63#include "QtTest/private/qbenchmark_p.h"
64#include "3rdparty/cycle_p.h"
65
66#include <stdarg.h>
67#include <stdio.h>
68#include <stdlib.h>
69
70#ifdef Q_OS_WIN
71#include <windows.h> // for Sleep
72#endif
73#ifdef Q_OS_UNIX
74#include <errno.h>
75#include <signal.h>
76#include <time.h>
77#endif
78
79#ifdef Q_WS_MAC
80#include <Carbon/Carbon.h> // for SetFrontProcess
81#ifdef QT_MAC_USE_COCOA
82#include <IOKit/pwr_mgt/IOPMLib.h>
83#else
84#include <Security/AuthSession.h>
85#endif
86#undef verify
87#endif
88
89QT_BEGIN_NAMESPACE
90
91/*!
92 \namespace QTest
93 \inmodule QtTest
94
95 \brief The QTest namespace contains all the functions and
96 declarations that are related to the QTestLib tool.
97
98 Please refer to the \l{QTestLib Manual} documentation for information on
99 how to write unit tests.
100*/
101
102/*! \macro QVERIFY(condition)
103
104 \relates QTest
105
106 The QVERIFY() macro checks whether the \a condition is true or not. If it is
107 true, execution continues. If not, a failure is recorded in the test log
108 and the test won't be executed further.
109
110 \bold {Note:} This macro can only be used in a test function that is invoked
111 by the test framework.
112
113 Example:
114 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 0
115
116 \sa QCOMPARE()
117*/
118
119/*! \macro QVERIFY2(condition, message)
120
121 \relates QTest
122
123 The QVERIFY2() macro behaves exactly like QVERIFY(), except that it outputs
124 a verbose \a message when \a condition is false. The \a message is a plain
125 C string.
126
127 Example:
128 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 1
129
130 \sa QVERIFY(), QCOMPARE()
131*/
132
133/*! \macro QCOMPARE(actual, expected)
134
135 \relates QTest
136
137 The QCOMPARE macro compares an \a actual value to an \a expected value using
138 the equals operator. If \a actual and \a expected are identical, execution
139 continues. If not, a failure is recorded in the test log and the test
140 won't be executed further.
141
142 In the case of comparing floats and doubles, qFuzzyCompare() is used for
143 comparing. This means that comparing to 0 will likely fail. One solution
144 to this is to compare to 1, and add 1 to the produced output.
145
146 QCOMPARE tries to output the contents of the values if the comparison fails,
147 so it is visible from the test log why the comparison failed.
148
149 QCOMPARE is very strict on the data types. Both \a actual and \a expected
150 have to be of the same type, otherwise the test won't compile. This prohibits
151 unspecified behavior from being introduced; that is behavior that usually
152 occurs when the compiler implicitly casts the argument.
153
154 If you use QCOMPARE() to compare two QStringList objects, it will start
155 comparing the objects from the end of the lists.
156
157 For your own classes, you can use \l QTest::toString() to format values for
158 outputting into the test log.
159
160 \note This macro can only be used in a test function that is invoked
161 by the test framework.
162
163 Example:
164 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 2
165
166 \sa QVERIFY(), QTest::toString()
167*/
168
169/*! \macro QFETCH(type, name)
170
171 \relates QTest
172
173 The fetch macro creates a local variable named \a name with the type \a type
174 on the stack. \a name has to match the element name from the test's data.
175 If no such element exists, the test will assert.
176
177 Assuming a test has the following data:
178
179 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 3
180
181 The test data has two elements, a QString called \c aString and an integer
182 called \c expected. To fetch these values in the actual test:
183
184 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 4
185
186 \c aString and \c expected are variables on the stack that are initialized with
187 the current test data.
188
189 \bold {Note:} This macro can only be used in a test function that is invoked
190 by the test framework. The test function must have a _data function.
191*/
192
193/*! \macro QWARN(message)
194
195 \relates QTest
196 \threadsafe
197
198 Appends \a message as a warning to the test log. This macro can be used anywhere
199 in your tests.
200*/
201
202/*! \macro QFAIL(message)
203
204 \relates QTest
205
206 This macro can be used to force a test failure. The test stops
207 executing and the failure \a message is appended to the test log.
208
209 \bold {Note:} This macro can only be used in a test function that is invoked
210 by the test framework.
211
212 Example:
213
214 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 5
215*/
216
217/*! \macro QTEST(actual, testElement)
218
219 \relates QTest
220
221 QTEST() is a convenience macro for \l QCOMPARE() that compares
222 the value \a actual with the element \a testElement from the test's data.
223 If there is no such element, the test asserts.
224
225 Apart from that, QTEST() behaves exactly as \l QCOMPARE().
226
227 Instead of writing:
228
229 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 6
230
231 you can write:
232
233 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 7
234
235 \sa QCOMPARE()
236*/
237
238/*! \macro QSKIP(description, mode)
239
240 \relates QTest
241
242 The QSKIP() macro stops execution of the test without adding a failure to the
243 test log. You can use it to skip tests that wouldn't make sense in the current
244 configuration. The text \a description is appended to the test log and should
245 contain an explanation why the test couldn't be executed. \a mode is a QTest::SkipMode
246 and describes whether to proceed with the rest of the test data or not.
247
248 \bold {Note:} This macro can only be used in a test function that is invoked
249 by the test framework.
250
251 Example:
252 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 8
253
254 \sa QTest::SkipMode
255*/
256
257/*! \macro QEXPECT_FAIL(dataIndex, comment, mode)
258
259 \relates QTest
260
261 The QEXPECT_FAIL() macro marks the next \l QCOMPARE() or \l QVERIFY() as an
262 expected failure. Instead of adding a failure to the test log, an expected
263 failure will be reported.
264
265 If a \l QVERIFY() or \l QCOMPARE() is marked as an expected failure,
266 but passes instead, an unexpected pass (XPASS) is written to the test log.
267
268 The parameter \a dataIndex describes for which entry in the test data the
269 failure is expected. Pass an empty string (\c{""}) if the failure
270 is expected for all entries or if no test data exists.
271
272 \a comment will be appended to the test log for the expected failure.
273
274 \a mode is a \l QTest::TestFailMode and sets whether the test should
275 continue to execute or not.
276
277 \bold {Note:} This macro can only be used in a test function that is invoked
278 by the test framework.
279
280 Example 1:
281 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 9
282
283 In the example above, an expected fail will be written into the test output
284 if the variable \c i is not 42. If the variable \c i is 42, an unexpected pass
285 is written instead. The QEXPECT_FAIL() has no influence on the second QCOMPARE()
286 statement in the example.
287
288 Example 2:
289 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 10
290
291 The above testfunction will not continue executing for the test data
292 entry \c{data27}.
293
294 \sa QTest::TestFailMode, QVERIFY(), QCOMPARE()
295*/
296
297/*! \macro QTEST_MAIN(TestClass)
298
299 \relates QTest
300
301 Implements a main() function that instantiates an application object and
302 the \a TestClass, and executes all tests in the order they were defined.
303 Use this macro to build stand-alone executables.
304
305 If \c QT_GUI_LIB is defined, the application object will be a QApplication,
306 otherwise it will be a QCoreApplication. If qmake is used and the configuration
307 includes \c{QT += gui}, then \c QT_GUI_LIB will be defined automatically.
308
309 \bold {Note:} On platforms that have keypad navigation enabled by default (eg: Symbian),
310 this macro will forcfully disable it to simplify the usage of key events when writing
311 autotests. If you wish to write a test case that uses keypad navigation, you should
312 enable it either in the \c {initTestCase()} or \c {init()} functions of your test case.
313
314 Example:
315 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 11
316
317 \sa QTEST_APPLESS_MAIN(), QTest::qExec(), QApplication::setNavigationMode()
318*/
319
320/*! \macro QTEST_APPLESS_MAIN(TestClass)
321
322 \relates QTest
323
324 Implements a main() function that executes all tests in \a TestClass.
325
326 Behaves like \l QTEST_MAIN(), but doesn't instantiate a QApplication
327 object. Use this macro for really simple stand-alone non-GUI tests.
328
329 \sa QTEST_MAIN()
330*/
331
332/*! \macro QTEST_NOOP_MAIN()
333
334 \relates QTest
335
336 Implements a main() function with a test class that does absolutely nothing.
337 Use this macro to create a test that produces valid test output but just
338 doesn't execute any test, for example in conditional compilations:
339
340 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 12
341
342 \sa QTEST_MAIN()
343*/
344
345/*!
346 \macro QBENCHMARK
347
348 \relates QTest
349
350 This macro is used to measure the performance of code within a test.
351 The code to be benchmarked is contained within a code block following
352 this macro.
353
354 For example:
355
356 \snippet examples/qtestlib/tutorial5/benchmarking.cpp 0
357
358 \sa {QTestLib Manual#Creating a Benchmark}{Creating a Benchmark},
359 {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
360*/
361
362/*!
363 \macro QBENCHMARK_ONCE
364 \since 4.6
365
366 \relates QTest
367
368 \brief The QBENCHMARK_ONCE macro is for measuring performance of a
369 code block by running it once.
370
371 This macro is used to measure the performance of code within a test.
372 The code to be benchmarked is contained within a code block following
373 this macro.
374
375 Unlike QBENCHMARK, the contents of the contained code block is only run
376 once. The elapsed time will be reported as "0" if it's to short to
377 be measured by the selected backend. (Use)
378
379 \sa {QTestLib Manual#Creating a Benchmark}{Creating a Benchmark},
380 {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
381*/
382
383
384
385/*! \enum QTest::SkipMode
386
387 This enum describes the modes for skipping tests during execution
388 of the test data.
389
390 \value SkipSingle Skips the current entry in the test table; continues
391 execution of all the other entries in the table.
392
393 \value SkipAll Skips all the entries in the test table; the test won't
394 be executed further.
395
396 \sa QSKIP()
397*/
398
399/*! \enum QTest::TestFailMode
400
401 This enum describes the modes for handling an expected failure of the
402 \l QVERIFY() or \l QCOMPARE() macros.
403
404 \value Abort Aborts the execution of the test. Use this mode when it
405 doesn't make sense to execute the test any further after the
406 expected failure.
407
408 \value Continue Continues execution of the test after the expected failure.
409
410 \sa QEXPECT_FAIL()
411*/
412
413/*! \enum QTest::KeyAction
414
415 This enum describes possible actions for key handling.
416
417 \value Press The key is pressed.
418 \value Release The key is released.
419 \value Click The key is clicked (pressed and released).
420*/
421
422/*! \enum QTest::MouseAction
423
424 This enum describes possible actions for mouse handling.
425
426 \value MousePress A mouse button is pressed.
427 \value MouseRelease A mouse button is released.
428 \value MouseClick A mouse button is clicked (pressed and released).
429 \value MouseDClick A mouse button is double clicked (pressed and released twice).
430 \value MouseMove The mouse pointer has moved.
431*/
432
433/*! \fn void QTest::keyClick(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
434
435 \overload
436
437 Simulates clicking of \a key with an optional \a modifier on a \a widget.
438 If \a delay is larger than 0, the test will wait for \a delay milliseconds.
439
440 Example:
441 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 13
442
443 The example above simulates clicking \c a on \c myWidget without
444 any keyboard modifiers and without delay of the test.
445
446 \sa QTest::keyClicks()
447*/
448
449/*! \fn void QTest::keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
450
451 Simulates clicking of \a key with an optional \a modifier on a \a widget.
452 If \a delay is larger than 0, the test will wait for \a delay milliseconds.
453
454 Examples:
455 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 14
456
457 The first example above simulates clicking the \c escape key on \c
458 myWidget without any keyboard modifiers and without delay. The
459 second example simulates clicking \c shift-escape on \c myWidget
460 with a following 200 ms delay of the test.
461
462 \sa QTest::keyClicks()
463*/
464
465/*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
466
467 Sends a Qt key event to \a widget with the given \a key and an associated \a action.
468 Optionally, a keyboard \a modifier can be specified, as well as a \a delay
469 (in milliseconds) of the test before sending the event.
470*/
471
472/*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, char ascii, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
473
474 \overload
475
476 Sends a Qt key event to \a widget with the given key \a ascii and an associated \a action.
477 Optionally, a keyboard \a modifier can be specified, as well as a \a delay
478 (in milliseconds) of the test before sending the event.
479
480*/
481
482/*! \fn void QTest::keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
483
484 Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay
485 is larger than 0, the test will wait for \a delay milliseconds.
486
487 \bold {Note:} At some point you should release the key using \l keyRelease().
488
489 \sa QTest::keyRelease(), QTest::keyClick()
490*/
491
492/*! \fn void QTest::keyPress(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
493
494 \overload
495
496 Simulates pressing a \a key with an optional \a modifier on a \a widget.
497 If \a delay is larger than 0, the test will wait for \a delay milliseconds.
498
499 \bold {Note:} At some point you should release the key using \l keyRelease().
500
501 \sa QTest::keyRelease(), QTest::keyClick()
502*/
503
504/*! \fn void QTest::keyRelease(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
505
506 Simulates releasing a \a key with an optional \a modifier on a \a widget.
507 If \a delay is larger than 0, the test will wait for \a delay milliseconds.
508
509 \sa QTest::keyPress(), QTest::keyClick()
510*/
511
512/*! \fn void QTest::keyRelease(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
513
514 \overload
515
516 Simulates releasing a \a key with an optional \a modifier on a \a widget.
517 If \a delay is larger than 0, the test will wait for \a delay milliseconds.
518
519 \sa QTest::keyClick()
520*/
521
522
523/*! \fn void QTest::keyClicks(QWidget *widget, const QString &sequence, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
524
525 Simulates clicking a \a sequence of keys on a \a
526 widget. Optionally, a keyboard \a modifier can be specified as
527 well as a \a delay (in milliseconds) of the test before each key
528 click.
529
530 Example:
531 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 15
532
533 The example above simulates clicking the sequence of keys
534 representing "hello world" on \c myWidget without any keyboard
535 modifiers and without delay of the test.
536
537 \sa QTest::keyClick()
538*/
539
540/*! \fn void QTest::mousePress(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
541
542 Simulates pressing a mouse \a button with an optional \a modifier
543 on a \a widget. The position is defined by \a pos; the default
544 position is the center of the widget. If \a delay is specified,
545 the test will wait for the specified amount of milliseconds before
546 the press.
547
548 \sa QTest::mouseRelease(), QTest::mouseClick()
549*/
550
551/*! \fn void QTest::mouseRelease(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
552
553 Simulates releasing a mouse \a button with an optional \a modifier
554 on a \a widget. The position of the release is defined by \a pos;
555 the default position is the center of the widget. If \a delay is
556 specified, the test will wait for the specified amount of
557 milliseconds before releasing the button.
558
559 \sa QTest::mousePress(), QTest::mouseClick()
560*/
561
562/*! \fn void QTest::mouseClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
563
564 Simulates clicking a mouse \a button with an optional \a modifier
565 on a \a widget. The position of the click is defined by \a pos;
566 the default position is the center of the widget. If \a delay is
567 specified, the test will wait for the specified amount of
568 milliseconds before pressing and before releasing the button.
569
570 \sa QTest::mousePress(), QTest::mouseRelease()
571*/
572
573/*! \fn void QTest::mouseDClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
574
575 Simulates double clicking a mouse \a button with an optional \a
576 modifier on a \a widget. The position of the click is defined by
577 \a pos; the default position is the center of the widget. If \a
578 delay is specified, the test will wait for the specified amount of
579 milliseconds before each press and release.
580
581 \sa QTest::mouseClick()
582*/
583
584/*! \fn void QTest::mouseMove(QWidget *widget, QPoint pos = QPoint(), int delay=-1)
585
586 Moves the mouse pointer to a \a widget. If \a pos is not
587 specified, the mouse pointer moves to the center of the widget. If
588 a \a delay (in milliseconds) is given, the test will wait before
589 moving the mouse pointer.
590*/
591
592/*!
593 \fn char *QTest::toString(const T &value)
594
595 Returns a textual representation of \a value. This function is used by
596 \l QCOMPARE() to output verbose information in case of a test failure.
597
598 You can add specializations of this function to your test to enable
599 verbose output.
600
601 \bold {Note:} The caller of toString() must delete the returned data
602 using \c{delete[]}. Your implementation should return a string
603 created with \c{new[]} or qstrdup().
604
605 Example:
606
607 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 16
608
609 The example above defines a toString() specialization for a class
610 called \c MyPoint. Whenever a comparison of two instances of \c
611 MyPoint fails, \l QCOMPARE() will call this function to output the
612 contents of \c MyPoint to the test log.
613
614 \sa QCOMPARE()
615*/
616
617/*!
618 \fn char *QTest::toString(const QLatin1String &string)
619 \overload
620
621 Returns a textual representation of the given \a string.
622*/
623
624/*!
625 \fn char *QTest::toString(const QString &string)
626 \overload
627
628 Returns a textual representation of the given \a string.
629*/
630
631/*!
632 \fn char *QTest::toString(const QByteArray &ba)
633 \overload
634
635 Returns a textual representation of the byte array \a ba.
636
637 \sa QTest::toHexRepresentation()
638*/
639
640/*!
641 \fn char *QTest::toString(const QTime &time)
642 \overload
643
644 Returns a textual representation of the given \a time.
645*/
646
647/*!
648 \fn char *QTest::toString(const QDate &date)
649 \overload
650
651 Returns a textual representation of the given \a date.
652*/
653
654/*!
655 \fn char *QTest::toString(const QDateTime &dateTime)
656 \overload
657
658 Returns a textual representation of the date and time specified by
659 \a dateTime.
660*/
661
662/*!
663 \fn char *QTest::toString(const QChar &character)
664 \overload
665
666 Returns a textual representation of the given \a character.
667*/
668
669/*!
670 \fn char *QTest::toString(const QPoint &point)
671 \overload
672
673 Returns a textual representation of the given \a point.
674*/
675
676/*!
677 \fn char *QTest::toString(const QSize &size)
678 \overload
679
680 Returns a textual representation of the given \a size.
681*/
682
683/*!
684 \fn char *QTest::toString(const QRect &rectangle)
685 \overload
686
687 Returns a textual representation of the given \a rectangle.
688*/
689
690/*!
691 \fn char *QTest::toString(const QUrl &url)
692 \since 4.4
693 \overload
694
695 Returns a textual representation of the given \a url.
696*/
697
698/*!
699 \fn char *QTest::toString(const QPointF &point)
700 \overload
701
702 Returns a textual representation of the given \a point.
703*/
704
705/*!
706 \fn char *QTest::toString(const QSizeF &size)
707 \overload
708
709 Returns a textual representation of the given \a size.
710*/
711
712/*!
713 \fn char *QTest::toString(const QRectF &rectangle)
714 \overload
715
716 Returns a textual representation of the given \a rectangle.
717*/
718
719/*!
720 \fn char *QTest::toString(const QVariant &variant)
721 \overload
722
723 Returns a textual representation of the given \a variant.
724*/
725
726/*! \fn void QTest::qWait(int ms)
727
728 Waits for \a ms milliseconds. While waiting, events will be processed and
729 your test will stay responsive to user interface events or network communication.
730
731 Example:
732 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 17
733
734 The code above will wait until the network server is responding for a
735 maximum of about 12.5 seconds.
736
737 \sa QTest::qSleep()
738*/
739
740/*! \fn bool QTest::qWaitForWindowShown(QWidget *window)
741 \since 4.6
742
743 Waits until the \a window is shown in the screen. This is mainly useful for
744 asynchronous systems like X11, where a window will be mapped to screen some
745 time after being asked to show itself on the screen. Returns true.
746
747 Example:
748 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 24
749*/
750
751/*!
752 \class QTest::QTouchEventSequence
753 \inmodule QtTest
754 \since 4.6
755
756 \brief The QTouchEventSequence class is used to simulate a sequence of touch events.
757
758 To simulate a sequence of touch events on a specific device for a widget, call
759 QTest::touchEvent to create a QTouchEventSequence instance. Add touch events to
760 the sequence by calling press(), move(), release() and stationary(), and let the
761 instance run out of scope to commit the sequence to the event system.
762
763 Example:
764 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 25
765*/
766
767/*!
768 \fn QTest::QTouchEventSequence::~QTouchEventSequence()
769
770 Commits this sequence of touch events and frees allocated resources.
771*/
772
773/*!
774 \fn QTouchEventSequence &QTest::QTouchEventSequence::press(int touchId, const QPoint &pt, QWidget *widget)
775
776 Adds a press event for touchpoint \a touchId at position \a pt to this sequence and returns
777 a reference to this QTouchEventSequence.
778
779 The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
780 \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
781
782 Simulates that the user pressed the touch screen or pad with the finger identified by \a touchId.
783*/
784
785/*!
786 \fn QTouchEventSequence &QTest::QTouchEventSequence::move(int touchId, const QPoint &pt, QWidget *widget)
787
788 Adds a move event for touchpoint \a touchId at position \a pt to this sequence and returns
789 a reference to this QTouchEventSequence.
790
791 The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
792 \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
793
794 Simulates that the user moved the finger identified by \a touchId.
795*/
796
797/*!
798 \fn QTouchEventSequence &QTest::QTouchEventSequence::release(int touchId, const QPoint &pt, QWidget *widget)
799
800 Adds a release event for touchpoint \a touchId at position \a pt to this sequence and returns
801 a reference to this QTouchEventSequence.
802
803 The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
804 \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
805
806 Simulates that the user lifted the finger identified by \a touchId.
807*/
808
809/*!
810 \fn QTouchEventSequence &QTest::QTouchEventSequence::stationary(int touchId)
811
812 Adds a stationary event for touchpoint \a touchId to this sequence and returns
813 a reference to this QTouchEventSequence.
814
815 Simulates that the user did not move the finger identified by \a touchId.
816*/
817
818/*!
819 \fn QTouchEventSequence QTest::touchEvent(QWidget *widget, QTouchEvent::DeviceType deviceType)
820
821 Creates and returns a QTouchEventSequence for the device \a deviceType to
822 simulate events for \a widget.
823
824 When adding touch events to the sequence, \a widget will also be used to translate
825 the position provided to screen coordinates, unless another widget is provided in the
826 respective calls to press(), move() etc.
827
828 The touch events are committed to the event system when the destructor of the
829 QTouchEventSequence is called (ie when the object returned runs out of scope).
830*/
831
832namespace QTest
833{
834 static QObject *currentTestObject = 0;
835
836 class TestFunction {
837 public:
838 TestFunction() : function_(-1), data_(0) {}
839 void set(int function, char *data) { function_ = function; data_ = data; }
840 char *data() const { return data_; }
841 int function() const { return function_; }
842 ~TestFunction() { delete[] data_; }
843 private:
844 int function_;
845 char *data_;
846 };
847 /**
848 * Contains the list of test functions that was supplied
849 * on the command line, if any. Hence, if not empty,
850 * those functions should be run instead of
851 * all appearing in the test case.
852 */
853 static TestFunction * testFuncs = 0;
854 static int testFuncCount = 0;
855
856 /** Don't leak testFuncs on exit even on error */
857 static struct TestFuncCleanup
858 {
859 void cleanup()
860 {
861 delete[] testFuncs;
862 testFuncCount = 0;
863 testFuncs = 0;
864 }
865
866 ~TestFuncCleanup() { cleanup(); }
867 } testFuncCleaner;
868
869 static int keyDelay = -1;
870 static int mouseDelay = -1;
871 static int eventDelay = -1;
872 static bool randomOrder = false;
873 static int keyVerbose = -1;
874 static unsigned int seed = 0;
875 static bool seedSet = false;
876#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
877 static bool noCrashHandler = false;
878#endif
879
880void filter_unprintable(char *str)
881{
882 char *idx = str;
883 while (*idx) {
884 if (((*idx < 0x20 && *idx != '\n' && *idx != '\t') || *idx > 0x7e))
885 *idx = '?';
886 ++idx;
887 }
888}
889
890/*! \internal
891 */
892int qt_snprintf(char *str, int size, const char *format, ...)
893{
894 va_list ap;
895 int res = 0;
896
897 va_start(ap, format);
898 qvsnprintf(str, size, format, ap);
899 va_end(ap);
900 str[size - 1] = '\0';
901
902 filter_unprintable(str);
903
904 return res;
905}
906
907/*! \internal
908 Invoke a method of the object without generating warning if the method does not exist
909 */
910static void invokeMethod(QObject *obj, const char *methodName)
911{
912 const QMetaObject *metaObject = obj->metaObject();
913 int funcIndex = metaObject->indexOfMethod(methodName);
914 if (funcIndex >= 0) {
915 QMetaMethod method = metaObject->method(funcIndex);
916 method.invoke(obj, Qt::DirectConnection);
917 }
918}
919
920bool Q_TESTLIB_EXPORT defaultKeyVerbose()
921{
922 if (keyVerbose == -1) {
923 keyVerbose = qgetenv("QTEST_KEYEVENT_VERBOSE").constData() ? 1 : 0;
924 }
925 return keyVerbose == 1;
926}
927
928int defaultEventDelay()
929{
930 if (eventDelay == -1) {
931 if (qgetenv("QTEST_EVENT_DELAY").constData())
932 eventDelay = atoi(qgetenv("QTEST_EVENT_DELAY"));
933 else
934 eventDelay = 0;
935 }
936 return eventDelay;
937}
938
939int Q_TESTLIB_EXPORT defaultMouseDelay()
940{
941 if (mouseDelay == -1) {
942 if (qgetenv("QTEST_MOUSEEVENT_DELAY").constData())
943 mouseDelay = atoi((qgetenv("QTEST_MOUSEEVENT_DELAY")));
944 else
945 mouseDelay = defaultEventDelay();
946 }
947 return mouseDelay;
948}
949
950int Q_TESTLIB_EXPORT defaultKeyDelay()
951{
952 if (keyDelay == -1) {
953 if (qgetenv("QTEST_KEYEVENT_DELAY").constData())
954 keyDelay = atoi(qgetenv("QTEST_KEYEVENT_DELAY").constData());
955 else
956 keyDelay = defaultEventDelay();
957 }
958 return keyDelay;
959}
960
961void seedRandom()
962{
963 static bool randomSeeded = false;
964 if (!randomSeeded) {
965 if (!QTest::seedSet) {
966 QElapsedTimer timer;
967 timer.start();
968 QTest::seed = timer.msecsSinceReference();
969 }
970 qsrand(QTest::seed);
971 randomSeeded = true;
972 }
973}
974
975int qTestRandomSeed()
976{
977 Q_ASSERT(QTest::seedSet);
978 return QTest::seed;
979}
980
981template<typename T>
982void swap(T * array, int pos, int otherPos)
983{
984 T tmp = array[pos];
985 array[pos] = array[otherPos];
986 array[otherPos] = tmp;
987}
988
989template<typename T>
990static void randomizeList(T * array, int size)
991{
992 for (int i = 0; i != size; i++) {
993 int pos = qrand() % size;
994 swap(array, pos, i);
995 }
996}
997
998static bool isValidSlot(const QMetaMethod &sl)
999{
1000 if (sl.access() != QMetaMethod::Private || !sl.parameterTypes().isEmpty()
1001 || qstrlen(sl.typeName()) || sl.methodType() != QMetaMethod::Slot)
1002 return false;
1003 const char *sig = sl.signature();
1004 int len = qstrlen(sig);
1005 if (len < 2)
1006 return false;
1007 if (sig[len - 2] != '(' || sig[len - 1] != ')')
1008 return false;
1009 if (len > 7 && strcmp(sig + (len - 7), "_data()") == 0)
1010 return false;
1011 if (strcmp(sig, "initTestCase()") == 0 || strcmp(sig, "cleanupTestCase()") == 0
1012 || strcmp(sig, "cleanup()") == 0 || strcmp(sig, "init()") == 0)
1013 return false;
1014 return true;
1015}
1016
1017Q_TESTLIB_EXPORT bool printAvailableFunctions = false;
1018Q_TESTLIB_EXPORT bool printAvailableTags = false;
1019Q_TESTLIB_EXPORT QStringList testFunctions;
1020Q_TESTLIB_EXPORT QStringList testTags;
1021
1022static void qPrintTestSlots()
1023{
1024 for (int i = 0; i < QTest::currentTestObject->metaObject()->methodCount(); ++i) {
1025 QMetaMethod sl = QTest::currentTestObject->metaObject()->method(i);
1026 if (isValidSlot(sl))
1027 printf("%s\n", sl.signature());
1028 }
1029}
1030
1031static void qPrintDataTags()
1032{
1033 // Get global data tags:
1034 QTestTable::globalTestTable();
1035 invokeMethod(QTest::currentTestObject, "initTestCase_data()");
1036 const QTestTable *gTable = QTestTable::globalTestTable();
1037
1038 const QMetaObject *currTestMetaObj = QTest::currentTestObject->metaObject();
1039
1040 // Process test functions:
1041 for (int i = 0; i < currTestMetaObj->methodCount(); ++i) {
1042 QMetaMethod tf = currTestMetaObj->method(i);
1043 if (isValidSlot(tf)) {
1044 // Retrieve local tags:
1045 QStringList localTags;
1046 QTestTable table;
1047 char member[512];
1048 char *slot = qstrdup(tf.signature());
1049 slot[strlen(slot) - 2] = '\0';
1050 QTest::qt_snprintf(member, 512, "%s_data()", slot);
1051 invokeMethod(QTest::currentTestObject, member);
1052 for (int j = 0; j < table.dataCount(); ++j)
1053 localTags << QLatin1String(table.testData(j)->dataTag());
1054
1055 // Print all tag combinations:
1056 if (gTable->dataCount() == 0) {
1057 if (localTags.count() == 0) {
1058 // No tags at all, so just print the test function:
1059 printf("%s %s\n", currTestMetaObj->className(), slot);
1060 } else {
1061 // Only local tags, so print each of them:
1062 for (int k = 0; k < localTags.size(); ++k)
1063 printf(
1064 "%s %s %s\n",
1065 currTestMetaObj->className(), slot, localTags.at(k).toLatin1().data());
1066 }
1067 } else {
1068 for (int j = 0; j < gTable->dataCount(); ++j) {
1069 if (localTags.count() == 0) {
1070 // Only global tags, so print the current one:
1071 printf(
1072 "%s %s __global__ %s\n",
1073 currTestMetaObj->className(), slot, gTable->testData(j)->dataTag());
1074 } else {
1075 // Local and global tags, so print each of the local ones and
1076 // the current global one:
1077 for (int k = 0; k < localTags.size(); ++k)
1078 printf(
1079 "%s %s %s __global__ %s\n", currTestMetaObj->className(), slot,
1080 localTags.at(k).toLatin1().data(), gTable->testData(j)->dataTag());
1081 }
1082 }
1083 }
1084
1085 delete[] slot;
1086 }
1087 }
1088}
1089
1090static int qToInt(char *str)
1091{
1092 char *pEnd;
1093 int l = (int)strtol(str, &pEnd, 10);
1094 if (*pEnd != 0) {
1095 printf("Invalid numeric parameter: '%s'\n", str);
1096 exit(1);
1097 }
1098 return l;
1099}
1100
1101Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
1102{
1103 const char *testOptions =
1104 " options:\n"
1105 " -functions : Returns a list of current testfunctions\n"
1106 " -datatags : Returns a list of current data tags.\n"
1107 " A global data tag is preceded by ' __global__ '.\n"
1108 " -xunitxml : Outputs results as XML XUnit document\n"
1109 " -xml : Outputs results as XML document\n"
1110 " -lightxml : Outputs results as stream of XML tags\n"
1111 " -flush : Flushes the results\n"
1112 " -o filename: Writes all output into a file\n"
1113 " -silent : Only outputs warnings and failures\n"
1114 " -v1 : Print enter messages for each testfunction\n"
1115 " -v2 : Also print out each QVERIFY/QCOMPARE/QTEST\n"
1116 " -vs : Print every signal emitted\n"
1117 " -random : Run testcases within each test in random order\n"
1118 " -seed n : Positive integer to be used as seed for -random. If not specified,\n"
1119 " the current time will be used as seed.\n"
1120 " -eventdelay ms : Set default delay for mouse and keyboard simulation to ms milliseconds\n"
1121 " -keydelay ms : Set default delay for keyboard simulation to ms milliseconds\n"
1122 " -mousedelay ms : Set default delay for mouse simulation to ms milliseconds\n"
1123 " -keyevent-verbose : Turn on verbose messages for keyboard simulation\n"
1124 " -maxwarnings n : Sets the maximum amount of messages to output.\n"
1125 " 0 means unlimited, default: 2000\n"
1126#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
1127 " -nocrashhandler : Disables the crash handler\n"
1128#endif
1129 "\n"
1130 " Benchmark related options:\n"
1131#ifdef QTESTLIB_USE_VALGRIND
1132 " -callgrind : Use callgrind to time benchmarks\n"
1133#endif
1134#ifdef HAVE_TICK_COUNTER
1135 " -tickcounter : Use CPU tick counters to time benchmarks\n"
1136#endif
1137 " -eventcounter : Counts events received during benchmarks\n"
1138 " -minimumvalue n : Sets the minimum acceptable measurement value\n"
1139 " -iterations n : Sets the number of accumulation iterations.\n"
1140 " -median n : Sets the number of median iterations.\n"
1141 " -vb : Print out verbose benchmarking information.\n"
1142 "\n"
1143 " -help : This help\n";
1144
1145 for (int i = 1; i < argc; ++i) {
1146 if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0
1147 || strcmp(argv[i], "/?") == 0) {
1148 printf(" Usage: %s [options] [testfunction[:testdata]]...\n"
1149 " By default, all testfunctions will be run.\n\n"
1150 "%s", argv[0], testOptions);
1151 exit(0);
1152 } else if (strcmp(argv[i], "-functions") == 0) {
1153 if (qml) {
1154 QTest::printAvailableFunctions = true;
1155 } else {
1156 qPrintTestSlots();
1157 exit(0);
1158 }
1159 } else if (strcmp(argv[i], "-datatags") == 0) {
1160 QTest::printAvailableTags = true;
1161 if (!qml) {
1162 qPrintDataTags();
1163 exit(0);
1164 }
1165 } else if(strcmp(argv[i], "-xunitxml") == 0){
1166 QTestLog::setLogMode(QTestLog::XunitXML);
1167 } else if (strcmp(argv[i], "-xml") == 0) {
1168 QTestLog::setLogMode(QTestLog::XML);
1169 } else if (strcmp(argv[i], "-lightxml") == 0) {
1170 QTestLog::setLogMode(QTestLog::LightXML);
1171 }else if(strcmp(argv[i], "-flush") == 0){
1172 QTestLog::setFlushMode(QTestLog::FLushOn);
1173 } else if (strcmp(argv[i], "-silent") == 0) {
1174 QTestLog::setVerboseLevel(-1);
1175 } else if (strcmp(argv[i], "-v1") == 0) {
1176 QTestLog::setVerboseLevel(1);
1177 } else if (strcmp(argv[i], "-v2") == 0) {
1178 QTestLog::setVerboseLevel(2);
1179 } else if (strcmp(argv[i], "-vs") == 0) {
1180 QSignalDumper::startDump();
1181 } else if (strcmp(argv[i], "-o") == 0) {
1182 if (i + 1 >= argc) {
1183 printf("-o needs an extra parameter specifying the filename\n");
1184 exit(1);
1185 } else {
1186 QTestLog::redirectOutput(argv[++i]);
1187 }
1188 } else if (strcmp(argv[i], "-eventdelay") == 0) {
1189 if (i + 1 >= argc) {
1190 printf("-eventdelay needs an extra parameter to indicate the delay(ms)\n");
1191 exit(1);
1192 } else {
1193 QTest::eventDelay = qToInt(argv[++i]);
1194 }
1195 } else if (strcmp(argv[i], "-keydelay") == 0) {
1196 if (i + 1 >= argc) {
1197 printf("-keydelay needs an extra parameter to indicate the delay(ms)\n");
1198 exit(1);
1199 } else {
1200 QTest::keyDelay = qToInt(argv[++i]);
1201 }
1202 } else if (strcmp(argv[i], "-mousedelay") == 0) {
1203 if (i + 1 >= argc) {
1204 printf("-mousedelay needs an extra parameter to indicate the delay(ms)\n");
1205 exit(1);
1206 } else {
1207 QTest::mouseDelay = qToInt(argv[++i]);
1208 }
1209 } else if (strcmp(argv[i], "-maxwarnings") == 0) {
1210 if (i + 1 >= argc) {
1211 printf("-maxwarnings needs an extra parameter with the amount of warnings\n");
1212 exit(1);
1213 } else {
1214 QTestLog::setMaxWarnings(qToInt(argv[++i]));
1215 }
1216#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
1217 } else if (strcmp(argv[i], "-nocrashhandler") == 0) {
1218 QTest::noCrashHandler = true;
1219#endif
1220 } else if (strcmp(argv[i], "-keyevent-verbose") == 0) {
1221 QTest::keyVerbose = 1;
1222#ifdef QTESTLIB_USE_VALGRIND
1223 } else if (strcmp(argv[i], "-callgrind") == 0) {
1224 if (QBenchmarkValgrindUtils::haveValgrind())
1225 if (QFileInfo(QDir::currentPath()).isWritable()) {
1226 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::CallgrindParentProcess);
1227 } else {
1228 printf("WARNING: Current directory not writable. Using the walltime measurer.\n");
1229 }
1230 else {
1231 printf("WARNING: Valgrind not found or too old. Make sure it is installed and in your path. "
1232 "Using the walltime measurer.\n");
1233 }
1234 } else if (strcmp(argv[i], "-callgrindchild") == 0) { // "private" option
1235 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::CallgrindChildProcess);
1236 QBenchmarkGlobalData::current->callgrindOutFileBase =
1237 QBenchmarkValgrindUtils::outFileBase();
1238#endif
1239#ifdef HAVE_TICK_COUNTER
1240 } else if (strcmp(argv[i], "-tickcounter") == 0) {
1241 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::TickCounter);
1242#endif
1243 } else if (strcmp(argv[i], "-eventcounter") == 0) {
1244 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::EventCounter);
1245 } else if (strcmp(argv[i], "-random") == 0) {
1246 QTest::randomOrder = true;
1247 } else if (strcmp(argv[i], "-seed") == 0) {
1248 bool argumentOk = false;
1249 if (i + 1 < argc) {
1250 char * endpt = 0;
1251 long longSeed = strtol(argv[++i], &endpt, 10);
1252 argumentOk = (*endpt == '\0' && longSeed >= 0);
1253 QTest::seed = longSeed;
1254 }
1255 if (!argumentOk) {
1256 printf("-seed needs an extra positive integer parameter to specify the seed\n");
1257 exit(1);
1258 } else {
1259 QTest::seedSet = true;
1260 }
1261 } else if (strcmp(argv[i], "-minimumvalue") == 0) {
1262 if (i + 1 >= argc) {
1263 printf("-minimumvalue needs an extra parameter to indicate the minimum time(ms)\n");
1264 exit(1);
1265 } else {
1266 QBenchmarkGlobalData::current->walltimeMinimum = qToInt(argv[++i]);
1267 }
1268 } else if (strcmp(argv[i], "-iterations") == 0) {
1269 if (i + 1 >= argc) {
1270 printf("-iterations needs an extra parameter to indicate the number of iterations\n");
1271 exit(1);
1272 } else {
1273 QBenchmarkGlobalData::current->iterationCount = qToInt(argv[++i]);
1274 }
1275 } else if (strcmp(argv[i], "-median") == 0) {
1276 if (i + 1 >= argc) {
1277 printf("-median needs an extra parameter to indicate the number of median iterations\n");
1278 exit(1);
1279 } else {
1280 QBenchmarkGlobalData::current->medianIterationCount = qToInt(argv[++i]);
1281 }
1282
1283 } else if (strcmp(argv[i], "-vb") == 0) {
1284 QBenchmarkGlobalData::current->verboseOutput = true;
1285 } else if (strcmp(argv[i], "-chart") == 0) {
1286 fprintf(stderr, "Warning: `-chart' option is not available\n");
1287 } else if (strcmp(argv[i], "-qws") == 0) {
1288 // do nothing
1289 } else if (strcmp(argv[i], "-graphicssystem") == 0) {
1290 // do nothing
1291 if (i + 1 >= argc) {
1292 printf("-graphicssystem needs an extra parameter specifying the graphics system\n");
1293 exit(1);
1294 } else {
1295 ++i;
1296 }
1297 } else if (argv[i][0] == '-') {
1298 printf("Unknown option: '%s'\n\n%s", argv[i], testOptions);
1299 exit(1);
1300 } else if (qml) {
1301 // We can't check the availability of test functions until
1302 // we load the QML files. So just store the data for now.
1303 int colon = -1;
1304 int offset;
1305 for(offset = 0; *(argv[i]+offset); ++offset) {
1306 if (*(argv[i]+offset) == ':') {
1307 if (*(argv[i]+offset+1) == ':') {
1308 // "::" is used as a test name separator.
1309 // e.g. "ClickTests::test_click:row1".
1310 ++offset;
1311 } else {
1312 colon = offset;
1313 break;
1314 }
1315 }
1316 }
1317 if (colon == -1) {
1318 QTest::testFunctions += QString::fromLatin1(argv[i]);
1319 QTest::testTags += QString();
1320 } else {
1321 QTest::testFunctions +=
1322 QString::fromLatin1(argv[i], colon);
1323 QTest::testTags +=
1324 QString::fromLatin1(argv[i] + colon + 1);
1325 }
1326 } else {
1327 if (!QTest::testFuncs) {
1328 QTest::testFuncs = new QTest::TestFunction[512];
1329 }
1330
1331 int colon = -1;
1332 char buf[512], *data=0;
1333 int off;
1334 for(off = 0; *(argv[i]+off); ++off) {
1335 if (*(argv[i]+off) == ':') {
1336 colon = off;
1337 break;
1338 }
1339 }
1340 if(colon != -1) {
1341 data = qstrdup(argv[i]+colon+1);
1342 }
1343 QTest::qt_snprintf(buf, qMin(512, off + 1), "%s", argv[i]); // copy text before the ':' into buf
1344 QTest::qt_snprintf(buf + off, qMin(512 - off, 3), "()"); // append "()"
1345 int idx = QTest::currentTestObject->metaObject()->indexOfMethod(buf);
1346 if (idx < 0 || !isValidSlot(QTest::currentTestObject->metaObject()->method(idx))) {
1347 printf("Unknown testfunction: '%s'\n", buf);
1348 printf("Available testfunctions:\n");
1349 qPrintTestSlots();
1350 exit(1);
1351 }
1352 testFuncs[testFuncCount].set(idx, data);
1353 testFuncCount++;
1354 QTEST_ASSERT(QTest::testFuncCount < 512);
1355 }
1356 }
1357
1358 if (QTest::seedSet && !QTest::randomOrder) {
1359 printf("-seed requires -random\n");
1360 exit(1);
1361 }
1362}
1363
1364QBenchmarkResult qMedian(const QList<QBenchmarkResult> &container)
1365{
1366 const int count = container.count();
1367 if (count == 0)
1368 return QBenchmarkResult();
1369
1370 if (count == 1)
1371 return container.at(0);
1372
1373 QList<QBenchmarkResult> containerCopy = container;
1374 qSort(containerCopy);
1375
1376 const int middle = count / 2;
1377
1378 // ### handle even-sized containers here by doing an aritmetic mean of the two middle items.
1379 return containerCopy.at(middle);
1380}
1381
1382struct QTestDataSetter
1383{
1384 QTestDataSetter(QTestData *data)
1385 {
1386 QTestResult::setCurrentTestData(data);
1387 }
1388 ~QTestDataSetter()
1389 {
1390 QTestResult::setCurrentTestData(0);
1391 }
1392};
1393
1394static void qInvokeTestMethodDataEntry(char *slot)
1395{
1396 /* Benchmarking: for each median iteration*/
1397
1398 int i = (QBenchmarkGlobalData::current->measurer->needsWarmupIteration()) ? -1 : 0;
1399
1400 QList<QBenchmarkResult> results;
1401 do {
1402 QBenchmarkTestMethodData::current->beginDataRun();
1403
1404 /* Benchmarking: for each accumulation iteration*/
1405 bool invokeOk;
1406 do {
1407 QTestResult::setCurrentTestLocation(QTestResult::InitFunc);
1408 invokeMethod(QTest::currentTestObject, "init()");
1409 if (QTestResult::skipCurrentTest())
1410 break;
1411
1412 QTestResult::setCurrentTestLocation(QTestResult::Func);
1413
1414 QBenchmarkTestMethodData::current->result = QBenchmarkResult();
1415 QBenchmarkTestMethodData::current->resultAccepted = false;
1416
1417 QBenchmarkGlobalData::current->context.tag =
1418 QLatin1String(
1419 QTestResult::currentDataTag()
1420 ? QTestResult::currentDataTag() : "");
1421
1422 invokeOk = QMetaObject::invokeMethod(QTest::currentTestObject, slot,
1423 Qt::DirectConnection);
1424 if (!invokeOk)
1425 QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__);
1426
1427 QTestResult::setCurrentTestLocation(QTestResult::CleanupFunc);
1428 invokeMethod(QTest::currentTestObject, "cleanup()");
1429 QTestResult::setCurrentTestLocation(QTestResult::NoWhere);
1430
1431 // If this test method has a benchmark, repeat until all measurements are
1432 // acceptable.
1433 // The QBENCHMARK macro increases the number of iterations for each run until
1434 // this happens.
1435 } while (invokeOk
1436 && QBenchmarkTestMethodData::current->isBenchmark()
1437 && QBenchmarkTestMethodData::current->resultsAccepted() == false);
1438
1439 QBenchmarkTestMethodData::current->endDataRun();
1440 if (i > -1) // iteration -1 is the warmup iteration.
1441 results.append(QBenchmarkTestMethodData::current->result);
1442
1443 if (QBenchmarkTestMethodData::current->isBenchmark() &&
1444 QBenchmarkGlobalData::current->verboseOutput) {
1445 if (i == -1) {
1446 qDebug() << "warmup stage result :" << QBenchmarkTestMethodData::current->result.value;
1447 } else {
1448 qDebug() << "accumulation stage result:" << QBenchmarkTestMethodData::current->result.value;
1449 }
1450 }
1451 } while (QBenchmarkTestMethodData::current->isBenchmark()
1452 && (++i < QBenchmarkGlobalData::current->adjustMedianIterationCount()));
1453
1454 if (QBenchmarkTestMethodData::current->isBenchmark()
1455 && QBenchmarkTestMethodData::current->resultsAccepted())
1456 QTestLog::addBenchmarkResult(qMedian(results));
1457}
1458
1459/*!
1460 \internal
1461
1462 Call init(), slot_data(), slot(), slot(), slot()..., cleanup()
1463 If data is set then it is the only test that is performed
1464
1465 If the function was successfully called, true is returned, otherwise
1466 false.
1467 */
1468static bool qInvokeTestMethod(const char *slotName, const char *data=0)
1469{
1470 QTEST_ASSERT(slotName);
1471
1472 QBenchmarkTestMethodData benchmarkData;
1473 QBenchmarkTestMethodData::current = &benchmarkData;
1474
1475 QBenchmarkGlobalData::current->context.slotName = QLatin1String(slotName);
1476
1477 char member[512];
1478 QTestTable table;
1479
1480 char *slot = qstrdup(slotName);
1481 slot[strlen(slot) - 2] = '\0';
1482 QTestResult::setCurrentTestFunction(slot);
1483
1484 const QTestTable *gTable = QTestTable::globalTestTable();
1485 const int globalDataCount = gTable->dataCount();
1486 int curGlobalDataIndex = 0;
1487
1488 /* For each test function that has a *_data() table/function, do: */
1489 do {
1490 if (!gTable->isEmpty())
1491 QTestResult::setCurrentGlobalTestData(gTable->testData(curGlobalDataIndex));
1492
1493 if (curGlobalDataIndex == 0) {
1494 QTestResult::setCurrentTestLocation(QTestResult::DataFunc);
1495 QTest::qt_snprintf(member, 512, "%s_data()", slot);
1496 invokeMethod(QTest::currentTestObject, member);
1497
1498 // if we encounter a SkipAll in the _data slot, we skip the whole
1499 // testfunction, no matter how much global data exists
1500 if (QTestResult::skipCurrentTest()) {
1501 QTestResult::setCurrentGlobalTestData(0);
1502 break;
1503 }
1504 }
1505
1506 bool foundFunction = false;
1507 if (!QTestResult::skipCurrentTest()) {
1508 int curDataIndex = 0;
1509 const int dataCount = table.dataCount();
1510 QTestResult::setSkipCurrentTest(false);
1511
1512 // Data tag requested but none available?
1513 if (data && !dataCount) {
1514 // Let empty data tag through.
1515 if (!*data)
1516 data = 0;
1517 else {
1518 printf("Unknown testdata for function %s: '%s'\n", slotName, data);
1519 printf("Function has no testdata.\n");
1520 return false;
1521 }
1522 }
1523
1524 /* For each entry in the data table, do: */
1525 do {
1526 if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) {
1527 foundFunction = true;
1528 QTestDataSetter s(curDataIndex >= dataCount ? static_cast<QTestData *>(0)
1529 : table.testData(curDataIndex));
1530
1531 qInvokeTestMethodDataEntry(slot);
1532
1533 if (QTestResult::skipCurrentTest())
1534 // check whether SkipAll was requested
1535 break;
1536 if (data)
1537 break;
1538 }
1539 ++curDataIndex;
1540 } while (curDataIndex < dataCount);
1541 }
1542
1543 if (data && !foundFunction) {
1544 printf("Unknown testdata for function %s: '%s'\n", slotName, data);
1545 printf("Available testdata:\n");
1546 for(int i = 0; i < table.dataCount(); ++i)
1547 printf("%s\n", table.testData(i)->dataTag());
1548 return false;
1549 }
1550
1551 QTestResult::setCurrentGlobalTestData(0);
1552 ++curGlobalDataIndex;
1553 } while (curGlobalDataIndex < globalDataCount);
1554
1555 QTestResult::finishedCurrentTestFunction();
1556 QTestResult::setSkipCurrentTest(false);
1557 QTestResult::setCurrentTestData(0);
1558 delete[] slot;
1559
1560 return true;
1561}
1562
1563void *fetchData(QTestData *data, const char *tagName, int typeId)
1564{
1565 QTEST_ASSERT(typeId);
1566 QTEST_ASSERT_X(data, "QTest::fetchData()", "Test data requested, but no testdata available.");
1567 QTEST_ASSERT(data->parent());
1568
1569 int idx = data->parent()->indexOf(tagName);
1570
1571 if (idx == -1 || idx >= data->dataCount()) {
1572 qFatal("QFETCH: Requested testdata '%s' not available, check your _data function.",
1573 tagName);
1574 }
1575
1576 if (typeId != data->parent()->elementTypeId(idx)) {
1577 qFatal("Requested type '%s' does not match available type '%s'.",
1578 QMetaType::typeName(typeId),
1579 QMetaType::typeName(data->parent()->elementTypeId(idx)));
1580 }
1581
1582 return data->data(idx);
1583}
1584
1585/*!
1586 \fn char* QTest::toHexRepresentation(const char *ba, int length)
1587
1588 Returns a pointer to a string that is the string \a ba represented
1589 as a space-separated sequence of hex characters. If the input is
1590 considered too long, it is truncated. A trucation is indicated in
1591 the returned string as an ellipsis at the end.
1592
1593 \a length is the length of the string \a ba.
1594 */
1595char *toHexRepresentation(const char *ba, int length)
1596{
1597 if(length == 0)
1598 return qstrdup("");
1599
1600 /* We output at maximum about maxLen characters in order to avoid
1601 * running out of memory and flooding things when the byte array
1602 * is large.
1603 *
1604 * maxLen can't be for example 200 because QTestLib is sprinkled with fixed
1605 * size char arrays.
1606 * */
1607 const int maxLen = 50;
1608 const int len = qMin(maxLen, length);
1609 char *result = 0;
1610
1611 if(length > maxLen) {
1612 const int size = len * 3 + 4;
1613 result = new char[size];
1614
1615 char *const forElipsis = result + size - 5;
1616 forElipsis[0] = ' ';
1617 forElipsis[1] = '.';
1618 forElipsis[2] = '.';
1619 forElipsis[3] = '.';
1620 result[size - 1] = '\0';
1621 }
1622 else {
1623 const int size = len * 3;
1624 result = new char[size];
1625 result[size - 1] = '\0';
1626 }
1627
1628 const char toHex[] = "0123456789ABCDEF";
1629 int i = 0;
1630 int o = 0;
1631
1632 while(true) {
1633 const char at = ba[i];
1634
1635 result[o] = toHex[(at >> 4) & 0x0F];
1636 ++o;
1637 result[o] = toHex[at & 0x0F];
1638
1639 ++i;
1640 ++o;
1641 if(i == len)
1642 break;
1643 else {
1644 result[o] = ' ';
1645 ++o;
1646 }
1647 }
1648
1649 return result;
1650}
1651
1652static void qInvokeTestMethods(QObject *testObject)
1653{
1654 const QMetaObject *metaObject = testObject->metaObject();
1655 QTEST_ASSERT(metaObject);
1656 if (QTest::randomOrder) {
1657 QTestLog::startLogging(QTest::seed);
1658 } else {
1659 QTestLog::startLogging();
1660 }
1661 QTestResult::setCurrentTestFunction("initTestCase");
1662 QTestResult::setCurrentTestLocation(QTestResult::DataFunc);
1663 QTestTable::globalTestTable();
1664 invokeMethod(testObject, "initTestCase_data()");
1665
1666 if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) {
1667 QTestResult::setCurrentTestLocation(QTestResult::InitFunc);
1668 invokeMethod(testObject, "initTestCase()");
1669
1670 // finishedCurrentTestFunction() resets QTestResult::testFailed(), so use a local copy.
1671 const bool previousFailed = QTestResult::testFailed();
1672 QTestResult::finishedCurrentTestFunction();
1673
1674 if(!QTestResult::skipCurrentTest() && !previousFailed) {
1675
1676 if (QTest::testFuncs) {
1677 if (QTest::randomOrder)
1678 randomizeList(QTest::testFuncs, QTest::testFuncCount);
1679 for (int i = 0; i != QTest::testFuncCount; i++) {
1680 if (!qInvokeTestMethod(metaObject->method(QTest::testFuncs[i].function()).signature(),
1681 QTest::testFuncs[i].data())) {
1682 break;
1683 }
1684 }
1685 testFuncCleaner.cleanup();
1686 } else {
1687 int methodCount = metaObject->methodCount();
1688 QMetaMethod *testMethods = new QMetaMethod[methodCount];
1689 for (int i = 0; i != methodCount; i++)
1690 testMethods[i] = metaObject->method(i);
1691 if (QTest::randomOrder)
1692 randomizeList(testMethods, methodCount);
1693 for (int i = 0; i != methodCount; i++) {
1694 if (!isValidSlot(testMethods[i]))
1695 continue;
1696 if (!qInvokeTestMethod(testMethods[i].signature()))
1697 break;
1698 }
1699 delete[] testMethods;
1700 testMethods = 0;
1701 }
1702 }
1703
1704 QTestResult::setSkipCurrentTest(false);
1705 QTestResult::setCurrentTestFunction("cleanupTestCase");
1706 invokeMethod(testObject, "cleanupTestCase()");
1707 }
1708 QTestResult::finishedCurrentTestFunction();
1709 QTestResult::setCurrentTestFunction(0);
1710 QTestTable::clearGlobalTestTable();
1711
1712 QTestLog::stopLogging();
1713}
1714
1715#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
1716class FatalSignalHandler
1717{
1718public:
1719 FatalSignalHandler();
1720 ~FatalSignalHandler();
1721
1722private:
1723 static void signal(int);
1724 sigset_t handledSignals;
1725};
1726
1727void FatalSignalHandler::signal(int signum)
1728{
1729 qFatal("Received signal %d", signum);
1730#if defined(Q_OS_INTEGRITY)
1731 {
1732 struct sigaction act;
1733 memset(&act, 0, sizeof(struct sigaction));
1734 act.sa_handler = SIG_DFL;
1735 sigaction(signum, &act, NULL);
1736 }
1737#endif
1738}
1739
1740FatalSignalHandler::FatalSignalHandler()
1741{
1742 sigemptyset(&handledSignals);
1743
1744 const int fatalSignals[] = {
1745 SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGFPE, SIGSEGV, SIGPIPE, SIGTERM, 0 };
1746
1747 struct sigaction act;
1748 memset(&act, 0, sizeof(act));
1749 act.sa_handler = FatalSignalHandler::signal;
1750
1751 // Remove the handler after it is invoked.
1752#if !defined(Q_OS_INTEGRITY)
1753 act.sa_flags = SA_RESETHAND;
1754#endif
1755 // Block all fatal signals in our signal handler so we don't try to close
1756 // the testlog twice.
1757 sigemptyset(&act.sa_mask);
1758 for (int i = 0; fatalSignals[i]; ++i)
1759 sigaddset(&act.sa_mask, fatalSignals[i]);
1760
1761 struct sigaction oldact;
1762
1763 for (int i = 0; fatalSignals[i]; ++i) {
1764 sigaction(fatalSignals[i], &act, &oldact);
1765#ifndef Q_WS_QWS
1766 // Don't overwrite any non-default handlers
1767 // however, we need to replace the default QWS handlers
1768 if (
1769#ifdef SA_SIGINFO
1770 oldact.sa_flags & SA_SIGINFO ||
1771#endif
1772 oldact.sa_handler != SIG_DFL) {
1773 sigaction(fatalSignals[i], &oldact, 0);
1774 } else
1775#endif
1776 {
1777 sigaddset(&handledSignals, fatalSignals[i]);
1778 }
1779 }
1780}
1781
1782
1783FatalSignalHandler::~FatalSignalHandler()
1784{
1785 // Unregister any of our remaining signal handlers
1786 struct sigaction act;
1787 memset(&act, 0, sizeof(act));
1788 act.sa_handler = SIG_DFL;
1789
1790 struct sigaction oldact;
1791
1792 for (int i = 1; i < 32; ++i) {
1793 if (!sigismember(&handledSignals, i))
1794 continue;
1795 sigaction(i, &act, &oldact);
1796
1797 // If someone overwrote it in the mean time, put it back
1798 if (oldact.sa_handler != FatalSignalHandler::signal)
1799 sigaction(i, &oldact, 0);
1800 }
1801}
1802
1803#endif
1804
1805
1806} // namespace
1807
1808/*!
1809 Executes tests declared in \a testObject. In addition, the private slots
1810 \c{initTestCase()}, \c{cleanupTestCase()}, \c{init()} and \c{cleanup()}
1811 are executed if they exist. See \l{Creating a Test} for more details.
1812
1813 Optionally, the command line arguments \a argc and \a argv can be provided.
1814 For a list of recognized arguments, read \l {QTestLib Command Line Arguments}.
1815
1816 For stand-alone tests, the convenience macro \l QTEST_MAIN() can
1817 be used to declare a main method that parses the command line arguments
1818 and executes the tests.
1819
1820 Returns 0 if all tests passed. Returns a value other than 0 if tests failed
1821 or in case of unhandled exceptions. The return value from this function is
1822 also the exit code of the test application when the \l QTEST_MAIN() macro
1823 is used.
1824
1825 The following example will run all tests in \c MyFirstTestObject and
1826 \c{MySecondTestObject}:
1827
1828 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 18
1829
1830 Note: This function is not reentrant, only one test can run at a time. A
1831 test that was executed with qExec() can't run another test via qExec() and
1832 threads are not allowed to call qExec() simultaneously.
1833
1834 If you have programatically created the arguments, as opposed to getting them
1835 from the arguments in \c main(), it is likely of interest to use
1836 QTest::qExec(QObject *, const QStringList &) since it is Unicode safe.
1837
1838 \sa QTEST_MAIN()
1839*/
1840
1841int QTest::qExec(QObject *testObject, int argc, char **argv)
1842{
1843 QBenchmarkGlobalData benchmarkData;
1844 QBenchmarkGlobalData::current = &benchmarkData;
1845
1846#ifdef QTESTLIB_USE_VALGRIND
1847 int callgrindChildExitCode = 0;
1848#endif
1849
1850#ifdef Q_WS_MAC
1851 bool macNeedsActivate = qApp && (qstrcmp(qApp->metaObject()->className(), "QApplication") == 0);
1852#ifdef QT_MAC_USE_COCOA
1853 IOPMAssertionID powerID;
1854#endif
1855#endif
1856#ifndef QT_NO_EXCEPTIONS
1857 try {
1858#endif
1859
1860 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1861 SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
1862 #endif
1863
1864#ifdef Q_WS_MAC
1865 // Starting with Qt 4.4, applications launched from the command line
1866 // no longer get focus automatically. Since some tests might depend
1867 // on this, call SetFrontProcess here to get the pre 4.4 behavior.
1868 if (macNeedsActivate) {
1869 ProcessSerialNumber psn = { 0, kCurrentProcess };
1870 SetFrontProcess(&psn);
1871# ifdef QT_MAC_USE_COCOA
1872 IOReturn ok = IOPMAssertionCreate(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, &powerID);
1873 if (ok != kIOReturnSuccess)
1874 macNeedsActivate = false; // no need to release the assertion on exit.
1875# else
1876 UpdateSystemActivity(1); // Wake the display.
1877# endif
1878 }
1879#endif
1880
1881#if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86)
1882 // Delay execution of tests in Symbian emulator.
1883 // Needed to allow worst of other higher priority apps and services launched by emulator
1884 // to get out of the way before we run our test. Otherwise some of the timing sensitive tests
1885 // will not work properly.
1886 qSleep(3000);
1887#endif
1888
1889 QTestResult::reset();
1890
1891 QTEST_ASSERT(testObject);
1892 QTEST_ASSERT(!currentTestObject);
1893 currentTestObject = testObject;
1894
1895 const QMetaObject *metaObject = testObject->metaObject();
1896 QTEST_ASSERT(metaObject);
1897
1898 QTestResult::setCurrentTestObject(metaObject->className());
1899 if (argc > 0)
1900 QTestResult::setCurrentAppName(argv[0]);
1901
1902 qtest_qParseArgs(argc, argv, false);
1903 if (QTest::randomOrder) {
1904 seedRandom();
1905 }
1906#ifdef QTESTLIB_USE_VALGRIND
1907 if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) {
1908 const QStringList origAppArgs(QCoreApplication::arguments());
1909 if (!QBenchmarkValgrindUtils::rerunThroughCallgrind(origAppArgs, callgrindChildExitCode))
1910 return -1;
1911
1912 QBenchmarkValgrindUtils::cleanup();
1913
1914 } else
1915#endif
1916 {
1917#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
1918 QScopedPointer<FatalSignalHandler> handler;
1919 if (!noCrashHandler)
1920 handler.reset(new FatalSignalHandler);
1921#endif
1922 qInvokeTestMethods(testObject);
1923 }
1924
1925#ifndef QT_NO_EXCEPTIONS
1926 } catch (...) {
1927 QTestResult::addFailure("Caught unhandled exception", __FILE__, __LINE__);
1928 if (QTestResult::currentTestFunction()) {
1929 QTestResult::finishedCurrentTestFunction();
1930 QTestResult::setCurrentTestFunction(0);
1931 }
1932
1933 QTestLog::stopLogging();
1934#ifdef QT_MAC_USE_COCOA
1935 if (macNeedsActivate) {
1936 IOPMAssertionRelease(powerID);
1937 }
1938#endif
1939 currentTestObject = 0;
1940
1941 // Rethrow exception to make debugging easier.
1942 throw;
1943 return 1;
1944 }
1945# endif
1946
1947 currentTestObject = 0;
1948#ifdef QT_MAC_USE_COCOA
1949 if (macNeedsActivate) {
1950 IOPMAssertionRelease(powerID);
1951 }
1952#endif
1953
1954#if defined(QTEST_NOEXITCODE)
1955 return 0;
1956#else
1957
1958#ifdef QTESTLIB_USE_VALGRIND
1959 if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess)
1960 return callgrindChildExitCode;
1961#endif
1962 // make sure our exit code is never going above 127
1963 // since that could wrap and indicate 0 test fails
1964 return qMin(QTestResult::failCount(), 127);
1965
1966#endif
1967}
1968
1969/*!
1970 \overload
1971 \since 4.4
1972
1973 Behaves identically to qExec(QObject *, int, char**) but takes a
1974 QStringList of \a arguments instead of a \c char** list.
1975 */
1976int QTest::qExec(QObject *testObject, const QStringList &arguments)
1977{
1978 const int argc = arguments.count();
1979 QVarLengthArray<char *> argv(argc);
1980
1981 QVector<QByteArray> args;
1982 args.reserve(argc);
1983
1984 for(int i = 0; i < argc; ++i)
1985 {
1986 args.append(arguments.at(i).toLocal8Bit().constData());
1987 argv[i] = args.last().data();
1988 }
1989
1990 return qExec(testObject, argc, argv.data());
1991}
1992
1993/*! \internal
1994 */
1995void QTest::qFail(const char *statementStr, const char *file, int line)
1996{
1997 QTestResult::addFailure(statementStr, file, line);
1998}
1999
2000/*! \internal
2001 */
2002bool QTest::qVerify(bool statement, const char *statementStr, const char *description,
2003 const char *file, int line)
2004{
2005 return QTestResult::verify(statement, statementStr, description, file, line);
2006}
2007
2008/*! \fn void QTest::qSkip(const char *message, SkipMode mode, const char *file, int line)
2009\internal
2010 */
2011void QTest::qSkip(const char *message, QTest::SkipMode mode,
2012 const char *file, int line)
2013{
2014 QTestResult::addSkip(message, mode, file, line);
2015 if (mode == QTest::SkipAll)
2016 QTestResult::setSkipCurrentTest(true);
2017}
2018
2019/*! \fn bool QTest::qExpectFail(const char *dataIndex, const char *comment, TestFailMode mode, const char *file, int line)
2020\internal
2021 */
2022bool QTest::qExpectFail(const char *dataIndex, const char *comment,
2023 QTest::TestFailMode mode, const char *file, int line)
2024{
2025 return QTestResult::expectFail(dataIndex, qstrdup(comment), mode, file, line);
2026}
2027
2028/*! \internal
2029 */
2030void QTest::qWarn(const char *message)
2031{
2032 QTestLog::warn(message);
2033}
2034
2035/*!
2036 Ignores messages created by qDebug() or qWarning(). If the \a message
2037 with the corresponding \a type is outputted, it will be removed from the
2038 test log. If the test finished and the \a message was not outputted,
2039 a test failure is appended to the test log.
2040
2041 \bold {Note:} Invoking this function will only ignore one message.
2042 If the message you want to ignore is outputted twice, you have to
2043 call ignoreMessage() twice, too.
2044
2045 Example:
2046 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 19
2047
2048 The example above tests that QDir::mkdir() outputs the right warning when invoked
2049 with an invalid file name.
2050*/
2051void QTest::ignoreMessage(QtMsgType type, const char *message)
2052{
2053 QTestResult::ignoreMessage(type, message);
2054}
2055
2056/*! \internal
2057 */
2058void *QTest::qData(const char *tagName, int typeId)
2059{
2060 return fetchData(QTestResult::currentTestData(), tagName, typeId);
2061}
2062
2063/*! \internal
2064 */
2065void *QTest::qGlobalData(const char *tagName, int typeId)
2066{
2067 return fetchData(QTestResult::currentGlobalTestData(), tagName, typeId);
2068}
2069
2070/*! \internal
2071 */
2072void *QTest::qElementData(const char *tagName, int metaTypeId)
2073{
2074 QTEST_ASSERT(tagName);
2075 QTestData *data = QTestResult::currentTestData();
2076 QTEST_ASSERT(data);
2077 QTEST_ASSERT(data->parent());
2078
2079 int idx = data->parent()->indexOf(tagName);
2080 QTEST_ASSERT(idx != -1);
2081 QTEST_ASSERT(data->parent()->elementTypeId(idx) == metaTypeId);
2082
2083 return data->data(data->parent()->indexOf(tagName));
2084}
2085
2086/*! \internal
2087 */
2088void QTest::addColumnInternal(int id, const char *name)
2089{
2090 QTestTable *tbl = QTestTable::currentTestTable();
2091 QTEST_ASSERT_X(tbl, "QTest::addColumn()", "Cannot add testdata outside of a _data slot.");
2092
2093 tbl->addColumn(id, name);
2094}
2095
2096/*!
2097 Appends a new row to the current test data. \a dataTag is the name of
2098 the testdata that will appear in the test output. Returns a QTestData reference
2099 that can be used to stream in data.
2100
2101 Example:
2102 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 20
2103
2104 \bold {Note:} This macro can only be used in a test's data function
2105 that is invoked by the test framework.
2106
2107 See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
2108 a more extensive example.
2109
2110 \sa addColumn(), QFETCH()
2111*/
2112QTestData &QTest::newRow(const char *dataTag)
2113{
2114 QTestTable *tbl = QTestTable::currentTestTable();
2115 QTEST_ASSERT_X(tbl, "QTest::addColumn()", "Cannot add testdata outside of a _data slot.");
2116
2117 return *tbl->newData(dataTag);
2118}
2119
2120/*! \fn void QTest::addColumn(const char *name, T *dummy = 0)
2121
2122 Adds a column with type \c{T} to the current test data.
2123 \a name is the name of the column. \a dummy is a workaround
2124 for buggy compilers and can be ignored.
2125
2126 To populate the column with values, newRow() can be used. Use
2127 \l QFETCH() to fetch the data in the actual test.
2128
2129 Example:
2130 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 21
2131
2132 To add custom types to the testdata, the type must be registered with
2133 QMetaType via \l Q_DECLARE_METATYPE().
2134
2135 \bold {Note:} This macro can only be used in a test's data function
2136 that is invoked by the test framework.
2137
2138 See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
2139 a more extensive example.
2140
2141 \sa QTest::newRow(), QFETCH(), QMetaType
2142*/
2143
2144/*!
2145 Returns the name of the binary that is currently executed.
2146*/
2147const char *QTest::currentAppName()
2148{
2149 return QTestResult::currentAppName();
2150}
2151
2152/*!
2153 Returns the name of the test function that is currently executed.
2154
2155 Example:
2156
2157 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 22
2158*/
2159const char *QTest::currentTestFunction()
2160{
2161 return QTestResult::currentTestFunction();
2162}
2163
2164/*!
2165 Returns the name of the current test data. If the test doesn't
2166 have any assigned testdata, the function returns 0.
2167*/
2168const char *QTest::currentDataTag()
2169{
2170 return QTestResult::currentDataTag();
2171}
2172
2173/*!
2174 Returns true if the current test function failed, otherwise false.
2175*/
2176bool QTest::currentTestFailed()
2177{
2178 return QTestResult::currentTestFailed();
2179}
2180
2181/*!
2182 Sleeps for \a ms milliseconds, blocking execution of the
2183 test. qSleep() will not do any event processing and leave your test
2184 unresponsive. Network communication might time out while
2185 sleeping. Use \l qWait() to do non-blocking sleeping.
2186
2187 \a ms must be greater than 0.
2188
2189 \bold {Note:} The qSleep() function calls either \c nanosleep() on
2190 unix or \c Sleep() on windows, so the accuracy of time spent in
2191 qSleep() depends on the operating system.
2192
2193 Example:
2194 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 23
2195
2196 \sa qWait()
2197*/
2198void QTest::qSleep(int ms)
2199{
2200 QTEST_ASSERT(ms > 0);
2201
2202#ifdef Q_OS_WIN
2203 Sleep(uint(ms));
2204#else
2205 struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
2206 nanosleep(&ts, NULL);
2207#endif
2208}
2209
2210/*! \internal
2211 */
2212QObject *QTest::testObject()
2213{
2214 return currentTestObject;
2215}
2216
2217/*! \internal
2218 */
2219bool QTest::compare_helper(bool success, const char *msg, const char *file, int line)
2220{
2221 return QTestResult::compare(success, msg, file, line);
2222}
2223
2224/*! \internal
2225 */
2226bool QTest::compare_helper(bool success, const char *msg, char *val1, char *val2,
2227 const char *actual, const char *expected, const char *file, int line)
2228{
2229 return QTestResult::compare(success, msg, val1, val2, actual, expected, file, line);
2230}
2231
2232/*! \fn bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected, const char *file, int line)
2233\internal
2234 */
2235template <>
2236Q_TESTLIB_EXPORT bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected,
2237 const char *file, int line)
2238{
2239 return qFuzzyCompare(t1, t2)
2240 ? compare_helper(true, "COMPARE()", file, line)
2241 : compare_helper(false, "Compared floats are not the same (fuzzy compare)",
2242 toString(t1), toString(t2), actual, expected, file, line);
2243}
2244
2245/*! \fn bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected, const char *file, int line)
2246\internal
2247 */
2248template <>
2249Q_TESTLIB_EXPORT bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected,
2250 const char *file, int line)
2251{
2252 return qFuzzyCompare(t1, t2)
2253 ? compare_helper(true, "COMPARE()", file, line)
2254 : compare_helper(false, "Compared doubles are not the same (fuzzy compare)",
2255 toString(t1), toString(t2), actual, expected, file, line);
2256}
2257
2258#define COMPARE_IMPL2(TYPE, FORMAT) \
2259template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE >(const TYPE &t) \
2260{ \
2261 char *msg = new char[128]; \
2262 qt_snprintf(msg, 128, #FORMAT, t); \
2263 return msg; \
2264}
2265
2266COMPARE_IMPL2(short, %hd)
2267COMPARE_IMPL2(ushort, %hu)
2268COMPARE_IMPL2(int, %d)
2269COMPARE_IMPL2(uint, %u)
2270COMPARE_IMPL2(long, %ld)
2271COMPARE_IMPL2(ulong, %lu)
2272#if defined(Q_OS_WIN)
2273COMPARE_IMPL2(qint64, %I64d)
2274COMPARE_IMPL2(quint64, %I64u)
2275#else
2276COMPARE_IMPL2(qint64, %lld)
2277COMPARE_IMPL2(quint64, %llu)
2278#endif
2279COMPARE_IMPL2(bool, %d)
2280COMPARE_IMPL2(char, %c)
2281COMPARE_IMPL2(float, %g)
2282COMPARE_IMPL2(double, %lg)
2283
2284/*! \internal
2285 */
2286char *QTest::toString(const char *str)
2287{
2288 if (!str)
2289 return 0;
2290 char *msg = new char[strlen(str) + 1];
2291 return qstrcpy(msg, str);
2292}
2293
2294/*! \internal
2295 */
2296char *QTest::toString(const void *p)
2297{
2298 char *msg = new char[128];
2299 qt_snprintf(msg, 128, "%p", p);
2300 return msg;
2301}
2302
2303/*! \internal
2304 */
2305bool QTest::compare_string_helper(const char *t1, const char *t2, const char *actual,
2306 const char *expected, const char *file, int line)
2307{
2308 return (qstrcmp(t1, t2) == 0)
2309 ? compare_helper(true, "COMPARE()", file, line)
2310 : compare_helper(false, "Compared strings are not the same",
2311 toString(t1), toString(t2), actual, expected, file, line);
2312}
2313
2314/*! \fn bool QTest::compare_ptr_helper(const void *t1, const void *t2, const char *actual, const char *expected, const char *file, int line);
2315 \internal
2316*/
2317
2318/*! \fn bool QTest::qCompare(T1 const &, T2 const &, const char *, const char *, const char *, int);
2319 \internal
2320*/
2321
2322
2323/*! \fn void QTest::mouseEvent(MouseAction action, QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
2324 \internal
2325*/
2326
2327/*! \fn bool QTest::qCompare(QIcon const &t1, QIcon const &t2, const char *actual, const char *expected, const char *file, int line)
2328 \internal
2329*/
2330
2331/*! \fn bool QTest::qCompare(QPixmap const &t1, QPixmap const &t2, const char *actual, const char *expected, const char *file, int line)
2332 \internal
2333*/
2334
2335/*! \fn bool QTest::qCompare(T const &t1, T const &t2, const char *actual, const char *expected, const char *file, int line)
2336 \internal
2337*/
2338
2339/*! \fn bool QTest::qCompare(const T *t1, const T *t2, const char *actual, const char *expected, const char *file, int line)
2340 \internal
2341*/
2342
2343/*! \fn bool QTest::qCompare(T *t1, T *t2, const char *actual, const char *expected, const char *file, int line)
2344 \internal
2345*/
2346
2347/*! \fn bool QTest::qCompare(const T1 *t1, const T2 *t2, const char *actual, const char *expected, const char *file, int line)
2348 \internal
2349*/
2350
2351/*! \fn bool QTest::qCompare(T1 *t1, T2 *t2, const char *actual, const char *expected, const char *file, int line)
2352 \internal
2353*/
2354
2355/*! \fn bool QTest::qCompare(const char *t1, const char *t2, const char *actual, const char *expected, const char *file, int line)
2356 \internal
2357*/
2358
2359/*! \fn bool QTest::qCompare(char *t1, char *t2, const char *actual, const char *expected, const char *file, int line)
2360 \internal
2361*/
2362
2363/*! \fn bool QTest::qCompare(char *t1, const char *t2, const char *actual, const char *expected, const char *file, int line)
2364 \internal
2365*/
2366
2367/*! \fn bool QTest::qCompare(const char *t1, char *t2, const char *actual, const char *expected, const char *file, int line)
2368 \internal
2369*/
2370
2371/*! \fn bool QTest::qCompare(QString const &t1, QLatin1String const &t2, const char *actual, const char *expected, const char *file, int line)
2372 \internal
2373*/
2374
2375/*! \fn bool QTest::qCompare(QLatin1String const &t1, QString const &t2, const char *actual, const char *expected, const char *file, int line)
2376 \internal
2377*/
2378
2379/*! \fn bool QTest::qCompare(QStringList const &t1, QStringList const &t2, const char *actual, const char *expected, const char *file, int line)
2380 \internal
2381*/
2382
2383/*! \fn bool QTest::qCompare(QFlags<T> const &t1, T const &t2, const char *actual, const char *expected, const char *file, int line)
2384 \internal
2385*/
2386
2387/*! \fn bool QTest::qCompare(QFlags<T> const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line)
2388 \internal
2389*/
2390
2391/*! \fn bool QTest::qCompare(bool const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line)
2392 \internal
2393 */
2394
2395/*! \fn bool QTest::qTest(const T& actual, const char *elementName, const char *actualStr, const char *expected, const char *file, int line)
2396 \internal
2397*/
2398
2399/*! \fn void QTest::sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code, QString text, Qt::KeyboardModifiers modifier, int delay=-1)
2400 \internal
2401*/
2402
2403/*! \fn void QTest::sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code, char ascii, Qt::KeyboardModifiers modifier, int delay=-1)
2404 \internal
2405*/
2406
2407/*! \fn void QTest::simulateEvent(QWidget *widget, bool press, int code, Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1)
2408 \internal
2409*/
2410
2411QT_END_NAMESPACE
2412