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

Last change on this file since 703 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

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