1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
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 The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
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 
89 QT_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 
832 namespace QTest
833 {
834     static QObject *currentTestObject = 0;
835 
836     class TestFunction {
837     public:
TestFunction()838         TestFunction() : function_(-1), data_(0) {}
set(int function,char * data)839         void set(int function, char *data) { function_ = function; data_ = data; }
data() const840         char *data() const { return data_; }
function() const841         int function() const { return function_; }
~TestFunction()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     {
cleanupQTest::TestFuncCleanup859         void cleanup()
860         {
861             delete[] testFuncs;
862             testFuncCount = 0;
863             testFuncs = 0;
864         }
865 
~TestFuncCleanupQTest::TestFuncCleanup866         ~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 
filter_unprintable(char * str)880 void 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  */
qt_snprintf(char * str,int size,const char * format,...)892 int 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  */
invokeMethod(QObject * obj,const char * methodName)910 static 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 
defaultKeyVerbose()920 bool 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 
defaultEventDelay()928 int 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 
defaultMouseDelay()939 int 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 
defaultKeyDelay()950 int 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 
seedRandom()961 void 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 
qTestRandomSeed()975 int qTestRandomSeed()
976 {
977     Q_ASSERT(QTest::seedSet);
978     return QTest::seed;
979 }
980 
981 template<typename T>
swap(T * array,int pos,int otherPos)982 void swap(T * array, int pos, int otherPos)
983 {
984     T tmp = array[pos];
985     array[pos] = array[otherPos];
986     array[otherPos] = tmp;
987 }
988 
989 template<typename T>
randomizeList(T * array,int size)990 static 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 
isValidSlot(const QMetaMethod & sl)998 static 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 
1017 Q_TESTLIB_EXPORT bool printAvailableFunctions = false;
1018 Q_TESTLIB_EXPORT bool printAvailableTags = false;
1019 Q_TESTLIB_EXPORT QStringList testFunctions;
1020 Q_TESTLIB_EXPORT QStringList testTags;
1021 
qPrintTestSlots()1022 static 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 
qPrintDataTags()1031 static 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 
qToInt(char * str)1090 static 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 
qtest_qParseArgs(int argc,char * argv[],bool qml)1101 Q_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 
qMedian(const QList<QBenchmarkResult> & container)1364 QBenchmarkResult 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 
1382 struct QTestDataSetter
1383 {
QTestDataSetterQTest::QTestDataSetter1384     QTestDataSetter(QTestData *data)
1385     {
1386         QTestResult::setCurrentTestData(data);
1387     }
~QTestDataSetterQTest::QTestDataSetter1388     ~QTestDataSetter()
1389     {
1390         QTestResult::setCurrentTestData(0);
1391     }
1392 };
1393 
qInvokeTestMethodDataEntry(char * slot)1394 static 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  */
qInvokeTestMethod(const char * slotName,const char * data=0)1468 static 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 
fetchData(QTestData * data,const char * tagName,int typeId)1563 void *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  */
toHexRepresentation(const char * ba,int length)1595 char *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 
qInvokeTestMethods(QObject * testObject)1652 static 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)
1716 class FatalSignalHandler
1717 {
1718 public:
1719     FatalSignalHandler();
1720     ~FatalSignalHandler();
1721 
1722 private:
1723     static void signal(int);
1724     sigset_t handledSignals;
1725 };
1726 
signal(int signum)1727 void 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 
FatalSignalHandler()1740 FatalSignalHandler::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 
~FatalSignalHandler()1783 FatalSignalHandler::~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 
qExec(QObject * testObject,int argc,char ** argv)1841 int 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  */
qExec(QObject * testObject,const QStringList & arguments)1976 int 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  */
qFail(const char * statementStr,const char * file,int line)1995 void QTest::qFail(const char *statementStr, const char *file, int line)
1996 {
1997     QTestResult::addFailure(statementStr, file, line);
1998 }
1999 
2000 /*! \internal
2001  */
qVerify(bool statement,const char * statementStr,const char * description,const char * file,int line)2002 bool 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  */
qSkip(const char * message,QTest::SkipMode mode,const char * file,int line)2011 void 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  */
qExpectFail(const char * dataIndex,const char * comment,QTest::TestFailMode mode,const char * file,int line)2022 bool 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  */
qWarn(const char * message)2030 void 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 */
ignoreMessage(QtMsgType type,const char * message)2051 void QTest::ignoreMessage(QtMsgType type, const char *message)
2052 {
2053     QTestResult::ignoreMessage(type, message);
2054 }
2055 
2056 /*! \internal
2057  */
qData(const char * tagName,int typeId)2058 void *QTest::qData(const char *tagName, int typeId)
2059 {
2060     return fetchData(QTestResult::currentTestData(), tagName, typeId);
2061 }
2062 
2063 /*! \internal
2064  */
qGlobalData(const char * tagName,int typeId)2065 void *QTest::qGlobalData(const char *tagName, int typeId)
2066 {
2067     return fetchData(QTestResult::currentGlobalTestData(), tagName, typeId);
2068 }
2069 
2070 /*! \internal
2071  */
qElementData(const char * tagName,int metaTypeId)2072 void *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  */
addColumnInternal(int id,const char * name)2088 void 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 */
newRow(const char * dataTag)2112 QTestData &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 */
currentAppName()2147 const 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 */
currentTestFunction()2159 const 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 */
currentDataTag()2168 const char *QTest::currentDataTag()
2169 {
2170     return QTestResult::currentDataTag();
2171 }
2172 
2173 /*!
2174     Returns true if the current test function failed, otherwise false.
2175 */
currentTestFailed()2176 bool 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 */
qSleep(int ms)2198 void 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  */
testObject()2212 QObject *QTest::testObject()
2213 {
2214     return currentTestObject;
2215 }
2216 
2217 /*! \internal
2218  */
compare_helper(bool success,const char * msg,const char * file,int line)2219 bool 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  */
compare_helper(bool success,const char * msg,char * val1,char * val2,const char * actual,const char * expected,const char * file,int line)2226 bool 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  */
2235 template <>
qCompare(float const & t1,float const & t2,const char * actual,const char * expected,const char * file,int line)2236 Q_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  */
2248 template <>
qCompare(double const & t1,double const & t2,const char * actual,const char * expected,const char * file,int line)2249 Q_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) \
2259 template <> 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 
2266 COMPARE_IMPL2(short, %hd)
2267 COMPARE_IMPL2(ushort, %hu)
2268 COMPARE_IMPL2(int, %d)
2269 COMPARE_IMPL2(uint, %u)
2270 COMPARE_IMPL2(long, %ld)
2271 COMPARE_IMPL2(ulong, %lu)
2272 #if defined(Q_OS_WIN)
2273 COMPARE_IMPL2(qint64, %I64d)
2274 COMPARE_IMPL2(quint64, %I64u)
2275 #else
2276 COMPARE_IMPL2(qint64, %lld)
2277 COMPARE_IMPL2(quint64, %llu)
2278 #endif
2279 COMPARE_IMPL2(bool, %d)
2280 COMPARE_IMPL2(char, %c)
2281 COMPARE_IMPL2(float, %g)
2282 COMPARE_IMPL2(double, %lg)
2283 
2284 /*! \internal
2285  */
toString(const char * str)2286 char *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  */
toString(const void * p)2296 char *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  */
compare_string_helper(const char * t1,const char * t2,const char * actual,const char * expected,const char * file,int line)2305 bool 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 
2411 QT_END_NAMESPACE
2412