diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-01-10 18:41:43 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-01-10 18:41:43 +0100 |
commit | cc0eb9c2aa9032c6a7bf2ab05d1eb913a09fa4f1 (patch) | |
tree | 7314014389e227bd7c9b28d97eebcd072e4852a2 /src/imports | |
parent | cb2ac154273a8c07a1e4a14246ae22f6e0deaeda (diff) | |
parent | 0a74dc69b4c57a15da90be29b598371dfa63f7ee (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Conflicts:
src/qml/jsruntime/qv4managed_p.h
Change-Id: I5da7ae9c87a539e42292f272d9e2b5faab619c9f
Diffstat (limited to 'src/imports')
-rw-r--r-- | src/imports/settings/settings.pro | 3 | ||||
-rw-r--r-- | src/imports/testlib/SignalSpy.qml | 129 | ||||
-rw-r--r-- | src/imports/testlib/TestCase.qml | 641 | ||||
-rw-r--r-- | src/imports/testlib/signalspy.h | 79 | ||||
-rw-r--r-- | src/imports/testlib/signalspy.qdoc | 169 | ||||
-rw-r--r-- | src/imports/testlib/testcase.h | 90 | ||||
-rw-r--r-- | src/imports/testlib/testcase.qdoc | 692 |
7 files changed, 767 insertions, 1036 deletions
diff --git a/src/imports/settings/settings.pro b/src/imports/settings/settings.pro index 29229f59cb..3d7c9c31b8 100644 --- a/src/imports/settings/settings.pro +++ b/src/imports/settings/settings.pro @@ -1,3 +1,6 @@ +load(qfeatures) +requires(!contains(QT_DISABLED_FEATURES, settings)) + CXX_MODULE = qml TARGET = qmlsettingsplugin TARGETPATH = Qt/labs/settings diff --git a/src/imports/testlib/SignalSpy.qml b/src/imports/testlib/SignalSpy.qml index 5b05778c5d..8318f156a0 100644 --- a/src/imports/testlib/SignalSpy.qml +++ b/src/imports/testlib/SignalSpy.qml @@ -42,6 +42,43 @@ import QtQuick 2.0 import QtTest 1.0 +/*! + \qmltype SignalSpy + \inqmlmodule QtTest + \brief Enables introspection of signal emission + \since 4.8 + \ingroup qtquicktest + + In the following example, a SignalSpy is installed to watch the + "clicked" signal on a user-defined Button type. When the signal + is emitted, the \l count property on the spy will be increased. + + \code + Button { + id: button + SignalSpy { + id: spy + target: button + signalName: "clicked" + } + TestCase { + name: "ButtonClick" + function test_click() { + compare(spy.count, 0) + button.clicked(); + compare(spy.count, 1) + } + } + } + \endcode + + The above style of test is suitable for signals that are emitted + synchronously. For asynchronous signals, the wait() method can be + used to block the test until the signal occurs (or a timeout expires). + + \sa {QtTest::TestCase}{TestCase}, {Qt Quick Test Reference Documentation} +*/ + Item { id: spy visible: false @@ -50,18 +87,101 @@ Item { id: util } // Public API. + /*! + \qmlproperty object SignalSpy::target + + This property defines the target object that will be used to + listen for emissions of the \l signalName signal. + + \sa signalName, count + */ property var target: null + /*! + \qmlproperty string SignalSpy::signalName + + This property defines the name of the signal on \l target to + listen for. + + \sa target, count + */ property string signalName: "" + /*! + \qmlproperty int SignalSpy::count + + This property defines the number of times that \l signalName has + been emitted from \l target since the last call to clear(). + + \sa target, signalName, clear() + \readonly + */ readonly property alias count: spy.qtest_count + /*! + \qmlproperty bool SignalSpy::valid + + This property defines the current signal connection status. It will be true when the \l signalName of the \l target is connected successfully, otherwise it will be false. + + \sa count, target, signalName, clear() + \readonly + */ readonly property alias valid:spy.qtest_valid + /*! + \qmlproperty list SignalSpy::signalArguments + + This property holds a list of emitted signal arguments. Each emission of the signal will append one item to the list, containing the arguments of the signal. + When connecting to a new \l target or new \l signalName or calling the \l clear() method, the \l signalArguments will be reset to empty. + + \sa signalName, clear() + \readonly + */ readonly property alias signalArguments:spy.qtest_signalArguments + /*! + \qmlmethod SignalSpy::clear() + + Clears \l count to 0, resets \l valid to false and clears the \l signalArguments to empty. + + \sa count, wait() + */ function clear() { qtest_count = 0 qtest_expectedCount = 0 qtest_signalArguments = [] } + /*! + \qmlmethod SignalSpy::wait(timeout = 5000) + + Waits for the signal \l signalName on \l target to be emitted, + for up to \a timeout milliseconds. The test case will fail if + the signal is not emitted. + + \code + SignalSpy { + id: spy + target: button + signalName: "clicked" + } + + function test_async_click() { + ... + // do something that will cause clicked() to be emitted + ... + spy.wait() + compare(spy.count, 1) + } + \endcode + + There are two possible scenarios: the signal has already been + emitted when wait() is called, or the signal has not yet been + emitted. The wait() function handles the first scenario by immediately + returning if the signal has already occurred. + + The clear() method can be used to discard information about signals + that have already occurred to synchronize wait() with future signal + emissions. + + \sa clear(), TestCase::tryCompare() + */ function wait(timeout) { if (timeout === undefined) timeout = 5000 @@ -87,13 +207,21 @@ Item { qtest_update() } + /*! \internal */ property var qtest_prevTarget: null + /*! \internal */ property string qtest_prevSignalName: "" + /*! \internal */ property int qtest_expectedCount: 0 + /*! \internal */ property var qtest_signalArguments:[] + /*! \internal */ property int qtest_count: 0 + /*! \internal */ property bool qtest_valid:false + /*! \internal */ + /*! \internal */ function qtest_update() { if (qtest_prevTarget != null) { var prevFunc = qtest_prevTarget[qtest_prevSignalName] @@ -119,6 +247,7 @@ Item { } } + /*! \internal */ function qtest_activated() { ++qtest_count spy.qtest_signalArguments[spy.qtest_signalArguments.length] = arguments diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml index 1544bb2799..71c87224d7 100644 --- a/src/imports/testlib/TestCase.qml +++ b/src/imports/testlib/TestCase.qml @@ -44,6 +44,174 @@ import QtTest 1.0 import "testlogger.js" as TestLogger import Qt.test.qtestroot 1.0 +/*! + \qmltype TestCase + \inqmlmodule QtTest + \brief Represents a unit test case + \since 4.8 + \ingroup qtquicktest + + \section1 Introduction to QML test cases + + Test cases are written as JavaScript functions within a TestCase + type: + + \code + import QtQuick 2.0 + import QtTest 1.0 + + TestCase { + name: "MathTests" + + function test_math() { + compare(2 + 2, 4, "2 + 2 = 4") + } + + function test_fail() { + compare(2 + 2, 5, "2 + 2 = 5") + } + } + \endcode + + Functions whose names start with "test_" are treated as test cases + to be executed. The \l name property is used to prefix the functions + in the output: + + \code + ********* Start testing of MathTests ********* + Config: Using QTest library 4.7.2, Qt 4.7.2 + PASS : MathTests::initTestCase() + FAIL! : MathTests::test_fail() 2 + 2 = 5 + Actual (): 4 + Expected (): 5 + Loc: [/home/.../tst_math.qml(12)] + PASS : MathTests::test_math() + PASS : MathTests::cleanupTestCase() + Totals: 3 passed, 1 failed, 0 skipped + ********* Finished testing of MathTests ********* + \endcode + + Because of the way JavaScript properties work, the order in which the + test functions are found is unpredictable. To assist with predictability, + the test framework will sort the functions on ascending order of name. + This can help when there are two tests that must be run in order. + + Multiple TestCase types can be supplied. The test program will exit + once they have all completed. If a test case doesn't need to run + (because a precondition has failed), then \l optional can be set to true. + + \section1 Data-driven tests + + Table data can be provided to a test using a function name that ends + with "_data". Alternatively, the \c init_data() function can be used + to provide default test data for all test functions in a TestCase type: + + + \code + import QtQuick 2.0 + import QtTest 1.0 + + TestCase { + name: "DataTests" + + function init_data() { + return [ + {tag:"init_data_1", a:1, b:2, answer: 3}, + {tag:"init_data_2", a:2, b:4, answer: 6} + ]; + } + + function test_table_data() { + return [ + {tag: "2 + 2 = 4", a: 2, b: 2, answer: 4 }, + {tag: "2 + 6 = 8", a: 2, b: 6, answer: 8 }, + ] + } + + function test_table(data) { + //data comes from test_table_data + compare(data.a + data.b, data.answer) + } + + function test__default_table(data) { + //data comes from init_data + compare(data.a + data.b, data.answer) + } + } + \endcode + + The test framework will iterate over all of the rows in the table + and pass each row to the test function. As shown, the columns can be + extracted for use in the test. The \c tag column is special - it is + printed by the test framework when a row fails, to help the reader + identify which case failed amongst a set of otherwise passing tests. + + \section1 Benchmarks + + Functions whose names start with "benchmark_" will be run multiple + times with the Qt benchmark framework, with an average timing value + reported for the runs. This is equivalent to using the \c{QBENCHMARK} + macro in the C++ version of QTestLib. + + \code + TestCase { + id: top + name: "CreateBenchmark" + + function benchmark_create_component() { + var component = Qt.createComponent("item.qml") + var obj = component.createObject(top) + obj.destroy() + component.destroy() + } + } + + RESULT : CreateBenchmark::benchmark_create_component: + 0.23 msecs per iteration (total: 60, iterations: 256) + PASS : CreateBenchmark::benchmark_create_component() + \endcode + + To get the effect of the \c{QBENCHMARK_ONCE} macro, prefix the test + function name with "benchmark_once_". + + \section1 Simulating keyboard and mouse events + + The keyPress(), keyRelease(), and keyClick() methods can be used + to simulate keyboard events within unit tests. The events are + delivered to the currently focused QML item. You can pass either + a Qt.Key enum value or a latin1 char (string of length one) + + \code + Rectangle { + width: 50; height: 50 + focus: true + + TestCase { + name: "KeyClick" + when: windowShown + + function test_key_click() { + keyClick(Qt.Key_Left) + keyClick("a") + ... + } + } + } + \endcode + + The mousePress(), mouseRelease(), mouseClick(), mouseDoubleClick(), + and mouseMove() methods can be used to simulate mouse events in a + similar fashion. + + \b{Note:} keyboard and mouse events can only be delivered once the + main window has been shown. Attempts to deliver events before then + will fail. Use the \l when and windowShown properties to track + when the main window has been shown. + + \sa {QtTest::SignalSpy}{SignalSpy}, {Qt Quick Test Reference Documentation} +*/ + + Item { id: testCase visible: false @@ -51,34 +219,154 @@ Item { id:util } - // Name of the test case to prefix the function name in messages. + /*! + \qmlproperty string TestCase::name + + This property defines the name of the test case for result reporting. + The default is the empty string. + + \code + TestCase { + name: "ButtonTests" + ... + } + \endcode + */ property string name - // Set to true to start the test running. + /*! + \qmlproperty bool TestCase::when + + This property should be set to true when the application wants + the test cases to run. The default value is true. In the following + example, a test is run when the user presses the mouse button: + + \code + Rectangle { + id: foo + width: 640; height: 480 + color: "cyan" + + MouseArea { + id: area + anchors.fill: parent + } + + property bool bar: true + + TestCase { + name: "ItemTests" + when: area.pressed + id: test1 + + function test_bar() { + verify(bar) + } + } + } + \endcode + + The test application will exit once all \l TestCase types + have been triggered and have run. The \l optional property can + be used to exclude a \l TestCase type. + + \sa optional, completed + */ property bool when: true - // Set to true once the test has completed. + /*! + \qmlproperty bool TestCase::completed + + This property will be set to true once the test case has completed + execution. Test cases are only executed once. The initial value + is false. + + \sa running, when + */ property bool completed: false - // Set to true when the test is running but not yet complete. + /*! + \qmlproperty bool TestCase::running + + This property will be set to true while the test case is running. + The initial value is false, and the value will become false again + once the test case completes. + + \sa completed, when + */ property bool running: false - // Set to true if the test doesn't have to run (because some - // other test failed which this one depends on). + /*! + \qmlproperty bool TestCase::optional + + Multiple \l TestCase types can be supplied in a test application. + The application will exit once they have all completed. If a test case + does not need to run (because a precondition has failed), then this + property can be set to true. The default value is false. + + \code + TestCase { + when: false + optional: true + function test_not_run() { + verify(false) + } + } + \endcode + + \sa when, completed + */ property bool optional: false + /*! + \qmlproperty bool TestCase::windowShown + + This property will be set to true after the QML viewing window has + been displayed. Normally test cases run as soon as the test application + is loaded and before a window is displayed. If the test case involves + visual types and behaviors, then it may need to be delayed until + after the window is shown. + + \code + Button { + id: button + onClicked: text = "Clicked" + TestCase { + name: "ClickTest" + when: windowShown + function test_click() { + button.clicked(); + compare(button.text, "Clicked"); + } + } + } + \endcode + */ property bool windowShown: QTestRootObject.windowShown // Internal private state. Identifiers prefixed with qtest are reserved. + /*! \internal */ property bool qtest_prevWhen: true + /*! \internal */ property int qtest_testId: -1 + /*! \internal */ property bool qtest_componentCompleted : false + /*! \internal */ property var qtest_testCaseResult + /*! \internal */ property var qtest_results: qtest_results_normal + /*! \internal */ TestResult { id: qtest_results_normal } + /*! \internal */ property var qtest_events: qtest_events_normal TestEvent { id: qtest_events_normal } + /*! + \qmlmethod TestCase::fail(message = "") + + Fails the current test case, with the optional \a message. + Similar to \c{QFAIL(message)} in C++. + */ function fail(msg) { if (msg === undefined) msg = ""; @@ -86,6 +374,7 @@ Item { throw new Error("QtQuickTest::fail") } + /*! \internal */ function qtest_fail(msg, frame) { if (msg === undefined) msg = ""; @@ -93,6 +382,13 @@ Item { throw new Error("QtQuickTest::fail") } + /*! + \qmlmethod TestCase::verify(condition, message = "") + + Fails the current test case if \a condition is false, and + displays the optional \a message. Similar to \c{QVERIFY(condition)} + or \c{QVERIFY2(condition, message)} in C++. + */ function verify(cond, msg) { if (msg === undefined) msg = ""; @@ -100,6 +396,7 @@ Item { throw new Error("QtQuickTest::fail") } + /*! \internal */ // Determine what is o. // Discussions and reference: http://philrathe.com/articles/equiv // Test suites: http://philrathe.com/tests/equiv @@ -154,6 +451,7 @@ Item { } } + /*! \internal */ // Test for equality // Large parts contain sources from QUnit or http://philrathe.com // Discussions and reference: http://philrathe.com/articles/equiv @@ -213,6 +511,7 @@ Item { return success } + /*! \internal */ function qtest_compareInternalObjects(act, exp) { var i; var eq = true; // unless we can proove it @@ -240,6 +539,7 @@ Item { } + /*! \internal */ function qtest_compareInternalArrays(actual, expected) { if (actual.length != expected.length) { return false @@ -254,6 +554,15 @@ Item { return true } + /*! + \qmlmethod TestCase::compare(actual, expected, message = "") + + Fails the current test case if \a actual is not the same as + \a expected, and displays the optional \a message. Similar + to \c{QCOMPARE(actual, expected)} in C++. + + \sa tryCompare(), fuzzyCompare + */ function compare(actual, expected, msg) { var act = qtest_results.stringify(actual) var exp = qtest_results.stringify(expected) @@ -270,6 +579,19 @@ Item { } } + /*! + \qmlmethod TestCase::fuzzyCompare(actual, expected, delta, message = "") + + Fails the current test case if the difference betwen \a actual and \a expected + is greater than \a delta, and displays the optional \a message. Similar + to \c{qFuzzyCompare(actual, expected)} in C++ but with a required \a delta value. + + This function can also be used for color comparisons if both the \a actual and + \a expected values can be converted into color values. If any of the differences + for RGBA channel values are greater than \a delta, the test fails. + + \sa tryCompare(), compare() + */ function fuzzyCompare(actual, expected, delta, msg) { if (delta === undefined) qtest_fail("A delta value is required for fuzzyCompare", 2) @@ -287,10 +609,59 @@ Item { } } + /*! + \qmlmethod object TestCase::grabImage(item) + + Returns a snapshot image object of the given \a item. + + The returned image object has the following methods: + \list + \li red(x, y) Returns the red channel value of the pixel at \a x, \a y position + \li green(x, y) Returns the green channel value of the pixel at \a x, \a y position + \li blue(x, y) Returns the blue channel value of the pixel at \a x, \a y position + \li alpha(x, y) Returns the alpha channel value of the pixel at \a x, \a y position + \li pixel(x, y) Returns the color value of the pixel at \a x, \a y position + For example: + + \code + var image = grabImage(rect); + compare(image.red(10, 10), 255); + compare(image.pixel(20, 20), Qt.rgba(255, 0, 0, 255); + \endcode + + \endlist + + \sa + */ function grabImage(item) { return qtest_results.grabImage(item); } + /*! + \qmlmethod TestCase::tryCompare(obj, property, expected, timeout = 5000, message = "") + + Fails the current test case if the specified \a property on \a obj + is not the same as \a expected, and displays the optional \a message. + The test will be retried multiple times until the + \a timeout (in milliseconds) is reached. + + This function is intended for testing applications where a property + changes value based on asynchronous events. Use compare() for testing + synchronous property changes. + + \code + tryCompare(img, "status", BorderImage.Ready) + compare(img.width, 120) + compare(img.height, 120) + compare(img.horizontalTileMode, BorderImage.Stretch) + compare(img.verticalTileMode, BorderImage.Stretch) + \endcode + + SignalSpy::wait() provides an alternative method to wait for a + signal to be emitted. + + \sa compare(), SignalSpy::wait() + */ function tryCompare(obj, prop, value, timeout, msg) { if (arguments.length == 2) { qtest_results.fail("A value is required for tryCompare", @@ -321,6 +692,13 @@ Item { throw new Error("QtQuickTest::fail") } + /*! + \qmlmethod TestCase::skip(message = "") + + Skips the current test case and prints the optional \a message. + If this is a data-driven test, then only the current row is skipped. + Similar to \c{QSKIP(message)} in C++. + */ function skip(msg) { if (msg === undefined) msg = "" @@ -328,6 +706,19 @@ Item { throw new Error("QtQuickTest::skip") } + /*! + \qmlmethod TestCase::expectFail(tag, message) + + In a data-driven test, marks the row associated with \a tag as + expected to fail. When the fail occurs, display the \a message, + abort the test, and mark the test as passing. Similar to + \c{QEXPECT_FAIL(tag, message, Abort)} in C++. + + If the test is not data-driven, then \a tag must be set to + the empty string. + + \sa expectFailContinue() + */ function expectFail(tag, msg) { if (tag === undefined) { warn("tag argument missing from expectFail()") @@ -341,6 +732,19 @@ Item { throw new Error("QtQuickTest::expectFail") } + /*! + \qmlmethod TestCase::expectFailContinue(tag, message) + + In a data-driven test, marks the row associated with \a tag as + expected to fail. When the fail occurs, display the \a message, + and then continue the test. Similar to + \c{QEXPECT_FAIL(tag, message, Continue)} in C++. + + If the test is not data-driven, then \a tag must be set to + the empty string. + + \sa expectFail() + */ function expectFailContinue(tag, msg) { if (tag === undefined) { warn("tag argument missing from expectFailContinue()") @@ -354,32 +758,84 @@ Item { throw new Error("QtQuickTest::expectFail") } + /*! + \qmlmethod TestCase::warn(message) + + Prints \a message as a warning message. Similar to + \c{QWARN(message)} in C++. + + \sa ignoreWarning() + */ function warn(msg) { if (msg === undefined) msg = "" qtest_results.warn(msg, util.callerFile(), util.callerLine()); } + /*! + \qmlmethod TestCase::ignoreWarning(message) + + Marks \a message as an ignored warning message. When it occurs, + the warning will not be printed and the test passes. If the message + does not occur, then the test will fail. Similar to + \c{QTest::ignoreMessage(QtWarningMsg, message)} in C++. + + \sa warn() + */ function ignoreWarning(msg) { if (msg === undefined) msg = "" qtest_results.ignoreWarning(msg) } + /*! + \qmlmethod TestCase::wait(ms) + + Waits for \a ms milliseconds while processing Qt events. + + \sa sleep(), waitForRendering() + */ function wait(ms) { qtest_results.wait(ms) } + /*! + \qmlmethod TestCase::waitForRendering(item, timeout = 5000) + + Waits for \a timeout milliseconds or until the \a item is rendered by the renderer. + Returns true if \c item is rendered in \a timeout milliseconds, otherwise returns false. + The default \a timeout value is 5000. + + \sa sleep(), wait() + */ function waitForRendering(item, timeout) { if (timeout === undefined) timeout = 5000 return qtest_results.waitForRendering(item, timeout) } + /*! + \qmlmethod TestCase::sleep(ms) + + Sleeps for \a ms milliseconds without processing Qt events. + + \sa wait(), waitForRendering() + */ function sleep(ms) { qtest_results.sleep(ms) } + /*! + \qmlmethod TestCase::keyPress(key, modifiers = Qt.NoModifier, delay = -1) + + Simulates pressing a \a key with an optional \a modifier on the currently + focused item. If \a delay is larger than 0, the test will wait for + \a delay milliseconds. + + \b{Note:} At some point you should release the key using keyRelease(). + + \sa keyRelease(), keyClick() + */ function keyPress(key, modifiers, delay) { if (modifiers === undefined) modifiers = Qt.NoModifier @@ -394,6 +850,15 @@ Item { } } + /*! + \qmlmethod TestCase::keyRelease(key, modifiers = Qt.NoModifier, delay = -1) + + Simulates releasing a \a key with an optional \a modifier on the currently + focused item. If \a delay is larger than 0, the test will wait for + \a delay milliseconds. + + \sa keyPress(), keyClick() + */ function keyRelease(key, modifiers, delay) { if (modifiers === undefined) modifiers = Qt.NoModifier @@ -408,6 +873,15 @@ Item { } } + /*! + \qmlmethod TestCase::keyClick(key, modifiers = Qt.NoModifier, delay = -1) + + Simulates clicking of \a key with an optional \a modifier on the currently + focused item. If \a delay is larger than 0, the test will wait for + \a delay milliseconds. + + \sa keyPress(), keyRelease() + */ function keyClick(key, modifiers, delay) { if (modifiers === undefined) modifiers = Qt.NoModifier @@ -422,6 +896,21 @@ Item { } } + /*! + \qmlmethod TestCase::mousePress(item, x, y, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) + + Simulates pressing a mouse \a button with an optional \a modifier + on an \a item. The position is defined by \a x and \a y. If \a delay is + specified, the test will wait for the specified amount of milliseconds + before the press. + + The position given by \a x and \a y is transformed from the co-ordinate + system of \a item into window co-ordinates and then delivered. + If \a item is obscured by another item, or a child of \a item occupies + that position, then the event will be delivered to the other item instead. + + \sa mouseRelease(), mouseClick(), mouseDoubleClick(), mouseMove(), mouseDrag(), mouseWheel() + */ function mousePress(item, x, y, button, modifiers, delay) { if (button === undefined) button = Qt.LeftButton @@ -433,6 +922,21 @@ Item { qtest_fail("window not shown", 2) } + /*! + \qmlmethod TestCase::mouseRelease(item, x, y, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) + + Simulates releasing a mouse \a button with an optional \a modifier + on an \a item. The position of the release is defined by \a x and \a y. + If \a delay is specified, the test will wait for the specified amount of + milliseconds before releasing the button. + + The position given by \a x and \a y is transformed from the co-ordinate + system of \a item into window co-ordinates and then delivered. + If \a item is obscured by another item, or a child of \a item occupies + that position, then the event will be delivered to the other item instead. + + \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseMove(), mouseDrag(), mouseWheel() + */ function mouseRelease(item, x, y, button, modifiers, delay) { if (button === undefined) button = Qt.LeftButton @@ -444,6 +948,24 @@ Item { qtest_fail("window not shown", 2) } + /*! + \qmlmethod TestCase::mouseDrag(item, x, y, dx, dy, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) + + Simulates dragging the mouse on an \a item with \a button pressed and an optional \a modifier. + The initial drag position is defined by \a x and \a y, + and drag distance is defined by \a dx and \a dy. If \a delay is specified, + the test will wait for the specified amount of milliseconds before releasing the button. + + The position given by \a x and \a y is transformed from the co-ordinate + system of \a item into window co-ordinates and then delivered. + If \a item is obscured by another item, or a child of \a item occupies + that position, then the event will be delivered to the other item instead. + + Note: this method does not imply a drop action, to make a drop, an additional + mouseRelease(item, x + dx, y + dy) is needed. + + \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseMove(), mouseRelease(), mouseWheel() + */ function mouseDrag(item, x, y, dx, dy, button, modifiers, delay) { if (item.x === undefined || item.y === undefined) return @@ -475,6 +997,21 @@ Item { mouseRelease(item, x + dx, y + dy, button, modifiers, delay) } + /*! + \qmlmethod TestCase::mouseClick(item, x, y, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) + + Simulates clicking a mouse \a button with an optional \a modifier + on an \a item. The position of the click is defined by \a x and \a y. + If \a delay is specified, the test will wait for the specified amount of + milliseconds before pressing and before releasing the button. + + The position given by \a x and \a y is transformed from the co-ordinate + system of \a item into window co-ordinates and then delivered. + If \a item is obscured by another item, or a child of \a item occupies + that position, then the event will be delivered to the other item instead. + + \sa mousePress(), mouseRelease(), mouseDoubleClick(), mouseMove(), mouseDrag(), mouseWheel() + */ function mouseClick(item, x, y, button, modifiers, delay) { if (button === undefined) button = Qt.LeftButton @@ -486,6 +1023,21 @@ Item { qtest_fail("window not shown", 2) } + /*! + \qmlmethod TestCase::mouseDoubleClick(item, x, y, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) + + Simulates double-clicking a mouse \a button with an optional \a modifier + on an \a item. The position of the click is defined by \a x and \a y. + If \a delay is specified, the test will wait for the specified amount of + milliseconds before pressing and before releasing the button. + + The position given by \a x and \a y is transformed from the co-ordinate + system of \a item into window co-ordinates and then delivered. + If \a item is obscured by another item, or a child of \a item occupies + that position, then the event will be delivered to the other item instead. + + \sa mousePress(), mouseRelease(), mouseClick(), mouseMove(), mouseDrag(), mouseWheel() + */ function mouseDoubleClick(item, x, y, button, modifiers, delay) { if (button === undefined) button = Qt.LeftButton @@ -497,6 +1049,20 @@ Item { qtest_fail("window not shown", 2) } + /*! + \qmlmethod TestCase::mouseMove(item, x, y, delay = -1) + + Moves the mouse pointer to the position given by \a x and \a y within + \a item. If a \a delay (in milliseconds) is given, the test will wait + before moving the mouse pointer. + + The position given by \a x and \a y is transformed from the co-ordinate + system of \a item into window co-ordinates and then delivered. + If \a item is obscured by another item, or a child of \a item occupies + that position, then the event will be delivered to the other item instead. + + \sa mousePress(), mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDrag(), mouseWheel() + */ function mouseMove(item, x, y, delay, buttons) { if (delay == undefined) delay = -1 @@ -506,6 +1072,22 @@ Item { qtest_fail("window not shown", 2) } + /*! + \qmlmethod TestCase::mouseWheel(item, x, y, xDelta, yDelta, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) + + Simulates rotating the mouse wheel on an \a item with \a button pressed and an optional \a modifier. + The position of the wheel event is defined by \a x and \a y. + If \a delay is specified, the test will wait for the specified amount of milliseconds before releasing the button. + + The position given by \a x and \a y is transformed from the co-ordinate + system of \a item into window co-ordinates and then delivered. + If \a item is obscured by another item, or a child of \a item occupies + that position, then the event will be delivered to the other item instead. + + The \a xDelta and \a yDelta contain the wheel rotation distance in eighths of a degree. see \l QWheelEvent::angleDelta() for more details. + + \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseMove(), mouseRelease(), mouseDrag(), QWheelEvent::angleDelta() + */ function mouseWheel(item, x, y, xDelta, yDelta, buttons, modifiers, delay) { if (delay == undefined) delay = -1 @@ -523,11 +1105,55 @@ Item { // Functions that can be overridden in subclasses for init/cleanup duties. + /*! + \qmlmethod TestCase::initTestCase() + + This function is called before any other test functions in the + \l TestCase type. The default implementation does nothing. + The application can provide its own implementation to perform + test case initialization. + + \sa cleanupTestCase(), init() + */ function initTestCase() {} + + /*! + \qmlmethod TestCase::cleanupTestCase() + + This function is called after all other test functions in the + \l TestCase type have completed. The default implementation + does nothing. The application can provide its own implementation + to perform test case cleanup. + + \sa initTestCase(), cleanup() + */ function cleanupTestCase() {} + + /*! + \qmlmethod TestCase::init() + + This function is called before each test function that is + executed in the \l TestCase type. The default implementation + does nothing. The application can provide its own implementation + to perform initialization before each test function. + + \sa cleanup(), initTestCase() + */ function init() {} + + /*! + \qmlmethod TestCase::cleanup() + + This function is called after each test function that is + executed in the \l TestCase type. The default implementation + does nothing. The application can provide its own implementation + to perform cleanup after each test function. + + \sa init(), cleanupTestCase() + */ function cleanup() {} + /*! \internal */ function qtest_runInternal(prop, arg) { try { qtest_testCaseResult = testCase[prop](arg) @@ -542,6 +1168,7 @@ Item { return !qtest_results.failed } + /*! \internal */ function qtest_runFunction(prop, arg) { qtest_runInternal("init") if (!qtest_results.skipped) { @@ -552,6 +1179,7 @@ Item { } } + /*! \internal */ function qtest_runBenchmarkFunction(prop, arg) { qtest_results.startMeasurement() do { @@ -584,6 +1212,7 @@ Item { } while (qtest_results.needsMoreMeasurements()) } + /*! \internal */ function qtest_run() { if (util.printAvailableFunctions) { completed = true diff --git a/src/imports/testlib/signalspy.h b/src/imports/testlib/signalspy.h deleted file mode 100644 index a7ff89f0b0..0000000000 --- a/src/imports/testlib/signalspy.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SIGNALSPY_H -#define SIGNALSPY_H - -// This is a dummy header for defining the interface of "SignalSpy.qml" to qdoc. - -#include <QtQuick/qquickitem.h> - -QT_BEGIN_NAMESPACE - -class SignalSpy : public QQuickItem -{ - Q_OBJECT - Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged) - Q_PROPERTY(QString signalName READ signalName WRITE signalName NOTIFY signalNameChanged) - Q_PROPERTY(int count READ count countChanged) -public: - SignalSpy(QQuickItem *parent) : QQuickItem(parent) {} - ~SignalSpy() - - QObject *target() const; - void setTarget(QObject *target); - - QString signalName() const; - void setSignalName(const QString &signalName); - - int count() const; - -Q_SIGNALS: - void targetChanged(); - void signalNameChanged(); - void countChanged(); -}; - -QML_DECLARE_TYPE(SignalSpy) - -QT_END_NAMESPACE - -#endif diff --git a/src/imports/testlib/signalspy.qdoc b/src/imports/testlib/signalspy.qdoc deleted file mode 100644 index c20e268138..0000000000 --- a/src/imports/testlib/signalspy.qdoc +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \qmltype SignalSpy - \instantiates SignalSpy - \inqmlmodule QtTest - \brief Enables introspection of signal emission - \ingroup qtquick-utility - \since 4.8 - \ingroup qtest::qml - - In the following example, a SignalSpy is installed to watch the - "clicked" signal on a user-defined Button type. When the signal - is emitted, the \l count property on the spy will be increased. - - \code - Button { - id: button - SignalSpy { - id: spy - target: button - signalName: "clicked" - } - TestCase { - name: "ButtonClick" - function test_click() { - compare(spy.count, 0) - button.clicked(); - compare(spy.count, 1) - } - } - } - \endcode - - The above style of test is suitable for signals that are emitted - synchronously. For asynchronous signals, the wait() method can be - used to block the test until the signal occurs (or a timeout expires). - - \sa TestCase, {Qt Quick Test Reference Documentation} -*/ - -/*! - \qmlproperty object SignalSpy::target - - This property defines the target object that will be used to - listen for emissions of the \l signalName signal. - - \sa signalName, count -*/ - -/*! - \qmlproperty string SignalSpy::signalName - - This property defines the name of the signal on \l target to - listen for. - - \sa target, count -*/ - -/*! - \qmlproperty list SignalSpy::signalArguments - - This property holds a list of emitted signal arguments. Each emission of the signal will append one item to the list, containing the arguments of the signal. - When connecting to a new \l target or new \l signalName or calling the \l clear() method, the \l signalArguments will be reset to empty. - - \sa signalName, clear() - \readonly -*/ - -/*! - \qmlproperty bool SignalSpy::valid - - This property defines the current signal connection status. It will be true when the \l signalName of the \l target is connected successfully, otherwise it will be false. - - \sa count, target, signalName, clear() - \readonly -*/ - -/*! - \qmlproperty int SignalSpy::count - - This property defines the number of times that \l signalName has - been emitted from \l target since the last call to clear(). - - \sa target, signalName, clear() - \readonly -*/ - -/*! - \qmlmethod SignalSpy::clear() - - Clears \l count to 0, resets \l valid to false and clears the \l signalArguments to empty. - - \sa count, wait() -*/ - -/*! - \qmlmethod SignalSpy::wait(timeout = 5000) - - Waits for the signal \l signalName on \l target to be emitted, - for up to \a timeout milliseconds. The test case will fail if - the signal is not emitted. - - \code - SignalSpy { - id: spy - target: button - signalName: "clicked" - } - - function test_async_click() { - ... - // do something that will cause clicked() to be emitted - ... - spy.wait() - compare(spy.count, 1) - } - \endcode - - There are two possible scenarios: the signal has already been - emitted when wait() is called, or the signal has not yet been - emitted. The wait() function handles the first scenario by immediately - returning if the signal has already occurred. - - The clear() method can be used to discard information about signals - that have already occurred to synchronize wait() with future signal - emissions. - - \sa clear(), TestCase::tryCompare() -*/ diff --git a/src/imports/testlib/testcase.h b/src/imports/testlib/testcase.h deleted file mode 100644 index 3b767981d0..0000000000 --- a/src/imports/testlib/testcase.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TESTCASE_H -#define TESTCASE_H - -// This is a dummy header for defining the interface of "TestCase.qml" to qdoc. - -#include <QtQuick/qquickitem.h> - -QT_BEGIN_NAMESPACE - -class TestCase : public QQuickItem -{ - Q_OBJECT - Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) - Q_PROPERTY(bool when READ when WRITE setWhen NOTIFY whenChanged) - Q_PROPERTY(bool optional READ optional WRITE setOptional NOTIFY optionalChanged) - Q_PROPERTY(bool completed READ completed NOTIFY completedChanged) - Q_PROPERTY(bool running READ running NOTIFY runningChanged) - Q_PROPERTY(bool windowShown READ windowShown NOTIFY windowShownChanged) -public: - TestCase(QQuickItem *parent) : QQuickItem(parent) {} - ~TestCase() - - QString name() const; - void setName(const QString &name); - - bool when() const; - void setWhen(bool when); - - bool optional() const; - void setOptional(bool optional); - - bool completed() const; - bool running() const; - bool windowShown() const; - -Q_SIGNALS: - void nameChanged(); - void whenChanged(); - void optionalChanged(); - void completedChanged(); - void runningChanged(); - void windowShownChanged(); -}; - -QML_DECLARE_TYPE(TestCase) - -QT_END_NAMESPACE - -#endif diff --git a/src/imports/testlib/testcase.qdoc b/src/imports/testlib/testcase.qdoc deleted file mode 100644 index 74d2c57098..0000000000 --- a/src/imports/testlib/testcase.qdoc +++ /dev/null @@ -1,692 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \qmltype TestCase - \instantiates TestCase - \inqmlmodule QtTest - \brief Represents a unit test case - \ingroup qtquick-utility - \since 4.8 - \ingroup qtest::qml - - \section1 Introduction to QML test cases - - Test cases are written as JavaScript functions within a TestCase - type: - - \code - import QtQuick 2.0 - import QtTest 1.0 - - TestCase { - name: "MathTests" - - function test_math() { - compare(2 + 2, 4, "2 + 2 = 4") - } - - function test_fail() { - compare(2 + 2, 5, "2 + 2 = 5") - } - } - \endcode - - Functions whose names start with "test_" are treated as test cases - to be executed. The \l name property is used to prefix the functions - in the output: - - \code - ********* Start testing of MathTests ********* - Config: Using QTest library 4.7.2, Qt 4.7.2 - PASS : MathTests::initTestCase() - FAIL! : MathTests::test_fail() 2 + 2 = 5 - Actual (): 4 - Expected (): 5 - Loc: [/home/.../tst_math.qml(12)] - PASS : MathTests::test_math() - PASS : MathTests::cleanupTestCase() - Totals: 3 passed, 1 failed, 0 skipped - ********* Finished testing of MathTests ********* - \endcode - - Because of the way JavaScript properties work, the order in which the - test functions are found is unpredictable. To assist with predictability, - the test framework will sort the functions on ascending order of name. - This can help when there are two tests that must be run in order. - - Multiple TestCase types can be supplied. The test program will exit - once they have all completed. If a test case doesn't need to run - (because a precondition has failed), then \l optional can be set to true. - - \section1 Data-driven tests - - Table data can be provided to a test using a function name that ends - with "_data". Alternatively, the \c init_data() function can be used - to provide default test data for all test functions in a TestCase type: - - - \code - import QtQuick 2.0 - import QtTest 1.0 - - TestCase { - name: "DataTests" - - function init_data() { - return [ - {tag:"init_data_1", a:1, b:2, answer: 3}, - {tag:"init_data_2", a:2, b:4, answer: 6} - ]; - } - - function test_table_data() { - return [ - {tag: "2 + 2 = 4", a: 2, b: 2, answer: 4 }, - {tag: "2 + 6 = 8", a: 2, b: 6, answer: 8 }, - ] - } - - function test_table(data) { - //data comes from test_table_data - compare(data.a + data.b, data.answer) - } - - function test__default_table(data) { - //data comes from init_data - compare(data.a + data.b, data.answer) - } - } - \endcode - - The test framework will iterate over all of the rows in the table - and pass each row to the test function. As shown, the columns can be - extracted for use in the test. The \c tag column is special - it is - printed by the test framework when a row fails, to help the reader - identify which case failed amongst a set of otherwise passing tests. - - \section1 Benchmarks - - Functions whose names start with "benchmark_" will be run multiple - times with the Qt benchmark framework, with an average timing value - reported for the runs. This is equivalent to using the \c{QBENCHMARK} - macro in the C++ version of QTestLib. - - \code - TestCase { - id: top - name: "CreateBenchmark" - - function benchmark_create_component() { - var component = Qt.createComponent("item.qml") - var obj = component.createObject(top) - obj.destroy() - component.destroy() - } - } - - RESULT : CreateBenchmark::benchmark_create_component: - 0.23 msecs per iteration (total: 60, iterations: 256) - PASS : CreateBenchmark::benchmark_create_component() - \endcode - - To get the effect of the \c{QBENCHMARK_ONCE} macro, prefix the test - function name with "benchmark_once_". - - \section1 Simulating keyboard and mouse events - - The keyPress(), keyRelease(), and keyClick() methods can be used - to simulate keyboard events within unit tests. The events are - delivered to the currently focused QML item. You can pass either - a Qt.Key enum value or a latin1 char (string of length one) - - \code - Rectangle { - width: 50; height: 50 - focus: true - - TestCase { - name: "KeyClick" - when: windowShown - - function test_key_click() { - keyClick(Qt.Key_Left) - keyClick("a") - ... - } - } - } - \endcode - - The mousePress(), mouseRelease(), mouseClick(), mouseDoubleClick(), - and mouseMove() methods can be used to simulate mouse events in a - similar fashion. - - \b{Note:} keyboard and mouse events can only be delivered once the - main window has been shown. Attempts to deliver events before then - will fail. Use the \l when and windowShown properties to track - when the main window has been shown. - - \sa SignalSpy, {Qt Quick Test Reference Documentation} -*/ - -/*! - \qmlproperty string TestCase::name - - This property defines the name of the test case for result reporting. - The default is the empty string. - - \code - TestCase { - name: "ButtonTests" - ... - } - \endcode -*/ - -/*! - \qmlproperty bool TestCase::when - - This property should be set to true when the application wants - the test cases to run. The default value is true. In the following - example, a test is run when the user presses the mouse button: - - \code - Rectangle { - id: foo - width: 640; height: 480 - color: "cyan" - - MouseArea { - id: area - anchors.fill: parent - } - - property bool bar: true - - TestCase { - name: "ItemTests" - when: area.pressed - id: test1 - - function test_bar() { - verify(bar) - } - } - } - \endcode - - The test application will exit once all \l TestCase types - have been triggered and have run. The \l optional property can - be used to exclude a \l TestCase type. - - \sa optional, completed -*/ - -/*! - \qmlproperty bool TestCase::optional - - Multiple \l TestCase types can be supplied in a test application. - The application will exit once they have all completed. If a test case - does not need to run (because a precondition has failed), then this - property can be set to true. The default value is false. - - \code - TestCase { - when: false - optional: true - function test_not_run() { - verify(false) - } - } - \endcode - - \sa when, completed -*/ - -/*! - \qmlproperty bool TestCase::completed - - This property will be set to true once the test case has completed - execution. Test cases are only executed once. The initial value - is false. - - \sa running, when -*/ - -/*! - \qmlproperty bool TestCase::running - - This property will be set to true while the test case is running. - The initial value is false, and the value will become false again - once the test case completes. - - \sa completed, when -*/ - -/*! - \qmlproperty bool TestCase::windowShown - - This property will be set to true after the QML viewing window has - been displayed. Normally test cases run as soon as the test application - is loaded and before a window is displayed. If the test case involves - visual types and behaviors, then it may need to be delayed until - after the window is shown. - - \code - Button { - id: button - onClicked: text = "Clicked" - TestCase { - name: "ClickTest" - when: windowShown - function test_click() { - button.clicked(); - compare(button.text, "Clicked"); - } - } - } - \endcode -*/ - -/*! - \qmlmethod TestCase::fail(message = "") - - Fails the current test case, with the optional \a message. - Similar to \c{QFAIL(message)} in C++. -*/ - -/*! - \qmlmethod TestCase::verify(condition, message = "") - - Fails the current test case if \a condition is false, and - displays the optional \a message. Similar to \c{QVERIFY(condition)} - or \c{QVERIFY2(condition, message)} in C++. -*/ - -/*! - \qmlmethod TestCase::compare(actual, expected, message = "") - - Fails the current test case if \a actual is not the same as - \a expected, and displays the optional \a message. Similar - to \c{QCOMPARE(actual, expected)} in C++. - - \sa tryCompare(), fuzzyCompare -*/ - - -/*! - \qmlmethod TestCase::fuzzyCompare(actual, expected, delta, message = "") - - Fails the current test case if the difference betwen \a actual and \a expected - is greater than \a delta, and displays the optional \a message. Similar - to \c{qFuzzyCompare(actual, expected)} in C++ but with a required \a delta value. - - This funtion can also be used for color comparisons if both the \a actual and - \a expected values can be converted into color values. If any of the differences - for RGBA channel values are greater than \a delta, the test fails. - - \sa tryCompare(), compare() -*/ - -/*! - \qmlmethod TestCase::tryCompare(obj, property, expected, timeout = 5000, message = "") - - Fails the current test case if the specified \a property on \a obj - is not the same as \a expected, and displays the optional \a message. - The test will be retried multiple times until the - \a timeout (in milliseconds) is reached. - - This function is intended for testing applications where a property - changes value based on asynchronous events. Use compare() for testing - synchronous property changes. - - \code - tryCompare(img, "status", BorderImage.Ready) - compare(img.width, 120) - compare(img.height, 120) - compare(img.horizontalTileMode, BorderImage.Stretch) - compare(img.verticalTileMode, BorderImage.Stretch) - \endcode - - SignalSpy::wait() provides an alternative method to wait for a - signal to be emitted. - - \sa compare(), SignalSpy::wait() -*/ - -/*! - \qmlmethod object TestCase::grabImage(item) - - Returns a snapshot image object of the given \a item. - - The returned image object has the following methods: - \list - \li red(x, y) Returns the red channel value of the pixel at \a x, \a y position - \li green(x, y) Returns the green channel value of the pixel at \a x, \a y position - \li blue(x, y) Returns the blue channel value of the pixel at \a x, \a y position - \li alpha(x, y) Returns the alpha channel value of the pixel at \a x, \a y position - \li pixel(x, y) Returns the color value of the pixel at \a x, \a y position - For example: - - \code - var image = grabImage(rect); - compare(image.red(10, 10), 255); - compare(image.pixel(20, 20), Qt.rgba(255, 0, 0, 255); - \endcode - - \endlist - - \sa -*/ - -/*! - \qmlmethod TestCase::skip(message = "") - - Skips the current test case and prints the optional \a message. - If this is a data-driven test, then only the current row is skipped. - Similar to \c{QSKIP(message)} in C++. -*/ - -/*! - \qmlmethod TestCase::expectFail(tag, message) - - In a data-driven test, marks the row associated with \a tag as - expected to fail. When the fail occurs, display the \a message, - abort the test, and mark the test as passing. Similar to - \c{QEXPECT_FAIL(tag, message, Abort)} in C++. - - If the test is not data-driven, then \a tag must be set to - the empty string. - - \sa expectFailContinue() -*/ - -/*! - \qmlmethod TestCase::expectFailContinue(tag, message) - - In a data-driven test, marks the row associated with \a tag as - expected to fail. When the fail occurs, display the \a message, - and then continue the test. Similar to - \c{QEXPECT_FAIL(tag, message, Continue)} in C++. - - If the test is not data-driven, then \a tag must be set to - the empty string. - - \sa expectFail() -*/ - -/*! - \qmlmethod TestCase::warn(message) - - Prints \a message as a warning message. Similar to - \c{QWARN(message)} in C++. - - \sa ignoreWarning() -*/ - -/*! - \qmlmethod TestCase::ignoreWarning(message) - - Marks \a message as an ignored warning message. When it occurs, - the warning will not be printed and the test passes. If the message - does not occur, then the test will fail. Similar to - \c{QTest::ignoreMessage(QtWarningMsg, message)} in C++. - - \sa warn() -*/ - -/*! - \qmlmethod TestCase::wait(ms) - - Waits for \a ms milliseconds while processing Qt events. - - \sa sleep(), waitForRendering() -*/ - -/*! - \qmlmethod TestCase::waitForRendering(item, timeout = 5000) - - Waits for \a timeout milliseconds or until the \a item is rendered by the renderer. - Returns true if \c item is rendered in \a timeout milliseconds, otherwise returns false. - The default \a timeout value is 5000. - - \sa sleep(), wait() -*/ - -/*! - \qmlmethod TestCase::sleep(ms) - - Sleeps for \a ms milliseconds without processing Qt events. - - \sa wait(), waitForRendering() -*/ - -/*! - \qmlmethod TestCase::keyClick(key, modifiers = Qt.NoModifier, delay = -1) - - Simulates clicking of \a key with an optional \a modifier on the currently - focused item. If \a delay is larger than 0, the test will wait for - \a delay milliseconds. - - \sa keyPress(), keyRelease() -*/ - -/*! - \qmlmethod TestCase::keyPress(key, modifiers = Qt.NoModifier, delay = -1) - - Simulates pressing a \a key with an optional \a modifier on the currently - focused item. If \a delay is larger than 0, the test will wait for - \a delay milliseconds. - - \b{Note:} At some point you should release the key using keyRelease(). - - \sa keyRelease(), keyClick() -*/ - -/*! - \qmlmethod TestCase::keyRelease(key, modifiers = Qt.NoModifier, delay = -1) - - Simulates releasing a \a key with an optional \a modifier on the currently - focused item. If \a delay is larger than 0, the test will wait for - \a delay milliseconds. - - \sa keyPress(), keyClick() -*/ - -/*! - \qmlmethod TestCase::mousePress(item, x, y, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) - - Simulates pressing a mouse \a button with an optional \a modifier - on an \a item. The position is defined by \a x and \a y. If \a delay is - specified, the test will wait for the specified amount of milliseconds - before the press. - - The position given by \a x and \a y is transformed from the co-ordinate - system of \a item into window co-ordinates and then delivered. - If \a item is obscured by another item, or a child of \a item occupies - that position, then the event will be delivered to the other item instead. - - \sa mouseRelease(), mouseClick(), mouseDoubleClick(), mouseMove(), mouseDrag(), mouseWheel() -*/ - -/*! - \qmlmethod TestCase::mouseRelease(item, x, y, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) - - Simulates releasing a mouse \a button with an optional \a modifier - on an \a item. The position of the release is defined by \a x and \a y. - If \a delay is specified, the test will wait for the specified amount of - milliseconds before releasing the button. - - The position given by \a x and \a y is transformed from the co-ordinate - system of \a item into window co-ordinates and then delivered. - If \a item is obscured by another item, or a child of \a item occupies - that position, then the event will be delivered to the other item instead. - - \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseMove(), mouseDrag(), mouseWheel() -*/ - -/*! - \qmlmethod TestCase::mouseClick(item, x, y, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) - - Simulates clicking a mouse \a button with an optional \a modifier - on an \a item. The position of the click is defined by \a x and \a y. - If \a delay is specified, the test will wait for the specified amount of - milliseconds before pressing and before releasing the button. - - The position given by \a x and \a y is transformed from the co-ordinate - system of \a item into window co-ordinates and then delivered. - If \a item is obscured by another item, or a child of \a item occupies - that position, then the event will be delivered to the other item instead. - - \sa mousePress(), mouseRelease(), mouseDoubleClick(), mouseMove(), mouseDrag(), mouseWheel() -*/ - -/*! - \qmlmethod TestCase::mouseDoubleClick(item, x, y, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) - - Simulates double-clicking a mouse \a button with an optional \a modifier - on an \a item. The position of the click is defined by \a x and \a y. - If \a delay is specified, the test will wait for the specified amount of - milliseconds before pressing and before releasing the button. - - The position given by \a x and \a y is transformed from the co-ordinate - system of \a item into window co-ordinates and then delivered. - If \a item is obscured by another item, or a child of \a item occupies - that position, then the event will be delivered to the other item instead. - - \sa mousePress(), mouseRelease(), mouseClick(), mouseMove(), mouseDrag(), mouseWheel() -*/ - -/*! - \qmlmethod TestCase::mouseMove(item, x, y, delay = -1) - - Moves the mouse pointer to the position given by \a x and \a y within - \a item. If a \a delay (in milliseconds) is given, the test will wait - before moving the mouse pointer. - - The position given by \a x and \a y is transformed from the co-ordinate - system of \a item into window co-ordinates and then delivered. - If \a item is obscured by another item, or a child of \a item occupies - that position, then the event will be delivered to the other item instead. - - \sa mousePress(), mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDrag(), mouseWheel() -*/ - -/*! - \qmlmethod TestCase::mouseDrag(item, x, y, dx, dy, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) - - Simulates dragging the mouse on an \a item with \a button pressed and an optional \a modifier. - The initial drag position is defined by \a x and \a y, - and drag distance is defined by \a dx and \a dy. If \a delay is specified, - the test will wait for the specified amount of milliseconds before releasing the button. - - The position given by \a x and \a y is transformed from the co-ordinate - system of \a item into window co-ordinates and then delivered. - If \a item is obscured by another item, or a child of \a item occupies - that position, then the event will be delivered to the other item instead. - - Note: this method does not imply a drop action, to make a drop, an additional - mouseRelease(item, x + dx, y + dy) is needed. - - \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseMove(), mouseRelease(), mouseWheel() -*/ - -/*! - \qmlmethod TestCase::mouseWheel(item, x, y, xDelta, yDelta, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1) - - Simulates rotating the mouse wheel on an \a item with \a button pressed and an optional \a modifier. - The position of the wheel event is defined by \a x and \a y. - If \a delay is specified, the test will wait for the specified amount of milliseconds before releasing the button. - - The position given by \a x and \a y is transformed from the co-ordinate - system of \a item into window co-ordinates and then delivered. - If \a item is obscured by another item, or a child of \a item occupies - that position, then the event will be delivered to the other item instead. - - The \a xDelta and \a yDelta contain the wheel rotation distance in eighths of a degree. see \l QWheelEvent::angleDelta() for more details. - - \sa mousePress(), mouseClick(), mouseDoubleClick(), mouseMove(), mouseRelease(), mouseDrag(), QWheelEvent::angleDelta() -*/ - -/*! - \qmlmethod TestCase::initTestCase() - - This function is called before any other test functions in the - \l TestCase type. The default implementation does nothing. - The application can provide its own implementation to perform - test case initialization. - - \sa cleanupTestCase(), init() -*/ - -/*! - \qmlmethod TestCase::cleanupTestCase() - - This function is called after all other test functions in the - \l TestCase type have completed. The default implementation - does nothing. The application can provide its own implementation - to perform test case cleanup. - - \sa initTestCase(), cleanup() -*/ - -/*! - \qmlmethod TestCase::init() - - This function is called before each test function that is - executed in the \l TestCase type. The default implementation - does nothing. The application can provide its own implementation - to perform initialization before each test function. - - \sa cleanup(), initTestCase() -*/ - -/*! - \qmlmethod TestCase::cleanup() - - This function is called after each test function that is - executed in the \l TestCase type. The default implementation - does nothing. The application can provide its own implementation - to perform cleanup after each test function. - - \sa init(), cleanupTestCase() -*/ |