source: trunk/src/testlib/qtestcase.cpp@ 1146

Last change on this file since 1146 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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