Merge "Merge remote-tracking branch 'origin/stable' into dev" into refs/staging/dev
This commit is contained in:
commit
679ea13790
|
@ -53,6 +53,7 @@ int main(int argc, char **argv)
|
|||
qmlRegisterType<Squircle>("OpenGLUnderQML", 1, 0, "Squircle");
|
||||
|
||||
QQuickView view;
|
||||
view.setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
view.setSource(QUrl("qrc:///scenegraph/openglunderqml/main.qml"));
|
||||
view.show();
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ Rectangle {
|
|||
// item visible.
|
||||
//
|
||||
// The second ListView sets a highlight range which attempts to keep the
|
||||
// current item within the the bounds of the range. However,
|
||||
// current item within the bounds of the range. However,
|
||||
// items will not scroll beyond the beginning or end of the view,
|
||||
// forcing the highlight to move outside the range at the ends.
|
||||
//
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
load(qfeatures)
|
||||
requires(!contains(QT_DISABLED_FEATURES, settings))
|
||||
|
||||
CXX_MODULE = qml
|
||||
TARGET = qmlsettingsplugin
|
||||
TARGETPATH = Qt/labs/settings
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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()
|
||||
*/
|
|
@ -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
|
|
@ -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()
|
||||
*/
|
|
@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE
|
|||
\qmlproperty bool QtQuick.Particles::GroupGoal::jump
|
||||
|
||||
If true, affected particles will jump directly to the target group instead of taking the
|
||||
the shortest valid path to get there. They will also not finish their current state,
|
||||
shortest valid path to get there. They will also not finish their current state,
|
||||
but immediately move to the beginning of the goal state.
|
||||
|
||||
Default is false.
|
||||
|
|
|
@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE
|
|||
\qmlproperty bool QtQuick.Particles::SpriteGoal::jump
|
||||
|
||||
If true, affected sprites will jump directly to the goal state instead of taking the
|
||||
the shortest valid path to get there. They will also not finish their current state,
|
||||
shortest valid path to get there. They will also not finish their current state,
|
||||
but immediately move to the beginning of the goal state.
|
||||
|
||||
Default is false.
|
||||
|
|
|
@ -431,58 +431,29 @@ void QQmlProfilerService::messageReceived(const QByteArray &message)
|
|||
*/
|
||||
void QQmlVmeProfiler::Data::clear()
|
||||
{
|
||||
url = QUrl();
|
||||
url.clear();
|
||||
line = 0;
|
||||
column = 0;
|
||||
typeName = QString();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief QQmlVmeProfiler::start Start profiler and set data
|
||||
* \param url URL of file being executed
|
||||
* \param line Curent line in file
|
||||
* \param column Current column in file
|
||||
* \param typeName Type of object be created
|
||||
* Stops the profiler previously running in the foreground if there is one, then starts a
|
||||
* new one and sets it up with the data given.
|
||||
* Preconditions: Profiling must be enabled.
|
||||
*/
|
||||
void QQmlVmeProfiler::start(const QUrl &url, int line, int column, const QString &typeName)
|
||||
{
|
||||
Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
|
||||
if (enabled) {
|
||||
switchRange();
|
||||
updateLocation(url, line, column);
|
||||
updateTypeName(typeName);
|
||||
}
|
||||
typeName.clear();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief QQmlVmeProfiler::start Start profiler without data
|
||||
* Clears the current range data, then stops the profiler previously running in the
|
||||
* foreground if any, then starts a new one.
|
||||
* Preconditions: Profiling must be enabled.
|
||||
*/
|
||||
void QQmlVmeProfiler::start()
|
||||
bool QQmlVmeProfiler::start()
|
||||
{
|
||||
Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
|
||||
if (enabled) {
|
||||
if (QQmlProfilerService::enabled) {
|
||||
currentRange.clear();
|
||||
switchRange();
|
||||
if (running)
|
||||
QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating);
|
||||
else
|
||||
running = true;
|
||||
QQmlProfilerService::instance->startRange(QQmlProfilerService::Creating);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief QQmlVmeProfiler::switchRange Switch foreground profilers
|
||||
* Stops the current profiler if any, and starts a new one.
|
||||
*/
|
||||
void QQmlVmeProfiler::switchRange()
|
||||
{
|
||||
if (running)
|
||||
QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating);
|
||||
else
|
||||
running = true;
|
||||
QQmlProfilerService::instance->startRange(QQmlProfilerService::Creating);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -491,13 +462,10 @@ void QQmlVmeProfiler::switchRange()
|
|||
* \param line line Curent line in file
|
||||
* \param column column Current column in file
|
||||
* Updates the current profiler's location information.
|
||||
* Preconditions: Profiling must be enabled and a profiler must be running in the foreground.
|
||||
*/
|
||||
void QQmlVmeProfiler::updateLocation(const QUrl &url, int line, int column)
|
||||
{
|
||||
Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
|
||||
Q_ASSERT_X(running, Q_FUNC_INFO, "trying to update location on stopped profiler");
|
||||
if (enabled && running) {
|
||||
if (QQmlProfilerService::enabled && running) {
|
||||
currentRange.url = url;
|
||||
currentRange.line = line;
|
||||
currentRange.column = column;
|
||||
|
@ -510,13 +478,10 @@ void QQmlVmeProfiler::updateLocation(const QUrl &url, int line, int column)
|
|||
* \brief QQmlVmeProfiler::updateTypeName Update current type information
|
||||
* \param typeName Type of object being created
|
||||
* Updates the current profiler's type information.
|
||||
* Preconditions: Profiling must be enabled and a profiler must be running in the foreground.
|
||||
*/
|
||||
void QQmlVmeProfiler::updateTypeName(const QString &typeName)
|
||||
{
|
||||
Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
|
||||
Q_ASSERT_X(running, Q_FUNC_INFO, "trying to update typeName on stopped profiler");
|
||||
if (enabled && running) {
|
||||
if (QQmlProfilerService::enabled && running) {
|
||||
currentRange.typeName = typeName;
|
||||
QQmlProfilerService::instance->rangeData(QQmlProfilerService::Creating, typeName);
|
||||
}
|
||||
|
@ -526,14 +491,10 @@ void QQmlVmeProfiler::updateTypeName(const QString &typeName)
|
|||
* \brief QQmlVmeProfiler::pop Pops a paused profiler from the stack and restarts it
|
||||
* Stops the currently running profiler, if any, then retrieves an old one from the stack
|
||||
* of paused profilers and starts that.
|
||||
* Preconditions: Profiling must be enabled and there must be at least one profiler on the
|
||||
* stack.
|
||||
*/
|
||||
void QQmlVmeProfiler::pop()
|
||||
{
|
||||
Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
|
||||
Q_ASSERT_X(ranges.count() > 0, Q_FUNC_INFO, "trying to pop an invalid profiler");
|
||||
if (enabled && ranges.count() > 0) {
|
||||
if (QQmlProfilerService::enabled && ranges.count() > 0) {
|
||||
start();
|
||||
currentRange = ranges.pop();
|
||||
QQmlProfilerService::instance->rangeLocation(
|
||||
|
@ -547,13 +508,10 @@ void QQmlVmeProfiler::pop()
|
|||
* Pushes the currently running profiler on the stack of paused profilers. Note: The profiler
|
||||
* isn't paused here. That's a separate step. If it's never paused, but pop()'ed later that
|
||||
* won't do any harm, though.
|
||||
* Preconditions: Profiling must be enabled and a profiler must be running in the foreground.
|
||||
*/
|
||||
void QQmlVmeProfiler::push()
|
||||
{
|
||||
Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
|
||||
Q_ASSERT_X(running, Q_FUNC_INFO, "trying to push stopped profiler");
|
||||
if (enabled && running)
|
||||
if (QQmlProfilerService::enabled && running)
|
||||
ranges.push(currentRange);
|
||||
}
|
||||
|
||||
|
@ -561,29 +519,26 @@ void QQmlVmeProfiler::push()
|
|||
* \brief QQmlVmeProfiler::clear Stop all running profilers and clear all data.
|
||||
* Stops the currently running (foreground and background) profilers and removes all saved
|
||||
* data about paused profilers.
|
||||
* Precondtions: Profiling must be enabled.
|
||||
*/
|
||||
void QQmlVmeProfiler::clear()
|
||||
{
|
||||
Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
|
||||
if (enabled) {
|
||||
stop();
|
||||
ranges.clear();
|
||||
stop();
|
||||
ranges.clear();
|
||||
if (QQmlProfilerService::enabled) {
|
||||
for (int i = 0; i < backgroundRanges.count(); ++i) {
|
||||
QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating);
|
||||
}
|
||||
backgroundRanges.clear();
|
||||
}
|
||||
backgroundRanges.clear();
|
||||
running = false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief QQmlVmeProfiler::stop Stop profiler running in the foreground, if any.
|
||||
* Precondition: Profiling must be enabled.
|
||||
*/
|
||||
void QQmlVmeProfiler::stop()
|
||||
{
|
||||
Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
|
||||
if (enabled && running) {
|
||||
if (QQmlProfilerService::enabled && running) {
|
||||
QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating);
|
||||
currentRange.clear();
|
||||
running = false;
|
||||
|
@ -595,13 +550,10 @@ void QQmlVmeProfiler::stop()
|
|||
* Push the profiler currently running in the foreground to the background so that it
|
||||
* won't be stopped by stop() or start(). There can be multiple profilers in the background.
|
||||
* You can retrieve them in reverse order by calling foreground().
|
||||
* Precondition: Profiling must be enabled and a profiler must be running in the foreground.
|
||||
*/
|
||||
void QQmlVmeProfiler::background()
|
||||
{
|
||||
Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
|
||||
Q_ASSERT_X(running, Q_FUNC_INFO, "trying to push stopped profiler to the background.");
|
||||
if (enabled && running) {
|
||||
if (QQmlProfilerService::enabled && running) {
|
||||
backgroundRanges.push(currentRange);
|
||||
running = false;
|
||||
}
|
||||
|
@ -611,18 +563,16 @@ void QQmlVmeProfiler::background()
|
|||
* \brief QQmlVmeProfiler::foreground Retrieve a profiler from the background
|
||||
* Stop the profiler currently running in the foreground, if any and put the next profiler
|
||||
* from the background in its place.
|
||||
* Preconditions: Profiling must be enabled and there must be at least one profiler in the
|
||||
* background.
|
||||
*/
|
||||
void QQmlVmeProfiler::foreground()
|
||||
bool QQmlVmeProfiler::foreground()
|
||||
{
|
||||
Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
|
||||
Q_ASSERT_X(backgroundRanges.count() > 0, Q_FUNC_INFO, "trying to foreground stopped profiler.");
|
||||
if (enabled && backgroundRanges.count() > 0) {
|
||||
if (QQmlProfilerService::enabled && backgroundRanges.count() > 0) {
|
||||
stop();
|
||||
currentRange = backgroundRanges.pop();
|
||||
running = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -237,32 +237,25 @@ private:
|
|||
struct QQmlBindingProfiler {
|
||||
QQmlBindingProfiler(const QString &url, int line, int column, QQmlProfilerService::BindingType bindingType)
|
||||
{
|
||||
QQmlProfilerService *instance = QQmlProfilerService::instance;
|
||||
enabled = instance ? instance->profilingEnabled() : false;
|
||||
if (enabled) {
|
||||
instance->startRange(QQmlProfilerService::Binding, bindingType);
|
||||
instance->rangeLocation(QQmlProfilerService::Binding, url, line, column);
|
||||
if (QQmlProfilerService::enabled) {
|
||||
QQmlProfilerService::instance->startRange(QQmlProfilerService::Binding, bindingType);
|
||||
QQmlProfilerService::instance->rangeLocation(QQmlProfilerService::Binding, url, line, column);
|
||||
}
|
||||
}
|
||||
|
||||
~QQmlBindingProfiler()
|
||||
{
|
||||
if (enabled)
|
||||
if (QQmlProfilerService::enabled)
|
||||
QQmlProfilerService::instance->endRange(QQmlProfilerService::Binding);
|
||||
}
|
||||
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
struct QQmlHandlingSignalProfiler {
|
||||
QQmlHandlingSignalProfiler(QQmlBoundSignalExpression *expression)
|
||||
{
|
||||
enabled = QQmlProfilerService::instance
|
||||
? QQmlProfilerService::instance->profilingEnabled() : false;
|
||||
if (enabled) {
|
||||
QQmlProfilerService *service = QQmlProfilerService::instance;
|
||||
service->startRange(QQmlProfilerService::HandlingSignal);
|
||||
service->rangeLocation(QQmlProfilerService::HandlingSignal,
|
||||
if (QQmlProfilerService::enabled) {
|
||||
QQmlProfilerService::instance->startRange(QQmlProfilerService::HandlingSignal);
|
||||
QQmlProfilerService::instance->rangeLocation(QQmlProfilerService::HandlingSignal,
|
||||
expression->sourceFile(), expression->lineNumber(),
|
||||
expression->columnNumber());
|
||||
}
|
||||
|
@ -270,38 +263,30 @@ struct QQmlHandlingSignalProfiler {
|
|||
|
||||
~QQmlHandlingSignalProfiler()
|
||||
{
|
||||
if (enabled)
|
||||
if (QQmlProfilerService::enabled)
|
||||
QQmlProfilerService::instance->endRange(QQmlProfilerService::HandlingSignal);
|
||||
}
|
||||
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
struct QQmlCompilingProfiler {
|
||||
QQmlCompilingProfiler(const QString &name)
|
||||
{
|
||||
QQmlProfilerService *instance = QQmlProfilerService::instance;
|
||||
enabled = instance ?
|
||||
instance->profilingEnabled() : false;
|
||||
if (enabled) {
|
||||
instance->startRange(QQmlProfilerService::Compiling);
|
||||
instance->rangeLocation(QQmlProfilerService::Compiling, name, 1, 1);
|
||||
instance->rangeData(QQmlProfilerService::Compiling, name);
|
||||
if (QQmlProfilerService::enabled) {
|
||||
QQmlProfilerService::instance->startRange(QQmlProfilerService::Compiling);
|
||||
QQmlProfilerService::instance->rangeLocation(QQmlProfilerService::Compiling, name, 1, 1);
|
||||
QQmlProfilerService::instance->rangeData(QQmlProfilerService::Compiling, name);
|
||||
}
|
||||
}
|
||||
|
||||
~QQmlCompilingProfiler()
|
||||
{
|
||||
if (enabled)
|
||||
if (QQmlProfilerService::enabled)
|
||||
QQmlProfilerService::instance->endRange(QQmlProfilerService::Compiling);
|
||||
}
|
||||
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
struct QQmlVmeProfiler {
|
||||
public:
|
||||
const bool enabled;
|
||||
|
||||
struct Data {
|
||||
Data() : line(0), column(0) {}
|
||||
|
@ -313,20 +298,18 @@ public:
|
|||
};
|
||||
|
||||
QQmlVmeProfiler() :
|
||||
enabled(QQmlProfilerService::instance ? QQmlProfilerService::instance->profilingEnabled() : false),
|
||||
running(false)
|
||||
{}
|
||||
|
||||
~QQmlVmeProfiler()
|
||||
{
|
||||
if (enabled)
|
||||
if (QQmlProfilerService::enabled)
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear();
|
||||
|
||||
void start(const QUrl &url, int line, int column, const QString &typeName);
|
||||
void start();
|
||||
bool start();
|
||||
void stop();
|
||||
|
||||
void updateLocation(const QUrl &url, int line, int column);
|
||||
|
@ -336,10 +319,9 @@ public:
|
|||
void push();
|
||||
|
||||
void background();
|
||||
void foreground();
|
||||
bool foreground();
|
||||
|
||||
private:
|
||||
void switchRange();
|
||||
|
||||
Data currentRange;
|
||||
QStack<Data> ranges;
|
||||
|
@ -348,46 +330,36 @@ private:
|
|||
};
|
||||
|
||||
struct QQmlPixmapProfiler {
|
||||
QQmlPixmapProfiler() {
|
||||
QQmlProfilerService *instance = QQmlProfilerService::instance;
|
||||
enabled = instance ?
|
||||
instance->profilingEnabled() : false;
|
||||
}
|
||||
|
||||
~QQmlPixmapProfiler() {}
|
||||
|
||||
void startLoading(const QUrl &pixmapUrl) {
|
||||
if (enabled) {
|
||||
if (QQmlProfilerService::enabled) {
|
||||
QQmlProfilerService::instance->pixmapEventImpl(QQmlProfilerService::PixmapLoadingStarted, pixmapUrl);
|
||||
}
|
||||
}
|
||||
void finishLoading(const QUrl &pixmapUrl) {
|
||||
if (enabled) {
|
||||
if (QQmlProfilerService::enabled) {
|
||||
QQmlProfilerService::instance->pixmapEventImpl(QQmlProfilerService::PixmapLoadingFinished, pixmapUrl);
|
||||
}
|
||||
}
|
||||
void errorLoading(const QUrl &pixmapUrl) {
|
||||
if (enabled) {
|
||||
if (QQmlProfilerService::enabled) {
|
||||
QQmlProfilerService::instance->pixmapEventImpl(QQmlProfilerService::PixmapLoadingError, pixmapUrl);
|
||||
}
|
||||
}
|
||||
void cacheCountChanged(const QUrl &pixmapUrl, int cacheCount) {
|
||||
if (enabled) {
|
||||
if (QQmlProfilerService::enabled) {
|
||||
QQmlProfilerService::instance->pixmapEventImpl(QQmlProfilerService::PixmapCacheCountChanged, pixmapUrl, cacheCount);
|
||||
}
|
||||
}
|
||||
void referenceCountChanged(const QUrl &pixmapUrl, int referenceCount) {
|
||||
if (enabled) {
|
||||
if (QQmlProfilerService::enabled) {
|
||||
QQmlProfilerService::instance->pixmapEventImpl(QQmlProfilerService::PixmapReferenceCountChanged, pixmapUrl, referenceCount);
|
||||
}
|
||||
}
|
||||
void setSize(const QUrl &pixmapUrl, const QSize &size) {
|
||||
if (enabled && size.width() > 0) {
|
||||
if (QQmlProfilerService::enabled && size.width() > 0) {
|
||||
QQmlProfilerService::instance->pixmapEventImpl(QQmlProfilerService::PixmapSizeKnown, pixmapUrl, size.width(), size.height());
|
||||
}
|
||||
}
|
||||
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
\title Property Binding
|
||||
\brief binding object properties
|
||||
|
||||
To make the fullest use of QML and its built-in support for implementing dynamic object behavioral changes, most QML objects will use \e {property binding}. This is a core feature of QML that allows objects to automatically update their properties in response to changing attributes in other objects or the occurence of some external event.
|
||||
To make the fullest use of QML and its built-in support for implementing dynamic object behavioral changes, most QML objects will use \e {property binding}. This is a core feature of QML that allows objects to automatically update their properties in response to changing attributes in other objects or the occurrence of some external event.
|
||||
|
||||
When an object's property is assigned a value, it can either be assigned a static value, or \e bound to a JavaScript expression. In the first case, the property's value will not change unless a new value is assigned to the property. In the latter case, a \e {property binding} is created and the property's value is automatically updated by the QML engine whenever the value of the evaluated expression changes.
|
||||
|
||||
|
|
|
@ -21,7 +21,8 @@ QMAKE_DOCS = $$PWD/doc/qtqml.qdocconf
|
|||
# 2415: variable "xx" of static storage duration was declared but never referenced
|
||||
# unused variable 'xx' [-Werror,-Wunused-const-variable]
|
||||
intel_icc: WERROR += -ww2415
|
||||
clang: WERROR += -Wno-error=unused-const-variable
|
||||
clang:if(greaterThan(QT_CLANG_MAJOR_VERSION, 3)|greaterThan(QT_CLANG_MINOR_VERSION, 3)): \
|
||||
WERROR += -Wno-error=unused-const-variable
|
||||
|
||||
load(qt_module)
|
||||
|
||||
|
|
|
@ -503,8 +503,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
|
|||
const QQmlCompiledData::TypeReference &type = TYPES.at(instr.type);
|
||||
Q_ASSERT(type.component);
|
||||
|
||||
if (profiler.enabled) {
|
||||
profiler.start();
|
||||
if (profiler.start()) {
|
||||
profiler.updateTypeName(type.component->name);
|
||||
profiler.background();
|
||||
}
|
||||
|
@ -530,10 +529,8 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
|
|||
QML_END_INSTR(CreateQMLObject)
|
||||
|
||||
QML_BEGIN_INSTR(CompleteQMLObject)
|
||||
if (profiler.enabled) {
|
||||
profiler.foreground();
|
||||
if (profiler.foreground())
|
||||
profiler.updateLocation(CTXT->url, instr.line, instr.column);
|
||||
}
|
||||
|
||||
QObject *o = objects.top();
|
||||
Q_ASSERT(o);
|
||||
|
@ -577,8 +574,10 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
|
|||
QML_BEGIN_INSTR(CreateCppObject)
|
||||
const QQmlCompiledData::TypeReference &type = TYPES.at(instr.type);
|
||||
Q_ASSERT(type.type);
|
||||
if (profiler.enabled)
|
||||
profiler.start(CTXT->url, instr.line, instr.column, type.type->qmlTypeName());
|
||||
if (profiler.start()) {
|
||||
profiler.updateLocation(CTXT->url, instr.line, instr.column);
|
||||
profiler.updateTypeName(type.type->qmlTypeName());
|
||||
}
|
||||
|
||||
QObject *o = 0;
|
||||
void *memory = 0;
|
||||
|
@ -651,8 +650,10 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
|
|||
|
||||
QML_BEGIN_INSTR(CreateSimpleObject)
|
||||
const QQmlCompiledData::TypeReference &ref = TYPES.at(instr.type);
|
||||
if (profiler.enabled)
|
||||
profiler.start(CTXT->url, instr.line, instr.column, ref.type->qmlTypeName());
|
||||
if (profiler.start()) {
|
||||
profiler.updateLocation(CTXT->url, instr.line, instr.column);
|
||||
profiler.updateTypeName(ref.type->qmlTypeName());
|
||||
}
|
||||
QObject *o = (QObject *)operator new(instr.typeSize + sizeof(QQmlData));
|
||||
::memset(static_cast<void *>(o), 0, instr.typeSize + sizeof(QQmlData));
|
||||
instr.create(o);
|
||||
|
@ -832,8 +833,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
|
|||
QML_END_INSTR(StoreScriptString)
|
||||
|
||||
QML_BEGIN_INSTR(BeginObject)
|
||||
if (profiler.enabled)
|
||||
profiler.push();
|
||||
profiler.push();
|
||||
QObject *target = objects.top();
|
||||
QQmlParserStatus *status = reinterpret_cast<QQmlParserStatus *>(reinterpret_cast<char *>(target) + instr.castValue);
|
||||
parserStatus.push(status);
|
||||
|
@ -1091,8 +1091,7 @@ normalExit:
|
|||
objects.deallocate();
|
||||
lists.deallocate();
|
||||
states.clear();
|
||||
if (profiler.enabled)
|
||||
profiler.stop();
|
||||
profiler.stop();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -1130,8 +1129,7 @@ void QQmlVME::reset()
|
|||
states.clear();
|
||||
rootContext = 0;
|
||||
creationContext = 0;
|
||||
if (profiler.enabled)
|
||||
profiler.clear();
|
||||
profiler.clear();
|
||||
}
|
||||
|
||||
#ifdef QML_THREADED_VME_INTERPRETER
|
||||
|
@ -1191,8 +1189,7 @@ QQmlContextData *QQmlVME::complete(const Interrupt &interrupt)
|
|||
if (componentCompleteEnabled()) { // the qml designer does the component complete later
|
||||
QQmlTrace trace("VME Component Complete");
|
||||
while (!parserStatus.isEmpty()) {
|
||||
if (profiler.enabled)
|
||||
profiler.pop();
|
||||
profiler.pop();
|
||||
QQmlParserStatus *status = parserStatus.pop();
|
||||
#ifdef QML_ENABLE_TRACE
|
||||
QQmlData *data = parserStatusData.pop();
|
||||
|
@ -1212,8 +1209,7 @@ QQmlContextData *QQmlVME::complete(const Interrupt &interrupt)
|
|||
return 0;
|
||||
}
|
||||
parserStatus.deallocate();
|
||||
if (profiler.enabled)
|
||||
profiler.clear();
|
||||
profiler.clear();
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -38,7 +38,8 @@ depends += qtcore qtxmlpatterns qtqml qtgui qtlinguist qtquickcontrols qtquickla
|
|||
|
||||
headerdirs += ..
|
||||
|
||||
sourcedirs += ..
|
||||
sourcedirs += .. \
|
||||
../../imports/testlib
|
||||
|
||||
exampledirs += ../../../examples/quick \
|
||||
snippets
|
||||
|
|
|
@ -42,11 +42,11 @@ by this module, organized according to category and purpose.
|
|||
The types provided by the \l {Qt Quick} module are only available in a QML document
|
||||
if that document imports the \c QtQuick namespace.
|
||||
|
||||
The current version of the \c QtQuick module is version 2.0, and thus it may be
|
||||
The current version of the \c QtQuick module is version 2.2, and thus it may be
|
||||
imported via the following statement:
|
||||
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import QtQuick 2.2
|
||||
\endqml
|
||||
|
||||
See the \l {Qt Quick} module documentation for more
|
||||
|
@ -310,6 +310,14 @@ set of Particle System types for Qt Quick 2
|
|||
\li \l {TextMetrics} - Provides text and font measurement data for use in a Canvas
|
||||
\endlist
|
||||
|
||||
\target qttest-types
|
||||
\section2 QtTest Types
|
||||
|
||||
\list
|
||||
\li \l {QtTest::TestCase}{TestCase} - Represents a unit test case
|
||||
\li \l {QtTest::SignalSpy}{SignalSpy} - Enables introspection of signal emission
|
||||
\endlist
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -1070,8 +1078,9 @@ console.log(c + " " + d); // false true
|
|||
|
||||
/*!
|
||||
\qmlmodule QtTest 1.0
|
||||
\title Qt Quick Test
|
||||
\title Qt Quick Test QML Types
|
||||
\brief This module provides QML types to unit test your QML application
|
||||
\ingroup qmlmodules
|
||||
|
||||
You can import this module using the following statement:
|
||||
\code
|
||||
|
|
|
@ -125,6 +125,7 @@ Additional Qt Quick information:
|
|||
top-level windows and accessing screen information
|
||||
\li \l{Qt Quick Dialogs}{Dialogs} - contains types for creating and
|
||||
interacting with system dialogs
|
||||
\li \l{Qt Quick Test QML Types}{Tests} - contains types for writing unit test for a QML application
|
||||
\endlist
|
||||
\li \l{Qt Quick Release Notes} - list of changes and additions in the Qt Quick
|
||||
\li \l{Qt Quick Code Samples} - list of all Qt Quick examples
|
||||
|
|
|
@ -1234,7 +1234,11 @@ void QQuickFlickable::mouseReleaseEvent(QMouseEvent *event)
|
|||
d->replayDelayedPress();
|
||||
|
||||
// Now send the release
|
||||
window()->sendEvent(window()->mouseGrabberItem(), event);
|
||||
if (window()->mouseGrabberItem()) {
|
||||
QPointF localPos = window()->mouseGrabberItem()->mapFromScene(event->windowPos());
|
||||
QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos));
|
||||
window()->sendEvent(window()->mouseGrabberItem(), mouseEvent.data());
|
||||
}
|
||||
|
||||
// And the event has been consumed
|
||||
d->stealMouse = false;
|
||||
|
|
|
@ -106,7 +106,8 @@ bool qsg_sort_batch_is_valid(Batch *a, Batch *b) { return a->first && !b->first;
|
|||
bool qsg_sort_batch_increasing_order(Batch *a, Batch *b) { return a->first->order < b->first->order; }
|
||||
bool qsg_sort_batch_decreasing_order(Batch *a, Batch *b) { return a->first->order > b->first->order; }
|
||||
|
||||
QSGMaterial::Flag QSGMaterial_RequiresFullMatrixBit = (QSGMaterial::Flag) (QSGMaterial::RequiresFullMatrix & ~QSGMaterial::RequiresFullMatrixExceptTranslate);
|
||||
QSGMaterial::Flag QSGMaterial_FullMatrix = (QSGMaterial::Flag) (QSGMaterial::RequiresFullMatrix & ~QSGMaterial::RequiresFullMatrixExceptTranslate);
|
||||
QSGMaterial::Flag QSGMaterial_FullExceptTranslate = (QSGMaterial::Flag) (QSGMaterial::RequiresFullMatrixExceptTranslate & ~QSGMaterial::RequiresDeterminant);
|
||||
|
||||
struct QMatrix4x4_Accessor
|
||||
{
|
||||
|
@ -1699,14 +1700,12 @@ void Renderer::uploadBatch(Batch *b)
|
|||
|
||||
QSGGeometryNode *gn = b->first->node;
|
||||
QSGGeometry *g = gn->geometry();
|
||||
|
||||
QSGMaterial::Flags flags = gn->activeMaterial()->flags();
|
||||
bool canMerge = (g->drawingMode() == GL_TRIANGLES || g->drawingMode() == GL_TRIANGLE_STRIP)
|
||||
&& b->positionAttribute >= 0
|
||||
&& g->indexType() == GL_UNSIGNED_SHORT
|
||||
&& (gn->activeMaterial()->flags() & QSGMaterial::CustomCompileStep) == 0
|
||||
&& (((gn->activeMaterial()->flags() & QSGMaterial::RequiresDeterminant) == 0)
|
||||
|| (((gn->activeMaterial()->flags() & QSGMaterial_RequiresFullMatrixBit) == 0) && b->isTranslateOnlyToRoot())
|
||||
)
|
||||
&& (flags & (QSGMaterial::CustomCompileStep | QSGMaterial_FullMatrix)) == 0
|
||||
&& ((flags & QSGMaterial_FullExceptTranslate) == 0 || b->isTranslateOnlyToRoot())
|
||||
&& b->isSafeToBatch();
|
||||
|
||||
b->merged = canMerge;
|
||||
|
|
|
@ -8,6 +8,11 @@ Flickable {
|
|||
contentHeight: 400
|
||||
pressDelay: 100
|
||||
|
||||
property real pressX
|
||||
property real pressY
|
||||
property real releaseX
|
||||
property real releaseY
|
||||
|
||||
MouseArea {
|
||||
id: ma
|
||||
objectName: "mouseArea"
|
||||
|
@ -16,6 +21,15 @@ Flickable {
|
|||
width: 240
|
||||
height: 100
|
||||
|
||||
onPressed: {
|
||||
pressX = mouse.x
|
||||
pressY = mouse.y
|
||||
}
|
||||
onReleased: {
|
||||
releaseX = mouse.x
|
||||
releaseY = mouse.y
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: parent.pressed ? 'blue' : 'green'
|
||||
|
|
|
@ -412,6 +412,29 @@ void tst_qquickflickable::pressDelay()
|
|||
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(150, 150));
|
||||
QCOMPARE(clickedSpy.count(),1);
|
||||
|
||||
// Press and release position should match
|
||||
QCOMPARE(flickable->property("pressX").toReal(), flickable->property("releaseX").toReal());
|
||||
QCOMPARE(flickable->property("pressY").toReal(), flickable->property("releaseY").toReal());
|
||||
|
||||
|
||||
// Test a quick tap within the pressDelay timeout
|
||||
clickedSpy.clear();
|
||||
QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(180, 180));
|
||||
|
||||
// The press should not occur immediately
|
||||
QVERIFY(mouseArea->property("pressed").toBool() == false);
|
||||
|
||||
QCOMPARE(clickedSpy.count(),0);
|
||||
|
||||
// On release the press, release and clicked signal should be emitted
|
||||
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(180, 180));
|
||||
QCOMPARE(clickedSpy.count(),1);
|
||||
|
||||
// Press and release position should match
|
||||
QCOMPARE(flickable->property("pressX").toReal(), flickable->property("releaseX").toReal());
|
||||
QCOMPARE(flickable->property("pressY").toReal(), flickable->property("releaseY").toReal());
|
||||
|
||||
|
||||
// QTBUG-31168
|
||||
QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(150, 110));
|
||||
|
||||
|
|
Loading…
Reference in New Issue