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

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

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

File size: 70.9 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 results\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 (strcmp(argv[i], "-graphicssystem") == 0) {
1117 // do nothing
1118 if (i + 1 >= argc) {
1119 printf("-graphicssystem needs an extra parameter specifying the graphics system\n");
1120 exit(1);
1121 } else {
1122 ++i;
1123 }
1124 } else if (argv[i][0] == '-') {
1125 printf("Unknown option: '%s'\n\n%s", argv[i], testOptions);
1126 exit(1);
1127 } else {
1128 int colon = -1;
1129 char buf[512], *data=0;
1130 int off;
1131 for(off = 0; *(argv[i]+off); ++off) {
1132 if (*(argv[i]+off) == ':') {
1133 colon = off;
1134 break;
1135 }
1136 }
1137 if(colon != -1) {
1138 data = qstrdup(argv[i]+colon+1);
1139 }
1140 QTest::qt_snprintf(buf, qMin(512, off + 1), "%s", argv[i]); // copy text before the ':' into buf
1141 QTest::qt_snprintf(buf + off, qMin(512 - off, 3), "()"); // append "()"
1142 int idx = QTest::currentTestObject->metaObject()->indexOfMethod(buf);
1143 if (idx < 0 || !isValidSlot(QTest::currentTestObject->metaObject()->method(idx))) {
1144 printf("Unknown testfunction: '%s'\n", buf);
1145 printf("Available testfunctions:\n");
1146 qPrintTestSlots();
1147 exit(1);
1148 }
1149 ++QTest::lastTestFuncIdx;
1150 if (!QTest::testFuncs) {
1151 struct Cleanup { ~Cleanup() { delete[] QTest::testFuncs; } };
1152 static Cleanup cleanup;
1153 QTest::testFuncs = new TestFunction[512];
1154 }
1155 QTest::testFuncs[QTest::lastTestFuncIdx].function = idx;
1156 QTest::testFuncs[QTest::lastTestFuncIdx].data = data;
1157 QTEST_ASSERT(QTest::lastTestFuncIdx < 512);
1158 }
1159 }
1160}
1161
1162QBenchmarkResult qMedian(const QList<QBenchmarkResult> &container)
1163{
1164 const int count = container.count();
1165 if (count == 0)
1166 return QBenchmarkResult();
1167
1168 if (count == 1)
1169 return container.at(0);
1170
1171 QList<QBenchmarkResult> containerCopy = container;
1172 qSort(containerCopy);
1173
1174 const int middle = count / 2;
1175
1176 // ### handle even-sized containers here by doing an aritmetic mean of the two middle items.
1177 return containerCopy.at(middle);
1178}
1179
1180struct QTestDataSetter
1181{
1182 QTestDataSetter(QTestData *data)
1183 {
1184 QTestResult::setCurrentTestData(data);
1185 }
1186 ~QTestDataSetter()
1187 {
1188 QTestResult::setCurrentTestData(0);
1189 }
1190};
1191
1192static void qInvokeTestMethodDataEntry(char *slot)
1193{
1194 /* Benchmarking: for each median iteration*/
1195
1196 int i = (QBenchmarkGlobalData::current->measurer->needsWarmupIteration()) ? -1 : 0;
1197
1198 QList<QBenchmarkResult> results;
1199 do {
1200 QBenchmarkTestMethodData::current->beginDataRun();
1201
1202 /* Benchmarking: for each accumulation iteration*/
1203 bool invokeOk;
1204 do {
1205 QTestResult::setCurrentTestLocation(QTestResult::InitFunc);
1206 QMetaObject::invokeMethod(QTest::currentTestObject, "init");
1207 if (QTestResult::skipCurrentTest())
1208 break;
1209
1210 QTestResult::setCurrentTestLocation(QTestResult::Func);
1211
1212 QBenchmarkTestMethodData::current->result = QBenchmarkResult();
1213 QBenchmarkTestMethodData::current->resultAccepted = false;
1214
1215 QBenchmarkGlobalData::current->context.tag =
1216 QLatin1String(
1217 QTestResult::currentDataTag()
1218 ? QTestResult::currentDataTag() : "");
1219
1220 invokeOk = QMetaObject::invokeMethod(QTest::currentTestObject, slot,
1221 Qt::DirectConnection);
1222 if (!invokeOk)
1223 QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__);
1224
1225 QTestResult::setCurrentTestLocation(QTestResult::CleanupFunc);
1226 QMetaObject::invokeMethod(QTest::currentTestObject, "cleanup");
1227 QTestResult::setCurrentTestLocation(QTestResult::NoWhere);
1228
1229 // If this test method has a benchmark, repeat until all measurements are
1230 // acceptable.
1231 // The QBENCHMARK macro increases the number of iterations for each run until
1232 // this happens.
1233 } while (invokeOk
1234 && QBenchmarkTestMethodData::current->isBenchmark()
1235 && QBenchmarkTestMethodData::current->resultsAccepted() == false);
1236
1237 QBenchmarkTestMethodData::current->endDataRun();
1238 if (i > -1) // iteration -1 is the warmup iteration.
1239 results.append(QBenchmarkTestMethodData::current->result);
1240
1241 if (QBenchmarkTestMethodData::current->isBenchmark() &&
1242 QBenchmarkGlobalData::current->verboseOutput) {
1243 if (i == -1) {
1244 qDebug() << "warmup stage result :" << QBenchmarkTestMethodData::current->result.value;
1245 } else {
1246 qDebug() << "accumulation stage result:" << QBenchmarkTestMethodData::current->result.value;
1247 }
1248 }
1249 } while (QBenchmarkTestMethodData::current->isBenchmark()
1250 && (++i < QBenchmarkGlobalData::current->adjustMedianIterationCount()));
1251
1252 if (QBenchmarkTestMethodData::current->isBenchmark()
1253 && QBenchmarkTestMethodData::current->resultsAccepted())
1254 QTestLog::addBenchmarkResult(qMedian(results));
1255}
1256
1257/*!
1258 \internal
1259
1260 Call init(), slot_data(), slot(), slot(), slot()..., cleanup()
1261 If data is set then it is the only test that is performed
1262
1263 If the function was successfully called, true is returned, otherwise
1264 false.
1265 */
1266static bool qInvokeTestMethod(const char *slotName, const char *data=0)
1267{
1268 QTEST_ASSERT(slotName);
1269
1270 QBenchmarkTestMethodData benchmarkData;
1271 QBenchmarkTestMethodData::current = &benchmarkData;
1272
1273 QBenchmarkGlobalData::current->context.slotName = QLatin1String(slotName);
1274
1275 char member[512];
1276 QTestTable table;
1277
1278 char *slot = qstrdup(slotName);
1279 slot[strlen(slot) - 2] = '\0';
1280 QTestResult::setCurrentTestFunction(slot);
1281
1282 const QTestTable *gTable = QTestTable::globalTestTable();
1283 const int globalDataCount = gTable->dataCount();
1284 int curGlobalDataIndex = 0;
1285
1286 /* For each test function that has a *_data() table/function, do: */
1287 do {
1288 if (!gTable->isEmpty())
1289 QTestResult::setCurrentGlobalTestData(gTable->testData(curGlobalDataIndex));
1290
1291 if (curGlobalDataIndex == 0) {
1292 QTestResult::setCurrentTestLocation(QTestResult::DataFunc);
1293 QTest::qt_snprintf(member, 512, "%s_data", slot);
1294 QMetaObject::invokeMethod(QTest::currentTestObject, member, Qt::DirectConnection);
1295 // if we encounter a SkipAll in the _data slot, we skip the whole
1296 // testfunction, no matter how much global data exists
1297 if (QTestResult::skipCurrentTest()) {
1298 QTestResult::setCurrentGlobalTestData(0);
1299 break;
1300 }
1301 }
1302
1303 bool foundFunction = false;
1304 if (!QTestResult::skipCurrentTest()) {
1305 int curDataIndex = 0;
1306 const int dataCount = table.dataCount();
1307 QTestResult::setSkipCurrentTest(false);
1308
1309 // Data tag requested but none available?
1310 if (data && !dataCount) {
1311 // Let empty data tag through.
1312 if (!*data)
1313 data = 0;
1314 else {
1315 printf("Unknown testdata for function %s: '%s'\n", slotName, data);
1316 printf("Function has no testdata.\n");
1317 return false;
1318 }
1319 }
1320
1321 /* For each entry in the data table, do: */
1322 do {
1323 if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) {
1324 foundFunction = true;
1325 QTestDataSetter s(curDataIndex >= dataCount ? static_cast<QTestData *>(0)
1326 : table.testData(curDataIndex));
1327
1328 qInvokeTestMethodDataEntry(slot);
1329
1330 if (QTestResult::skipCurrentTest())
1331 // check whether SkipAll was requested
1332 break;
1333 if (data)
1334 break;
1335 }
1336 ++curDataIndex;
1337 } while (curDataIndex < dataCount);
1338 }
1339
1340 if (data && !foundFunction) {
1341 printf("Unknown testdata for function %s: '%s'\n", slotName, data);
1342 printf("Available testdata:\n");
1343 for(int i = 0; i < table.dataCount(); ++i)
1344 printf("%s\n", table.testData(i)->dataTag());
1345 return false;
1346 }
1347
1348 QTestResult::setCurrentGlobalTestData(0);
1349 ++curGlobalDataIndex;
1350 } while (curGlobalDataIndex < globalDataCount);
1351
1352 QTestResult::finishedCurrentTestFunction();
1353 QTestResult::setSkipCurrentTest(false);
1354 QTestResult::setCurrentTestData(0);
1355 delete[] slot;
1356
1357 return true;
1358}
1359
1360void *fetchData(QTestData *data, const char *tagName, int typeId)
1361{
1362 QTEST_ASSERT(typeId);
1363 QTEST_ASSERT_X(data, "QTest::fetchData()", "Test data requested, but no testdata available.");
1364 QTEST_ASSERT(data->parent());
1365
1366 int idx = data->parent()->indexOf(tagName);
1367
1368 if (idx == -1 || idx >= data->dataCount()) {
1369 qFatal("QFETCH: Requested testdata '%s' not available, check your _data function.",
1370 tagName);
1371 }
1372
1373 if (typeId != data->parent()->elementTypeId(idx)) {
1374 qFatal("Requested type '%s' does not match available type '%s'.",
1375 QMetaType::typeName(typeId),
1376 QMetaType::typeName(data->parent()->elementTypeId(idx)));
1377 }
1378
1379 return data->data(idx);
1380}
1381
1382/*!
1383 \fn char* QTest::toHexRepresentation(const char *ba, int length)
1384
1385 Returns a pointer to a string that is the string \a ba represented
1386 as a space-separated sequence of hex characters. If the input is
1387 considered too long, it is truncated. A trucation is indicated in
1388 the returned string as an ellipsis at the end.
1389
1390 \a length is the length of the string \a ba.
1391 */
1392char *toHexRepresentation(const char *ba, int length)
1393{
1394 if(length == 0)
1395 return qstrdup("");
1396
1397 /* We output at maximum about maxLen characters in order to avoid
1398 * running out of memory and flooding things when the byte array
1399 * is large.
1400 *
1401 * maxLen can't be for example 200 because QTestLib is sprinkled with fixed
1402 * size char arrays.
1403 * */
1404 const int maxLen = 50;
1405 const int len = qMin(maxLen, length);
1406 char *result = 0;
1407
1408 if(length > maxLen) {
1409 const int size = len * 3 + 4;
1410 result = new char[size];
1411
1412 char *const forElipsis = result + size - 5;
1413 forElipsis[0] = ' ';
1414 forElipsis[1] = '.';
1415 forElipsis[2] = '.';
1416 forElipsis[3] = '.';
1417 result[size - 1] = '\0';
1418 }
1419 else {
1420 const int size = len * 3;
1421 result = new char[size];
1422 result[size - 1] = '\0';
1423 }
1424
1425 const char toHex[] = "0123456789ABCDEF";
1426 int i = 0;
1427 int o = 0;
1428
1429 while(true) {
1430 const char at = ba[i];
1431
1432 result[o] = toHex[(at >> 4) & 0x0F];
1433 ++o;
1434 result[o] = toHex[at & 0x0F];
1435
1436 ++i;
1437 ++o;
1438 if(i == len)
1439 break;
1440 else {
1441 result[o] = ' ';
1442 ++o;
1443 }
1444 }
1445
1446 return result;
1447}
1448
1449static void qInvokeTestMethods(QObject *testObject)
1450{
1451 const QMetaObject *metaObject = testObject->metaObject();
1452 QTEST_ASSERT(metaObject);
1453
1454 QTestLog::startLogging();
1455
1456 QTestResult::setCurrentTestFunction("initTestCase");
1457 QTestResult::setCurrentTestLocation(QTestResult::DataFunc);
1458 QTestTable::globalTestTable();
1459 QMetaObject::invokeMethod(testObject, "initTestCase_data", Qt::DirectConnection);
1460
1461 if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) {
1462 QTestResult::setCurrentTestLocation(QTestResult::InitFunc);
1463 QMetaObject::invokeMethod(testObject, "initTestCase");
1464
1465 // finishedCurrentTestFunction() resets QTestResult::testFailed(), so use a local copy.
1466 const bool previousFailed = QTestResult::testFailed();
1467 QTestResult::finishedCurrentTestFunction();
1468
1469 if(!QTestResult::skipCurrentTest() && !previousFailed) {
1470
1471 if (lastTestFuncIdx >= 0) {
1472 for (int i = 0; i <= lastTestFuncIdx; ++i) {
1473 if (!qInvokeTestMethod(metaObject->method(testFuncs[i].function).signature(),
1474 testFuncs[i].data))
1475 break;
1476 }
1477 } else {
1478 int methodCount = metaObject->methodCount();
1479 for (int i = 0; i < methodCount; ++i) {
1480 QMetaMethod slotMethod = metaObject->method(i);
1481 if (!isValidSlot(slotMethod))
1482 continue;
1483 if (!qInvokeTestMethod(slotMethod.signature()))
1484 break;
1485 }
1486 }
1487 }
1488
1489 QTestResult::setSkipCurrentTest(false);
1490 QTestResult::setCurrentTestFunction("cleanupTestCase");
1491 QMetaObject::invokeMethod(testObject, "cleanupTestCase");
1492 }
1493 QTestResult::finishedCurrentTestFunction();
1494 QTestResult::setCurrentTestFunction(0);
1495 QTestTable::clearGlobalTestTable();
1496
1497 QTestLog::stopLogging();
1498}
1499
1500#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
1501class FatalSignalHandler
1502{
1503public:
1504 FatalSignalHandler();
1505 ~FatalSignalHandler();
1506
1507private:
1508 static void signal(int);
1509 sigset_t handledSignals;
1510};
1511
1512void FatalSignalHandler::signal(int signum)
1513{
1514 qFatal("Received signal %d", signum);
1515}
1516
1517FatalSignalHandler::FatalSignalHandler()
1518{
1519 sigemptyset(&handledSignals);
1520
1521 const int fatalSignals[] = {
1522 SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGFPE, SIGSEGV, SIGPIPE, SIGTERM, 0 };
1523
1524 struct sigaction act;
1525 memset(&act, 0, sizeof(act));
1526 act.sa_handler = FatalSignalHandler::signal;
1527
1528 // Remove the handler after it is invoked.
1529 act.sa_flags = SA_RESETHAND;
1530
1531 // Block all fatal signals in our signal handler so we don't try to close
1532 // the testlog twice.
1533 sigemptyset(&act.sa_mask);
1534 for (int i = 0; fatalSignals[i]; ++i)
1535 sigaddset(&act.sa_mask, fatalSignals[i]);
1536
1537 struct sigaction oldact;
1538
1539 for (int i = 0; fatalSignals[i]; ++i) {
1540 sigaction(fatalSignals[i], &act, &oldact);
1541#ifndef Q_WS_QWS
1542 // Don't overwrite any non-default handlers
1543 // however, we need to replace the default QWS handlers
1544 if (oldact.sa_flags & SA_SIGINFO || oldact.sa_handler != SIG_DFL) {
1545 sigaction(fatalSignals[i], &oldact, 0);
1546 } else
1547#endif
1548 {
1549 sigaddset(&handledSignals, fatalSignals[i]);
1550 }
1551 }
1552}
1553
1554
1555FatalSignalHandler::~FatalSignalHandler()
1556{
1557 // Unregister any of our remaining signal handlers
1558 struct sigaction act;
1559 memset(&act, 0, sizeof(act));
1560 act.sa_handler = SIG_DFL;
1561
1562 struct sigaction oldact;
1563
1564 for (int i = 1; i < 32; ++i) {
1565 if (!sigismember(&handledSignals, i))
1566 continue;
1567 sigaction(i, &act, &oldact);
1568
1569 // If someone overwrote it in the mean time, put it back
1570 if (oldact.sa_handler != FatalSignalHandler::signal)
1571 sigaction(i, &oldact, 0);
1572 }
1573}
1574
1575#endif
1576
1577
1578} // namespace
1579
1580/*!
1581 Executes tests declared in \a testObject. In addition, the private slots
1582 \c{initTestCase()}, \c{cleanupTestCase()}, \c{init()} and \c{cleanup()}
1583 are executed if they exist. See \l{Creating a Test} for more details.
1584
1585 Optionally, the command line arguments \a argc and \a argv can be provided.
1586 For a list of recognized arguments, read \l {QTestLib Command Line Arguments}.
1587
1588 For stand-alone tests, the convenience macro \l QTEST_MAIN() can
1589 be used to declare a main method that parses the command line arguments
1590 and executes the tests.
1591
1592 Returns 0 if all tests passed. Returns a value other than 0 if tests failed
1593 or in case of unhandled exceptions. The return value from this function is
1594 also the exit code of the test application when the \l QTEST_MAIN() macro
1595 is used.
1596
1597 The following example will run all tests in \c MyFirstTestObject and
1598 \c{MySecondTestObject}:
1599
1600 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 18
1601
1602 Note: This function is not reentrant, only one test can run at a time. A
1603 test that was executed with qExec() can't run another test via qExec() and
1604 threads are not allowed to call qExec() simultaneously.
1605
1606 If you have programatically created the arguments, as opposed to getting them
1607 from the arguments in \c main(), it is likely of interest to use
1608 QTest::qExec(QObject *, const QStringList &) since it is Unicode safe.
1609
1610 \sa QTEST_MAIN()
1611*/
1612
1613int QTest::qExec(QObject *testObject, int argc, char **argv)
1614{
1615 QBenchmarkGlobalData benchmarkData;
1616 QBenchmarkGlobalData::current = &benchmarkData;
1617
1618#ifdef QTESTLIB_USE_VALGRIND
1619 int callgrindChildExitCode = 0;
1620#endif
1621
1622#ifdef Q_WS_MAC
1623 bool macNeedsActivate = qApp && (qstrcmp(qApp->metaObject()->className(), "QApplication") == 0);
1624#ifdef QT_MAC_USE_COCOA
1625 IOPMAssertionID powerID;
1626#endif
1627#endif
1628#ifndef QT_NO_EXCEPTIONS
1629 try {
1630#endif
1631
1632 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1633 SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
1634 #endif
1635
1636#ifdef Q_WS_MAC
1637 // Starting with Qt 4.4, applications launched from the command line
1638 // no longer get focus automatically. Since some tests might depend
1639 // on this, call SetFrontProcess here to get the pre 4.4 behavior.
1640 if (macNeedsActivate) {
1641 ProcessSerialNumber psn = { 0, kCurrentProcess };
1642 SetFrontProcess(&psn);
1643# ifdef QT_MAC_USE_COCOA
1644 IOReturn ok = IOPMAssertionCreate(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, &powerID);
1645 if (ok != kIOReturnSuccess)
1646 macNeedsActivate = false; // no need to release the assertion on exit.
1647# else
1648 UpdateSystemActivity(1); // Wake the display.
1649# endif
1650 }
1651#endif
1652
1653#if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86)
1654 // Delay execution of tests in Symbian emulator.
1655 // Needed to allow worst of other higher priority apps and services launched by emulator
1656 // to get out of the way before we run our test. Otherwise some of the timing sensitive tests
1657 // will not work properly.
1658 qSleep(3000);
1659#endif
1660
1661 QTestResult::reset();
1662
1663 QTEST_ASSERT(testObject);
1664 QTEST_ASSERT(!currentTestObject);
1665 currentTestObject = testObject;
1666
1667 const QMetaObject *metaObject = testObject->metaObject();
1668 QTEST_ASSERT(metaObject);
1669
1670 QTestResult::setCurrentTestObject(metaObject->className());
1671 qParseArgs(argc, argv);
1672#ifdef QTESTLIB_USE_VALGRIND
1673 if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) {
1674 const QStringList origAppArgs(QCoreApplication::arguments());
1675 if (!QBenchmarkValgrindUtils::rerunThroughCallgrind(origAppArgs, callgrindChildExitCode))
1676 return -1;
1677
1678 QBenchmarkValgrindUtils::cleanup();
1679
1680 } else
1681#endif
1682 {
1683#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
1684 FatalSignalHandler handler;
1685#endif
1686 qInvokeTestMethods(testObject);
1687 }
1688
1689#ifndef QT_NO_EXCEPTIONS
1690 } catch (...) {
1691 QTestResult::addFailure("Caught unhandled exception", __FILE__, __LINE__);
1692 if (QTestResult::currentTestFunction()) {
1693 QTestResult::finishedCurrentTestFunction();
1694 QTestResult::setCurrentTestFunction(0);
1695 }
1696
1697 QTestLog::stopLogging();
1698#ifdef QT_MAC_USE_COCOA
1699 if (macNeedsActivate) {
1700 IOPMAssertionRelease(powerID);
1701 }
1702#endif
1703 // Rethrow exception to make debugging easier.
1704 throw;
1705 return 1;
1706 }
1707# endif
1708
1709 currentTestObject = 0;
1710#ifdef QT_MAC_USE_COCOA
1711 if (macNeedsActivate) {
1712 IOPMAssertionRelease(powerID);
1713 }
1714#endif
1715
1716
1717#if !defined(QT_NO_PROCESS) && !defined(QT_NO_SETTINGS)
1718 if (QBenchmarkGlobalData::current->createChart) {
1719 QString chartLocation = QLibraryInfo::location(QLibraryInfo::BinariesPath);
1720#ifdef Q_OS_WIN
1721 chartLocation += QLatin1String("/../tools/qtestlib/chart/release/chart.exe");
1722#else
1723 chartLocation += QLatin1String("/../tools/qtestlib/chart/chart");
1724#endif
1725 if (QFile::exists(chartLocation)) {
1726 QProcess p;
1727 p.setProcessChannelMode(QProcess::ForwardedChannels);
1728 p.start(chartLocation, QStringList() << QLatin1String("results.xml"));
1729 p.waitForFinished(-1);
1730 } else {
1731 qDebug() << QLatin1String("Could not find the chart tool in ") + chartLocation + QLatin1String(", please make sure it is compiled.");
1732 }
1733 }
1734#endif
1735
1736#if defined(QTEST_NOEXITCODE)
1737 return 0;
1738#else
1739
1740#ifdef QTESTLIB_USE_VALGRIND
1741 if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess)
1742 return callgrindChildExitCode;
1743#endif
1744 // make sure our exit code is never going above 127
1745 // since that could wrap and indicate 0 test fails
1746 return qMin(QTestResult::failCount(), 127);
1747
1748#endif
1749}
1750
1751/*!
1752 \overload
1753 \since 4.4
1754
1755 Behaves identically to qExec(QObject *, int, char**) but takes a
1756 QStringList of \a arguments instead of a \c char** list.
1757 */
1758int QTest::qExec(QObject *testObject, const QStringList &arguments)
1759{
1760 const int argc = arguments.count();
1761 QVarLengthArray<char *> argv(argc);
1762
1763 QVector<QByteArray> args;
1764 args.reserve(argc);
1765
1766 for(int i = 0; i < argc; ++i)
1767 {
1768 args.append(arguments.at(i).toLocal8Bit().constData());
1769 argv[i] = args.last().data();
1770 }
1771
1772 return qExec(testObject, argc, argv.data());
1773}
1774
1775/*! \internal
1776 */
1777void QTest::qFail(const char *statementStr, const char *file, int line)
1778{
1779 QTestResult::addFailure(statementStr, file, line);
1780}
1781
1782/*! \internal
1783 */
1784bool QTest::qVerify(bool statement, const char *statementStr, const char *description,
1785 const char *file, int line)
1786{
1787 return QTestResult::verify(statement, statementStr, description, file, line);
1788}
1789
1790/*! \fn void QTest::qSkip(const char *message, SkipMode mode, const char *file, int line)
1791\internal
1792 */
1793void QTest::qSkip(const char *message, QTest::SkipMode mode,
1794 const char *file, int line)
1795{
1796 QTestResult::addSkip(message, mode, file, line);
1797 if (mode == QTest::SkipAll)
1798 QTestResult::setSkipCurrentTest(true);
1799}
1800
1801/*! \fn bool QTest::qExpectFail(const char *dataIndex, const char *comment, TestFailMode mode, const char *file, int line)
1802\internal
1803 */
1804bool QTest::qExpectFail(const char *dataIndex, const char *comment,
1805 QTest::TestFailMode mode, const char *file, int line)
1806{
1807 return QTestResult::expectFail(dataIndex, qstrdup(comment), mode, file, line);
1808}
1809
1810/*! \internal
1811 */
1812void QTest::qWarn(const char *message)
1813{
1814 QTestLog::warn(message);
1815}
1816
1817/*!
1818 Ignores messages created by qDebug() or qWarning(). If the \a message
1819 with the corresponding \a type is outputted, it will be removed from the
1820 test log. If the test finished and the \a message was not outputted,
1821 a test failure is appended to the test log.
1822
1823 \bold {Note:} Invoking this function will only ignore one message.
1824 If the message you want to ignore is outputted twice, you have to
1825 call ignoreMessage() twice, too.
1826
1827 Example:
1828 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 19
1829
1830 The example above tests that QDir::mkdir() outputs the right warning when invoked
1831 with an invalid file name.
1832*/
1833void QTest::ignoreMessage(QtMsgType type, const char *message)
1834{
1835 QTestResult::ignoreMessage(type, message);
1836}
1837
1838/*! \internal
1839 */
1840void *QTest::qData(const char *tagName, int typeId)
1841{
1842 return fetchData(QTestResult::currentTestData(), tagName, typeId);
1843}
1844
1845/*! \internal
1846 */
1847void *QTest::qGlobalData(const char *tagName, int typeId)
1848{
1849 return fetchData(QTestResult::currentGlobalTestData(), tagName, typeId);
1850}
1851
1852/*! \internal
1853 */
1854void *QTest::qElementData(const char *tagName, int metaTypeId)
1855{
1856 QTEST_ASSERT(tagName);
1857 QTestData *data = QTestResult::currentTestData();
1858 QTEST_ASSERT(data);
1859 QTEST_ASSERT(data->parent());
1860
1861 int idx = data->parent()->indexOf(tagName);
1862 QTEST_ASSERT(idx != -1);
1863 QTEST_ASSERT(data->parent()->elementTypeId(idx) == metaTypeId);
1864
1865 return data->data(data->parent()->indexOf(tagName));
1866}
1867
1868/*! \internal
1869 */
1870void QTest::addColumnInternal(int id, const char *name)
1871{
1872 QTestTable *tbl = QTestTable::currentTestTable();
1873 QTEST_ASSERT_X(tbl, "QTest::addColumn()", "Cannot add testdata outside of a _data slot.");
1874
1875 tbl->addColumn(id, name);
1876}
1877
1878/*!
1879 Appends a new row to the current test data. \a dataTag is the name of
1880 the testdata that will appear in the test output. Returns a QTestData reference
1881 that can be used to stream in data.
1882
1883 Example:
1884 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 20
1885
1886 \bold {Note:} This macro can only be used in a test's data function
1887 that is invoked by the test framework.
1888
1889 See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
1890 a more extensive example.
1891
1892 \sa addColumn(), QFETCH()
1893*/
1894QTestData &QTest::newRow(const char *dataTag)
1895{
1896 QTestTable *tbl = QTestTable::currentTestTable();
1897 QTEST_ASSERT_X(tbl, "QTest::addColumn()", "Cannot add testdata outside of a _data slot.");
1898
1899 return *tbl->newData(dataTag);
1900}
1901
1902/*! \fn void QTest::addColumn(const char *name, T *dummy = 0)
1903
1904 Adds a column with type \c{T} to the current test data.
1905 \a name is the name of the column. \a dummy is a workaround
1906 for buggy compilers and can be ignored.
1907
1908 To populate the column with values, newRow() can be used. Use
1909 \l QFETCH() to fetch the data in the actual test.
1910
1911 Example:
1912 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 21
1913
1914 To add custom types to the testdata, the type must be registered with
1915 QMetaType via \l Q_DECLARE_METATYPE().
1916
1917 \bold {Note:} This macro can only be used in a test's data function
1918 that is invoked by the test framework.
1919
1920 See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
1921 a more extensive example.
1922
1923 \sa QTest::newRow(), QFETCH(), QMetaType
1924*/
1925
1926/*!
1927 Returns the name of the test function that is currently executed.
1928
1929 Example:
1930
1931 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 22
1932*/
1933const char *QTest::currentTestFunction()
1934{
1935 return QTestResult::currentTestFunction();
1936}
1937
1938/*!
1939 Returns the name of the current test data. If the test doesn't
1940 have any assigned testdata, the function returns 0.
1941*/
1942const char *QTest::currentDataTag()
1943{
1944 return QTestResult::currentDataTag();
1945}
1946
1947/*!
1948 Returns true if the current test function failed, otherwise false.
1949*/
1950bool QTest::currentTestFailed()
1951{
1952 return QTestResult::currentTestFailed();
1953}
1954
1955/*!
1956 Sleeps for \a ms milliseconds, blocking execution of the
1957 test. qSleep() will not do any event processing and leave your test
1958 unresponsive. Network communication might time out while
1959 sleeping. Use \l qWait() to do non-blocking sleeping.
1960
1961 \a ms must be greater than 0.
1962
1963 \bold {Note:} The qSleep() function calls either \c nanosleep() on
1964 unix or \c Sleep() on windows, so the accuracy of time spent in
1965 qSleep() depends on the operating system.
1966
1967 Example:
1968 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 23
1969
1970 \sa qWait()
1971*/
1972void QTest::qSleep(int ms)
1973{
1974 QTEST_ASSERT(ms > 0);
1975
1976#ifdef Q_OS_WIN
1977 Sleep(uint(ms));
1978#else
1979 struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
1980 nanosleep(&ts, NULL);
1981#endif
1982}
1983
1984/*! \internal
1985 */
1986QObject *QTest::testObject()
1987{
1988 return currentTestObject;
1989}
1990
1991/*! \internal
1992 */
1993bool QTest::compare_helper(bool success, const char *msg, const char *file, int line)
1994{
1995 return QTestResult::compare(success, msg, file, line);
1996}
1997
1998/*! \internal
1999 */
2000bool QTest::compare_helper(bool success, const char *msg, char *val1, char *val2,
2001 const char *actual, const char *expected, const char *file, int line)
2002{
2003 return QTestResult::compare(success, msg, val1, val2, actual, expected, file, line);
2004}
2005
2006/*! \fn bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected, const char *file, int line)
2007\internal
2008 */
2009template <>
2010Q_TESTLIB_EXPORT bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected,
2011 const char *file, int line)
2012{
2013 return qFuzzyCompare(t1, t2)
2014 ? compare_helper(true, "COMPARE()", file, line)
2015 : compare_helper(false, "Compared floats are not the same (fuzzy compare)",
2016 toString(t1), toString(t2), actual, expected, file, line);
2017}
2018
2019/*! \fn bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected, const char *file, int line)
2020\internal
2021 */
2022template <>
2023Q_TESTLIB_EXPORT bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected,
2024 const char *file, int line)
2025{
2026 return qFuzzyCompare(t1, t2)
2027 ? compare_helper(true, "COMPARE()", file, line)
2028 : compare_helper(false, "Compared doubles are not the same (fuzzy compare)",
2029 toString(t1), toString(t2), actual, expected, file, line);
2030}
2031
2032#define COMPARE_IMPL2(TYPE, FORMAT) \
2033template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE >(const TYPE &t) \
2034{ \
2035 char *msg = new char[128]; \
2036 qt_snprintf(msg, 128, #FORMAT, t); \
2037 return msg; \
2038}
2039
2040COMPARE_IMPL2(short, %hd)
2041COMPARE_IMPL2(ushort, %hu)
2042COMPARE_IMPL2(int, %d)
2043COMPARE_IMPL2(uint, %u)
2044COMPARE_IMPL2(long, %ld)
2045COMPARE_IMPL2(ulong, %lu)
2046#if defined(Q_OS_WIN)
2047COMPARE_IMPL2(qint64, %I64d)
2048COMPARE_IMPL2(quint64, %I64u)
2049#else
2050COMPARE_IMPL2(qint64, %lld)
2051COMPARE_IMPL2(quint64, %llu)
2052#endif
2053COMPARE_IMPL2(bool, %d)
2054COMPARE_IMPL2(char, %c)
2055COMPARE_IMPL2(float, %g)
2056COMPARE_IMPL2(double, %lg)
2057
2058/*! \internal
2059 */
2060char *QTest::toString(const char *str)
2061{
2062 if (!str)
2063 return 0;
2064 char *msg = new char[strlen(str) + 1];
2065 return qstrcpy(msg, str);
2066}
2067
2068/*! \internal
2069 */
2070char *QTest::toString(const void *p)
2071{
2072 char *msg = new char[128];
2073 qt_snprintf(msg, 128, "%p", p);
2074 return msg;
2075}
2076
2077/*! \internal
2078 */
2079bool QTest::compare_string_helper(const char *t1, const char *t2, const char *actual,
2080 const char *expected, const char *file, int line)
2081{
2082 return (qstrcmp(t1, t2) == 0)
2083 ? compare_helper(true, "COMPARE()", file, line)
2084 : compare_helper(false, "Compared strings are not the same",
2085 toString(t1), toString(t2), actual, expected, file, line);
2086}
2087
2088/*! \fn bool QTest::compare_ptr_helper(const void *t1, const void *t2, const char *actual, const char *expected, const char *file, int line);
2089 \internal
2090*/
2091
2092/*! \fn bool QTest::qCompare(T1 const &, T2 const &, const char *, const char *, const char *, int);
2093 \internal
2094*/
2095
2096
2097/*! \fn void QTest::mouseEvent(MouseAction action, QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
2098 \internal
2099*/
2100
2101/*! \fn bool QTest::qCompare(QIcon const &t1, QIcon const &t2, const char *actual, const char *expected, const char *file, int line)
2102 \internal
2103*/
2104
2105/*! \fn bool QTest::qCompare(QPixmap const &t1, QPixmap const &t2, const char *actual, const char *expected, const char *file, int line)
2106 \internal
2107*/
2108
2109/*! \fn bool QTest::qCompare(T const &t1, T const &t2, const char *actual, const char *expected, const char *file, int line)
2110 \internal
2111*/
2112
2113/*! \fn bool QTest::qCompare(const T *t1, const T *t2, const char *actual, const char *expected, const char *file, int line)
2114 \internal
2115*/
2116
2117/*! \fn bool QTest::qCompare(T *t1, T *t2, const char *actual, const char *expected, const char *file, int line)
2118 \internal
2119*/
2120
2121/*! \fn bool QTest::qCompare(const T1 *t1, const T2 *t2, const char *actual, const char *expected, const char *file, int line)
2122 \internal
2123*/
2124
2125/*! \fn bool QTest::qCompare(T1 *t1, T2 *t2, const char *actual, const char *expected, const char *file, int line)
2126 \internal
2127*/
2128
2129/*! \fn bool QTest::qCompare(const char *t1, const char *t2, const char *actual, const char *expected, const char *file, int line)
2130 \internal
2131*/
2132
2133/*! \fn bool QTest::qCompare(char *t1, char *t2, const char *actual, const char *expected, const char *file, int line)
2134 \internal
2135*/
2136
2137/*! \fn bool QTest::qCompare(char *t1, const char *t2, const char *actual, const char *expected, const char *file, int line)
2138 \internal
2139*/
2140
2141/*! \fn bool QTest::qCompare(const char *t1, char *t2, const char *actual, const char *expected, const char *file, int line)
2142 \internal
2143*/
2144
2145/*! \fn bool QTest::qCompare(QString const &t1, QLatin1String const &t2, const char *actual, const char *expected, const char *file, int line)
2146 \internal
2147*/
2148
2149/*! \fn bool QTest::qCompare(QLatin1String const &t1, QString const &t2, const char *actual, const char *expected, const char *file, int line)
2150 \internal
2151*/
2152
2153/*! \fn bool QTest::qCompare(QStringList const &t1, QStringList const &t2, const char *actual, const char *expected, const char *file, int line)
2154 \internal
2155*/
2156
2157/*! \fn bool QTest::qCompare(QFlags<T> const &t1, T const &t2, const char *actual, const char *expected, const char *file, int line)
2158 \internal
2159*/
2160
2161/*! \fn bool QTest::qCompare(QFlags<T> const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line)
2162 \internal
2163*/
2164
2165/*! \fn bool QTest::qCompare(bool const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line)
2166 \internal
2167 */
2168
2169/*! \fn bool QTest::qTest(const T& actual, const char *elementName, const char *actualStr, const char *expected, const char *file, int line)
2170 \internal
2171*/
2172
2173/*! \fn void QTest::sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code, QString text, Qt::KeyboardModifiers modifier, int delay=-1)
2174 \internal
2175*/
2176
2177/*! \fn void QTest::sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code, char ascii, Qt::KeyboardModifiers modifier, int delay=-1)
2178 \internal
2179*/
2180
2181/*! \fn void QTest::simulateEvent(QWidget *widget, bool press, int code, Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1)
2182 \internal
2183*/
2184
2185QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.