diff options
Diffstat (limited to 'tests/auto/controls')
50 files changed, 4716 insertions, 839 deletions
diff --git a/tests/auto/controls/controls.pro b/tests/auto/controls/controls.pro index d1dd6814..8f2f8e69 100644 --- a/tests/auto/controls/controls.pro +++ b/tests/auto/controls/controls.pro @@ -1,12 +1,5 @@ -TEMPLATE = app -TARGET = tst_controls -CONFIG += qmltestcase - -SOURCES += \ - $$PWD/tst_controls.cpp - -OTHER_FILES += \ - $$PWD/data/* - -TESTDATA += \ - $$PWD/data/tst_* +TEMPLATE = subdirs +SUBDIRS += \ + default \ + material \ + universal diff --git a/tests/auto/controls/data/ControlSpy.qml b/tests/auto/controls/data/SignalSequenceSpy.qml index 45d603b8..798b8b9c 100644 --- a/tests/auto/controls/data/ControlSpy.qml +++ b/tests/auto/controls/data/SignalSequenceSpy.qml @@ -42,6 +42,11 @@ import QtQuick 2.5 QtObject { property QtObject target: null + // We could just listen to all signals (try { signal.connect(/*...*/) } catch (e)) + // if it weren't for the fact the spy is often declared as a property of the control, + // which creates a "spyChanged" signal, which leads to an unexpected spyChanged signal + // emission. However, we don't know what the property will be called, so the signals + // have to be listed explicitly. property var signals: [] property var expectedSequence: [] property int sequenceIndex: 0 @@ -86,7 +91,7 @@ QtObject { return; if (sequenceIndex >= expectedSequence.length) { - console.warn("ControlSpy: Received unexpected signal '" + signalName + "' (none expected).") + console.warn("SignalSequenceSpy: Received unexpected signal '" + signalName + "' (none expected).") sequenceFailure = true return } @@ -104,7 +109,7 @@ QtObject { var expectedValues = expectedSignalData[1] for (var p in expectedValues) { if (target[p] != expectedValues[p]) { - console.warn("ControlSpy: Value mismatch for property '" + p + "' after '" + signalName + "' signal." + + console.warn("SignalSequenceSpy: Value mismatch for property '" + p + "' after '" + signalName + "' signal." + __mismatchValuesFormat(target[p], expectedValues[p])) sequenceFailure = true return @@ -114,7 +119,7 @@ QtObject { return } } - console.warn("ControlSpy: Received unexpected signal." + + console.warn("SignalSequenceSpy: Received unexpected signal (is \"" + expectedSignal + "\" listed in the signals array?)" + __mismatchValuesFormat(signalName, expectedSignal)) sequenceFailure = true } diff --git a/tests/auto/controls/data/TumblerDatePicker.qml b/tests/auto/controls/data/TumblerDatePicker.qml index a929a53f..18d7fb97 100644 --- a/tests/auto/controls/data/TumblerDatePicker.qml +++ b/tests/auto/controls/data/TumblerDatePicker.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 Row { id: datePicker diff --git a/tests/auto/controls/data/tst_abstractbutton.qml b/tests/auto/controls/data/tst_abstractbutton.qml index 4e635d63..ba5ee94c 100644 --- a/tests/auto/controls/data/tst_abstractbutton.qml +++ b/tests/auto/controls/data/tst_abstractbutton.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.templates 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -55,6 +55,11 @@ TestCase { AbstractButton {} } + Component { + id: item + Item { } + } + function test_text() { var control = button.createObject(testCase); verify(control); @@ -68,12 +73,34 @@ TestCase { control.destroy(); } - function test_highlighted() { + function test_baseline() { + var control = button.createObject(testCase, {padding: 6}) + verify(control) + compare(control.baselineOffset, 0) + control.contentItem = item.createObject(control, {baselineOffset: 12}) + compare(control.baselineOffset, 18) + control.destroy() + } + + function test_implicitSize() { var control = button.createObject(testCase) verify(control) - compare(control.highlighted, false) - control.highlighted = true - compare(control.highlighted, true) + compare(control.implicitWidth, 0) + compare(control.implicitHeight, 0) + + control.contentItem = item.createObject(control, {implicitWidth: 10, implicitHeight: 20}) + compare(control.implicitWidth, 10) + compare(control.implicitHeight, 20) + + control.background = item.createObject(control, {implicitWidth: 20, implicitHeight: 30}) + compare(control.implicitWidth, 20) + compare(control.implicitHeight, 30) + + control.padding = 100 + compare(control.implicitWidth, 210) + compare(control.implicitHeight, 220) + + control.destroy() } } diff --git a/tests/auto/controls/data/tst_busyindicator.qml b/tests/auto/controls/data/tst_busyindicator.qml index d4cb9d31..142ec70a 100644 --- a/tests/auto/controls/data/tst_busyindicator.qml +++ b/tests/auto/controls/data/tst_busyindicator.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase diff --git a/tests/auto/controls/data/tst_button.qml b/tests/auto/controls/data/tst_button.qml index 45fad8cb..9038f1d6 100644 --- a/tests/auto/controls/data/tst_button.qml +++ b/tests/auto/controls/data/tst_button.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -52,16 +52,21 @@ TestCase { Component { id: button - Button { - id: control + Button { } + } - property ControlSpy spy: ControlSpy { - target: control - signals: ["pressed", "released", "canceled", "clicked", "doubleClicked", "pressedChanged"] - } + Component { + id: signalSequenceSpy + SignalSequenceSpy { + signals: ["pressed", "released", "canceled", "clicked", "doubleClicked", "pressedChanged", "downChanged", "checkedChanged"] } } + Component { + id: signalSpy + SignalSpy { } + } + function test_text() { var control = button.createObject(testCase) verify(control) @@ -79,58 +84,70 @@ TestCase { var control = button.createObject(testCase) verify(control) + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + // click - control.spy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed"] + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed"] mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.pressed, true) - verify(control.spy.success) + verify(sequenceSpy.success) - control.spy.expectedSequence = [["pressedChanged", { "pressed": false }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], "released", "clicked"] mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) // release outside - control.spy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed"] + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed"] mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.pressed, true) - verify(control.spy.success) + verify(sequenceSpy.success) - control.spy.expectedSequence = [["pressedChanged", { "pressed": false }]] + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }]] mouseMove(control, control.width * 2, control.height * 2, 0, Qt.LeftButton) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) - control.spy.expectedSequence = [["canceled", { "pressed": false }]] + sequenceSpy.expectedSequence = [["canceled", { "pressed": false }]] mouseRelease(control, control.width * 2, control.height * 2, Qt.LeftButton) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) // right button - control.spy.expectedSequence = [] + sequenceSpy.expectedSequence = [] mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) compare(control.pressed, false) mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) // double click - control.spy.expectedSequence = [["pressedChanged", { "pressed": true }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], "pressed", ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], "released", "clicked", ["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], "pressed", "doubleClicked", ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], "released", "clicked"] mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton) - verify(control.spy.success) + verify(sequenceSpy.success) control.destroy() } @@ -142,22 +159,26 @@ TestCase { control.forceActiveFocus() verify(control.activeFocus) + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + // click - control.spy.expectedSequence = [["pressedChanged", { "pressed": true }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], "pressed", ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], "released", "clicked"] keyClick(Qt.Key_Space) - verify(control.spy.success) + verify(sequenceSpy.success) // no change - control.spy.expectedSequence = [] + sequenceSpy.expectedSequence = [] var keys = [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab] for (var i = 0; i < keys.length; ++i) { - control.spy.reset() + sequenceSpy.reset() keyClick(keys[i]) - verify(control.spy.success) + verify(sequenceSpy.success) } control.destroy() @@ -167,8 +188,6 @@ TestCase { return "actual event:" + JSON.stringify(actual) + ", expected event:" + JSON.stringify(expected) } - SignalSpy { id: clickSpy; signalName: "clicked" } - function test_autoRepeat() { var control = button.createObject(testCase) verify(control) @@ -180,47 +199,77 @@ TestCase { control.forceActiveFocus() verify(control.activeFocus) - clickSpy.target = control + var clickSpy = signalSpy.createObject(control, {target: control, signalName: "clicked"}) verify(clickSpy.valid) + var pressSpy = signalSpy.createObject(control, {target: control, signalName: "pressed"}) + verify(pressSpy.valid) + var releaseSpy = signalSpy.createObject(control, {target: control, signalName: "released"}) + verify(releaseSpy.valid) - var repeatCount = 2 - var repeatSequence = [["pressedChanged", { "pressed": true }], - "pressed", - "released", - "clicked", - "pressed", - "released", - "clicked", - "pressed"] - - // auto-repeat a couple of mouse clicks - control.spy.expectedSequence = repeatSequence + // auto-repeat mouse click mousePress(control) compare(control.pressed, true) - tryCompare(clickSpy, "count", repeatCount) - verify(control.spy.success) - - control.spy.expectedSequence = [["pressedChanged", { "pressed": false }], - "released", - "clicked"] + clickSpy.wait() + clickSpy.wait() + compare(pressSpy.count, clickSpy.count + 1) + compare(releaseSpy.count, clickSpy.count) mouseRelease(control) compare(control.pressed, false) - verify(control.spy.success) + compare(clickSpy.count, pressSpy.count) + compare(releaseSpy.count, pressSpy.count) - // auto-repeat a couple of key clicks clickSpy.clear() - control.spy.expectedSequence = repeatSequence + pressSpy.clear() + releaseSpy.clear() + + // auto-repeat key click keyPress(Qt.Key_Space) compare(control.pressed, true) - tryCompare(clickSpy, "count", repeatCount) - verify(control.spy.success) - - control.spy.expectedSequence = [["pressedChanged", { "pressed": false }], - "released", - "clicked"] + clickSpy.wait() + clickSpy.wait() + compare(pressSpy.count, clickSpy.count + 1) + compare(releaseSpy.count, clickSpy.count) keyRelease(Qt.Key_Space) compare(control.pressed, false) - verify(control.spy.success) + compare(clickSpy.count, pressSpy.count) + compare(releaseSpy.count, pressSpy.count) + + clickSpy.clear() + pressSpy.clear() + releaseSpy.clear() + + mousePress(control) + compare(control.pressed, true) + clickSpy.wait() + compare(pressSpy.count, clickSpy.count + 1) + compare(releaseSpy.count, clickSpy.count) + + // move inside during repeat -> continue repeat + mouseMove(control, control.width / 4, control.height / 4) + clickSpy.wait() + compare(pressSpy.count, clickSpy.count + 1) + compare(releaseSpy.count, clickSpy.count) + + clickSpy.clear() + pressSpy.clear() + releaseSpy.clear() + + // move outside during repeat -> stop repeat + mouseMove(control, -1, -1) + // NOTE: The following wait() is NOT a reliable way to test that the + // auto-repeat timer is not running, but there's no way dig into the + // private APIs from QML. If this test ever fails in the future, it + // indicates that the auto-repeat timer logic is broken. + wait(125) + compare(clickSpy.count, 0) + compare(pressSpy.count, 0) + compare(releaseSpy.count, 0) + + mouseRelease(control, -1, -1) + compare(control.pressed, false) + compare(clickSpy.count, 0) + compare(pressSpy.count, 0) + compare(releaseSpy.count, 0) control.destroy() } @@ -228,7 +277,65 @@ TestCase { function test_baseline() { var control = button.createObject(testCase) verify(control) - compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + control.destroy() + } + + function test_checkable() { + var control = button.createObject(testCase) + verify(control) + verify(control.hasOwnProperty("checkable")) + verify(!control.checkable) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + "released", + "clicked"] + mouseClick(control) + verify(!control.checked) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + ["checkedChanged", { "checked": true }], + "released", + "clicked"] + control.checkable = true + mouseClick(control) + verify(control.checked) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + ["checkedChanged", { "checked": false }], + "released", + "clicked"] + mouseClick(control) + verify(!control.checked) + verify(sequenceSpy.success) + + control.destroy() + } + + function test_highlighted() { + var control = button.createObject(testCase) + verify(control) + verify(!control.highlighted) + + control.highlighted = true + verify(control.highlighted) + control.destroy() } } diff --git a/tests/auto/controls/data/tst_buttongroup.qml b/tests/auto/controls/data/tst_buttongroup.qml index b640a868..754e4f0b 100644 --- a/tests/auto/controls/data/tst_buttongroup.qml +++ b/tests/auto/controls/data/tst_buttongroup.qml @@ -40,8 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 -import Qt.labs.templates 1.0 as T +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -56,30 +55,9 @@ TestCase { ButtonGroup { } } - SignalSpy { - id: checkedButtonSpy - signalName: "checkedButtonChanged" - } - - SignalSpy { - id: buttonsSpy - signalName: "buttonsChanged" - } - - function init() { - verify(!checkedButtonSpy.target) - compare(checkedButtonSpy.count, 0) - - verify(!buttonsSpy.target) - compare(buttonsSpy.count, 0) - } - - function cleanup() { - checkedButtonSpy.target = null - checkedButtonSpy.clear() - - buttonsSpy.target = null - buttonsSpy.clear() + Component { + id: signalSpy + SignalSpy { } } function test_null() { @@ -106,7 +84,7 @@ TestCase { var group = buttonGroup.createObject(testCase) verify(group) - checkedButtonSpy.target = group + var checkedButtonSpy = signalSpy.createObject(testCase, {target: group, signalName: "checkedButtonChanged"}) verify(checkedButtonSpy.valid) verify(!group.checkedButton) @@ -177,7 +155,7 @@ TestCase { var group = buttonGroup.createObject(testCase) verify(group) - buttonsSpy.target = group + var buttonsSpy = signalSpy.createObject(testCase, {target: group, signalName: "buttonsChanged"}) verify(buttonsSpy.valid) compare(group.buttons.length, 0) @@ -212,7 +190,7 @@ TestCase { group.buttons = [] compare(group.buttons.length, 0) - compare(group.checkedButton, null) + tryCompare(group, "checkedButton", null) compare(buttonsSpy.count, 5) group.destroy() @@ -302,7 +280,7 @@ TestCase { var group = buttonGroup.createObject(testCase) verify(group) - buttonsSpy.target = group + var buttonsSpy = signalSpy.createObject(testCase, {target: group, signalName: "buttonsChanged"}) verify(buttonsSpy.valid) var button1 = button.createObject(testCase, {objectName: "button1", checked: true}) @@ -321,4 +299,31 @@ TestCase { group.destroy() } + + Component { + id: repeater + Column { + id: column + property ButtonGroup group: ButtonGroup { buttons: column.children } + property alias repeater: r + Repeater { + id: r + model: 3 + delegate: RadioDelegate { + checked: index == 0 + objectName: index + } + } + } + } + + function test_repeater() { + var container = repeater.createObject(testCase) + verify(container) + + verify(container.group.checkedButton) + compare(container.group.checkedButton.objectName, "0") + + container.destroy() + } } diff --git a/tests/auto/controls/data/tst_checkbox.qml b/tests/auto/controls/data/tst_checkbox.qml index 4efc7223..044b0006 100644 --- a/tests/auto/controls/data/tst_checkbox.qml +++ b/tests/auto/controls/data/tst_checkbox.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -52,13 +52,13 @@ TestCase { Component { id: checkBox - CheckBox { - id: control + CheckBox { } + } - property ControlSpy spy: ControlSpy { - target: control - signals: ["pressed", "released", "canceled", "clicked", "pressedChanged", "checkedChanged", "checkStateChanged"] - } + Component { + id: signalSequenceSpy + SignalSequenceSpy { + signals: ["pressed", "released", "canceled", "clicked", "pressedChanged", "checkedChanged", "checkStateChanged"] } } @@ -79,24 +79,26 @@ TestCase { var control = checkBox.createObject(testCase) verify(control) - control.spy.expectedSequence = [] + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [] compare(control.checked, false) compare(control.checkState, Qt.Unchecked) - verify(control.spy.success) + verify(sequenceSpy.success) - control.spy.expectedSequence = [["checkStateChanged", { "checked": true, "checkState": Qt.Checked }], + sequenceSpy.expectedSequence = [["checkStateChanged", { "checked": true, "checkState": Qt.Checked }], ["checkedChanged", { "checked": true, "checkState": Qt.Checked }]] control.checked = true compare(control.checked, true) compare(control.checkState, Qt.Checked) - verify(control.spy.success) + verify(sequenceSpy.success) - control.spy.expectedSequence = [["checkStateChanged", { "checked": false, "checkState": Qt.Unchecked }], + sequenceSpy.expectedSequence = [["checkStateChanged", { "checked": false, "checkState": Qt.Unchecked }], ["checkedChanged", { "checked": false, "checkState": Qt.Unchecked }]] control.checked = false compare(control.checked, false) compare(control.checkState, Qt.Unchecked) - verify(control.spy.success) + verify(sequenceSpy.success) control.destroy() } @@ -105,24 +107,26 @@ TestCase { var control = checkBox.createObject(testCase) verify(control) - control.spy.expectedSequence = [] + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [] compare(control.checked, false) compare(control.checkState, Qt.Unchecked) - verify(control.spy.success) + verify(sequenceSpy.success) - control.spy.expectedSequence = [["checkStateChanged", { "checked": true, "checkState": Qt.Checked }], + sequenceSpy.expectedSequence = [["checkStateChanged", { "checked": true, "checkState": Qt.Checked }], ["checkedChanged", { "checked": true, "checkState": Qt.Checked }]] control.checkState = Qt.Checked compare(control.checked, true) compare(control.checkState, Qt.Checked) - verify(control.spy.success) + verify(sequenceSpy.success) - control.spy.expectedSequence = [["checkStateChanged", { "checked": false, "checkState": Qt.Unchecked }], + sequenceSpy.expectedSequence = [["checkStateChanged", { "checked": false, "checkState": Qt.Unchecked }], ["checkedChanged", { "checked": false, "checkState": Qt.Unchecked }]] control.checkState = Qt.Unchecked compare(control.checked, false) compare(control.checkState, Qt.Unchecked) - verify(control.spy.success) + verify(sequenceSpy.success) control.destroy() } @@ -131,67 +135,69 @@ TestCase { var control = checkBox.createObject(testCase) verify(control) + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + // check - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], "pressed"] mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.pressed, true) - verify(control.spy.success) + verify(sequenceSpy.success) - control.spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], - "released", - "clicked", + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], - ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }]] + ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + "released", + "clicked"] mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.checked, true) compare(control.checkState, Qt.Checked) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) // uncheck - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], "pressed"] mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.pressed, true) - verify(control.spy.success) - control.spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], - "released", - "clicked", + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], ["checkStateChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], - ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }]] + ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + "released", + "clicked"] mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.checked, false) compare(control.checkState, Qt.Unchecked) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) // release outside - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], "pressed"] mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.pressed, true) - verify(control.spy.success) - control.spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }]] + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }]] mouseMove(control, control.width * 2, control.height * 2, 0, Qt.LeftButton) compare(control.pressed, false) - verify(control.spy.success) - control.spy.expectedSequence = [["canceled", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }]] + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["canceled", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }]] mouseRelease(control, control.width * 2, control.height * 2, Qt.LeftButton) compare(control.checked, false) compare(control.checkState, Qt.Unchecked) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) // right button - control.spy.expectedSequence = [] + sequenceSpy.expectedSequence = [] mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) compare(control.pressed, false) mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) compare(control.checked, false) compare(control.checkState, Qt.Unchecked) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) control.destroy() } @@ -200,45 +206,47 @@ TestCase { var control = checkBox.createObject(testCase) verify(control) - control.spy.expectedSequence = [] + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [] control.forceActiveFocus() verify(control.activeFocus) - verify(control.spy.success) + verify(sequenceSpy.success) // check - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], "pressed", ["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], - "released", - "clicked", ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], - ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }]] + ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + "released", + "clicked"] keyClick(Qt.Key_Space) compare(control.checked, true) compare(control.checkState, Qt.Checked) - verify(control.spy.success) + verify(sequenceSpy.success) // uncheck - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], "pressed", ["pressedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], - "released", - "clicked", ["checkStateChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], - ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }]] + ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + "released", + "clicked"] keyClick(Qt.Key_Space) compare(control.checked, false) compare(control.checkState, Qt.Unchecked) - verify(control.spy.success) + verify(sequenceSpy.success) // no change - control.spy.expectedSequence = [] + sequenceSpy.expectedSequence = [] var keys = [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab] for (var i = 0; i < keys.length; ++i) { - control.spy.reset() + sequenceSpy.reset() keyClick(keys[i]) compare(control.checked, false) - verify(control.spy.success) + verify(sequenceSpy.success) } control.destroy() @@ -323,7 +331,9 @@ TestCase { function test_tristate() { var control = checkBox.createObject(testCase) - control.spy.expectedSequence = [] + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [] control.forceActiveFocus() verify(control.activeFocus) @@ -331,89 +341,89 @@ TestCase { compare(control.checked, false) compare(control.checkState, Qt.Unchecked) - control.spy.expectedSequence = [["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.PartiallyChecked }], + sequenceSpy.expectedSequence = [["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.PartiallyChecked }], ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.PartiallyChecked }]] control.checkState = Qt.PartiallyChecked compare(control.tristate, true) compare(control.checked, true) compare(control.checkState, Qt.PartiallyChecked) - verify(control.spy.success) + verify(sequenceSpy.success) // key: partial -> checked - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.PartiallyChecked }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.PartiallyChecked }], "pressed", ["pressedChanged", { "pressed": false, "checked": true, "checkState": Qt.PartiallyChecked }], + ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], "released", - "clicked", - ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }]] + "clicked"] keyClick(Qt.Key_Space) compare(control.checked, true) compare(control.checkState, Qt.Checked) - verify(control.spy.success) + verify(sequenceSpy.success) // key: checked -> unchecked - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], "pressed", ["pressedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], - "released", - "clicked", ["checkStateChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], - ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }]] + ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + "released", + "clicked"] keyClick(Qt.Key_Space) compare(control.checked, false) compare(control.checkState, Qt.Unchecked) - verify(control.spy.success) + verify(sequenceSpy.success) // key: unchecked -> partial - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], "pressed", ["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], - "released", - "clicked", ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.PartiallyChecked }], - ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.PartiallyChecked }]] + ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.PartiallyChecked }], + "released", + "clicked"] keyClick(Qt.Key_Space) compare(control.checked, true) compare(control.checkState, Qt.PartiallyChecked) - verify(control.spy.success) + verify(sequenceSpy.success) // mouse: partial -> checked - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.PartiallyChecked }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.PartiallyChecked }], "pressed", ["pressedChanged", { "pressed": false, "checked": true, "checkState": Qt.PartiallyChecked }], + ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], "released", - "clicked", - ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }]] + "clicked"] mouseClick(control) compare(control.checked, true) compare(control.checkState, Qt.Checked) - verify(control.spy.success) + verify(sequenceSpy.success) // mouse: checked -> unchecked - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], "pressed", ["pressedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], - "released", - "clicked", ["checkStateChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], - ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }]] + ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + "released", + "clicked"] mouseClick(control) compare(control.checked, false) compare(control.checkState, Qt.Unchecked) - verify(control.spy.success) + verify(sequenceSpy.success) // mouse: unchecked -> partial - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], "pressed", ["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], - "released", - "clicked", ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.PartiallyChecked }], - ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.PartiallyChecked }]] + ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.PartiallyChecked }], + "released", + "clicked"] mouseClick(control) compare(control.checked, true) compare(control.checkState, Qt.PartiallyChecked) - verify(control.spy.success) + verify(sequenceSpy.success) control.destroy() } @@ -421,7 +431,7 @@ TestCase { function test_baseline() { var control = checkBox.createObject(testCase) verify(control) - compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) control.destroy() } } diff --git a/tests/auto/controls/data/tst_checkdelegate.qml b/tests/auto/controls/data/tst_checkdelegate.qml new file mode 100644 index 00000000..a471b1d6 --- /dev/null +++ b/tests/auto/controls/data/tst_checkdelegate.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtTest 1.0 +import QtQuick.Controls 2.0 + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "CheckDelegate" + + Component { + id: checkDelegate + CheckDelegate {} + } + + // TODO: data-fy tst_checkbox (rename to tst_check?) so we don't duplicate its tests here? + + function test_defaults() { + var control = checkDelegate.createObject(testCase); + verify(control); + verify(!control.checked); + control.destroy(); + } + + function test_checked() { + var control = checkDelegate.createObject(testCase); + verify(control); + + mouseClick(control); + verify(control.checked); + + mouseClick(control); + verify(!control.checked); + + control.destroy(); + } + + function test_baseline() { + var control = checkDelegate.createObject(testCase); + verify(control); + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset); + control.destroy(); + } +} diff --git a/tests/auto/controls/data/tst_combobox.qml b/tests/auto/controls/data/tst_combobox.qml index 0a2c3101..607de2e8 100644 --- a/tests/auto/controls/data/tst_combobox.qml +++ b/tests/auto/controls/data/tst_combobox.qml @@ -39,35 +39,30 @@ ****************************************************************************/ import QtQuick 2.2 +import QtQuick.Window 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase width: 200 height: 200 + visible: true + when: windowShown name: "ComboBox" - ApplicationWindow { - id: window - visible: true - width: 400 - height: 400 - font.pixelSize: 25 - } - - SignalSpy { - id: activatedSpy - signalName: "activated" + Component { + id: signalSpy + SignalSpy { } } - SignalSpy { - id: highlightedSpy - signalName: "highlighted" + Component { + id: comboBox + ComboBox { } } Component { - id: comboBox + id: emptyBox ComboBox { delegate: ItemDelegate { width: popup.width @@ -75,29 +70,8 @@ TestCase { } } - function initTestCase() { - window.requestActivate() - tryCompare(window, "active", true) - } - - function init() { - verify(!activatedSpy.target) - compare(activatedSpy.count, 0) - - verify(!highlightedSpy.target) - compare(highlightedSpy.count, 0) - } - - function cleanup() { - activatedSpy.target = null - activatedSpy.clear() - - highlightedSpy.target = null - highlightedSpy.clear() - } - function test_defaults() { - var control = comboBox.createObject(window.contentItem) + var control = comboBox.createObject(testCase) verify(control) compare(control.count, 0) @@ -107,13 +81,14 @@ TestCase { compare(control.highlightedIndex, -1) compare(control.currentText, "") verify(control.delegate) + verify(control.indicator) verify(control.popup) control.destroy() } function test_array() { - var control = comboBox.createObject(window.contentItem) + var control = comboBox.createObject(testCase) verify(control) var items = [ "Banana", "Apple", "Coconut" ] @@ -139,7 +114,7 @@ TestCase { } function test_objects() { - var control = comboBox.createObject(window.contentItem) + var control = emptyBox.createObject(testCase) verify(control) var items = [ @@ -169,7 +144,7 @@ TestCase { } function test_number() { - var control = comboBox.createObject(window.contentItem) + var control = comboBox.createObject(testCase) verify(control) control.model = 10 @@ -202,7 +177,7 @@ TestCase { } function test_listModel() { - var control = comboBox.createObject(window.contentItem) + var control = comboBox.createObject(testCase) verify(control) control.model = listmodel @@ -246,7 +221,7 @@ TestCase { } function test_textRole(data) { - var control = comboBox.createObject(window.contentItem) + var control = emptyBox.createObject(testCase) verify(control) control.model = data.model @@ -274,7 +249,7 @@ TestCase { } function test_textAt() { - var control = comboBox.createObject(window.contentItem) + var control = comboBox.createObject(testCase) verify(control) control.model = ["Apple", "Orange", "Banana"] @@ -316,7 +291,7 @@ TestCase { } function test_find(data) { - var control = comboBox.createObject(window.contentItem) + var control = comboBox.createObject(testCase) verify(control) control.model = ["Banana", "banana", "Coconut", "Apple", "Cocomuffin"] @@ -326,14 +301,15 @@ TestCase { control.destroy() } + function test_arrowKeys() { - var control = comboBox.createObject(window.contentItem, {model: 3}) + var control = comboBox.createObject(testCase, {model: 3}) verify(control) - activatedSpy.target = control + var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"}) verify(activatedSpy.valid) - highlightedSpy.target = control + var highlightedSpy = signalSpy.createObject(control, {target: control, signalName: "highlighted"}) verify(highlightedSpy.valid) waitForRendering(control) @@ -450,29 +426,30 @@ TestCase { keyClick(Qt.Key_Space) compare(control.currentIndex, 1) - compare(control.highlightedIndex, -1) + tryCompare(control, "highlightedIndex", -1) control.destroy() } - function test_keys_data() { + function test_keys_space_enter_escape_data() { return [ { tag: "space-space", key1: Qt.Key_Space, key2: Qt.Key_Space, showPopup: true, showPress: true, hidePopup: true, hidePress: true }, { tag: "space-enter", key1: Qt.Key_Space, key2: Qt.Key_Enter, showPopup: true, showPress: true, hidePopup: true, hidePress: true }, { tag: "space-return", key1: Qt.Key_Space, key2: Qt.Key_Return, showPopup: true, showPress: true, hidePopup: true, hidePress: true }, { tag: "space-escape", key1: Qt.Key_Space, key2: Qt.Key_Escape, showPopup: true, showPress: true, hidePopup: true, hidePress: false }, { tag: "space-0", key1: Qt.Key_Space, key2: Qt.Key_0, showPopup: true, showPress: true, hidePopup: false, hidePress: false }, - { tag: "enter-enter", key1: Qt.Key_Enter, key2: Qt.Key_Enter, showPopup: false, showPress: false, hidePopup: true, hidePress: false }, { tag: "return-return", key1: Qt.Key_Return, key2: Qt.Key_Return, showPopup: false, showPress: false, hidePopup: true, hidePress: false }, - { tag: "escape-escape", key1: Qt.Key_Escape, key2: Qt.Key_Escape, showPopup: false, showPress: false, hidePopup: true, hidePress: false }, + { tag: "escape-escape", key1: Qt.Key_Escape, key2: Qt.Key_Escape, showPopup: false, showPress: false, hidePopup: true, hidePress: false } ] } - function test_keys(data) { - var control = comboBox.createObject(window.contentItem, {model: 3}) + function test_keys_space_enter_escape(data) { + var control = comboBox.createObject(testCase, {model: 3}) verify(control) + waitForRendering(control) + control.forceActiveFocus() verify(control.activeFocus) @@ -490,7 +467,6 @@ TestCase { // hide popup keyPress(data.key2) compare(control.pressed, data.hidePress) - compare(control.popup.visible, data.showPopup) keyRelease(data.key2) compare(control.pressed, false) tryCompare(control.popup, "visible", !data.hidePopup) @@ -498,8 +474,164 @@ TestCase { control.destroy() } + function test_keys_home_end() { + var control = comboBox.createObject(testCase, {model: 5}) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + compare(control.currentIndex, 0) + compare(control.highlightedIndex, -1) + + var activatedCount = 0 + var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"}) + verify(activatedSpy.valid) + + var highlightedCount = 0 + var highlightedSpy = signalSpy.createObject(control, {target: control, signalName: "highlighted"}) + verify(highlightedSpy.valid) + + var currentIndexCount = 0 + var currentIndexSpy = signalSpy.createObject(control, {target: control, signalName: "currentIndexChanged"}) + verify(currentIndexSpy.valid) + + var highlightedIndexCount = 0 + var highlightedIndexSpy = signalSpy.createObject(control, {target: control, signalName: "highlightedIndexChanged"}) + verify(highlightedIndexSpy.valid) + + // end (popup closed) + keyClick(Qt.Key_End) + compare(control.currentIndex, 4) + compare(currentIndexSpy.count, ++currentIndexCount) + + compare(control.highlightedIndex, -1) + compare(highlightedIndexSpy.count, highlightedIndexCount) + + compare(activatedSpy.count, ++activatedCount) + compare(activatedSpy.signalArguments[activatedCount-1][0], 4) + + compare(highlightedSpy.count, highlightedCount) + + // repeat (no changes/signals) + keyClick(Qt.Key_End) + compare(currentIndexSpy.count, currentIndexCount) + compare(highlightedIndexSpy.count, highlightedIndexCount) + compare(activatedSpy.count, activatedCount) + compare(highlightedSpy.count, highlightedCount) + + // home (popup closed) + keyClick(Qt.Key_Home) + compare(control.currentIndex, 0) + compare(currentIndexSpy.count, ++currentIndexCount) + + compare(control.highlightedIndex, -1) + compare(highlightedIndexSpy.count, highlightedIndexCount) + + compare(activatedSpy.count, ++activatedCount) + compare(activatedSpy.signalArguments[activatedCount-1][0], 0) + + compare(highlightedSpy.count, highlightedCount) + + // repeat (no changes/signals) + keyClick(Qt.Key_Home) + compare(currentIndexSpy.count, currentIndexCount) + compare(highlightedIndexSpy.count, highlightedIndexCount) + compare(activatedSpy.count, activatedCount) + compare(highlightedSpy.count, highlightedCount) + + control.popup.open() + compare(control.highlightedIndex, 0) + compare(highlightedIndexSpy.count, ++highlightedIndexCount) + compare(highlightedSpy.count, highlightedCount) + + // end (popup open) + keyClick(Qt.Key_End) + compare(control.currentIndex, 0) + compare(currentIndexSpy.count, currentIndexCount) + + compare(control.highlightedIndex, 4) + compare(highlightedIndexSpy.count, ++highlightedIndexCount) + + compare(activatedSpy.count, activatedCount) + + compare(highlightedSpy.count, ++highlightedCount) + compare(highlightedSpy.signalArguments[highlightedCount-1][0], 4) + + // repeat (no changes/signals) + keyClick(Qt.Key_End) + compare(currentIndexSpy.count, currentIndexCount) + compare(highlightedIndexSpy.count, highlightedIndexCount) + compare(activatedSpy.count, activatedCount) + compare(highlightedSpy.count, highlightedCount) + + // home (popup open) + keyClick(Qt.Key_Home) + compare(control.currentIndex, 0) + compare(currentIndexSpy.count, currentIndexCount) + + compare(control.highlightedIndex, 0) + compare(highlightedIndexSpy.count, ++highlightedIndexCount) + + compare(activatedSpy.count, activatedCount) + + compare(highlightedSpy.count, ++highlightedCount) + compare(highlightedSpy.signalArguments[highlightedCount-1][0], 0) + + // repeat (no changes/signals) + keyClick(Qt.Key_Home) + compare(currentIndexSpy.count, currentIndexCount) + compare(highlightedIndexSpy.count, highlightedIndexCount) + compare(activatedSpy.count, activatedCount) + compare(highlightedSpy.count, highlightedCount) + + control.destroy() + } + + function test_keySearch() { + var control = comboBox.createObject(testCase, {model: ["Banana", "Coco", "Coconut", "Apple", "Cocomuffin"]}) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + + compare(control.currentIndex, 0) + compare(control.currentText, "Banana") + + keyPress(Qt.Key_C) + compare(control.currentIndex, 1) + compare(control.currentText, "Coco") + + // no match + keyPress(Qt.Key_N) + compare(control.currentIndex, 1) + compare(control.currentText, "Coco") + + keyPress(Qt.Key_C) + compare(control.currentIndex, 2) + compare(control.currentText, "Coconut") + + keyPress(Qt.Key_C) + compare(control.currentIndex, 4) + compare(control.currentText, "Cocomuffin") + + // wrap + keyPress(Qt.Key_C) + compare(control.currentIndex, 1) + compare(control.currentText, "Coco") + + keyPress(Qt.Key_A) + compare(control.currentIndex, 3) + compare(control.currentText, "Apple") + + keyPress(Qt.Key_B) + compare(control.currentIndex, 0) + compare(control.currentText, "Banana") + + control.destroy() + } + function test_popup() { - var control = comboBox.createObject(window.contentItem, {model: 3}) + var control = comboBox.createObject(testCase, {model: 3}) verify(control) // show below @@ -517,7 +649,7 @@ TestCase { tryCompare(control.popup, "visible", false) // show above - control.y = window.height - control.height + control.y = control.Window.height - control.height mousePress(control) compare(control.pressed, true) compare(control.popup.visible, false) @@ -526,17 +658,25 @@ TestCase { compare(control.popup.visible, true) verify(control.popup.contentItem.y < control.y) + // follow the control outside the horizontal window bounds + control.x = -control.width / 2 + compare(control.x, -control.width / 2) + compare(control.popup.contentItem.parent.x, -control.width / 2) + control.x = testCase.width - control.width / 2 + compare(control.x, testCase.width - control.width / 2) + compare(control.popup.contentItem.parent.x, testCase.width - control.width / 2) + control.destroy() } function test_mouse() { - var control = comboBox.createObject(window.contentItem, {model: 3}) + var control = comboBox.createObject(testCase, {model: 3}) verify(control) - activatedSpy.target = control + var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"}) verify(activatedSpy.valid) - highlightedSpy.target = control + var highlightedSpy = signalSpy.createObject(control, {target: control, signalName: "highlighted"}) verify(highlightedSpy.valid) mouseClick(control) @@ -573,17 +713,18 @@ TestCase { } function test_focus() { - var control = comboBox.createObject(window.contentItem, {model: 3}) + var control = comboBox.createObject(testCase, {model: 3}) verify(control) + waitForRendering(control) + // click - gain focus - show popup mouseClick(control) verify(control.activeFocus) compare(control.popup.visible, true) // lose focus - hide popup - window.contentItem.forceActiveFocus() - verify(window.contentItem.activeFocus) + control.focus = false verify(!control.activeFocus) tryCompare(control.popup, "visible", false) @@ -648,11 +789,9 @@ TestCase { width: _combobox.width text: _combobox.textRole ? (Array.isArray(_combobox.model) ? modelData[_combobox.textRole] : model[_combobox.textRole]) : modelData objectName: "delegate" - checkable: true autoExclusive: true checked: _combobox.currentIndex === index highlighted: _combobox.highlightedIndex === index - pressed: highlighted && _combobox.pressed } } } @@ -672,52 +811,72 @@ TestCase { } function test_font() { // QTBUG_50984, QTBUG-51696 - var control = component.createObject(window.contentItem) + var control = component.createObject(testCase) verify(control) verify(control.button) verify(control.combobox) waitForRendering(control) - control.forceActiveFocus() - verify(control.activeFocus) - compare(control.font.pixelSize, 30) compare(control.button.font.pixelSize, 20) compare(control.combobox.font.pixelSize, 30) - verify(control.combobox.popup) - var popup = control.combobox.popup - popup.open() +// verify(control.combobox.popup) +// var popup = control.combobox.popup +// popup.open() - verify(popup.contentItem) +// verify(popup.contentItem) - var listview = popup.contentItem - verify(listview.contentItem) - waitForRendering(listview) +// var listview = popup.contentItem +// verify(listview.contentItem) +// waitForRendering(listview) - var idx1 = getChild(listview.contentItem, "delegate", -1) - compare(listview.contentItem.children[idx1].font.pixelSize, 25) - var idx2 = getChild(listview.contentItem, "delegate", idx1) - compare(listview.contentItem.children[idx2].font.pixelSize, 25) +// var idx1 = getChild(listview.contentItem, "delegate", -1) +// compare(listview.contentItem.children[idx1].font.pixelSize, 25) +// var idx2 = getChild(listview.contentItem, "delegate", idx1) +// compare(listview.contentItem.children[idx2].font.pixelSize, 25) - compare(listview.contentItem.children[idx1].font.pixelSize, 25) - compare(listview.contentItem.children[idx2].font.pixelSize, 25) +// compare(listview.contentItem.children[idx1].font.pixelSize, 25) +// compare(listview.contentItem.children[idx2].font.pixelSize, 25) control.font.pixelSize = control.font.pixelSize + 10 compare(control.combobox.font.pixelSize, 40) - waitForRendering(listview) - compare(listview.contentItem.children[idx1].font.pixelSize, 25) - compare(listview.contentItem.children[idx2].font.pixelSize, 25) +// waitForRendering(listview) +// compare(listview.contentItem.children[idx1].font.pixelSize, 25) +// compare(listview.contentItem.children[idx2].font.pixelSize, 25) control.combobox.font.pixelSize = control.combobox.font.pixelSize + 5 compare(control.combobox.font.pixelSize, 45) - waitForRendering(listview) +// waitForRendering(listview) + +// idx1 = getChild(listview.contentItem, "delegate", -1) +// compare(listview.contentItem.children[idx1].font.pixelSize, 25) +// idx2 = getChild(listview.contentItem, "delegate", idx1) +// compare(listview.contentItem.children[idx2].font.pixelSize, 25) + + control.destroy() + } + + function test_wheel() { + var control = comboBox.createObject(testCase, {model: 2, wheelEnabled: true}) + verify(control) + + var delta = 120 + + mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta) + compare(control.currentIndex, 1) + + // reached bounds -> no change + mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta) + compare(control.currentIndex, 1) + + mouseWheel(control, control.width / 2, control.height / 2, delta, delta) + compare(control.currentIndex, 0) - idx1 = getChild(listview.contentItem, "delegate", -1) - compare(listview.contentItem.children[idx1].font.pixelSize, 25) - idx2 = getChild(listview.contentItem, "delegate", idx1) - compare(listview.contentItem.children[idx2].font.pixelSize, 25) + // reached bounds -> no change + mouseWheel(control, control.width / 2, control.height / 2, delta, delta) + compare(control.currentIndex, 0) control.destroy() } @@ -733,7 +892,7 @@ TestCase { // QTBUG-51645 function test_activation(data) { - var control = comboBox.createObject(window.contentItem, {currentIndex: 1, model: ["Apple", "Orange", "Banana"]}) + var control = comboBox.createObject(testCase, {currentIndex: 1, model: ["Apple", "Orange", "Banana"]}) verify(control) waitForRendering(control) @@ -781,4 +940,110 @@ TestCase { loader.destroy() } + + // QTBUG-52615 + function test_currentIndex() { + var control = comboBox.createObject(testCase, {currentIndex: -1, model: 3}) + verify(control) + + compare(control.currentIndex, -1) + + control.destroy() + } + + ListModel { + id: resetmodel + ListElement { text: "First" } + ListElement { text: "Second" } + ListElement { text: "Third" } + } + + // QTBUG-54573 + function test_modelReset() { + var control = comboBox.createObject(testCase, {model: resetmodel}) + verify(control) + control.popup.open() + + var listview = control.popup.contentItem + verify(listview) + + waitForRendering(listview) + compare(listview.contentItem.children.length, resetmodel.count + 1) // + highlight item + + resetmodel.clear() + resetmodel.append({text: "Fourth"}) + resetmodel.append({text: "Fifth"}) + + waitForRendering(listview) + compare(listview.contentItem.children.length, resetmodel.count + 1) // + highlight item + + control.destroy() + } + + // QTBUG-55118 + function test_currentText() { + var control = comboBox.createObject(testCase, {model: listmodel}) + verify(control) + + compare(control.currentIndex, 0) + compare(control.currentText, "First") + + listmodel.setProperty(0, "text", "1st") + compare(control.currentText, "1st") + + control.currentIndex = 1 + compare(control.currentText, "Second") + + listmodel.setProperty(0, "text", "First") + compare(control.currentText, "Second") + + control.destroy() + } + + // QTBUG-55030 + function test_highlightRange() { + var control = comboBox.createObject(testCase, {model: 100}) + verify(control) + + control.currentIndex = 50 + compare(control.currentIndex, 50) + compare(control.highlightedIndex, -1) + + var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"}) + verify(openedSpy.valid) + + control.popup.open() + compare(control.highlightedIndex, 50) + tryCompare(openedSpy, "count", 1) + + var listview = control.popup.contentItem + verify(listview) + + var first = listview.itemAt(0, listview.contentY) + verify(first) + compare(first.text, "50") + + var closedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "closed"}) + verify(closedSpy.valid) + + control.popup.close() + tryCompare(closedSpy, "count", 1) + compare(control.highlightedIndex, -1) + + control.currentIndex = 99 + compare(control.currentIndex, 99) + compare(control.highlightedIndex, -1) + + control.popup.open() + compare(control.highlightedIndex, 99) + tryCompare(openedSpy, "count", 2) + + var last = listview.itemAt(0, listview.contentY + listview.height - 1) + verify(last) + compare(last.text, "99") + + openedSpy.target = null + closedSpy.target = null + control.destroy() + } } diff --git a/tests/auto/controls/data/tst_container.qml b/tests/auto/controls/data/tst_container.qml new file mode 100644 index 00000000..d1ff54e0 --- /dev/null +++ b/tests/auto/controls/data/tst_container.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtTest 1.0 +import QtQuick.Controls 2.0 +import QtQuick.Templates 2.0 as T + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "Container" + + Component { + id: container + Container { } + } + + Component { + id: rectangle + Rectangle { } + } + + function test_implicitSize() { + var control = container.createObject(testCase) + verify(control) + + compare(control.implicitWidth, 0) + compare(control.implicitHeight, 0) + + control.contentItem = rectangle.createObject(control, {implicitWidth: 10, implicitHeight: 20}) + compare(control.implicitWidth, 10) + compare(control.implicitHeight, 20) + + control.background = rectangle.createObject(control, {implicitWidth: 20, implicitHeight: 30}) + compare(control.implicitWidth, 20) + compare(control.implicitHeight, 30) + + control.padding = 100 + compare(control.implicitWidth, 210) + compare(control.implicitHeight, 220) + + control.destroy() + } +} diff --git a/tests/auto/controls/data/tst_control.qml b/tests/auto/controls/data/tst_control.qml index dd9abefe..3018498e 100644 --- a/tests/auto/controls/data/tst_control.qml +++ b/tests/auto/controls/data/tst_control.qml @@ -40,8 +40,8 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 -import Qt.labs.templates 1.0 as T +import QtQuick.Controls 2.0 +import QtQuick.Templates 2.0 as T TestCase { id: testCase @@ -53,27 +53,22 @@ TestCase { Component { id: component - T.Control { } + Control { } } Component { - id: signalSpy - SignalSpy { } + id: rectangle + Rectangle { } } - SignalSpy { - id: mirroredSpy - signalName: "mirroredChanged" - } - - SignalSpy { - id: availableWidthSpy - signalName: "availableWidthChanged" + Component { + id: button + T.Button { } } - SignalSpy { - id: availableHeightSpy - signalName: "availableHeightChanged" + Component { + id: signalSpy + SignalSpy { } } function test_padding() { @@ -140,10 +135,10 @@ TestCase { var control = component.createObject(testCase) verify(control) - availableWidthSpy.target = control - availableHeightSpy.target = control - + var availableWidthSpy = signalSpy.createObject(control, {target: control, signalName: "availableWidthChanged"}) verify(availableWidthSpy.valid) + + var availableHeightSpy = signalSpy.createObject(control, {target: control, signalName: "availableHeightChanged"}) verify(availableHeightSpy.valid) var availableWidthChanges = 0 @@ -212,7 +207,7 @@ TestCase { var control = component.createObject(testCase) verify(control) - mirroredSpy.target = control + var mirroredSpy = signalSpy.createObject(control, {target: control, signalName: "mirroredChanged"}) verify(mirroredSpy.valid) control.locale = Qt.locale("en_US") @@ -334,20 +329,10 @@ TestCase { compare(control2.font.family, "Arial") compare(control2.item2_2.font.family, control2.font.family) - compare(control2.item2_2.font.pointSize, control2.font.pointSize) - compare(control2.item2_2.font.weight, control2.font.weight) compare(control2.item2_3.font.family, control2.font.family) - compare(control2.item2_3.font.pointSize, control2.font.pointSize) - compare(control2.item2_3.font.weight, control2.font.weight) compare(control2.item2_4.font.family, control2.font.family) - compare(control2.item2_4.font.pointSize, control2.font.pointSize) - compare(control2.item2_4.font.weight, control2.font.weight) compare(control2.item2_5.font.family, control2.font.family) - compare(control2.item2_5.font.pointSize, control2.font.pointSize) - compare(control2.item2_5.font.weight, control2.font.weight) compare(control2.item2_6.font.family, control2.font.family) - compare(control2.item2_6.font.pointSize, control2.font.pointSize) - compare(control2.item2_6.font.weight, control2.font.weight) control2.font.pointSize = 48 compare(control2.item2_2.font.pointSize, 48) @@ -491,20 +476,10 @@ TestCase { compare(control3.font.family, "Arial") compare(control3.item3_3.font.family, control3.font.family) - compare(control3.item3_3.font.pointSize, control3.font.pointSize) - compare(control3.item3_3.font.weight, control3.font.weight) compare(control3.item3_4.font.family, control3.font.family) - compare(control3.item3_4.font.pointSize, control3.font.pointSize) - compare(control3.item3_4.font.weight, control3.font.weight) compare(control3.item3_5.font.family, control3.font.family) - compare(control3.item3_5.font.pointSize, control3.font.pointSize) - compare(control3.item3_5.font.weight, control3.font.weight) compare(control3.item3_7.font.family, control3.font.family) - compare(control3.item3_7.font.pointSize, control3.font.pointSize) - compare(control3.item3_7.font.weight, control3.font.weight) compare(control3.item3_8.font.family, control3.font.family) - compare(control3.item3_8.font.pointSize, control3.font.pointSize) - compare(control3.item3_8.font.weight, control3.font.weight) control3.font.pointSize = 48 compare(control3.item3_3.font.pointSize, 48) @@ -872,28 +847,68 @@ TestCase { compare(control.mirroredspy_5.count, 1) } - function test_focusReason_data() { + function test_hover_data() { return [ - { tag: "Control", qml: "import Qt.labs.controls 1.0; Control { }" }, - { tag: "TextField", qml: "import Qt.labs.controls 1.0; TextField { }" }, - { tag: "TextArea", qml: "import Qt.labs.controls 1.0; TextArea { }" }, - { tag: "SpinBox", qml: "import Qt.labs.controls 1.0; SpinBox { }" }, - { tag: "ComboBox", qml: "import Qt.labs.controls 1.0; ComboBox { }" } + { tag: "normal", target: component, pressed: false }, + { tag: "pressed", target: button, pressed: true } ] } - function test_focusReason(data) { - var control = Qt.createQmlObject(data.qml, testCase) + function test_hover(data) { + var control = data.target.createObject(testCase, {width: 100, height: 100}) verify(control) - compare(control.focusReason, Qt.OtherFocusReason) - control.forceActiveFocus(Qt.MouseFocusReason) - compare(control.activeFocus, true) - compare(control.focusReason, Qt.MouseFocusReason) + compare(control.hovered, false) + compare(control.hoverEnabled, false) + + mouseMove(control, control.width / 2, control.height / 2) + compare(control.hovered, false) + + control.hoverEnabled = true + + mouseMove(control, control.width / 2, control.height / 2) + compare(control.hovered, true) + + if (data.pressed) { + mousePress(control, control.width / 2, control.height / 2) + compare(control.hovered, true) + } + + mouseMove(control, -10, -10) + compare(control.hovered, false) + + if (data.pressed) { + mouseRelease(control, -10, control.height / 2) + compare(control.hovered, false) + } + + mouseMove(control, control.width / 2, control.height / 2) + compare(control.hovered, true) + + control.visible = false + compare(control.hovered, false) + + control.destroy() + } + + function test_implicitSize() { + var control = component.createObject(testCase) + verify(control) + + compare(control.implicitWidth, 0) + compare(control.implicitHeight, 0) + + control.contentItem = rectangle.createObject(control, {implicitWidth: 10, implicitHeight: 20}) + compare(control.implicitWidth, 10) + compare(control.implicitHeight, 20) + + control.background = rectangle.createObject(control, {implicitWidth: 20, implicitHeight: 30}) + compare(control.implicitWidth, 20) + compare(control.implicitHeight, 30) - testCase.forceActiveFocus(Qt.TabFocusReason) - compare(control.activeFocus, false) - compare(control.focusReason, Qt.TabFocusReason) + control.padding = 100 + compare(control.implicitWidth, 210) + compare(control.implicitHeight, 220) control.destroy() } diff --git a/tests/auto/controls/data/tst_dial.qml b/tests/auto/controls/data/tst_dial.qml index e0eba27e..a2ebf192 100644 --- a/tests/auto/controls/data/tst_dial.qml +++ b/tests/auto/controls/data/tst_dial.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -179,6 +179,8 @@ TestCase { } function test_dragging(data) { + dial.wrap = true; + verify(dial.wrap); dial.from = data.from; dial.to = data.to; @@ -210,6 +212,43 @@ TestCase { valueSpy.clear(); } + function test_nonWrapping() { + compare(dial.wrap, false); + dial.value = 0; + + // Ensure that dragging from bottom left to bottom right doesn't work. + var yPos = dial.height * 0.75; + mousePress(dial, dial.width * 0.25, yPos, Qt.LeftButton); + var positionAtPress = dial.position; + mouseMove(dial, dial.width * 0.5, yPos, Qt.LeftButton); + compare(dial.position, positionAtPress); + mouseMove(dial, dial.width * 0.75, yPos, Qt.LeftButton); + compare(dial.position, positionAtPress); + mouseRelease(dial, dial.width * 0.75, yPos, Qt.LeftButton); + compare(dial.position, positionAtPress); + + // Try the same thing, but a bit higher. + yPos = dial.height * 0.6; + mousePress(dial, dial.width * 0.25, yPos, Qt.LeftButton); + positionAtPress = dial.position; + mouseMove(dial, dial.width * 0.5, yPos, Qt.LeftButton); + compare(dial.position, positionAtPress); + mouseMove(dial, dial.width * 0.75, yPos, Qt.LeftButton); + compare(dial.position, positionAtPress); + mouseRelease(dial, dial.width * 0.75, yPos, Qt.LeftButton); + compare(dial.position, positionAtPress); + + // Going from below the center of the dial to above it should work (once it gets above the center). + mousePress(dial, dial.width * 0.25, dial.height * 0.75, Qt.LeftButton); + positionAtPress = dial.position; + mouseMove(dial, dial.width * 0.5, dial.height * 0.6, Qt.LeftButton); + compare(dial.position, positionAtPress); + mouseMove(dial, dial.width * 0.75, dial.height * 0.4, Qt.LeftButton); + verify(dial.position > positionAtPress); + mouseRelease(dial, dial.width * 0.75, dial.height * 0.3, Qt.LeftButton); + verify(dial.position > positionAtPress); + } + property Component focusTest: Component { FocusScope { signal receivedKeyPress @@ -282,4 +321,39 @@ TestCase { focusScope.destroy(); } + + function test_snapMode_data() { + return [ + { tag: "NoSnap", snapMode: Slider.NoSnap, from: 0, to: 2, values: [0, 0, 1], positions: [0, 0.5, 0.5] }, + { tag: "SnapAlways (0..2)", snapMode: Slider.SnapAlways, from: 0, to: 2, values: [0.0, 0.0, 1.0], positions: [0.0, 0.5, 0.5] }, + { tag: "SnapAlways (1..3)", snapMode: Slider.SnapAlways, from: 1, to: 3, values: [1.0, 1.0, 2.0], positions: [0.0, 0.5, 0.5] }, + { tag: "SnapAlways (-1..1)", snapMode: Slider.SnapAlways, from: -1, to: 1, values: [0.0, 0.0, 0.0], positions: [0.5, 0.5, 0.5] }, + { tag: "SnapAlways (1..-1)", snapMode: Slider.SnapAlways, from: 1, to: -1, values: [1.0, 1.0, 0.0], positions: [0.0, 0.5, 0.5] }, + { tag: "SnapOnRelease (0..2)", snapMode: Slider.SnapOnRelease, from: 0, to: 2, values: [0.0, 0.0, 1.0], positions: [0.0, 0.5, 0.5] }, + { tag: "SnapOnRelease (1..3)", snapMode: Slider.SnapOnRelease, from: 1, to: 3, values: [1.0, 1.0, 2.0], positions: [0.0, 0.5, 0.5] }, + { tag: "SnapOnRelease (-1..1)", snapMode: Slider.SnapOnRelease, from: -1, to: 1, values: [0.0, 0.0, 0.0], positions: [0.5, 0.5, 0.5] }, + { tag: "SnapOnRelease (1..-1)", snapMode: Slider.SnapOnRelease, from: 1, to: -1, values: [1.0, 1.0, 0.0], positions: [0.0, 0.5, 0.5] } + ] + } + + function test_snapMode(data) { + dial.snapMode = data.snapMode; + dial.from = data.from; + dial.to = data.to; + dial.stepSize = 0.2; + + var fuzz = 0.05; + + mousePress(dial, dial.width * 0.25, dial.height * 0.75); + compare(dial.value, data.values[0]); + compare(dial.position, data.positions[0]); + + mouseMove(dial, dial.width * 0.5, dial.height * 0.25); + fuzzyCompare(dial.value, data.values[1], fuzz); + fuzzyCompare(dial.position, data.positions[1], fuzz); + + mouseRelease(dial, dial.width * 0.5, dial.height * 0.25); + fuzzyCompare(dial.value, data.values[2], fuzz); + fuzzyCompare(dial.position, data.positions[2], fuzz); + } } diff --git a/tests/auto/controls/data/tst_drawer.qml b/tests/auto/controls/data/tst_drawer.qml index 28db11c8..021afdb2 100644 --- a/tests/auto/controls/data/tst_drawer.qml +++ b/tests/auto/controls/data/tst_drawer.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -57,10 +57,45 @@ TestCase { function test_defaults() { var control = drawer.createObject(testCase) - verify(!control.contentItem) compare(control.edge, Qt.LeftEdge) compare(control.position, 0.0) - verify(control.animation) + compare(control.dragMargin, Qt.styleHints.startDragDistance) + compare(control.parent, ApplicationWindow.overlay) + control.destroy() + } + + Component { + id: rectDrawer + + Drawer { + Rectangle { + width: 200 + height: 400 + color: "steelblue" + } + } + } + + function test_swipeVelocity() { + skip("QTBUG-52003"); + + var control = rectDrawer.createObject(testCase) + verify(control.contentItem) + compare(control.edge, Qt.LeftEdge) + compare(control.position, 0.0) + + var dragDistance = Math.max(20, Qt.styleHints.startDragDistance + 5) + var distance = dragDistance * 1.1 + if (distance >= control.width * 0.7) + skip("This test requires a startDragDistance that is less than the opening threshold of the drawer") + + mousePress(control, 0, 0, Qt.LeftButton) + mouseMove(control, distance, 0, Qt.LeftButton) + verify(control.position > 0) + tryCompare(control, "position", distance / control.contentItem.width) + mouseRelease(control, distance, 0, Qt.LeftButton) + tryCompare(control, "position", 1.0) + control.destroy() } } diff --git a/tests/auto/controls/data/tst_frame.qml b/tests/auto/controls/data/tst_frame.qml index d50a0dfc..a96397de 100644 --- a/tests/auto/controls/data/tst_frame.qml +++ b/tests/auto/controls/data/tst_frame.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase diff --git a/tests/auto/controls/data/tst_groupbox.qml b/tests/auto/controls/data/tst_groupbox.qml index 0f0e33fb..0181ea6b 100644 --- a/tests/auto/controls/data/tst_groupbox.qml +++ b/tests/auto/controls/data/tst_groupbox.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase diff --git a/tests/auto/controls/data/tst_itemdelegate.qml b/tests/auto/controls/data/tst_itemdelegate.qml index e2f78ac5..37b0db2a 100644 --- a/tests/auto/controls/data/tst_itemdelegate.qml +++ b/tests/auto/controls/data/tst_itemdelegate.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -58,7 +58,18 @@ TestCase { function test_baseline() { var control = itemDelegate.createObject(testCase) verify(control) - compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + control.destroy() + } + + function test_highlighted() { + var control = itemDelegate.createObject(testCase) + verify(control) + verify(!control.highlighted) + + control.highlighted = true + verify(control.highlighted) + control.destroy() } } diff --git a/tests/auto/controls/data/tst_label.qml b/tests/auto/controls/data/tst_label.qml index b93ca3c7..6dae0992 100644 --- a/tests/auto/controls/data/tst_label.qml +++ b/tests/auto/controls/data/tst_label.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase diff --git a/tests/auto/controls/data/tst_menuitem.qml b/tests/auto/controls/data/tst_menuitem.qml index 8581a43f..be0c0652 100644 --- a/tests/auto/controls/data/tst_menuitem.qml +++ b/tests/auto/controls/data/tst_menuitem.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -58,7 +58,37 @@ TestCase { function test_baseline() { var control = menuItem.createObject(testCase) verify(control) - compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + control.destroy() + } + + function test_checkable() { + var control = menuItem.createObject(testCase) + verify(control) + verify(control.hasOwnProperty("checkable")) + verify(!control.checkable) + + mouseClick(control) + verify(!control.checked) + + control.checkable = true + mouseClick(control) + verify(control.checked) + + mouseClick(control) + verify(!control.checked) + + control.destroy() + } + + function test_highlighted() { + var control = menuItem.createObject(testCase) + verify(control) + verify(!control.highlighted) + + control.highlighted = true + verify(control.highlighted) + control.destroy() } } diff --git a/tests/auto/controls/data/tst_page.qml b/tests/auto/controls/data/tst_page.qml index 60a1b2ef..bc7afa50 100644 --- a/tests/auto/controls/data/tst_page.qml +++ b/tests/auto/controls/data/tst_page.qml @@ -40,8 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 -import Qt.labs.templates 1.0 as T +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -113,6 +112,18 @@ TestCase { compare(control.contentItem.width, control.availableWidth) compare(control.contentItem.height, control.availableHeight - control.header.height - control.footer.height) + control.header.visible = false + compare(control.contentItem.x, control.leftPadding) + compare(control.contentItem.y, control.topPadding) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight - control.footer.height) + + control.footer.visible = false + compare(control.contentItem.x, control.leftPadding) + compare(control.contentItem.y, control.topPadding) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight) + control.destroy() } } diff --git a/tests/auto/controls/data/tst_pageindicator.qml b/tests/auto/controls/data/tst_pageindicator.qml index 11b2ec31..d1f1223a 100644 --- a/tests/auto/controls/data/tst_pageindicator.qml +++ b/tests/auto/controls/data/tst_pageindicator.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase diff --git a/tests/auto/controls/data/tst_pane.qml b/tests/auto/controls/data/tst_pane.qml index 1fdec049..a0b8a5c8 100644 --- a/tests/auto/controls/data/tst_pane.qml +++ b/tests/auto/controls/data/tst_pane.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase diff --git a/tests/auto/controls/data/tst_popup.qml b/tests/auto/controls/data/tst_popup.qml index 02635c9a..0ca8ce57 100644 --- a/tests/auto/controls/data/tst_popup.qml +++ b/tests/auto/controls/data/tst_popup.qml @@ -40,8 +40,8 @@ import QtQuick 2.4 import QtTest 1.0 -import Qt.labs.controls 1.0 -import Qt.labs.templates 1.0 as T +import QtQuick.Controls 2.0 +import QtQuick.Templates 2.0 as T TestCase { id: testCase @@ -72,55 +72,28 @@ TestCase { Rectangle { } } - SignalSpy { - id: availableWidthSpy - signalName: "availableWidthChanged" - } - - SignalSpy { - id: availableHeightSpy - signalName: "availableHeightChanged" - } - - SignalSpy { - id: paddingSpy - signalName: "paddingChanged" - } - - SignalSpy { - id: topPaddingSpy - signalName: "topPaddingChanged" - } - - SignalSpy { - id: leftPaddingSpy - signalName: "leftPaddingChanged" - } - - SignalSpy { - id: rightPaddingSpy - signalName: "rightPaddingChanged" - } - - SignalSpy { - id: bottomPaddingSpy - signalName: "bottomPaddingChanged" + Component { + id: signalSpy + SignalSpy { } } function test_padding() { var control = popupTemplate.createObject(testCase) verify(control) - paddingSpy.target = control - topPaddingSpy.target = control - leftPaddingSpy.target = control - rightPaddingSpy.target = control - bottomPaddingSpy.target = control - + var paddingSpy = signalSpy.createObject(testCase, {target: control, signalName: "paddingChanged"}) verify(paddingSpy.valid) + + var topPaddingSpy = signalSpy.createObject(testCase, {target: control, signalName: "topPaddingChanged"}) verify(topPaddingSpy.valid) + + var leftPaddingSpy = signalSpy.createObject(testCase, {target: control, signalName: "leftPaddingChanged"}) verify(leftPaddingSpy.valid) + + var rightPaddingSpy = signalSpy.createObject(testCase, {target: control, signalName: "rightPaddingChanged"}) verify(rightPaddingSpy.valid) + + var bottomPaddingSpy = signalSpy.createObject(testCase, {target: control, signalName: "bottomPaddingChanged"}) verify(bottomPaddingSpy.valid) var paddingChanges = 0 @@ -219,10 +192,10 @@ TestCase { var control = popupTemplate.createObject(testCase) verify(control) - availableWidthSpy.target = control - availableHeightSpy.target = control - + var availableWidthSpy = signalSpy.createObject(testCase, {target: control, signalName: "availableWidthChanged"}) verify(availableWidthSpy.valid) + + var availableHeightSpy = signalSpy.createObject(testCase, {target: control, signalName: "availableHeightChanged"}) verify(availableHeightSpy.valid) var availableWidthChanges = 0 @@ -287,6 +260,106 @@ TestCase { control.destroy() } + function test_position() { + var control = popupControl.createObject(testCase, {visible: true, leftMargin: 10, topMargin: 20, width: 100, height: 100}) + verify(control) + verify(control.visible) + + var xSpy = signalSpy.createObject(testCase, {target: control, signalName: "xChanged"}) + verify(xSpy.valid) + + var ySpy = signalSpy.createObject(testCase, {target: control, signalName: "yChanged"}) + verify(ySpy.valid) + + // moving outside margins does not trigger change notifiers + control.x = -100 + compare(control.x, 10) + compare(control.y, 20) + compare(xSpy.count, 0) + compare(ySpy.count, 0) + + control.y = -200 + compare(control.x, 10) + compare(control.y, 20) + compare(xSpy.count, 0) + compare(ySpy.count, 0) + + // moving within margins triggers change notifiers + control.x = 30 + compare(control.x, 30) + compare(control.y, 20) + compare(xSpy.count, 1) + compare(ySpy.count, 0) + + control.y = 40 + compare(control.x, 30) + compare(control.y, 40) + compare(xSpy.count, 1) + compare(ySpy.count, 1) + + // re-parent and reset the position + control.parent = rect.createObject(testCase, {color: "red", width: 100, height: 100}) + control.x = 0 + control.y = 0 + compare(xSpy.count, 2) + compare(ySpy.count, 2) + + // moving parent outside margins triggers change notifiers + control.parent.x = -50 + compare(control.x, 50 + control.leftMargin) + compare(xSpy.count, 3) + compare(ySpy.count, 2) + + control.parent.y = -60 + compare(control.y, 60 + control.topMargin) + compare(xSpy.count, 3) + compare(ySpy.count, 3) + + control.destroy() + } + + function test_resetSize() { + var control = popupControl.createObject(testCase, {visible: true, margins: 0}) + verify(control) + + control.width = control.implicitWidth = testCase.width + 10 + control.height = control.implicitHeight = testCase.height + 10 + + compare(control.width, testCase.width + 10) + compare(control.height, testCase.height + 10) + + control.width = undefined + control.height = undefined + compare(control.width, testCase.width) + compare(control.height, testCase.height) + + control.destroy() + } + + function test_negativeMargins() { + var control = popupControl.createObject(testCase, {implicitWidth: testCase.width, implicitHeight: testCase.height}) + verify(control) + + control.open() + verify(control.visible) + + compare(control.x, 0) + compare(control.y, 0) + + compare(control.margins, -1) + compare(control.topMargin, -1) + compare(control.leftMargin, -1) + compare(control.rightMargin, -1) + compare(control.bottomMargin, -1) + + control.x = -10 + control.y = -10 + compare(control.x, 0) + compare(control.y, 0) + + control.destroy() + } + function test_margins() { var control = popupControl.createObject(testCase, {width: 100, height: 100}) verify(control) @@ -344,6 +417,34 @@ TestCase { compare(control.contentItem.parent.x, testCase.width - control.width - 20) compare(control.contentItem.parent.y, testCase.height - control.height - 20) + control.margins = undefined + compare(control.margins, -1) + + control.bottomMargin = undefined + compare(control.bottomMargin, -1) + compare(control.contentItem.parent.x, testCase.width - control.width - 20) + compare(control.contentItem.parent.y, testCase.height) + + control.rightMargin = undefined + compare(control.rightMargin, -1) + compare(control.contentItem.parent.x, testCase.width) + compare(control.contentItem.parent.y, testCase.height) + + control.x = -testCase.width + control.y = -testCase.height + compare(control.contentItem.parent.x, 20) + compare(control.contentItem.parent.y, 20) + + control.topMargin = undefined + compare(control.topMargin, -1) + compare(control.contentItem.parent.x, 20) + compare(control.contentItem.parent.y, -testCase.height) + + control.leftMargin = undefined + compare(control.leftMargin, -1) + compare(control.contentItem.parent.x, -testCase.width) + compare(control.contentItem.parent.y, -testCase.height) + control.destroy() } @@ -409,38 +510,52 @@ TestCase { Component { id: component ApplicationWindow { + id: _window width: 400 height: 400 visible: true font.pixelSize: 40 property alias pane: _pane + property alias popup: _popup + property SignalSpy fontspy: SignalSpy { target: _window; signalName: "fontChanged" } Pane { id: _pane - property alias button: _button; - property alias popup: _popup; - property alias listview: _listview + property alias button: _button font.pixelSize: 30 + property SignalSpy fontspy: SignalSpy { target: _pane; signalName: "fontChanged" } Column { Button { id: _button text: "Button" font.pixelSize: 20 - + property SignalSpy fontspy: SignalSpy { target: _button; signalName: "fontChanged" } Popup { id: _popup + property alias button: _button2 + property alias listview: _listview y: _button.height implicitHeight: Math.min(396, _listview.contentHeight) - contentItem: ListView { - id: _listview - height: _button.height * 20 - model: 2 - delegate: Button { - objectName: "delegate" - width: _button.width - height: _button.height - text: "N: " + index - checkable: true - autoExclusive: true + property SignalSpy fontspy: SignalSpy { target: _popup; signalName: "fontChanged" } + contentItem: Column { + Button { + id: _button2 + text: "Button" + property SignalSpy fontspy: SignalSpy { target: _button2; signalName: "fontChanged" } + } + ListView { + id: _listview + height: _button.height * 20 + model: 2 + delegate: Button { + id: _button3 + objectName: "delegate" + width: _button.width + height: _button.height + text: "N: " + index + checkable: true + autoExclusive: true + property SignalSpy fontspy: SignalSpy { target: _button3; signalName: "fontChanged" } + } } } } @@ -454,43 +569,80 @@ TestCase { var window = component.createObject(testCase) verify(window) - window.requestActivate() - tryCompare(window, "active", true) - - var control = window.pane - waitForRendering(control) - - control.forceActiveFocus() - verify(control.activeFocus) - compare(window.font.pixelSize, 40) - compare(control.font.pixelSize, 30) - compare(control.button.font.pixelSize, 20) - - var popup = control.popup - popup.open() + compare(window.pane.font.pixelSize, 30) + compare(window.pane.button.font.pixelSize, 20) + compare(window.popup.font.pixelSize, 40) + compare(window.popup.button.font.pixelSize, 40) - verify(popup.contentItem) + var idx1 = getChild(window.popup.listview.contentItem, "delegate", -1) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 40) + var idx2 = getChild(window.popup.listview.contentItem, "delegate", idx1) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 40) - var listview = popup.contentItem - verify(listview.contentItem) - waitForRendering(listview) - - var idx1 = getChild(listview.contentItem, "delegate", -1) - compare(listview.contentItem.children[idx1].font.pixelSize, 40) - var idx2 = getChild(listview.contentItem, "delegate", idx1) - compare(listview.contentItem.children[idx2].font.pixelSize, 40) - - control.button.font.pixelSize = 30 - compare(control.button.font.pixelSize, 30) - waitForRendering(listview) - compare(listview.contentItem.children[idx1].font.pixelSize, 40) - compare(listview.contentItem.children[idx2].font.pixelSize, 40) + window.pane.button.font.pixelSize = 30 + compare(window.font.pixelSize, 40) + compare(window.fontspy.count, 0) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.fontspy.count, 0) + compare(window.pane.button.font.pixelSize, 30) + compare(window.pane.button.fontspy.count, 1) + compare(window.popup.font.pixelSize, 40) + compare(window.popup.fontspy.count, 0) + compare(window.popup.button.font.pixelSize, 40) + compare(window.popup.button.fontspy.count, 0) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 40) + compare(window.popup.listview.contentItem.children[idx1].fontspy.count, 0) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 40) + compare(window.popup.listview.contentItem.children[idx2].fontspy.count, 0) window.font.pixelSize = 50 - waitForRendering(listview) - compare(listview.contentItem.children[idx1].font.pixelSize, 50) - compare(listview.contentItem.children[idx2].font.pixelSize, 50) + compare(window.font.pixelSize, 50) + compare(window.fontspy.count, 1) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.fontspy.count, 0) + compare(window.pane.button.font.pixelSize, 30) + compare(window.pane.button.fontspy.count, 1) + compare(window.popup.font.pixelSize, 50) + compare(window.popup.fontspy.count, 1) + compare(window.popup.button.font.pixelSize, 50) + compare(window.popup.button.fontspy.count, 1) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 50) + compare(window.popup.listview.contentItem.children[idx1].fontspy.count, 1) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 50) + compare(window.popup.listview.contentItem.children[idx2].fontspy.count, 1) + + window.popup.button.font.pixelSize = 10 + compare(window.font.pixelSize, 50) + compare(window.fontspy.count, 1) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.fontspy.count, 0) + compare(window.pane.button.font.pixelSize, 30) + compare(window.pane.button.fontspy.count, 1) + compare(window.popup.font.pixelSize, 50) + compare(window.popup.fontspy.count, 1) + compare(window.popup.button.font.pixelSize, 10) + compare(window.popup.button.fontspy.count, 2) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 50) + compare(window.popup.listview.contentItem.children[idx1].fontspy.count, 1) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 50) + compare(window.popup.listview.contentItem.children[idx2].fontspy.count, 1) + + window.popup.font.pixelSize = 60 + compare(window.font.pixelSize, 50) + compare(window.fontspy.count, 1) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.fontspy.count, 0) + compare(window.pane.button.font.pixelSize, 30) + compare(window.pane.button.fontspy.count, 1) + compare(window.popup.font.pixelSize, 60) + compare(window.popup.fontspy.count, 2) + compare(window.popup.button.font.pixelSize, 10) + compare(window.popup.button.fontspy.count, 2) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 60) + compare(window.popup.listview.contentItem.children[idx1].fontspy.count, 2) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 60) + compare(window.popup.listview.contentItem.children[idx2].fontspy.count, 2) window.destroy() } @@ -511,16 +663,20 @@ TestCase { property alias button1: _button1 property alias button2: _button2 y: _button.height + locale: Qt.locale("fi_FI") implicitHeight: Math.min(396, _column.contentHeight) contentItem: Column { id: _column Button { id: _button1 text: "Button 1" + objectName: "1" } Button { id: _button2 text: "Button 2" + locale: Qt.locale("nb_NO") + objectName: "2" } } } @@ -533,26 +689,14 @@ TestCase { // test looking up natural locale from ancestors var control = localeComponent.createObject(applicationWindow.contentItem) verify(control) - verify(control.button) - verify(control.popup) - verify(control.popup.button1) - verify(control.popup.button2) - - applicationWindow.visible = true - waitForRendering(control) - - control.popup.open() - verify(control.popup.visible) - control.ApplicationWindow.window.locale = Qt.locale("fi_FI") - compare(control.ApplicationWindow.window.locale.name, "fi_FI") compare(control.locale.name, "en_US") compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "fi_FI") compare(control.popup.button1.locale.name, "fi_FI") - compare(control.popup.button2.locale.name, "fi_FI") + compare(control.popup.button2.locale.name, "nb_NO") control.ApplicationWindow.window.locale = undefined - applicationWindow.visible = false control.destroy() } @@ -588,6 +732,10 @@ TestCase { property alias button2: _button2 y: _button.height implicitHeight: Math.min(396, _column.contentHeight) + property SignalSpy localespy: SignalSpy { + target: _popup + signalName: "localeChanged" + } contentItem: Column { id: _column Button { @@ -625,21 +773,12 @@ TestCase { // test default locale and locale inheritance var control = localeChangeComponent.createObject(applicationWindow.contentItem) verify(control) - verify(control.button) - verify(control.popup) - verify(control.popup.button1) - verify(control.popup.button2) - - applicationWindow.visible = true - waitForRendering(control) - - control.popup.open() - verify(control.popup.visible) var defaultLocale = Qt.locale() compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) compare(control.locale.name, defaultLocale.name) compare(control.button.locale.name, defaultLocale.name) + compare(control.popup.locale.name, defaultLocale.name) compare(control.popup.button1.locale.name, defaultLocale.name) compare(control.popup.button2.locale.name, defaultLocale.name) @@ -647,10 +786,12 @@ TestCase { compare(control.ApplicationWindow.window.locale.name, "nb_NO") compare(control.locale.name, "nb_NO") compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "nb_NO") compare(control.popup.button1.locale.name, "nb_NO") compare(control.popup.button2.locale.name, "nb_NO") compare(control.localespy.count, 1) compare(control.button.localespy.count, 1) + compare(control.popup.localespy.count, 1) compare(control.popup.button1.localespy.count, 1) compare(control.popup.button2.localespy.count, 1) @@ -658,10 +799,12 @@ TestCase { compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) compare(control.locale.name, defaultLocale.name) compare(control.button.locale.name, defaultLocale.name) + compare(control.popup.locale.name, defaultLocale.name) compare(control.popup.button1.locale.name, defaultLocale.name) compare(control.popup.button2.locale.name, defaultLocale.name) compare(control.localespy.count, 2) compare(control.button.localespy.count, 2) + compare(control.popup.localespy.count, 2) compare(control.popup.button1.localespy.count, 2) compare(control.popup.button2.localespy.count, 2) @@ -669,12 +812,14 @@ TestCase { compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) compare(control.locale.name, "ar_EG") compare(control.button.locale.name, "ar_EG") + compare(control.popup.locale.name, defaultLocale.name) compare(control.popup.button1.locale.name, defaultLocale.name) compare(control.popup.button2.locale.name, defaultLocale.name) compare(control.localespy.count, 3) compare(control.mirrorspy.count, 1) compare(control.button.localespy.count, 3) compare(control.button.mirrorspy.count, 1) + compare(control.popup.localespy.count, 2) compare(control.popup.button1.localespy.count, 2) compare(control.popup.button2.localespy.count, 2) @@ -682,12 +827,14 @@ TestCase { compare(control.ApplicationWindow.window.locale.name, "ar_EG") compare(control.locale.name, "ar_EG") compare(control.button.locale.name, "ar_EG") + compare(control.popup.locale.name, "ar_EG") compare(control.popup.button1.locale.name, "ar_EG") compare(control.popup.button2.locale.name, "ar_EG") compare(control.localespy.count, 3) compare(control.mirrorspy.count, 1) compare(control.button.localespy.count, 3) compare(control.button.mirrorspy.count, 1) + compare(control.popup.localespy.count, 3) compare(control.popup.button1.localespy.count, 3) compare(control.popup.button1.mirrorspy.count, 1) compare(control.popup.button2.localespy.count, 3) @@ -697,12 +844,14 @@ TestCase { compare(control.ApplicationWindow.window.locale.name, "ar_EG") compare(control.locale.name, "ar_EG") compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "ar_EG") compare(control.popup.button1.locale.name, "ar_EG") compare(control.popup.button2.locale.name, "ar_EG") compare(control.localespy.count, 3) compare(control.mirrorspy.count, 1) compare(control.button.localespy.count, 4) compare(control.button.mirrorspy.count, 2) + compare(control.popup.localespy.count, 3) compare(control.popup.button1.localespy.count, 3) compare(control.popup.button2.localespy.count, 3) @@ -710,12 +859,14 @@ TestCase { compare(control.ApplicationWindow.window.locale.name, "ar_EG") compare(control.locale.name, "ar_EG") compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "ar_EG") compare(control.popup.button1.locale.name, "ar_EG") compare(control.popup.button2.locale.name, "ar_EG") compare(control.localespy.count, 3) compare(control.mirrorspy.count, 1) compare(control.button.localespy.count, 4) compare(control.button.mirrorspy.count, 2) + compare(control.popup.localespy.count, 3) compare(control.popup.button1.localespy.count, 3) compare(control.popup.button2.localespy.count, 3) @@ -723,33 +874,70 @@ TestCase { compare(control.ApplicationWindow.window.locale.name, "ar_EG") compare(control.locale.name, "ar_EG") compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "ar_EG") compare(control.popup.button1.locale.name, "nb_NO") compare(control.popup.button2.locale.name, "ar_EG") compare(control.localespy.count, 3) compare(control.mirrorspy.count, 1) compare(control.button.localespy.count, 4) compare(control.button.mirrorspy.count, 2) + compare(control.popup.localespy.count, 3) compare(control.popup.button1.localespy.count, 4) compare(control.popup.button1.mirrorspy.count, 2) compare(control.popup.button2.localespy.count, 3) compare(control.popup.button2.mirrorspy.count, 1) + control.popup.locale = Qt.locale("fi_FI") + compare(control.ApplicationWindow.window.locale.name, "ar_EG") + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "fi_FI") + compare(control.popup.button1.locale.name, "nb_NO") + compare(control.popup.button2.locale.name, "fi_FI") + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 1) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 2) + compare(control.popup.localespy.count, 4) + compare(control.popup.button1.localespy.count, 4) + compare(control.popup.button1.mirrorspy.count, 2) + compare(control.popup.button2.localespy.count, 4) + compare(control.popup.button2.mirrorspy.count, 2) + control.ApplicationWindow.window.locale = undefined compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) compare(control.locale.name, defaultLocale.name) compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "fi_FI") compare(control.popup.button1.locale.name, "nb_NO") - compare(control.popup.button2.locale.name, defaultLocale.name) + compare(control.popup.button2.locale.name, "fi_FI") compare(control.localespy.count, 4) compare(control.mirrorspy.count, 2) compare(control.button.localespy.count, 4) compare(control.button.mirrorspy.count, 2) + compare(control.popup.localespy.count, 4) compare(control.popup.button1.localespy.count, 4) compare(control.popup.button1.mirrorspy.count, 2) compare(control.popup.button2.localespy.count, 4) compare(control.popup.button2.mirrorspy.count, 2) - applicationWindow.visible = false + control.popup.locale = undefined + compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) + compare(control.locale.name, defaultLocale.name) + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, defaultLocale.name) + compare(control.popup.button1.locale.name, "nb_NO") + compare(control.popup.button2.locale.name, defaultLocale.name) + compare(control.localespy.count, 4) + compare(control.mirrorspy.count, 2) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 2) + compare(control.popup.localespy.count, 5) + compare(control.popup.button1.localespy.count, 4) + compare(control.popup.button1.mirrorspy.count, 2) + compare(control.popup.button2.localespy.count, 5) + compare(control.popup.button2.mirrorspy.count, 2) + control.destroy() } @@ -757,14 +945,66 @@ TestCase { var control = popupControl.createObject(testCase) verify(control) - control.width = 200 - control.height = 200 - control.open() waitForRendering(control.contentItem) - compare(control.width, 200) - compare(control.height, 200) + // implicit size of the content + control.contentItem.implicitWidth = 10 + compare(control.implicitWidth, 10 + control.leftPadding + control.rightPadding) + compare(control.width, control.implicitWidth) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + + control.contentItem.implicitHeight = 20 + compare(control.implicitHeight, 20 + control.topPadding + control.bottomPadding) + compare(control.height, control.implicitHeight) + compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding) + + // implicit size of the popup + control.implicitWidth = 30 + compare(control.implicitWidth, 30) + compare(control.width, 30) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + + control.implicitHeight = 40 + compare(control.implicitHeight, 40) + compare(control.height, 40) + compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding) + + // set explicit size + control.width = 50 + compare(control.implicitWidth, 30) + compare(control.width, 50) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + + control.height = 60 + compare(control.implicitHeight, 40) + compare(control.height, 60) + compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding) + + // reset explicit size + control.width = undefined + compare(control.implicitWidth, 30) + compare(control.width, 30) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + + control.height = undefined + compare(control.implicitHeight, 40) + compare(control.height, 40) + compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding) + + control.destroy() + } + + function test_visible() { + var control = popupTemplate.createObject(testCase, {visible: true}) + verify(control) + + // QTBUG-51989 + tryCompare(control, "visible", true) + + // QTBUG-55347 + control.parent = null + verify(!control.visible) control.destroy() } @@ -772,40 +1012,252 @@ TestCase { Component { id: overlayTest ApplicationWindow { - property alias popup1: popup1 - property alias popup2: popup2 + property alias firstDrawer: firstDrawer + property alias secondDrawer: secondDrawer + property alias modalPopup: modalPopup + property alias modelessPopup: modelessPopup + property alias plainPopup: plainPopup + property alias modalPopupWithoutDim: modalPopupWithoutDim visible: true + Drawer { + z: 0 + id: firstDrawer + } + Drawer { + z: 1 + id: secondDrawer + } Popup { - id: popup1 + id: modalPopup + z: 2 modal: true exit: Transition { PauseAnimation { duration: 200 } } } Popup { - id: popup2 + id: modelessPopup + z: 3 + dim: true + exit: Transition { PauseAnimation { duration: 200 } } + } + Popup { + id: plainPopup + z: 4 + enter: Transition { PauseAnimation { duration: 200 } } + exit: Transition { PauseAnimation { duration: 200 } } + } + Popup { + id: modalPopupWithoutDim + z: 5 + dim: false modal: true + exit: Transition { PauseAnimation { duration: 200 } } } } } + function indexOf(array, item) { + for (var idx = 0; idx < array.length; ++idx) { + if (item === array[idx]) + return idx; + } + return -1 + } + + function findOverlay(window, popup) { + var item = popup.contentItem.parent + var idx = indexOf(window.overlay.children, item) + return window.overlay.children[idx - 1] + } + function test_overlay() { var window = overlayTest.createObject(testCase) verify(window) window.requestActivate() tryCompare(window, "active", true) - compare(window.overlay.background.opacity, 0.0) - window.popup1.open() - compare(window.popup1.visible, true) - compare(window.popup2.visible, false) - tryCompare(window.overlay.background, "opacity", 1.0) + compare(window.overlay.children.length, 0) + + var firstOverlay = findOverlay(window, window.firstDrawer) + verify(!firstOverlay) + window.firstDrawer.open() + compare(window.overlay.children.length, 2) // 1 drawer + 1 overlay + firstOverlay = findOverlay(window, window.firstDrawer) + verify(firstOverlay) + compare(firstOverlay.z, window.firstDrawer.z) + compare(indexOf(window.overlay.children, firstOverlay), + indexOf(window.overlay.children, window.firstDrawer.contentItem.parent) - 1) + tryCompare(firstOverlay, "opacity", 1.0) + + var secondOverlay = findOverlay(window, window.secondDrawer) + verify(!secondOverlay) + window.secondDrawer.open() + compare(window.overlay.children.length, 4) // 2 drawers + 2 overlays + secondOverlay = findOverlay(window, window.secondDrawer) + verify(secondOverlay) + compare(secondOverlay.z, window.secondDrawer.z) + compare(indexOf(window.overlay.children, secondOverlay), + indexOf(window.overlay.children, window.secondDrawer.contentItem.parent) - 1) + tryCompare(secondOverlay, "opacity", 1.0) + + window.firstDrawer.close() + tryCompare(window.firstDrawer, "visible", false) + firstOverlay = findOverlay(window, window.firstDrawer) + verify(!firstOverlay) + compare(window.overlay.children.length, 2) // 1 drawer + 1 overlay + + window.secondDrawer.close() + tryCompare(window.secondDrawer, "visible", false) + secondOverlay = findOverlay(window, window.secondDrawer) + verify(!secondOverlay) + compare(window.overlay.children.length, 0) + + var modalOverlay = findOverlay(window, window.modalPopup) + verify(!modalOverlay) + window.modalPopup.open() + modalOverlay = findOverlay(window, window.modalPopup) + verify(modalOverlay) + compare(modalOverlay.z, window.modalPopup.z) + compare(window.modalPopup.visible, true) + tryCompare(modalOverlay, "opacity", 1.0) + compare(window.overlay.children.length, 2) // 1 popup + 1 overlay + + var modelessOverlay = findOverlay(window, window.modelessPopup) + verify(!modelessOverlay) + window.modelessPopup.open() + modelessOverlay = findOverlay(window, window.modelessPopup) + verify(modelessOverlay) + compare(modelessOverlay.z, window.modelessPopup.z) + compare(window.modelessPopup.visible, true) + tryCompare(modelessOverlay, "opacity", 1.0) + compare(window.overlay.children.length, 4) // 2 popups + 2 overlays + + window.modelessPopup.close() + tryCompare(window.modelessPopup, "visible", false) + modelessOverlay = findOverlay(window, window.modelessPopup) + verify(!modelessOverlay) + compare(window.overlay.children.length, 2) // 1 popup + 1 overlay + + compare(window.modalPopup.visible, true) + compare(modalOverlay.opacity, 1.0) + + window.modalPopup.close() + tryCompare(window.modalPopup, "visible", false) + modalOverlay = findOverlay(window, window.modalPopup) + verify(!modalOverlay) + compare(window.overlay.children.length, 0) + + window.plainPopup.open() + tryCompare(window.plainPopup, "visible", true) + compare(window.overlay.children.length, 1) // only popup added, no overlays involved + + window.plainPopup.modal = true + compare(window.overlay.children.length, 2) // overlay added + + window.plainPopup.close() + tryCompare(window.plainPopup, "visible", false) + compare(window.overlay.children.length, 0) // popup + overlay removed + + window.modalPopupWithoutDim.open() + tryCompare(window.modalPopupWithoutDim, "visible", true) + compare(window.overlay.children.length, 1) // only popup added, no overlays involved + + window.modalPopupWithoutDim.dim = true + compare(window.overlay.children.length, 2) // overlay added + + window.modalPopupWithoutDim.close() + tryCompare(window.modalPopupWithoutDim, "visible", false) + compare(window.overlay.children.length, 0) // popup + overlay removed + + window.destroy() + } + + function test_attached_applicationwindow() { + var control = popupControl.createObject(applicationWindow.contentItem) + verify(control) + + var child = rect.createObject(control.contentItem) + + compare(control.ApplicationWindow.window, applicationWindow) + compare(control.contentItem.ApplicationWindow.window, applicationWindow) + compare(child.ApplicationWindow.window, applicationWindow) + + control.parent = null + compare(control.ApplicationWindow.window, null) + compare(control.contentItem.ApplicationWindow.window, null) + compare(child.ApplicationWindow.window, null) - window.popup1.close() - window.popup2.open() - compare(window.popup2.visible, true) - tryCompare(window.popup1, "visible", false) - compare(window.overlay.background.opacity, 1.0) + control.destroy() + } + + SignalSpy { + id: openedSpy + signalName: "opened" + } + SignalSpy { + id: closedSpy + signalName: "closed" + } + + Component { + id: pausePopup + Popup { + enter: Transition { PauseAnimation { duration: 200 } } + exit: Transition { PauseAnimation { duration: 200 } } + } + } + + function test_openedClosed() { + var control = pausePopup.createObject(testCase) + verify(control) + + openedSpy.target = control + closedSpy.target = control + + control.open() + compare(control.visible, true) + compare(openedSpy.count, 0) + tryCompare(openedSpy, "count", 1) + compare(closedSpy.count, 0) + + control.close() + compare(openedSpy.count, 1) + compare(closedSpy.count, 0) + tryCompare(closedSpy, "count", 1) + compare(control.visible, false) + + control.destroy() + } + + Component { + id: xyBindingLoop + ApplicationWindow { + id: window + width: 360 + height: 360 + visible: true + property alias popup: popup + + Popup { + id: popup + visible: true + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + Label { + text: "Content" + anchors.fill: parent + } + } + } + } + + function test_xyBindingLoop() { + var window = xyBindingLoop.createObject(testCase) + var control = window.popup + waitForRendering(control.contentItem) + compare(control.x, (control.parent.width - control.width) / 2) + compare(control.y, (control.parent.height - control.height) / 2) window.destroy() } } diff --git a/tests/auto/controls/data/tst_progressbar.qml b/tests/auto/controls/data/tst_progressbar.qml index 1aea09f5..5603c280 100644 --- a/tests/auto/controls/data/tst_progressbar.qml +++ b/tests/auto/controls/data/tst_progressbar.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase diff --git a/tests/auto/controls/data/tst_radiobutton.qml b/tests/auto/controls/data/tst_radiobutton.qml index d4cdf0ad..e86b862e 100644 --- a/tests/auto/controls/data/tst_radiobutton.qml +++ b/tests/auto/controls/data/tst_radiobutton.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -52,13 +52,13 @@ TestCase { Component { id: radioButton - RadioButton { - id: control + RadioButton { } + } - property ControlSpy spy: ControlSpy { - target: control - signals: ["pressed", "released", "canceled", "clicked", "pressedChanged", "checkedChanged"] - } + Component { + id: signalSequenceSpy + SignalSequenceSpy { + signals: ["pressed", "released", "canceled", "clicked", "pressedChanged", "checkedChanged"] } } @@ -79,19 +79,21 @@ TestCase { var control = radioButton.createObject(testCase) verify(control) - control.spy.expectedSequence = [] // No change expected + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [] // No change expected compare(control.checked, false) - verify(control.spy.success) + verify(sequenceSpy.success) - control.spy.expectedSequence = ["checkedChanged"] + sequenceSpy.expectedSequence = ["checkedChanged"] control.checked = true compare(control.checked, true) - verify(control.spy.success) + verify(sequenceSpy.success) - control.spy.reset() + sequenceSpy.reset() control.checked = false compare(control.checked, false) - verify(control.spy.success) + verify(sequenceSpy.success) control.destroy() } @@ -100,59 +102,61 @@ TestCase { var control = radioButton.createObject(testCase) verify(control) + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + // check - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], "pressed"] mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.pressed, true) - verify(control.spy.success) - control.spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], "released", - "clicked", - ["checkedChanged", { "pressed": false, "checked": true }]] + "clicked"] mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.checked, true) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) // attempt uncheck - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], "pressed"] mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.pressed, true) - verify(control.spy.success) - control.spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], "released", "clicked"] mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.checked, true) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) // release outside - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], "pressed"] mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) compare(control.pressed, true) - verify(control.spy.success) - control.spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }]] + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }]] mouseMove(control, control.width * 2, control.height * 2, 0, Qt.LeftButton) compare(control.pressed, false) - control.spy.expectedSequence = [["canceled", { "pressed": false, "checked": true }]] + sequenceSpy.expectedSequence = [["canceled", { "pressed": false, "checked": true }]] mouseRelease(control, control.width * 2, control.height * 2, Qt.LeftButton) compare(control.checked, true) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) // right button - control.spy.expectedSequence = [] + sequenceSpy.expectedSequence = [] mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) compare(control.checked, true) compare(control.pressed, false) - verify(control.spy.success) + verify(sequenceSpy.success) control.destroy() } @@ -161,40 +165,42 @@ TestCase { var control = radioButton.createObject(testCase) verify(control) - control.spy.expectedSequence = [] + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [] control.forceActiveFocus() verify(control.activeFocus) - verify(control.spy.success) + verify(sequenceSpy.success) // check - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], "pressed", ["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], "released", - "clicked", - ["checkedChanged", { "pressed": false, "checked": true }]] + "clicked"] keyClick(Qt.Key_Space) compare(control.checked, true) - verify(control.spy.success) + verify(sequenceSpy.success) // attempt uncheck - control.spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], "pressed", ["pressedChanged", { "pressed": false, "checked": true }], "released", "clicked"] keyClick(Qt.Key_Space) compare(control.checked, true) - verify(control.spy.success) + verify(sequenceSpy.success) // no change - control.spy.expectedSequence = [] + sequenceSpy.expectedSequence = [] var keys = [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab] for (var i = 0; i < keys.length; ++i) { - control.spy.reset() + sequenceSpy.reset() keyClick(keys[i]) compare(control.checked, true) - verify(control.spy.success) + verify(sequenceSpy.success) } control.destroy() @@ -312,7 +318,7 @@ TestCase { function test_baseline() { var control = radioButton.createObject(testCase) verify(control) - compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) control.destroy() } } diff --git a/tests/auto/controls/data/tst_radiodelegate.qml b/tests/auto/controls/data/tst_radiodelegate.qml new file mode 100644 index 00000000..1a424a32 --- /dev/null +++ b/tests/auto/controls/data/tst_radiodelegate.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtTest 1.0 +import QtQuick.Controls 2.0 + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "RadioDelegate" + + Component { + id: radioDelegate + RadioDelegate {} + } + + // TODO: data-fy tst_radiobutton (rename to tst_radio?) so we don't duplicate its tests here? + + function test_defaults() { + var control = radioDelegate.createObject(testCase); + verify(control); + verify(!control.checked); + control.destroy(); + } + + function test_checked() { + var control = radioDelegate.createObject(testCase); + verify(control); + + mouseClick(control); + verify(control.checked); + + mouseClick(control); + verify(control.checked); + + control.destroy(); + } + + function test_baseline() { + var control = radioDelegate.createObject(testCase); + verify(control); + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset); + control.destroy(); + } +} diff --git a/tests/auto/controls/data/tst_rangeslider.qml b/tests/auto/controls/data/tst_rangeslider.qml index cc12b851..3167be0b 100644 --- a/tests/auto/controls/data/tst_rangeslider.qml +++ b/tests/auto/controls/data/tst_rangeslider.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -50,14 +50,9 @@ TestCase { when: windowShown name: "RangeSlider" - SignalSpy { - id: firstPressedSpy - signalName: "pressedChanged" - } - - SignalSpy { - id: secondPressedSpy - signalName: "pressedChanged" + Component { + id: signalSpy + SignalSpy { } } Component { @@ -84,21 +79,6 @@ TestCase { } } - function init() { - verify(!firstPressedSpy.target) - compare(firstPressedSpy.count, 0) - - verify(!secondPressedSpy.target) - compare(secondPressedSpy.count, 0) - } - - function cleanup() { - firstPressedSpy.target = null - firstPressedSpy.clear() - secondPressedSpy.target = null - secondPressedSpy.clear() - } - function test_defaults() { var control = sliderComponent.createObject(testCase) verify(control) @@ -303,10 +283,10 @@ TestCase { var control = sliderComponent.createObject(testCase, { orientation: data.orientation }) verify(control) - firstPressedSpy.target = control.first + var firstPressedSpy = signalSpy.createObject(control, {target: control.first, signalName: "pressedChanged"}) verify(firstPressedSpy.valid) - secondPressedSpy.target = control.second + var secondPressedSpy = signalSpy.createObject(control, {target: control.second, signalName: "pressedChanged"}) verify(secondPressedSpy.valid) mousePress(control, control.width * 0.25, control.height * 0.75, Qt.LeftButton) @@ -473,7 +453,7 @@ TestCase { var pressedCount = 0 - firstPressedSpy.target = control.first + var firstPressedSpy = signalSpy.createObject(control, {target: control.first, signalName: "pressedChanged"}) verify(firstPressedSpy.valid) control.first.handle.forceActiveFocus() @@ -511,7 +491,7 @@ TestCase { control.stepSize = 0.25 pressedCount = 0; - secondPressedSpy.target = control.second + var secondPressedSpy = signalSpy.createObject(control, {target: control.second, signalName: "pressedChanged"}) verify(secondPressedSpy.valid) control.second.handle.forceActiveFocus() @@ -553,7 +533,7 @@ TestCase { var control = sliderComponent.createObject(testCase, { leftPadding: 10, rightPadding: 20 }) verify(control) - firstPressedSpy.target = control.first + var firstPressedSpy = signalSpy.createObject(control, {target: control.first, signalName: "pressedChanged"}) verify(firstPressedSpy.valid) mousePress(control, control.first.handle.x, control.first.handle.y, Qt.LeftButton) @@ -621,18 +601,24 @@ TestCase { function test_snapMode_data() { return [ - { tag: "NoSnap", snapMode: Slider.NoSnap, values: [0, 0, 0.25], positions: [0, 0.1, 0.1] }, - { tag: "SnapAlways", snapMode: Slider.SnapAlways, values: [0, 0, 0.2], positions: [0, 0.1, 0.1] }, - { tag: "SnapOnRelease", snapMode: Slider.SnapOnRelease, values: [0, 0, 0.2], positions: [0, 0.1, 0.1] } + { tag: "NoSnap", snapMode: RangeSlider.NoSnap, from: 0, to: 2, values: [0, 0, 0.25], positions: [0, 0.1, 0.1] }, + { tag: "SnapAlways (0..2)", snapMode: RangeSlider.SnapAlways, from: 0, to: 2, values: [0.0, 0.0, 0.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapAlways (1..3)", snapMode: RangeSlider.SnapAlways, from: 1, to: 3, values: [1.0, 1.0, 1.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapAlways (-1..1)", snapMode: RangeSlider.SnapAlways, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [0.5, 0.1, 0.1] }, + { tag: "SnapAlways (1..-1)", snapMode: RangeSlider.SnapAlways, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [0.5, 0.1, 0.1] }, + { tag: "SnapOnRelease (0..2)", snapMode: RangeSlider.SnapOnRelease, from: 0, to: 2, values: [0.0, 0.0, 0.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapOnRelease (1..3)", snapMode: RangeSlider.SnapOnRelease, from: 1, to: 3, values: [1.0, 1.0, 1.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapOnRelease (-1..1)", snapMode: RangeSlider.SnapOnRelease, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [0.5, 0.1, 0.1] }, + { tag: "SnapOnRelease (1..-1)", snapMode: RangeSlider.SnapOnRelease, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [0.5, 0.1, 0.1] } ] } function test_snapMode(data) { - var control = sliderComponent.createObject(testCase, {snapMode: data.snapMode, from: 0, to: 2, stepSize: 0.2}) + var control = sliderComponent.createObject(testCase, {snapMode: data.snapMode, from: data.from, to: data.to, stepSize: 0.2}) verify(control) control.first.value = 0 - control.second.value = 2 + control.second.value = data.to function sliderCompare(left, right) { return Math.abs(left - right) < 0.05 diff --git a/tests/auto/controls/data/tst_scrollbar.qml b/tests/auto/controls/data/tst_scrollbar.qml index 6e021ccf..7c83cca9 100644 --- a/tests/auto/controls/data/tst_scrollbar.qml +++ b/tests/auto/controls/data/tst_scrollbar.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -50,9 +50,9 @@ TestCase { when: windowShown name: "ScrollBar" - SignalSpy{ - id: pressedSpy - signalName: "pressedChanged" + Component { + id: signalSpy + SignalSpy { } } Component { @@ -72,16 +72,6 @@ TestCase { } } - function init() { - verify(!pressedSpy.target) - compare(pressedSpy.count, 0) - } - - function cleanup() { - pressedSpy.target = null - pressedSpy.clear() - } - function test_attach() { var container = flickable.createObject(testCase) verify(container) @@ -151,6 +141,22 @@ TestCase { compare(horizontal.size, container.visibleArea.widthRatio) compare(horizontal.position, container.visibleArea.xPosition) + var oldY = vertical.y + var oldHeight = vertical.height + vertical.parent = testCase + vertical.y -= 10 + container.height += 10 + compare(vertical.y, oldY - 10) + compare(vertical.height, oldHeight) + + var oldX = horizontal.x + var oldWidth = horizontal.width + horizontal.parent = testCase + horizontal.x -= 10 + container.width += 10 + compare(horizontal.x, oldX - 10) + compare(horizontal.width, oldWidth) + container.destroy() } @@ -165,7 +171,7 @@ TestCase { var control = scrollBar.createObject(testCase, data.properties) verify(control) - pressedSpy.target = control + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) verify(pressedSpy.valid) mousePress(control, 0, 0, Qt.LeftButton) @@ -211,6 +217,69 @@ TestCase { control.destroy() } + function test_increase_decrease_data() { + return [ + { tag: "increase:active", increase: true, active: true }, + { tag: "decrease:active", increase: false, active: true }, + { tag: "increase:inactive", increase: true, active: false }, + { tag: "decrease:inactive", increase: false, active: false } + ] + } + + function test_increase_decrease(data) { + var control = scrollBar.createObject(testCase, {position: 0.5, active: data.active}) + verify(control) + + if (data.increase) { + control.increase() + compare(control.position, 0.6) + } else { + control.decrease() + compare(control.position, 0.4) + } + compare(control.active, data.active) + + control.destroy() + } + + function test_stepSize_data() { + return [ + { tag: "0.0", stepSize: 0.0 }, + { tag: "0.1", stepSize: 0.1 }, + { tag: "0.5", stepSize: 0.5 } + ] + } + + function test_stepSize(data) { + var control = scrollBar.createObject(testCase, {stepSize: data.stepSize}) + verify(control) + + compare(control.stepSize, data.stepSize) + compare(control.position, 0.0) + + var count = 10 + if (data.stepSize !== 0.0) + count = 1.0 / data.stepSize + + // increase until 1.0 + for (var i = 1; i <= count; ++i) { + control.increase() + compare(control.position, i / count) + } + control.increase() + compare(control.position, 1.0) + + // decrease until 0.0 + for (var d = count - 1; d >= 0; --d) { + control.decrease() + compare(control.position, d / count) + } + control.decrease() + compare(control.position, 0.0) + + control.destroy() + } + function test_padding_data() { return [ { tag: "horizontal", properties: { visible: true, orientation: Qt.Horizontal, width: testCase.width, leftPadding: testCase.width * 0.1 } }, @@ -225,5 +294,25 @@ TestCase { mouseRelease(control, control.leftPadding + control.availableWidth * 0.5, control.topPadding + control.availableHeight * 0.5, Qt.LeftButton) compare(control.position, 0.5) + + control.destroy() + } + + function test_warning() { + ignoreWarning(Qt.resolvedUrl("tst_scrollbar.qml") + ":45:1: QML TestCase: ScrollBar must be attached to a Flickable") + testCase.ScrollBar.vertical = null + } + + function test_mirrored() { + var container = flickable.createObject(testCase) + verify(container) + waitForRendering(container) + + container.ScrollBar.vertical = scrollBar.createObject(container) + compare(container.ScrollBar.vertical.x, container.width - container.ScrollBar.vertical.width) + container.ScrollBar.vertical.locale = Qt.locale("ar_EG") + compare(container.ScrollBar.vertical.x, 0) + + container.destroy() } } diff --git a/tests/auto/controls/data/tst_scrollindicator.qml b/tests/auto/controls/data/tst_scrollindicator.qml index 99eef833..f5e57e2d 100644 --- a/tests/auto/controls/data/tst_scrollindicator.qml +++ b/tests/auto/controls/data/tst_scrollindicator.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -136,6 +136,61 @@ TestCase { compare(horizontal.size, container.visibleArea.widthRatio) compare(horizontal.position, container.visibleArea.xPosition) + var oldY = vertical.y + var oldHeight = vertical.height + vertical.parent = testCase + vertical.y -= 10 + container.height += 10 + compare(vertical.y, oldY - 10) + compare(vertical.height, oldHeight) + + var oldX = horizontal.x + var oldWidth = horizontal.width + horizontal.parent = testCase + horizontal.x -= 10 + container.width += 10 + compare(horizontal.x, oldX - 10) + compare(horizontal.width, oldWidth) + + container.destroy() + } + + function test_warning() { + ignoreWarning(Qt.resolvedUrl("tst_scrollindicator.qml") + ":45:1: QML TestCase: ScrollIndicator must be attached to a Flickable") + testCase.ScrollIndicator.vertical = null + } + + function test_overshoot() { + var container = flickable.createObject(testCase) + verify(container) + waitForRendering(container) + + var vertical = scrollIndicator.createObject(container, {size: 0.5}) + container.ScrollIndicator.vertical = vertical + + var horizontal = scrollIndicator.createObject(container, {size: 0.5}) + container.ScrollIndicator.horizontal = horizontal + + // negative vertical overshoot (pos < 0) + vertical.position = -0.1 + compare(vertical.contentItem.y, vertical.topPadding) + compare(vertical.contentItem.height, 0.4 * vertical.availableHeight) + + // positive vertical overshoot (pos + size > 1) + vertical.position = 0.8 + compare(vertical.contentItem.y, vertical.topPadding + 0.8 * vertical.availableHeight) + compare(vertical.contentItem.height, 0.2 * vertical.availableHeight) + + // negative horizontal overshoot (pos < 0) + horizontal.position = -0.1 + compare(horizontal.contentItem.x, horizontal.leftPadding) + compare(horizontal.contentItem.width, 0.4 * horizontal.availableWidth) + + // positive horizontal overshoot (pos + size > 1) + horizontal.position = 0.8 + compare(horizontal.contentItem.x, horizontal.leftPadding + 0.8 * horizontal.availableWidth) + compare(horizontal.contentItem.width, 0.2 * horizontal.availableWidth) + container.destroy() } } diff --git a/tests/auto/controls/data/tst_slider.qml b/tests/auto/controls/data/tst_slider.qml index 53e2fb8f..4a698076 100644 --- a/tests/auto/controls/data/tst_slider.qml +++ b/tests/auto/controls/data/tst_slider.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -50,9 +50,9 @@ TestCase { when: windowShown name: "Slider" - SignalSpy{ - id: pressedSpy - signalName: "pressedChanged" + Component { + id: signalSpy + SignalSpy { } } Component { @@ -60,16 +60,6 @@ TestCase { Slider { } } - function init() { - verify(!pressedSpy.target) - compare(pressedSpy.count, 0) - } - - function cleanup() { - pressedSpy.target = null - pressedSpy.clear() - } - function test_defaults() { var control = slider.createObject(testCase) verify(control) @@ -232,7 +222,7 @@ TestCase { var control = slider.createObject(testCase, {orientation: data.orientation}) verify(control) - pressedSpy.target = control + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) verify(pressedSpy.valid) mousePress(control, 0, 0, Qt.LeftButton) @@ -286,6 +276,12 @@ TestCase { verify(control.value <= 0.25 && control.value >= 0.0) verify(control.position <= 0.25 && control.position >= 0.0) + // QTBUG-53846 + mouseClick(control, control.width * 0.5, control.height * 0.5, Qt.LeftButton) + compare(pressedSpy.count, 6) + compare(control.value, 0.5) + compare(control.position, 0.5) + control.destroy() } @@ -302,7 +298,7 @@ TestCase { var pressedCount = 0 - pressedSpy.target = control + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) verify(pressedSpy.valid) control.forceActiveFocus() @@ -374,7 +370,7 @@ TestCase { var control = slider.createObject(testCase, {leftPadding: 10, rightPadding: 20}) verify(control) - pressedSpy.target = control + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) verify(pressedSpy.valid) mousePress(control, 0, 0, Qt.LeftButton) @@ -442,14 +438,20 @@ TestCase { function test_snapMode_data() { return [ - { tag: "NoSnap", snapMode: Slider.NoSnap, values: [0, 0, 0.25], positions: [0, 0.1, 0.1] }, - { tag: "SnapAlways", snapMode: Slider.SnapAlways, values: [0, 0, 0.2], positions: [0, 0.1, 0.1] }, - { tag: "SnapOnRelease", snapMode: Slider.SnapOnRelease, values: [0, 0, 0.2], positions: [0, 0.1, 0.1] } + { tag: "NoSnap", snapMode: Slider.NoSnap, from: 0, to: 2, values: [0, 0, 0.25], positions: [0, 0.1, 0.1] }, + { tag: "SnapAlways (0..2)", snapMode: Slider.SnapAlways, from: 0, to: 2, values: [0.0, 0.0, 0.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapAlways (1..3)", snapMode: Slider.SnapAlways, from: 1, to: 3, values: [1.0, 1.0, 1.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapAlways (-1..1)", snapMode: Slider.SnapAlways, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [0.5, 0.1, 0.1] }, + { tag: "SnapAlways (1..-1)", snapMode: Slider.SnapAlways, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [0.5, 0.1, 0.1] }, + { tag: "SnapOnRelease (0..2)", snapMode: Slider.SnapOnRelease, from: 0, to: 2, values: [0.0, 0.0, 0.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapOnRelease (1..3)", snapMode: Slider.SnapOnRelease, from: 1, to: 3, values: [1.0, 1.0, 1.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapOnRelease (-1..1)", snapMode: Slider.SnapOnRelease, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [0.5, 0.1, 0.1] }, + { tag: "SnapOnRelease (1..-1)", snapMode: Slider.SnapOnRelease, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [0.5, 0.1, 0.1] } ] } function test_snapMode(data) { - var control = slider.createObject(testCase, {snapMode: data.snapMode, from: 0, to: 2, stepSize: 0.2}) + var control = slider.createObject(testCase, {snapMode: data.snapMode, from: data.from, to: data.to, stepSize: 0.2}) verify(control) function sliderCompare(left, right) { @@ -471,4 +473,51 @@ TestCase { control.destroy() } + + function test_wheel_data() { + return [ + { tag: "horizontal", orientation: Qt.Horizontal, dx: 120, dy: 0 }, + { tag: "vertical", orientation: Qt.Vertical, dx: 0, dy: 120 } + ] + } + + function test_wheel(data) { + var control = slider.createObject(testCase, {wheelEnabled: true, orientation: data.orientation}) + verify(control) + + compare(control.value, 0.0) + + mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(control.value, 0.1) + compare(control.position, 0.1) + + control.stepSize = 0.2 + + mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(control.value, 0.3) + compare(control.position, 0.3) + + control.stepSize = 10.0 + + mouseWheel(control, control.width / 2, control.height / 2, -data.dx, -data.dy) + compare(control.value, 0.0) + compare(control.position, 0.0) + + control.to = 10.0 + control.stepSize = 5.0 + + mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(control.value, 5.0) + compare(control.position, 0.5) + + mouseWheel(control, control.width / 2, control.height / 2, 0.5 * data.dx, 0.5 * data.dy) + compare(control.value, 7.5) + compare(control.position, 0.75) + + mouseWheel(control, control.width / 2, control.height / 2, -data.dx, -data.dy) + compare(control.value, 2.5) + compare(control.position, 0.25) + + control.destroy() + } } diff --git a/tests/auto/controls/data/tst_spinbox.qml b/tests/auto/controls/data/tst_spinbox.qml index cdea8b66..f2d8d3ef 100644 --- a/tests/auto/controls/data/tst_spinbox.qml +++ b/tests/auto/controls/data/tst_spinbox.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -50,14 +50,9 @@ TestCase { when: windowShown name: "SpinBox" - SignalSpy{ - id: upPressedSpy - signalName: "pressedChanged" - } - - SignalSpy{ - id: downPressedSpy - signalName: "pressedChanged" + Component { + id: signalSpy + SignalSpy { } } Component { @@ -65,20 +60,6 @@ TestCase { SpinBox { } } - function init() { - verify(!upPressedSpy.target) - compare(upPressedSpy.count, 0) - verify(!downPressedSpy.target) - compare(downPressedSpy.count, 0) - } - - function cleanup() { - upPressedSpy.target = null - upPressedSpy.clear() - downPressedSpy.target = null - downPressedSpy.clear() - } - function test_defaults() { var control = spinBox.createObject(testCase) verify(control) @@ -87,8 +68,11 @@ TestCase { compare(control.to, 99) compare(control.value, 0) compare(control.stepSize, 1) + compare(control.editable, false) compare(control.up.pressed, false) + compare(control.up.indicator.enabled, true) compare(control.down.pressed, false) + compare(control.down.indicator.enabled, false) control.destroy() } @@ -117,23 +101,40 @@ TestCase { compare(control.from, 0) compare(control.to, 100) compare(control.value, 50) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, true) control.value = 1000 compare(control.value, 100) + compare(control.up.indicator.enabled, false) + compare(control.down.indicator.enabled, true) control.value = -1 compare(control.value, 0) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, false) control.from = 25 compare(control.from, 25) compare(control.value, 25) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, false) control.to = 75 compare(control.to, 75) compare(control.value, 25) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, false) control.value = 50 compare(control.value, 50) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, true) + + control.to = 40; + compare(control.value, 40) + compare(control.up.indicator.enabled, false) + compare(control.down.indicator.enabled, true) control.destroy() } @@ -145,15 +146,23 @@ TestCase { compare(control.from, 100) compare(control.to, -100) compare(control.value, 0) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, true) control.value = 200 compare(control.value, 100) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, false) control.value = -200 compare(control.value, -100) + compare(control.up.indicator.enabled, false) + compare(control.down.indicator.enabled, true) control.value = 0 compare(control.value, 0) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, true) control.destroy() } @@ -162,9 +171,12 @@ TestCase { var control = spinBox.createObject(testCase, {stepSize: 50}) verify(control) - upPressedSpy.target = control.up + var upPressedSpy = signalSpy.createObject(control, {target: control.up, signalName: "pressedChanged"}) verify(upPressedSpy.valid) + var downPressedSpy = signalSpy.createObject(control, {target: control.down, signalName: "pressedChanged"}) + verify(downPressedSpy.valid) + mousePress(control.up.indicator) compare(upPressedSpy.count, 1) compare(control.up.pressed, true) @@ -179,9 +191,25 @@ TestCase { compare(control.down.pressed, false) compare(control.value, 50) - downPressedSpy.target = control.down - verify(downPressedSpy.valid) + // Disable the up button and try again. + control.value = control.to + compare(control.up.indicator.enabled, false) + mousePress(control.up.indicator) + compare(upPressedSpy.count, 2) + compare(control.up.pressed, false) + compare(downPressedSpy.count, 0) + compare(control.down.pressed, false) + compare(control.value, control.to) + + mouseRelease(control.up.indicator) + compare(upPressedSpy.count, 2) + compare(control.up.pressed, false) + compare(downPressedSpy.count, 0) + compare(control.down.pressed, false) + compare(control.value, control.to) + + control.value = 50; mousePress(control.down.indicator) compare(downPressedSpy.count, 1) compare(control.down.pressed, true) @@ -196,6 +224,24 @@ TestCase { compare(control.up.pressed, false) compare(control.value, 0) + // Disable the down button and try again. + control.value = control.from + compare(control.down.indicator.enabled, false) + + mousePress(control.down.indicator) + compare(downPressedSpy.count, 2) + compare(control.down.pressed, false) + compare(upPressedSpy.count, 2) + compare(control.up.pressed, false) + compare(control.value, control.from) + + mouseRelease(control.down.indicator) + compare(downPressedSpy.count, 2) + compare(control.down.pressed, false) + compare(upPressedSpy.count, 2) + compare(control.up.pressed, false) + compare(control.value, control.from) + control.destroy() } @@ -206,10 +252,10 @@ TestCase { var upPressedCount = 0 var downPressedCount = 0 - upPressedSpy.target = control.up + var upPressedSpy = signalSpy.createObject(control, {target: control.up, signalName: "pressedChanged"}) verify(upPressedSpy.valid) - downPressedSpy.target = control.down + var downPressedSpy = signalSpy.createObject(control, {target: control.down, signalName: "pressedChanged"}) verify(downPressedSpy.valid) control.forceActiveFocus() @@ -252,32 +298,42 @@ TestCase { compare(control.stepSize, 25) for (var d2 = 1; d2 <= 10; ++d2) { + var wasDownEnabled = control.value > control.from keyPress(Qt.Key_Down) - compare(control.down.pressed, true) + compare(control.down.pressed, wasDownEnabled) compare(control.up.pressed, false) - compare(downPressedSpy.count, ++downPressedCount) + if (wasDownEnabled) + ++downPressedCount + compare(downPressedSpy.count, downPressedCount) compare(control.value, Math.max(0, 50 - d2 * 25)) keyRelease(Qt.Key_Down) compare(control.down.pressed, false) compare(control.up.pressed, false) - compare(downPressedSpy.count, ++downPressedCount) + if (wasDownEnabled) + ++downPressedCount + compare(downPressedSpy.count, downPressedCount) } compare(control.value, 0) for (var i2 = 1; i2 <= 10; ++i2) { + var wasUpEnabled = control.value < control.to keyPress(Qt.Key_Up) - compare(control.up.pressed, true) + compare(control.up.pressed, wasUpEnabled) compare(control.down.pressed, false) - compare(upPressedSpy.count, ++upPressedCount) + if (wasUpEnabled) + ++upPressedCount + compare(upPressedSpy.count, upPressedCount) compare(control.value, Math.min(99, i2 * 25)) keyRelease(Qt.Key_Up) compare(control.down.pressed, false) compare(control.up.pressed, false) - compare(upPressedSpy.count, ++upPressedCount) + if (wasUpEnabled) + ++upPressedCount + compare(upPressedSpy.count, upPressedCount) } compare(control.value, 99) @@ -326,4 +382,175 @@ TestCase { control.destroy() } + + function test_editable() { + var control = spinBox.createObject(testCase) + verify(control) + + control.contentItem.forceActiveFocus() + compare(control.contentItem.activeFocus, true) + + compare(control.editable, false) + control.contentItem.selectAll() + keyClick(Qt.Key_5) + keyClick(Qt.Key_Return) + compare(control.value, 0) + + control.editable = true + compare(control.editable, true) + control.contentItem.selectAll() + keyClick(Qt.Key_5) + keyClick(Qt.Key_Return) + compare(control.value, 5) + + control.destroy() + } + + function test_wheel(data) { + var control = spinBox.createObject(testCase, {wheelEnabled: true}) + verify(control) + + var delta = 120 + + compare(control.value, 0) + + mouseWheel(control, control.width / 2, control.height / 2, delta, delta) + compare(control.value, 1) + + control.stepSize = 2 + + mouseWheel(control, control.width / 2, control.height / 2, delta, delta) + compare(control.value, 3) + + control.stepSize = 10 + + mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta) + compare(control.value, 0) + + control.stepSize = 5 + + mouseWheel(control, control.width / 2, control.height / 2, delta, delta) + compare(control.value, 5) + + mouseWheel(control, control.width / 2, control.height / 2, 0.5 * delta, 0.5 * delta) + compare(control.value, 8) + + mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta) + compare(control.value, 3) + + control.destroy() + } + + function test_initiallyDisabledIndicators_data() { + return [ + { tag: "down disabled", from: 0, value: 0, to: 99, upEnabled: true, downEnabled: false }, + { tag: "up disabled", from: 0, value: 99, to: 99, upEnabled: false, downEnabled: true }, + { tag: "inverted, down disabled", from: 99, value: 99, to: 0, upEnabled: true, downEnabled: false }, + { tag: "inverted, up disabled", from: 99, value: 0, to: 0, upEnabled: false, downEnabled: true } + ] + } + + function test_initiallyDisabledIndicators(data) { + var control = spinBox.createObject(testCase, { from: data.from, value: data.value, to: data.to }) + verify(control) + + compare(control.up.indicator.enabled, data.upEnabled) + compare(control.down.indicator.enabled, data.downEnabled) + + control.destroy() + } + + function test_valueFromText_data() { + return [ + { tag: "editable", editable: true }, + { tag: "non-editable", editable: false } + ] + } + + function test_valueFromText(data) { + var control = spinBox.createObject(testCase, {editable: data.editable}) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + + var valueFromTextCalls = 0 + control.valueFromText = function(text, locale) { + ++valueFromTextCalls + return Number.fromLocaleString(locale, text); + } + + keyClick(Qt.Key_Enter) + compare(valueFromTextCalls, data.editable ? 1 : 0) + + keyClick(Qt.Key_Return) + compare(valueFromTextCalls, data.editable ? 2 : 0) + + control.focus = false + compare(valueFromTextCalls, data.editable ? 3 : 0) + + control.destroy() + } + + function test_autoRepeat() { + var control = spinBox.createObject(testCase) + verify(control) + + compare(control.value, 0) + + var valueSpy = signalSpy.createObject(control, {target: control, signalName: "valueChanged"}) + verify(valueSpy.valid) + + var countBefore = 0 + + // repeat up + mousePress(control.up.indicator) + verify(control.up.pressed) + compare(valueSpy.count, 0) + valueSpy.wait() + valueSpy.wait() + countBefore = valueSpy.count + mouseRelease(control.up.indicator) + verify(!control.up.pressed) + compare(valueSpy.count, countBefore) + + valueSpy.clear() + + // repeat down + mousePress(control.down.indicator) + verify(control.down.pressed) + compare(valueSpy.count, 0) + valueSpy.wait() + valueSpy.wait() + countBefore = valueSpy.count + mouseRelease(control.down.indicator) + verify(!control.down.pressed) + compare(valueSpy.count, countBefore) + + mousePress(control.up.indicator) + verify(control.up.pressed) + valueSpy.wait() + + // move inside during repeat -> continue repeat (QTBUG-57085) + mouseMove(control.up.indicator, control.up.indicator.width / 4, control.up.indicator.height / 4) + verify(control.up.pressed) + valueSpy.wait() + + valueSpy.clear() + + // move outside during repeat -> stop repeat + mouseMove(control.up.indicator, -1, -1) + verify(!control.up.pressed) + // NOTE: The following wait() is NOT a reliable way to test that the + // auto-repeat timer is not running, but there's no way dig into the + // private APIs from QML. If this test ever fails in the future, it + // indicates that the auto-repeat timer logic is broken. + wait(125) + compare(valueSpy.count, 0) + + mouseRelease(control.up.indicator, -1, -1) + verify(!control.up.pressed) + + control.destroy() + } } diff --git a/tests/auto/controls/data/tst_stackview.qml b/tests/auto/controls/data/tst_stackview.qml index 762be4cc..28a22306 100644 --- a/tests/auto/controls/data/tst_stackview.qml +++ b/tests/auto/controls/data/tst_stackview.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -59,6 +59,11 @@ TestCase { StackView { } } + Component { + id: signalSpy + SignalSpy { } + } + function test_initialItem() { var control1 = stackView.createObject(testCase) verify(control1) @@ -87,18 +92,13 @@ TestCase { control.destroy() } - SignalSpy { - id: busySpy - signalName: "busyChanged" - } - function test_busy() { var control = stackView.createObject(testCase) verify(control) compare(control.busy, false) var busyCount = 0 - busySpy.target = control + var busySpy = signalSpy.createObject(control, {target: control, signalName: "busyChanged"}) verify(busySpy.valid) control.push(component) @@ -243,10 +243,31 @@ TestCase { verify(container) var control = stackView.createObject(container, {width: 100, height: 100}) verify(control) + container.width += 10 container.height += 20 compare(control.width, 100) compare(control.height, 100) + + control.push(item, StackView.Immediate) + compare(item.width, control.width) + compare(item.height, control.height) + + control.width = 200 + control.height = 200 + compare(item.width, control.width) + compare(item.height, control.height) + + control.clear() + control.width += 10 + control.height += 20 + verify(item.width !== control.width) + verify(item.height !== control.height) + + control.push(item, StackView.Immediate) + compare(item.width, control.width) + compare(item.height, control.height) + container.destroy() } @@ -385,6 +406,11 @@ TestCase { compare(control.depth, 6) compare(control.currentItem, items[5]) + // pop down to the current item + compare(control.pop(control.currentItem, StackView.Immediate), null) + compare(control.depth, 6) + compare(control.currentItem, items[5]) + // pop down to (but not including) the Nth item compare(control.pop(items[3], StackView.Immediate), items[5]) compare(control.depth, 4) @@ -835,4 +861,22 @@ TestCase { control.destroy() } + + // QTBUG-56158 + function test_repeatedPop() { + var control = stackView.createObject(testCase, {initialItem: component, width: testCase.width, height: testCase.height}) + verify(control) + + for (var i = 0; i < 12; ++i) + control.push(component) + tryCompare(control, "busy", false) + + while (control.depth > 1) { + control.pop() + wait(50) + } + tryCompare(control, "busy", false) + + control.destroy() + } } diff --git a/tests/auto/controls/data/tst_swipedelegate.qml b/tests/auto/controls/data/tst_swipedelegate.qml new file mode 100644 index 00000000..0404fd86 --- /dev/null +++ b/tests/auto/controls/data/tst_swipedelegate.qml @@ -0,0 +1,1076 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtTest 1.0 +import QtQuick.Controls 2.0 + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "SwipeDelegate" + + readonly property int dragDistance: Math.max(20, Qt.styleHints.startDragDistance + 5) + + Component { + id: backgroundFillComponent + SwipeDelegate { + background: Item { anchors.fill: parent } + } + } + + Component { + id: backgroundCenterInComponent + SwipeDelegate { + background: Item { anchors.centerIn: parent } + } + } + + Component { + id: backgroundLeftComponent + SwipeDelegate { + background: Item { anchors.left: parent.left } + } + } + + Component { + id: backgroundRightComponent + SwipeDelegate { + background: Item { anchors.right: parent.right } + } + } + + Component { + id: contentItemFillComponent + SwipeDelegate { + contentItem: Item { anchors.fill: parent } + } + } + + Component { + id: contentItemCenterInComponent + SwipeDelegate { + contentItem: Item { anchors.centerIn: parent } + } + } + + Component { + id: contentItemLeftComponent + SwipeDelegate { + contentItem: Item { anchors.left: parent.left } + } + } + + Component { + id: contentItemRightComponent + SwipeDelegate { + contentItem: Item { anchors.right: parent.right } + } + } + + function test_horizontalAnchors_data() { + return [ + { tag: "background, fill", component: backgroundFillComponent, itemName: "background", warningLocation: ":58:25" }, + { tag: "background, centerIn", component: backgroundCenterInComponent, itemName: "background", warningLocation: ":65:25" }, + { tag: "background, left", component: backgroundLeftComponent, itemName: "background", warningLocation: ":72:25" }, + { tag: "background, right", component: backgroundRightComponent, itemName: "background", warningLocation: ":79:25" }, + { tag: "contentItem, fill", component: contentItemFillComponent, itemName: "contentItem", warningLocation: ":86:26" }, + { tag: "contentItem, centerIn", component: contentItemCenterInComponent, itemName: "contentItem", warningLocation: ":93:26" }, + { tag: "contentItem, left", component: contentItemLeftComponent, itemName: "contentItem", warningLocation: ":100:26" }, + { tag: "contentItem, right", component: contentItemRightComponent, itemName: "contentItem", warningLocation: ":107:26" } + ]; + } + + function test_horizontalAnchors(data) { + var warningMessage = Qt.resolvedUrl("tst_swipedelegate.qml") + data.warningLocation + + ": QML : SwipeDelegate: cannot use horizontal anchors with " + data.itemName + "; unable to layout the item." + + ignoreWarning(warningMessage); + + var control = data.component.createObject(testCase); + verify(control.contentItem); + + control.destroy(); + } + + Component { + id: greenLeftComponent + + Rectangle { + objectName: "leftItem" + anchors.fill: parent + color: "green" + } + } + + Component { + id: redRightComponent + + Rectangle { + objectName: "rightItem" + anchors.fill: parent + color: "red" + } + } + + Component { + id: swipeDelegateComponent + + SwipeDelegate { + id: swipeDelegate + text: "SwipeDelegate" + width: 150 + swipe.left: greenLeftComponent + swipe.right: redRightComponent + } + } + + Component { + id: itemComponent + + Item {} + } + + // Assumes that the delegate is smaller than the width of the control. + function swipe(control, from, to) { + // Sanity check. + compare(control.swipe.position, from); + + var distance = (to - from) * control.width; + + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width / 2 + distance, control.height / 2, Qt.LeftButton); + mouseRelease(control, control.width / 2 + distance, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, to); + + if (control.swipe.position === -1.0) { + if (control.swipe.right) + verify(control.swipe.rightItem); + else if (control.swipe.behind) + verify(control.swipe.behindItem); + } else if (control.swipe.position === 1.0) { + if (control.swipe.left) + verify(control.swipe.leftItem); + else if (control.swipe.behind) + verify(control.swipe.behindItem); + } + } + + function test_settingDelegates() { + var control = swipeDelegateComponent.createObject(testCase); + verify(control); + + ignoreWarning(Qt.resolvedUrl("tst_swipedelegate.qml") + + ":159:9: QML SwipeDelegate: cannot set both behind and left/right properties") + control.swipe.behind = itemComponent; + + // Shouldn't be any warnings when unsetting delegates. + control.swipe.left = null; + compare(control.swipe.leftItem, null); + + // right is still set. + ignoreWarning(Qt.resolvedUrl("tst_swipedelegate.qml") + + ":159:9: QML SwipeDelegate: cannot set both behind and left/right properties") + control.swipe.behind = itemComponent; + + control.swipe.right = null; + compare(control.swipe.rightItem, null); + + control.swipe.behind = itemComponent; + + ignoreWarning(Qt.resolvedUrl("tst_swipedelegate.qml") + + ":159:9: QML SwipeDelegate: cannot set both behind and left/right properties") + control.swipe.left = itemComponent; + + ignoreWarning(Qt.resolvedUrl("tst_swipedelegate.qml") + + ":159:9: QML SwipeDelegate: cannot set both behind and left/right properties") + control.swipe.right = itemComponent; + + control.swipe.behind = null; + control.swipe.left = greenLeftComponent; + control.swipe.right = redRightComponent; + + // Test that the user is warned when attempting to set or unset left or + // right item while they're exposed. + // First, try the left item. + swipe(control, 0.0, 1.0); + + var oldLeft = control.swipe.left; + var oldLeftItem = control.swipe.leftItem; + ignoreWarning(Qt.resolvedUrl("tst_swipedelegate.qml") + + ":159:9: QML SwipeDelegate: left/right/behind properties may only be set when swipe.position is 0") + control.swipe.left = null; + compare(control.swipe.left, oldLeft); + compare(control.swipe.leftItem, oldLeftItem); + + // Try the same thing with the right item. + swipe(control, 1.0, -1.0); + + var oldRight = control.swipe.right; + var oldRightItem = control.swipe.rightItem; + ignoreWarning(Qt.resolvedUrl("tst_swipedelegate.qml") + + ":159:9: QML SwipeDelegate: left/right/behind properties may only be set when swipe.position is 0") + control.swipe.right = null; + compare(control.swipe.right, oldRight); + compare(control.swipe.rightItem, oldRightItem); + + // Return to the default position. + swipe(control, -1.0, 0.0); + + tryCompare(control.background, "x", 0, 1000); + + // Try the same thing with the behind item. + control.swipe.left = null; + verify(!control.swipe.left); + verify(!control.swipe.leftItem); + control.swipe.right = null; + verify(!control.swipe.right); + verify(!control.swipe.rightItem); + control.swipe.behind = greenLeftComponent; + verify(control.swipe.behind); + verify(!control.swipe.behindItem); + + swipe(control, 0.0, 1.0); + + var oldBehind = control.swipe.behind; + var oldBehindItem = control.swipe.behindItem; + ignoreWarning(Qt.resolvedUrl("tst_swipedelegate.qml") + + ":159:9: QML SwipeDelegate: left/right/behind properties may only be set when swipe.position is 0") + control.swipe.behind = null; + compare(control.swipe.behind, oldBehind); + compare(control.swipe.behindItem, oldBehindItem); + + control.destroy(); + } + + function test_defaults() { + var control = swipeDelegateComponent.createObject(testCase); + verify(control); + + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset); + compare(control.swipe.position, 0); + verify(!control.pressed); + verify(!control.swipe.complete); + + control.destroy(); + } + + SignalSequenceSpy { + id: mouseSignalSequenceSpy + signals: ["pressed", "released", "canceled", "clicked", "doubleClicked", "pressedChanged"] + } + + function test_swipe() { + var control = swipeDelegateComponent.createObject(testCase); + verify(control); + + var overDragDistance = Math.round(dragDistance * 1.1); + + mouseSignalSequenceSpy.target = control; + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed"]; + mousePress(control, control.width / 2, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 0.0); + verify(!control.swipe.complete); + verify(mouseSignalSequenceSpy.success); + verify(!control.swipe.leftItem); + verify(!control.swipe.rightItem); + + // Drag to the right so that leftItem is created and visible. + mouseMove(control, control.width / 2 + overDragDistance, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, overDragDistance / control.width); + verify(!control.swipe.complete); + verify(control.swipe.leftItem); + verify(control.swipe.leftItem.visible); + compare(control.swipe.leftItem.parent, control); + compare(control.swipe.leftItem.objectName, "leftItem"); + verify(!control.swipe.rightItem); + + // Go back to 0. + mouseMove(control, control.width / 2, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 0.0); + verify(!control.swipe.complete); + verify(control.swipe.leftItem); + verify(control.swipe.leftItem.visible); + compare(control.swipe.leftItem.parent, control); + compare(control.swipe.leftItem.objectName, "leftItem"); + verify(!control.swipe.rightItem); + + // Try the other direction. The right item should be created and visible, + // and the left item should be hidden. + mouseMove(control, control.width / 2 - overDragDistance, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, -overDragDistance / control.width); + verify(!control.swipe.complete); + verify(control.swipe.leftItem); + verify(!control.swipe.leftItem.visible); + verify(control.swipe.rightItem); + verify(control.swipe.rightItem.visible); + compare(control.swipe.rightItem.parent, control); + compare(control.swipe.rightItem.objectName, "rightItem"); + + // Now release outside the right edge of the control. + mouseMove(control, control.width * 1.1, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 0.6); + verify(!control.swipe.complete); + verify(control.swipe.leftItem); + verify(control.swipe.leftItem.visible); + verify(control.swipe.rightItem); + verify(!control.swipe.rightItem.visible); + + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "canceled"]; + mouseRelease(control, control.width / 2, control.height / 2); + verify(!control.pressed); + compare(control.swipe.position, 1.0); + verify(control.swipe.complete); + verify(mouseSignalSequenceSpy.success); + verify(control.swipe.leftItem); + verify(control.swipe.leftItem.visible); + verify(control.swipe.rightItem); + verify(!control.swipe.rightItem.visible); + tryCompare(control.contentItem, "x", control.width + control.leftPadding); + + // Swiping from the right and releasing early should return position to 1.0. + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed"]; + mousePress(control, control.width / 2, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 1.0); + // complete should still be true, because we haven't moved yet, and hence + // haven't started grabbing behind's mouse events. + verify(control.swipe.complete); + verify(mouseSignalSequenceSpy.success); + + mouseMove(control, control.width / 2 - overDragDistance, control.height / 2); + verify(control.pressed); + verify(!control.swipe.complete); + compare(control.swipe.position, 1.0 - overDragDistance / control.width); + + // Since we went over the drag distance, we should expect canceled() to be emitted. + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "canceled"]; + mouseRelease(control, control.width * 0.4, control.height / 2); + verify(!control.pressed); + compare(control.swipe.position, 1.0); + verify(control.swipe.complete); + verify(mouseSignalSequenceSpy.success); + tryCompare(control.contentItem, "x", control.width + control.leftPadding); + + // Swiping from the right and releasing should return contents to default position. + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed"]; + mousePress(control, control.width / 2, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 1.0); + verify(control.swipe.complete); + verify(mouseSignalSequenceSpy.success); + + mouseMove(control, control.width * -0.1, control.height / 2); + verify(control.pressed); + verify(!control.swipe.complete); + compare(control.swipe.position, 0.4); + + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "canceled"]; + mouseRelease(control, control.width * -0.1, control.height / 2); + verify(!control.pressed); + compare(control.swipe.position, 0.0); + verify(!control.swipe.complete); + verify(mouseSignalSequenceSpy.success); + tryCompare(control.contentItem, "x", control.leftPadding); + + control.destroy(); + } + + function test_swipeVelocity_data() { + return [ + { tag: "positive velocity", direction: 1 }, + { tag: "negative velocity", direction: -1 } + ]; + } + + function test_swipeVelocity(data) { + skip("QTBUG-52003"); + + var control = swipeDelegateComponent.createObject(testCase); + verify(control); + + var distance = Math.round(dragDistance * 1.1); + if (distance >= control.width / 2) + skip("This test requires a startDragDistance that is less than half the width of the control"); + + distance *= data.direction; + + mouseSignalSequenceSpy.target = control; + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed"]; + mousePress(control, control.width / 2, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 0.0); + verify(!control.swipe.complete); + verify(mouseSignalSequenceSpy.success); + verify(!control.swipe.leftItem); + verify(!control.swipe.rightItem); + + // Swipe quickly to the side over a distance that is longer than the drag threshold, + // quicker than the expose velocity threshold, but shorter than the halfway mark. + mouseMove(control, control.width / 2 + distance, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, distance / control.width); + verify(control.swipe.position < 0.5); + verify(!control.swipe.complete); + + var expectedVisibleItem; + var expectedVisibleObjectName; + var expectedHiddenItem; + var expectedContentItemX; + if (distance > 0) { + expectedVisibleObjectName = "leftItem"; + expectedVisibleItem = control.swipe.leftItem; + expectedHiddenItem = control.swipe.rightItem; + expectedContentItemX = control.width + control.leftPadding; + } else { + expectedVisibleObjectName = "rightItem"; + expectedVisibleItem = control.swipe.rightItem; + expectedHiddenItem = control.swipe.leftItem; + expectedContentItemX = -control.width + control.leftPadding; + } + verify(expectedVisibleItem); + verify(expectedVisibleItem.visible); + compare(expectedVisibleItem.parent, control); + compare(expectedVisibleItem.objectName, expectedVisibleObjectName); + verify(!expectedHiddenItem); + + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "released", "clicked"]; + // Add a delay to ensure that the release event doesn't happen too quickly, + // and hence that the second timestamp isn't zero (can happen with e.g. release builds). + mouseRelease(control, control.width / 2 + distance, control.height / 2, Qt.LeftButton, Qt.NoModifier, 30); + verify(!control.pressed); + compare(control.swipe.position, data.direction); + verify(control.swipe.complete); + verify(mouseSignalSequenceSpy.success); + verify(expectedVisibleItem); + verify(expectedVisibleItem.visible); + verify(!expectedHiddenItem); + tryCompare(control.contentItem, "x", expectedContentItemX); + + control.destroy(); + } + + Component { + id: swipeDelegateWithButtonComponent + SwipeDelegate { + text: "SwipeDelegate" + width: 150 + swipe.right: Button { + width: parent.width + height: parent.height + text: "Boo!" + } + } + } + + Component { + id: signalSpyComponent + + SignalSpy {} + } + + function test_eventsToLeftAndRight() { + var control = swipeDelegateWithButtonComponent.createObject(testCase); + verify(control); + + // The button should be pressed instead of the SwipeDelegate. + mouseDrag(control, control.width / 2, control.height / 2, -control.width, 0); + // Mouse has been released by this stage. + verify(!control.pressed); + compare(control.swipe.position, -1.0); + verify(control.swipe.rightItem); + verify(control.swipe.rightItem.visible); + compare(control.swipe.rightItem.parent, control); + + var buttonPressedSpy = signalSpyComponent.createObject(control, { target: control.swipe.rightItem, signalName: "pressed" }); + verify(buttonPressedSpy); + verify(buttonPressedSpy.valid); + var buttonReleasedSpy = signalSpyComponent.createObject(control, { target: control.swipe.rightItem, signalName: "released" }); + verify(buttonReleasedSpy); + verify(buttonReleasedSpy.valid); + var buttonClickedSpy = signalSpyComponent.createObject(control, { target: control.swipe.rightItem, signalName: "clicked" }); + verify(buttonClickedSpy); + verify(buttonClickedSpy.valid); + + // Now press the button. + mousePress(control, control.width / 2, control.height / 2); + verify(!control.pressed); + var button = control.swipe.rightItem; + verify(button.pressed); + compare(buttonPressedSpy.count, 1); + compare(buttonReleasedSpy.count, 0); + compare(buttonClickedSpy.count, 0); + + mouseRelease(control, control.width / 2, control.height / 2); + verify(!button.pressed); + compare(buttonPressedSpy.count, 1); + compare(buttonReleasedSpy.count, 1); + compare(buttonClickedSpy.count, 1); + + // Returning back to a position of 0 and pressing on the control should + // result in the control being pressed. + mouseDrag(control, control.width / 2, control.height / 2, control.width * 0.6, 0); + compare(control.swipe.position, 0); + mousePress(control, control.width / 2, control.height / 2); + verify(control.pressed); + verify(!button.pressed); + mouseRelease(control, control.width / 2, control.height / 2); + verify(!control.pressed); + + control.destroy(); + } + + function test_mouseButtons() { + var control = swipeDelegateComponent.createObject(testCase); + verify(control); + + // click + mouseSignalSequenceSpy.target = control; + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed"]; + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + compare(control.pressed, true); + + verify(mouseSignalSequenceSpy.success); + + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "released", "clicked"]; + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton); + compare(control.pressed, false); + verify(mouseSignalSequenceSpy.success); + + // right button + mouseSignalSequenceSpy.expectedSequence = []; + mousePress(control, control.width / 2, control.height / 2, Qt.RightButton); + compare(control.pressed, false); + + mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton); + compare(control.pressed, false); + verify(mouseSignalSequenceSpy.success); + + // double click + mouseSignalSequenceSpy.expectedSequence = [ + ["pressedChanged", { "pressed": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + "released", + "clicked", + ["pressedChanged", { "pressed": true }], + "pressed", + "doubleClicked", + ["pressedChanged", { "pressed": false }], + "released", + "clicked" + ]; + mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton); + verify(mouseSignalSequenceSpy.success); + + control.destroy(); + } + + Component { + id: removableDelegatesComponent + + ListView { + id: listView + width: 100 + height: 120 + + model: ListModel { + ListElement { name: "Apple" } + ListElement { name: "Orange" } + ListElement { name: "Pear" } + } + + delegate: SwipeDelegate { + id: rootDelegate + text: modelData + width: listView.width + + onClicked: if (swipe.complete) ListView.view.model.remove(index) + + property alias removeAnimation: onRemoveAnimation + + ListView.onRemove: SequentialAnimation { + id: onRemoveAnimation + + PropertyAction { + target: rootDelegate + property: "ListView.delayRemove" + value: true + } + NumberAnimation { + target: rootDelegate + property: "height" + to: 0 + easing.type: Easing.InOutQuad + } + PropertyAction { + target: rootDelegate; + property: "ListView.delayRemove"; + value: false + } + } + + swipe.left: Rectangle { + color: rootDelegate.swipe.complete && rootDelegate.pressed ? "#333" : "#444" + anchors.fill: parent + + Label { + objectName: "label" + text: "Remove" + color: "white" + anchors.centerIn: parent + } + } + } + } + } + + function test_removableDelegates() { + var listView = removableDelegatesComponent.createObject(testCase); + verify(listView); + compare(listView.count, 3); + + // Expose the remove button. + var firstItem = listView.itemAt(0, 0); + mousePress(listView, firstItem.width / 2, firstItem.height / 2); + verify(firstItem.pressed); + compare(firstItem.swipe.position, 0.0); + verify(!firstItem.swipe.complete); + + mouseMove(listView, firstItem.width * 1.1, firstItem.height / 2); + verify(firstItem.pressed); + compare(firstItem.swipe.position, 0.6); + verify(!firstItem.swipe.complete); + + mouseRelease(listView, firstItem.width / 2, firstItem.height / 2); + verify(!firstItem.pressed); + compare(firstItem.swipe.position, 1.0); + verify(firstItem.swipe.complete); + compare(listView.count, 3); + + // Wait for it to settle down. + tryCompare(firstItem.contentItem, "x", firstItem.leftPadding + firstItem.width); + + // Click the button to remove the item. + var contentItemX = firstItem.contentItem.x; + mouseClick(listView, firstItem.width / 2, firstItem.height / 2); + tryCompare(firstItem.removeAnimation, "running", true); + // There was a bug where the resizeContent() would be called because the height + // of the control was changing due to the animation. contentItem would then + // change x position and hence be visible when it shouldn't be. + verify(firstItem.removeAnimation.running); + while (1) { + wait(10) + if (firstItem && firstItem.removeAnimation && firstItem.removeAnimation.running) + compare(firstItem.contentItem.x, contentItemX); + else + break; + } + compare(listView.count, 2); + + listView.destroy(); + } + + Component { + id: leadingTrailingXComponent + SwipeDelegate { + id: delegate + width: 150 + text: "SwipeDelegate" + + swipe.left: Rectangle { + x: delegate.background.x - width + width: delegate.width + height: delegate.height + color: "green" + } + + swipe.right: Rectangle { + x: delegate.background.x + delegate.background.width + width: delegate.width + height: delegate.height + color: "red" + } + } + } + + Component { + id: leadingTrailingAnchorsComponent + SwipeDelegate { + id: delegate + width: 150 + text: "SwipeDelegate" + + swipe.left: Rectangle { + anchors.right: delegate.background.left + width: delegate.width + height: delegate.height + color: "green" + } + + swipe.right: Rectangle { + anchors.left: delegate.background.right + width: delegate.width + height: delegate.height + color: "red" + } + } + } + + function test_leadingTrailing_data() { + return [ + { tag: "x", component: leadingTrailingXComponent }, + { tag: "anchors", component: leadingTrailingAnchorsComponent }, + ]; + } + + function test_leadingTrailing(data) { + var control = data.component.createObject(testCase); + verify(control); + + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width, control.height / 2, Qt.LeftButton); + verify(control.swipe.leftItem); + compare(control.swipe.leftItem.x, -control.width / 2); + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton); + + control.destroy(); + } + + function test_minMaxPosition() { + var control = leadingTrailingXComponent.createObject(testCase); + verify(control); + + // Should be limited within the range -1.0 to 1.0. + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width * 1.5, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, 1.0); + mouseMove(control, control.width * 1.6, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, 1.0); + mouseMove(control, control.width * -1.6, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, -1.0); + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton); + + control.destroy(); + } + + Component { + id: emptySwipeDelegateComponent + + SwipeDelegate { + text: "SwipeDelegate" + width: 150 + } + } + + Component { + id: smallLeftComponent + + Rectangle { + width: 80 + height: 40 + color: "green" + } + } + + // swipe.position should be scaled to the width of the relevant delegate, + // and it shouldn't be possible to drag past the delegate (so that content behind the control is visible). + function test_delegateWidth() { + var control = emptySwipeDelegateComponent.createObject(testCase); + verify(control); + + control.swipe.left = smallLeftComponent; + + // Ensure that the position is scaled to the width of the currently visible delegate. + var overDragDistance = Math.round(dragDistance * 1.1); + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width / 2 + overDragDistance, control.height / 2, Qt.LeftButton); + verify(control.swipe.leftItem); + compare(control.swipe.position, overDragDistance / control.swipe.leftItem.width); + + mouseMove(control, control.width / 2 + control.swipe.leftItem.width, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, 1.0); + + // Ensure that it's not possible to drag past the (left) delegate. + mouseMove(control, control.width / 2 + control.swipe.leftItem.width + 1, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, 1.0); + + // Now release over the right side; the position should be 1.0 and the background + // should be "anchored" to the right side of the left delegate item. + mouseMove(control, control.width / 2 + control.swipe.leftItem.width, control.height / 2, Qt.LeftButton); + mouseRelease(control, control.width / 2 + control.swipe.leftItem.width, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, 1.0); + tryCompare(control.background, "x", control.swipe.leftItem.width, 1000); + + control.destroy(); + } + + SignalSpy { + id: leftVisibleSpy + signalName: "visibleChanged" + } + + SignalSpy { + id: rightVisibleSpy + signalName: "visibleChanged" + } + + function test_positionAfterSwipeCompleted() { + var control = swipeDelegateComponent.createObject(testCase); + verify(control); + + // Ensure that both delegates are constructed. + mousePress(control, 0, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width * 1.1, control.height / 2, Qt.LeftButton); + verify(control.swipe.leftItem); + mouseMove(control, control.width * -0.1, control.height / 2, Qt.LeftButton); + verify(control.swipe.rightItem); + + // Expose the left delegate. + mouseMove(control, control.swipe.leftItem.width, control.height / 2, Qt.LeftButton); + mouseRelease(control, control.swipe.leftItem.width, control.height / 2); + verify(control.swipe.complete); + compare(control.swipe.position, 1.0); + + leftVisibleSpy.target = control.swipe.leftItem; + rightVisibleSpy.target = control.swipe.rightItem; + + // Swipe from right to left without exposing the right item, + // and make sure that the right item never becomes visible + // (and hence that the left item never loses visibility). + mousePress(control, control.swipe.leftItem.width, control.height / 2, Qt.LeftButton); + compare(leftVisibleSpy.count, 0); + compare(rightVisibleSpy.count, 0); + var newX = control.swipe.leftItem.width - Math.round(dragDistance * 1.1); + mouseMove(control, newX, control.height / 2, Qt.LeftButton, Qt.LeftButton); + compare(leftVisibleSpy.count, 0); + compare(rightVisibleSpy.count, 0); + compare(control.swipe.position, newX / control.swipe.leftItem.width); + + mouseMove(control, 0, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, 0); + + // Test swiping over a distance that is greater than the width of the left item. + mouseMove(control, -1, control.height / 2, Qt.LeftButton); + verify(control.swipe.rightItem); + compare(control.swipe.position, -1 / control.swipe.rightItem.width); + + // Now go back to 1.0. + mouseMove(control, control.swipe.leftItem.width, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, 1.0); + tryCompare(control.background, "x", control.swipe.leftItem.width, 1000); + mouseRelease(control, control.swipe.leftItem.width, control.height / 2, Qt.LeftButton); + + control.destroy(); + } + + // TODO: this somehow results in the behind item having a negative width +// Component { +// id: behindSwipeDelegateComponent +// SwipeDelegate { +// anchors.centerIn: parent +// swipe.behind: Rectangle { +// onXChanged: print("x changed", x) +// anchors.left: { +// print("anchors.left expression", swipe.position) +// swipe.position < 0 ? parent.background.right : undefined +// } +// anchors.right: { +// print("anchors.right expression", swipe.position) +// swipe.position > 0 ? parent.background.left : undefined +// } +// width: parent.width +// height: parent.height +// color: "green" +// } +// swipe.left: null +// swipe.right: null +// Rectangle { +// anchors.fill: parent +// color: "transparent" +// border.color: "darkorange" +// } +// } +// } + + Component { + id: behindSwipeDelegateComponent + SwipeDelegate { + text: "SwipeDelegate" + width: 150 + anchors.centerIn: parent + swipe.behind: Rectangle { + x: swipe.position < 0 ? parent.background.x + parent.background.width + : (swipe.position > 0 ? parent.background.x - width : 0) + width: parent.width + height: parent.height + color: "green" + } + swipe.left: null + swipe.right: null + } + } + + function test_leadingTrailingBehindItem() { + var control = behindSwipeDelegateComponent.createObject(testCase); + verify(control); + + swipe(control, 0.0, 1.0); + verify(control.swipe.behindItem.visible); + compare(control.swipe.behindItem.x, control.background.x - control.background.width); + + swipe(control, 1.0, -1.0); + verify(control.swipe.behindItem.visible); + compare(control.swipe.behindItem.x, control.background.x + control.background.width); + + swipe(control, -1.0, 1.0); + verify(control.swipe.behindItem.visible); + compare(control.swipe.behindItem.x, control.background.x - control.background.width); + + // Should be possible to "wrap" with a behind delegate specified. + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width / 2 + control.swipe.behindItem.width * 0.8, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, -0.2); + mouseRelease(control, control.width / 2 + control.swipe.behindItem.width * 0.8, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, 0.0); + + // Try wrapping the other way. + swipe(control, 0.0, -1.0); + verify(control.swipe.behindItem.visible); + compare(control.swipe.behindItem.x, control.background.x + control.background.width); + + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width / 2 - control.swipe.behindItem.width * 0.8, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, 0.2); + mouseRelease(control, control.width / 2 - control.swipe.behindItem.width * 0.8, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, 0.0); + + control.destroy(); + } + + // When the width of a SwipeDelegate changes (as it does upon portrait => landscape + // rotation, for example), the positions of the contentItem and background items + // should be updated accordingly. + function test_contentItemPosOnWidthChanged() { + var control = swipeDelegateComponent.createObject(testCase); + verify(control); + + swipe(control, 0.0, 1.0); + + var oldContentItemX = control.contentItem.x; + var oldBackgroundX = control.background.x; + control.width += 100; + compare(control.contentItem.x, oldContentItemX + 100); + compare(control.background.x, oldBackgroundX + 100); + + control.destroy(); + } + + function test_contentItemHeightOnHeightChanged() { + var control = swipeDelegateComponent.createObject(testCase); + verify(control); + + // Try when swipe.complete is false. + var originalHeight = control.height; + var originalContentItemHeight = control.contentItem.height; + verify(control.height !== 10); + control.height = 10; + compare(control.contentItem.height, control.availableHeight); + verify(control.contentItem.height < originalContentItemHeight); + compare(control.contentItem.y, control.topPadding); + + // Try when swipe.complete is true. + control.height = originalHeight; + swipe(control, 0.0, 1.0); + control.height = 10; + compare(control.contentItem.height, control.availableHeight); + verify(control.contentItem.height < originalContentItemHeight); + compare(control.contentItem.y, control.topPadding); + + control.destroy(); + } + + function test_releaseOutside_data() { + return [ + { tag: "no delegates", component: emptySwipeDelegateComponent }, + { tag: "delegates", component: swipeDelegateComponent }, + ]; + } + + function test_releaseOutside(data) { + var control = data.component.createObject(testCase); + verify(control); + + // Press and then release below the control. + mouseSignalSequenceSpy.target = control; + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed", ["pressedChanged", { "pressed": false }]]; + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width / 2, control.height + 10, Qt.LeftButton); + verify(mouseSignalSequenceSpy.success); + + mouseSignalSequenceSpy.expectedSequence = ["canceled"]; + mouseRelease(control, control.width / 2, control.height + 10, Qt.LeftButton); + verify(mouseSignalSequenceSpy.success); + + // Press and then release to the right of the control. + var hasDelegates = control.swipe.left || control.swipe.right || control.swipe.behind; + mouseSignalSequenceSpy.target = control; + mouseSignalSequenceSpy.expectedSequence = hasDelegates + ? [["pressedChanged", { "pressed": true }], "pressed"] + : [["pressedChanged", { "pressed": true }], "pressed", ["pressedChanged", { "pressed": false }]]; + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width + 10, control.height / 2, Qt.LeftButton); + if (hasDelegates) + verify(control.swipe.position > 0); + verify(mouseSignalSequenceSpy.success); + + mouseSignalSequenceSpy.expectedSequence = hasDelegates ? [["pressedChanged", { "pressed": false }], "canceled"] : ["canceled"]; + mouseRelease(control, control.width + 10, control.height / 2, Qt.LeftButton); + verify(mouseSignalSequenceSpy.success); + } +} diff --git a/tests/auto/controls/data/tst_swipeview.qml b/tests/auto/controls/data/tst_swipeview.qml index a17b9fc0..3afcdf16 100644 --- a/tests/auto/controls/data/tst_swipeview.qml +++ b/tests/auto/controls/data/tst_swipeview.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -60,20 +60,16 @@ TestCase { Text { } } - SignalSpy { - id: currentItemChangedSpy - signalName: "currentItemChanged" - } - - function cleanup() { - currentItemChangedSpy.clear() - currentItemChangedSpy.target = null + Component { + id: signalSpy + SignalSpy { } } function test_current() { var control = swipeView.createObject(testCase) - currentItemChangedSpy.target = control + var currentItemChangedSpy = signalSpy.createObject(testCase, {target: control, signalName: "currentItemChanged"}) + verify(currentItemChangedSpy.valid) compare(control.count, 0) compare(control.currentIndex, -1) @@ -146,7 +142,8 @@ TestCase { control.currentIndexChanged.connect(verifyCurrentIndexCountDiff) control.countChanged.connect(verifyCurrentIndexCountDiff) - currentItemChangedSpy.target = control; + var currentItemChangedSpy = signalSpy.createObject(testCase, {target: control, signalName: "currentItemChanged"}) + verify(currentItemChangedSpy.valid) compare(control.count, 0) compare(control.currentIndex, -1) diff --git a/tests/auto/controls/data/tst_switch.qml b/tests/auto/controls/data/tst_switch.qml index 13924ed0..93773e0d 100644 --- a/tests/auto/controls/data/tst_switch.qml +++ b/tests/auto/controls/data/tst_switch.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -50,42 +50,16 @@ TestCase { when: windowShown name: "Switch" - SignalSpy { - id: checkedSpy - signalName: "checkedChanged" - } - - SignalSpy { - id: pressedSpy - signalName: "pressedChanged" - } - - SignalSpy { - id: clickedSpy - signalName: "clicked" - } - Component { id: swtch Switch { } } - function init() { - verify(!checkedSpy.target) - verify(!pressedSpy.target) - verify(!clickedSpy.target) - compare(checkedSpy.count, 0) - compare(pressedSpy.count, 0) - compare(clickedSpy.count, 0) - } - - function cleanup() { - checkedSpy.target = null - pressedSpy.target = null - clickedSpy.target = null - checkedSpy.clear() - pressedSpy.clear() - clickedSpy.clear() + Component { + id: signalSequenceSpy + SignalSequenceSpy { + signals: ["pressed", "released", "canceled", "clicked", "pressedChanged", "checkedChanged"] + } } function test_text() { @@ -105,19 +79,41 @@ TestCase { var control = swtch.createObject(testCase) verify(control) - checkedSpy.target = control - verify(checkedSpy.valid) - compare(control.checked, false) - compare(checkedSpy.count, 0) + var spy = signalSequenceSpy.createObject(control, {target: control}) + spy.expectedSequence = [["checkedChanged", { "checked": true }]] control.checked = true compare(control.checked, true) - compare(checkedSpy.count, 1) + verify(spy.success) + spy.expectedSequence = [["checkedChanged", { "checked": false }]] control.checked = false compare(control.checked, false) - compare(checkedSpy.count, 2) + verify(spy.success) + + control.destroy() + } + + function test_pressed_data() { + return [ + { tag: "indicator", x: 15 }, + { tag: "background", x: 5 } + ] + } + + function test_pressed(data) { + var control = swtch.createObject(testCase, {padding: 10}) + verify(control) + + // stays pressed when dragged outside + compare(control.pressed, false) + mousePress(control, data.x, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + mouseMove(control, -1, control.height / 2) + compare(control.pressed, true) + mouseRelease(control, -1, control.height / 2, Qt.LeftButton) + compare(control.pressed, false) control.destroy() } @@ -126,71 +122,184 @@ TestCase { var control = swtch.createObject(testCase) verify(control) - checkedSpy.target = control - pressedSpy.target = control - clickedSpy.target = control - verify(checkedSpy.valid) - verify(pressedSpy.valid) - verify(clickedSpy.valid) - // check + var spy = signalSequenceSpy.createObject(control, {target: control}) + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) - compare(pressedSpy.count, 1) compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) - compare(clickedSpy.count, 1) - compare(checkedSpy.count, 1) - compare(pressedSpy.count, 2) compare(control.checked, true) compare(control.pressed, false) + verify(spy.success) // uncheck + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) - compare(pressedSpy.count, 3) compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) - compare(clickedSpy.count, 2) - compare(checkedSpy.count, 2) - compare(pressedSpy.count, 4) compare(control.checked, false) compare(control.pressed, false) + verify(spy.success) // release on the right + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) - compare(pressedSpy.count, 5) compare(control.pressed, true) + verify(spy.success) mouseMove(control, control.width * 2, control.height / 2, 0, Qt.LeftButton) compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] mouseRelease(control, control.width * 2, control.height / 2, Qt.LeftButton) - compare(clickedSpy.count, 2) - compare(checkedSpy.count, 3) - compare(pressedSpy.count, 6) compare(control.checked, true) compare(control.pressed, false) + verify(spy.success) // release on the left + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) - compare(pressedSpy.count, 7) compare(control.pressed, true) + verify(spy.success) mouseMove(control, -control.width, control.height / 2, 0, Qt.LeftButton) compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] mouseRelease(control, -control.width, control.height / 2, Qt.LeftButton) - compare(clickedSpy.count, 2) - compare(checkedSpy.count, 4) - compare(pressedSpy.count, 8) compare(control.checked, false) compare(control.pressed, false) + verify(spy.success) // right button + spy.expectedSequence = [] mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) - compare(pressedSpy.count, 8) compare(control.pressed, false) + verify(spy.success) mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) - compare(clickedSpy.count, 2) - compare(checkedSpy.count, 4) - compare(pressedSpy.count, 8) compare(control.checked, false) compare(control.pressed, false) + verify(spy.success) + + control.destroy() + } + + function test_drag() { + var control = swtch.createObject(testCase, {leftPadding: 100, rightPadding: 100}) + verify(control) + + var spy = signalSequenceSpy.createObject(control, {target: control}) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + + // press-drag-release inside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control.indicator, 0) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control.indicator, control.width) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control.indicator, control.indicator.width) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, 0) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, true) + compare(control.pressed, true) + + mouseMove(control, control.leftPadding) + compare(control.position, 0.0) + compare(control.checked, true) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] + mouseRelease(control, control.width) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release from and to outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control, control.width) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) control.destroy() } @@ -199,33 +308,39 @@ TestCase { var control = swtch.createObject(testCase) verify(control) - checkedSpy.target = control - clickedSpy.target = control - verify(checkedSpy.valid) - verify(clickedSpy.valid) - control.forceActiveFocus() verify(control.activeFocus) // check + var spy = signalSequenceSpy.createObject(control, {target: control}) + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] keyClick(Qt.Key_Space) - compare(clickedSpy.count, 1) - compare(checkedSpy.count, 1) compare(control.checked, true) + verify(spy.success) // uncheck + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] keyClick(Qt.Key_Space) - compare(clickedSpy.count, 2) - compare(checkedSpy.count, 2) compare(control.checked, false) + verify(spy.success) // no change + spy.expectedSequence = [] var keys = [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab] for (var i = 0; i < keys.length; ++i) { keyClick(keys[i]) - compare(clickedSpy.count, 2) - compare(checkedSpy.count, 2) compare(control.checked, false) + verify(spy.success) } control.destroy() @@ -260,7 +375,18 @@ TestCase { function test_baseline() { var control = swtch.createObject(testCase) verify(control) - compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + control.destroy() + } + + function test_focus() { + var control = swtch.createObject(testCase) + verify(control) + + verify(!control.activeFocus) + mouseClick(control.indicator) + verify(control.activeFocus) + control.destroy() } } diff --git a/tests/auto/controls/data/tst_switchdelegate.qml b/tests/auto/controls/data/tst_switchdelegate.qml new file mode 100644 index 00000000..8bc0e4c3 --- /dev/null +++ b/tests/auto/controls/data/tst_switchdelegate.qml @@ -0,0 +1,302 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtTest 1.0 +import QtQuick.Controls 2.0 + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "SwitchDelegate" + + Component { + id: switchDelegate + SwitchDelegate {} + } + + Component { + id: signalSequenceSpy + SignalSequenceSpy { + signals: ["pressed", "released", "canceled", "clicked", "pressedChanged", "checkedChanged"] + } + } + + // TODO: data-fy tst_checkbox (rename to tst_check?) so we don't duplicate its tests here? + + function test_defaults() { + var control = switchDelegate.createObject(testCase); + verify(control); + verify(!control.checked); + control.destroy(); + } + + function test_checked() { + var control = switchDelegate.createObject(testCase); + verify(control); + + mouseClick(control); + verify(control.checked); + + mouseClick(control); + verify(!control.checked); + + control.destroy(); + } + + function test_baseline() { + var control = switchDelegate.createObject(testCase); + verify(control); + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset); + control.destroy(); + } + + function test_pressed_data() { + return [ + { tag: "indicator", x: 15 }, + { tag: "background", x: 5 } + ] + } + + function test_pressed(data) { + var control = switchDelegate.createObject(testCase, {padding: 10}) + verify(control) + + // stays pressed when dragged outside + compare(control.pressed, false) + mousePress(control, data.x, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + mouseMove(control, -1, control.height / 2) + compare(control.pressed, true) + mouseRelease(control, -1, control.height / 2, Qt.LeftButton) + compare(control.pressed, false) + + control.destroy() + } + + function test_mouse() { + var control = switchDelegate.createObject(testCase) + verify(control) + + // check + var spy = signalSequenceSpy.createObject(control, {target: control}) + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // uncheck + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // release on the right + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + mouseMove(control, control.width * 2, control.height / 2, 0, Qt.LeftButton) + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control, control.width * 2, control.height / 2, Qt.LeftButton) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // release on the left + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + mouseMove(control, -control.width, control.height / 2, 0, Qt.LeftButton) + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] + mouseRelease(control, -control.width, control.height / 2, Qt.LeftButton) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // right button + spy.expectedSequence = [] + mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.pressed, false) + verify(spy.success) + mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + control.destroy() + } + + function test_drag() { + var control = switchDelegate.createObject(testCase, {leftPadding: 100, rightPadding: 100}) + verify(control) + + var spy = signalSequenceSpy.createObject(control, {target: control}) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + + // press-drag-release inside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control.indicator, 0) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control.indicator, control.width) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control.indicator, control.indicator.width) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, 0) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, true) + compare(control.pressed, true) + + mouseMove(control, control.leftPadding) + compare(control.position, 0.0) + compare(control.checked, true) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] + mouseRelease(control, control.width) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release from and to outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control, control.width) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + control.destroy() + } +} diff --git a/tests/auto/controls/data/tst_tabbar.qml b/tests/auto/controls/data/tst_tabbar.qml index d40d5c0b..9268f765 100644 --- a/tests/auto/controls/data/tst_tabbar.qml +++ b/tests/auto/controls/data/tst_tabbar.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -85,19 +85,9 @@ TestCase { } } - SignalSpy { - id: contentChildrenSpy - signalName: "contentChildrenChanged" - } - - function init() { - verify(!contentChildrenSpy.target) - compare(contentChildrenSpy.count, 0) - } - - function cleanup() { - contentChildrenSpy.target = null - contentChildrenSpy.clear() + Component { + id: signalSpy + SignalSpy { } } function test_defaults() { @@ -176,7 +166,7 @@ TestCase { control.currentIndexChanged.connect(verifyCurrentIndexCountDiff) control.countChanged.connect(verifyCurrentIndexCountDiff) - contentChildrenSpy.target = control + var contentChildrenSpy = signalSpy.createObject(testCase, {target: control, signalName: "contentChildrenChanged"}) verify(contentChildrenSpy.valid) compare(control.count, 0) @@ -293,7 +283,7 @@ TestCase { return true } - contentChildrenSpy.target = control + var contentChildrenSpy = signalSpy.createObject(testCase, {target: control, signalName: "contentChildrenChanged"}) verify(contentChildrenSpy.valid) verify(compareObjectNames(control.contentData, ["object", "button1", "timer", "button2", ""])) @@ -504,17 +494,37 @@ TestCase { control.destroy() } - function test_layout() { - var control = tabBar.createObject(testCase, {spacing: 0, width: 200}) + function test_layout_data() { + return [ + { tag: "spacing:0", spacing: 0 }, + { tag: "spacing:1", spacing: 1 }, + { tag: "spacing:10", spacing: 10 }, + ] + } + + function test_layout(data) { + var control = tabBar.createObject(testCase, {spacing: data.spacing, width: 200}) - var tab1 = tabButton.createObject(control) + var tab1 = tabButton.createObject(control, {text: "First"}) control.addItem(tab1) tryCompare(tab1, "width", control.width) - var tab2 = tabButton.createObject(control) + var tab2 = tabButton.createObject(control, {text: "Second"}) control.addItem(tab2) - tryCompare(tab1, "width", control.width / 2) - tryCompare(tab2, "width", control.width / 2) + tryCompare(tab1, "width", (control.width - data.spacing) / 2) + compare(tab2.width, (control.width - data.spacing) / 2) + + var tab3 = tabButton.createObject(control, {width: 50, text: "Third"}) + control.addItem(tab3) + tryCompare(tab1, "width", (control.width - 2 * data.spacing - 50) / 2) + compare(tab2.width, (control.width - 2 * data.spacing - 50) / 2) + compare(tab3.width, 50) + + var expectedWidth = tab3.contentItem.implicitWidth + tab3.leftPadding + tab3.rightPadding + tab3.width = tab3.implicitWidth + tryCompare(tab1, "width", (control.width - 2 * data.spacing - expectedWidth) / 2) + tryCompare(tab2, "width", (control.width - 2 * data.spacing - expectedWidth) / 2) + compare(tab3.width, expectedWidth) control.destroy() } diff --git a/tests/auto/controls/data/tst_tabbutton.qml b/tests/auto/controls/data/tst_tabbutton.qml index 3a817cfd..4ab9d955 100644 --- a/tests/auto/controls/data/tst_tabbutton.qml +++ b/tests/auto/controls/data/tst_tabbutton.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -85,7 +85,7 @@ TestCase { function test_baseline() { var control = tabButton.createObject(testCase) verify(control) - compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) control.destroy() } } diff --git a/tests/auto/controls/data/tst_textarea.qml b/tests/auto/controls/data/tst_textarea.qml index 269e11ec..bda0b3e3 100644 --- a/tests/auto/controls/data/tst_textarea.qml +++ b/tests/auto/controls/data/tst_textarea.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -56,6 +56,15 @@ TestCase { } Component { + id: flickable + Flickable { + width: 200 + height: 200 + TextArea.flickable: TextArea { } + } + } + + Component { id: signalSpy SignalSpy { } } @@ -68,10 +77,16 @@ TestCase { function test_implicitSize() { var control = textArea.createObject(testCase) + + var implicitWidthSpy = signalSpy.createObject(control, { target: control, signalName: "implicitWidthChanged"} ) + var implicitHeightSpy = signalSpy.createObject(control, { target: control, signalName: "implicitHeightChanged"} ) control.background.implicitWidth = 400 control.background.implicitHeight = 200 compare(control.implicitWidth, 400) compare(control.implicitHeight, 200) + compare(implicitWidthSpy.count, 1) + compare(implicitHeightSpy.count, 1) + control.destroy() } @@ -137,4 +152,69 @@ TestCase { control.destroy() } + + function test_flickable() { + var control = flickable.createObject(testCase, {text:"line0", selectByMouse: true}) + verify(control) + + var textArea = control.TextArea.flickable + verify(textArea) + + for (var i = 1; i <= 100; ++i) + textArea.text += "line\n" + i + + verify(textArea.contentWidth > 0) + verify(textArea.contentHeight > 200) + + compare(control.contentWidth, textArea.contentWidth + textArea.leftPadding + textArea.rightPadding) + compare(control.contentHeight, textArea.contentHeight + textArea.topPadding + textArea.bottomPadding) + + compare(textArea.cursorPosition, 0) + + var center = textArea.positionAt(control.width / 2, control.height / 2) + verify(center > 0) + mouseClick(textArea, control.width / 2, control.height / 2) + compare(textArea.cursorPosition, center) + + // click inside text area, but below flickable + var below = textArea.positionAt(control.width / 2, control.height + 1) + verify(below > center) + mouseClick(textArea, control.width / 2, control.height + 1) + compare(textArea.cursorPosition, center) // no change + + // scroll down + control.contentY = -(control.contentHeight - control.height) / 2 + + // click inside textarea, but above flickable + var above = textArea.positionAt(control.width / 2, textArea.topPadding) + verify(above > 0 && above < center) + mouseClick(textArea, control.width / 2, 0) + compare(textArea.cursorPosition, center) // no change + + control.destroy() + } + + function test_warning() { + ignoreWarning(Qt.resolvedUrl("tst_textarea.qml") + ":45:1: QML TestCase: TextArea must be attached to a Flickable") + testCase.TextArea.flickable = null + } + + function test_multiClick() { + var control = textArea.createObject(testCase, {text: "Qt Quick Controls 2 TextArea", selectByMouse: true}) + verify(control) + + waitForRendering(control) + control.width = control.contentWidth + var rect = control.positionToRectangle(12) + + // double click -> select word + mouseDoubleClickSequence(control, rect.x + rect.width / 2, rect.y + rect.height / 2) + compare(control.selectedText, "Controls") + + // tripple click -> select whole line + mouseClick(control, rect.x + rect.width / 2, rect.y + rect.height / 2) + compare(control.selectedText, "Qt Quick Controls 2 TextArea") + + control.destroy() + } } diff --git a/tests/auto/controls/data/tst_textfield.qml b/tests/auto/controls/data/tst_textfield.qml index a7e2f6ec..959662ee 100644 --- a/tests/auto/controls/data/tst_textfield.qml +++ b/tests/auto/controls/data/tst_textfield.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -69,10 +69,35 @@ TestCase { function test_implicitSize() { var control = textField.createObject(testCase) verify(control.implicitWidth > control.leftPadding + control.rightPadding) + + var implicitWidthSpy = signalSpy.createObject(control, { target: control, signalName: "implicitWidthChanged"} ) + var implicitHeightSpy = signalSpy.createObject(control, { target: control, signalName: "implicitHeightChanged"} ) + control.background.implicitWidth = 400 control.background.implicitHeight = 200 compare(control.implicitWidth, 400) compare(control.implicitHeight, 200) + compare(implicitWidthSpy.count, 1) + compare(implicitHeightSpy.count, 1) + + control.background = null + compare(control.implicitWidth, control.leftPadding + control.rightPadding) + compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding) + compare(implicitWidthSpy.count, 2) + compare(implicitHeightSpy.count, 2) + + control.text = "TextField" + compare(control.implicitWidth, control.contentWidth + control.leftPadding + control.rightPadding) + compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding) + compare(implicitWidthSpy.count, 3) + compare(implicitHeightSpy.count, 2) + + control.placeholderText = "..." + verify(control.implicitWidth < control.contentWidth + control.leftPadding + control.rightPadding) + compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding) + compare(implicitWidthSpy.count, 4) + compare(implicitHeightSpy.count, 2) + control.destroy() } @@ -138,4 +163,23 @@ TestCase { control.destroy() } + + function test_multiClick() { + var control = textField.createObject(testCase, {text: "Qt Quick Controls 2 TextArea", selectByMouse: true}) + verify(control) + + waitForRendering(control) + control.width = control.contentWidth + var rect = control.positionToRectangle(12) + + // double click -> select word + mouseDoubleClickSequence(control, rect.x + rect.width / 2, rect.y + rect.height / 2) + compare(control.selectedText, "Controls") + + // tripple click -> select whole line + mouseClick(control, rect.x + rect.width / 2, rect.y + rect.height / 2) + compare(control.selectedText, "Qt Quick Controls 2 TextArea") + + control.destroy() + } } diff --git a/tests/auto/controls/data/tst_toolbar.qml b/tests/auto/controls/data/tst_toolbar.qml index 128aa403..b68f26e6 100644 --- a/tests/auto/controls/data/tst_toolbar.qml +++ b/tests/auto/controls/data/tst_toolbar.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase diff --git a/tests/auto/controls/data/tst_toolbutton.qml b/tests/auto/controls/data/tst_toolbutton.qml index 63a87ec2..73431ca6 100644 --- a/tests/auto/controls/data/tst_toolbutton.qml +++ b/tests/auto/controls/data/tst_toolbutton.qml @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -50,14 +50,9 @@ TestCase { when: windowShown name: "ToolButton" - SignalSpy { - id: pressedSpy - signalName: "pressedChanged" - } - - SignalSpy { - id: clickedSpy - signalName: "clicked" + Component { + id: signalSpy + SignalSpy { } } Component { @@ -65,20 +60,6 @@ TestCase { ToolButton { } } - function init() { - verify(!pressedSpy.target) - verify(!clickedSpy.target) - compare(pressedSpy.count, 0) - compare(clickedSpy.count, 0) - } - - function cleanup() { - pressedSpy.target = null - clickedSpy.target = null - pressedSpy.clear() - clickedSpy.clear() - } - function test_text() { var control = toolButton.createObject(testCase) verify(control) @@ -96,48 +77,69 @@ TestCase { var control = toolButton.createObject(testCase) verify(control) - pressedSpy.target = control - clickedSpy.target = control + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) verify(pressedSpy.valid) + + var downSpy = signalSpy.createObject(control, {target: control, signalName: "downChanged"}) + verify(downSpy.valid) + + var clickedSpy = signalSpy.createObject(control, {target: control, signalName: "clicked"}) verify(clickedSpy.valid) // check mousePress(control, control.width / 2, control.height / 2, Qt.LeftToolButton) compare(pressedSpy.count, 1) + compare(downSpy.count, 1) compare(control.pressed, true) + compare(control.down, true) mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftToolButton) compare(clickedSpy.count, 1) compare(pressedSpy.count, 2) + compare(downSpy.count, 2) compare(control.pressed, false) + compare(control.down, false) // uncheck mousePress(control, control.width / 2, control.height / 2, Qt.LeftToolButton) compare(pressedSpy.count, 3) + compare(downSpy.count, 3) compare(control.pressed, true) + compare(control.down, true) mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftToolButton) compare(clickedSpy.count, 2) compare(pressedSpy.count, 4) + compare(downSpy.count, 4) compare(control.pressed, false) + compare(control.down, false) // release outside mousePress(control, control.width / 2, control.height / 2, Qt.LeftToolButton) compare(pressedSpy.count, 5) + compare(downSpy.count, 5) compare(control.pressed, true) + compare(control.down, true) mouseMove(control, control.width * 2, control.height * 2, 0, Qt.LeftToolButton) compare(control.pressed, false) + compare(control.down, false) mouseRelease(control, control.width * 2, control.height * 2, Qt.LeftToolButton) compare(clickedSpy.count, 2) compare(pressedSpy.count, 6) + compare(downSpy.count, 6) compare(control.pressed, false) + compare(control.down, false) // right button mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) compare(pressedSpy.count, 6) + compare(downSpy.count, 6) compare(control.pressed, false) + compare(control.down, false) mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) compare(clickedSpy.count, 2) compare(pressedSpy.count, 6) + compare(downSpy.count, 6) compare(control.pressed, false) + compare(control.down, false) control.destroy() } @@ -146,7 +148,7 @@ TestCase { var control = toolButton.createObject(testCase) verify(control) - clickedSpy.target = control + var clickedSpy = signalSpy.createObject(control, {target: control, signalName: "clicked"}) verify(clickedSpy.valid) control.forceActiveFocus() @@ -173,7 +175,7 @@ TestCase { function test_baseline() { var control = toolButton.createObject(testCase) verify(control) - compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) control.destroy() } } diff --git a/tests/auto/controls/data/tst_tooltip.qml b/tests/auto/controls/data/tst_tooltip.qml new file mode 100644 index 00000000..c78a7770 --- /dev/null +++ b/tests/auto/controls/data/tst_tooltip.qml @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtTest 1.0 +import QtQuick.Controls 2.0 + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "ToolTip" + + Component { + id: toolTip + ToolTip { } + } + + Component { + id: mouseArea + MouseArea { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + QtObject { + id: object + } + + function test_properties_data() { + return [ + {tag: "text", property: "text", defaultValue: "", setValue: "Hello", signalName: "textChanged"}, + {tag: "delay", property: "delay", defaultValue: 0, setValue: 1000, signalName: "delayChanged"}, + {tag: "timeout", property: "timeout", defaultValue: -1, setValue: 2000, signalName: "timeoutChanged"} + ] + } + + function test_properties(data) { + var control = toolTip.createObject(testCase) + verify(control) + + compare(control[data.property], data.defaultValue) + + var spy = signalSpy.createObject(testCase, {target: control, signalName: data.signalName}) + verify(spy.valid) + + control[data.property] = data.setValue + compare(control[data.property], data.setValue) + compare(spy.count, 1) + + spy.destroy() + control.destroy() + } + + function test_attached_data() { + return [ + {tag: "text", property: "text", defaultValue: "", setValue: "Hello", signalName: "textChanged"}, + {tag: "delay", property: "delay", defaultValue: 0, setValue: 1000, signalName: "delayChanged"}, + {tag: "timeout", property: "timeout", defaultValue: -1, setValue: 2000, signalName: "timeoutChanged"} + ] + } + + function test_attached(data) { + var item1 = mouseArea.createObject(testCase) + verify(item1) + + var item2 = mouseArea.createObject(testCase) + verify(item2) + + compare(item1.ToolTip[data.property], data.defaultValue) + compare(item2.ToolTip[data.property], data.defaultValue) + + var spy1 = signalSpy.createObject(item1, {target: item1.ToolTip, signalName: data.signalName}) + verify(spy1.valid) + + var spy2 = signalSpy.createObject(item2, {target: item2.ToolTip, signalName: data.signalName}) + verify(spy2.valid) + + var sharedTip = ToolTip.toolTip + var sharedSpy = signalSpy.createObject(testCase, {target: sharedTip, signalName: data.signalName}) + verify(sharedSpy.valid) + + // change attached properties while the shared tooltip is not visible + item1.ToolTip[data.property] = data.setValue + compare(item1.ToolTip[data.property], data.setValue) + compare(spy1.count, 1) + + compare(spy2.count, 0) + compare(item2.ToolTip[data.property], data.defaultValue) + + // the shared tooltip is not visible for item1, so the attached + // property change should therefore not apply to the shared instance + compare(sharedSpy.count, 0) + compare(sharedTip[data.property], data.defaultValue) + + // show the shared tooltip for item2 + item2.ToolTip.visible = true + verify(item2.ToolTip.visible) + verify(sharedTip.visible) + + // change attached properties while the shared tooltip is visible + item2.ToolTip[data.property] = data.setValue + compare(item2.ToolTip[data.property], data.setValue) + compare(spy2.count, 1) + + // the shared tooltip is visible for item2, so the attached + // property change should apply to the shared instance + compare(sharedSpy.count, 1) + compare(sharedTip[data.property], data.setValue) + + item1.destroy() + item2.destroy() + } + + function test_delay_data() { + return [ + {tag: "imperative:0", delay: 0, imperative: true}, + {tag: "imperative:100", delay: 100, imperative: true}, + {tag: "declarative:0", delay: 0, imperative: false}, + {tag: "declarative:100", delay: 100, imperative: false} + ] + } + + function test_delay(data) { + var control = toolTip.createObject(testCase, {delay: data.delay}) + + compare(control.visible, false) + if (data.imperative) + control.open() + else + control.visible = true + compare(control.visible, data.delay <= 0) + tryCompare(control, "visible", true) + + control.destroy() + } + + function test_timeout_data() { + return [ + {tag: "imperative", imperative: true}, + {tag: "declarative", imperative: false} + ] + } + + function test_timeout(data) { + var control = toolTip.createObject(testCase, {timeout: 100}) + + compare(control.visible, false) + if (data.imperative) + control.open() + else + control.visible = true + compare(control.visible, true) + tryCompare(control, "visible", false) + + control.destroy() + } + + function test_warning() { + ignoreWarning(Qt.resolvedUrl("tst_tooltip.qml") + ":68:5: QML QtObject: ToolTip must be attached to an Item") + ignoreWarning("<Unknown File>:1:30: QML ToolTip: cannot find any window to open popup in.") + object.ToolTip.show("") // don't crash (QTBUG-56243) + } + + Component { + id: toolTipWithExitTransition + + ToolTip { + enter: Transition { + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 100 } + } + exit: Transition { + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 1000 } + } + } + } + + function test_makeVisibleWhileExitTransitionRunning_data() { + return [ + { tag: "imperative", imperative: true }, + { tag: "declarative", imperative: false } + ] + } + + function test_makeVisibleWhileExitTransitionRunning(data) { + var control = toolTipWithExitTransition.createObject(testCase) + + // Show, hide, and show the tooltip again. Its exit transition should + // start and get cancelled, and then its enter transition should run. + if (data.imperative) + control.open() + else + control.visible = true + tryCompare(control, "opacity", 1) + + if (data.imperative) + control.close() + else + control.visible = false + verify(control.exit.running) + wait(100) // TODO: replace with tryVerify() in 5.8 + verify(control.opacity < 1) + + if (data.imperative) + control.open() + else + control.visible = true + tryCompare(control, "opacity", 1) + + control.destroy() + } +} diff --git a/tests/auto/controls/data/tst_tumbler.qml b/tests/auto/controls/data/tst_tumbler.qml index 58d74c40..2e0e3295 100644 --- a/tests/auto/controls/data/tst_tumbler.qml +++ b/tests/auto/controls/data/tst_tumbler.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -40,7 +40,7 @@ import QtQuick 2.2 import QtTest 1.0 -import Qt.labs.controls 1.0 +import QtQuick.Controls 2.0 TestCase { id: testCase @@ -51,19 +51,38 @@ TestCase { name: "Tumbler" property var tumbler: null + // With the help of cleanup(), ensures that all items created during a test function + // are destroyed if that test fails. + property Item cleanupItem readonly property real implicitTumblerWidth: 60 readonly property real implicitTumblerHeight: 200 readonly property real defaultImplicitDelegateHeight: implicitTumblerHeight / 3 readonly property real defaultListViewTumblerOffset: -defaultImplicitDelegateHeight + Component { + id: itemComponent + + Item { + anchors.fill: parent + } + } + function init() { - tumbler = Qt.createQmlObject("import Qt.labs.controls 1.0; Tumbler { }", testCase, ""); - verify(tumbler, "Tumbler: failed to create an instance"); - compare(tumbler.contentItem.parent, tumbler); + cleanupItem = itemComponent.createObject(testCase); + verify(cleanupItem); } function cleanup() { - tumbler.destroy(); + var destroyed = false; + cleanupItem.Component.destruction.connect(function() { destroyed = true; }); + + cleanupItem.destroy(); + + // Waiting until it's deleted before continuing makes debugging + // test failures much easier, because there aren't unrelated items hanging around. + // TODO: Replace with tryVerify(!tumbler) in 5.8. + while (!destroyed) + wait(0) } function tumblerXCenter() { @@ -92,11 +111,21 @@ TestCase { } } - function tst_dynamicContentItemChange() { - // test that currentIndex is maintained between contentItem changes... + Component { + id: tumblerComponent + + Tumbler {} } + // TODO: test that currentIndex is maintained between contentItem changes... +// function tst_dynamicContentItemChange() { +// } + function test_currentIndex() { + tumbler = tumblerComponent.createObject(cleanupItem); + verify(tumbler); + compare(tumbler.contentItem.parent, tumbler); + tumbler.model = 5; compare(tumbler.currentIndex, 0); @@ -122,6 +151,9 @@ TestCase { } function test_keyboardNavigation() { + tumbler = tumblerComponent.createObject(cleanupItem); + verify(tumbler); + tumbler.model = 5; tumbler.forceActiveFocus(); tumbler.contentItem.highlightMoveDuration = 0; @@ -150,6 +182,9 @@ TestCase { } function test_itemsCorrectlyPositioned() { + tumbler = tumblerComponent.createObject(cleanupItem); + verify(tumbler); + tumbler.model = 4; tumbler.height = 120; compare(tumbler.contentItem.delegateHeight, 40); @@ -158,7 +193,7 @@ TestCase { wait(tumbler.contentItem.highlightMoveDuration); var firstItemCenterPos = itemCenterPos(1); var firstItem = tumbler.contentItem.itemAt(firstItemCenterPos.x, firstItemCenterPos.y); - var actualPos = testCase.mapFromItem(firstItem, 0, 0); + var actualPos = cleanupItem.mapFromItem(firstItem, 0, 0); compare(actualPos.x, tumbler.leftPadding); compare(actualPos.y, tumbler.topPadding + 40); @@ -169,7 +204,7 @@ TestCase { firstItem = tumbler.contentItem.itemAt(firstItemCenterPos.x, firstItemCenterPos.y); verify(firstItem); // Test QTBUG-40298. - actualPos = testCase.mapFromItem(firstItem, 0, 0); + actualPos = cleanupItem.mapFromItem(firstItem, 0, 0); compare(actualPos.x, tumbler.leftPadding); compare(actualPos.y, tumbler.topPadding); @@ -186,8 +221,11 @@ TestCase { } function test_focusPastTumbler() { + tumbler = tumblerComponent.createObject(cleanupItem); + verify(tumbler); + var mouseArea = Qt.createQmlObject( - "import QtQuick 2.2; TextInput { activeFocusOnTab: true; width: 50; height: 50 }", testCase, ""); + "import QtQuick 2.2; TextInput { activeFocusOnTab: true; width: 50; height: 50 }", cleanupItem, ""); tumbler.forceActiveFocus(); verify(tumbler.activeFocus); @@ -195,16 +233,12 @@ TestCase { keyClick(Qt.Key_Tab); verify(!tumbler.activeFocus); verify(mouseArea.activeFocus); - - mouseArea.destroy(); } function test_datePicker() { - tumbler.destroy(); - var component = Qt.createComponent("TumblerDatePicker.qml"); compare(component.status, Component.Ready, component.errorString()); - tumbler = component.createObject(testCase); + tumbler = component.createObject(cleanupItem); // Should not be any warnings. compare(tumbler.dayTumbler.currentIndex, 0); @@ -234,28 +268,75 @@ TestCase { tryCompare(tumbler.dayTumbler, "currentIndex", 27); } + Component { + id: timePickerComponent + + Row { + property alias minuteTumbler: minuteTumbler + property alias amPmTumbler: amPmTumbler + + Tumbler { + id: minuteTumbler + currentIndex: 6 + model: 60 + width: 50 + height: 150 + } + + Tumbler { + id: amPmTumbler + model: ["AM", "PM"] + width: 50 + height: 150 + contentItem: ListView { + anchors.fill: parent + model: amPmTumbler.model + delegate: amPmTumbler.delegate + } + } + } + } + + function test_listViewTimePicker() { + var root = timePickerComponent.createObject(cleanupItem); + verify(root); + + mouseDrag(root.minuteTumbler, root.minuteTumbler.width / 2, root.minuteTumbler.height / 2, 0, 50); + // Shouldn't crash. + mouseDrag(root.amPmTumbler, root.amPmTumbler.width / 2, root.amPmTumbler.height / 2, 0, 50); + } + function test_displacement_data() { var data = [ // At 0 offset, the first item is current. - { index: 0, offset: 0, expectedDisplacement: 0 }, - { index: 1, offset: 0, expectedDisplacement: -1 }, - { index: 5, offset: 0, expectedDisplacement: 1 }, + { count: 6, index: 0, offset: 0, expectedDisplacement: 0 }, + { count: 6, index: 1, offset: 0, expectedDisplacement: -1 }, + { count: 6, index: 5, offset: 0, expectedDisplacement: 1 }, // When we start to move the first item down, the second item above it starts to become current. - { index: 0, offset: 0.25, expectedDisplacement: -0.25 }, - { index: 1, offset: 0.25, expectedDisplacement: -1.25 }, - { index: 5, offset: 0.25, expectedDisplacement: 0.75 }, - { index: 0, offset: 0.5, expectedDisplacement: -0.5 }, - { index: 1, offset: 0.5, expectedDisplacement: -1.5 }, - { index: 5, offset: 0.5, expectedDisplacement: 0.5 }, + { count: 6, index: 0, offset: 0.25, expectedDisplacement: -0.25 }, + { count: 6, index: 1, offset: 0.25, expectedDisplacement: -1.25 }, + { count: 6, index: 5, offset: 0.25, expectedDisplacement: 0.75 }, + { count: 6, index: 0, offset: 0.5, expectedDisplacement: -0.5 }, + { count: 6, index: 1, offset: 0.5, expectedDisplacement: -1.5 }, + { count: 6, index: 5, offset: 0.5, expectedDisplacement: 0.5 }, // By this stage, the delegate at index 1 is destroyed, so we can't test its displacement. - { index: 0, offset: 0.75, expectedDisplacement: -0.75 }, - { index: 5, offset: 0.75, expectedDisplacement: 0.25 }, - { index: 0, offset: 4.75, expectedDisplacement: 1.25 }, - { index: 1, offset: 4.75, expectedDisplacement: 0.25 }, - { index: 0, offset: 4.5, expectedDisplacement: 1.5 }, - { index: 1, offset: 4.5, expectedDisplacement: 0.5 }, - { index: 0, offset: 4.25, expectedDisplacement: 1.75 }, - { index: 1, offset: 4.25, expectedDisplacement: 0.75 } + { count: 6, index: 0, offset: 0.75, expectedDisplacement: -0.75 }, + { count: 6, index: 5, offset: 0.75, expectedDisplacement: 0.25 }, + { count: 6, index: 0, offset: 4.75, expectedDisplacement: 1.25 }, + { count: 6, index: 1, offset: 4.75, expectedDisplacement: 0.25 }, + { count: 6, index: 0, offset: 4.5, expectedDisplacement: 1.5 }, + { count: 6, index: 1, offset: 4.5, expectedDisplacement: 0.5 }, + { count: 6, index: 0, offset: 4.25, expectedDisplacement: 1.75 }, + { count: 6, index: 1, offset: 4.25, expectedDisplacement: 0.75 }, + // count == visibleItemCount + { count: 3, index: 0, offset: 0, expectedDisplacement: 0 }, + { count: 3, index: 1, offset: 0, expectedDisplacement: -1 }, + { count: 3, index: 2, offset: 0, expectedDisplacement: 1 }, + // count < visibleItemCount + { count: 2, index: 0, offset: 0, expectedDisplacement: 0 }, + { count: 2, index: 1, offset: 0, expectedDisplacement: 1 }, + // count == 1 + { count: 1, index: 0, offset: 0, expectedDisplacement: 0 } ]; for (var i = 0; i < data.length; ++i) { var row = data[i]; @@ -280,11 +361,14 @@ TestCase { } function test_displacement(data) { + tumbler = tumblerComponent.createObject(cleanupItem); + verify(tumbler); + // TODO: test setting these in the opposite order (delegate after model // doesn't seem to cause a change in delegates in PathView) tumbler.delegate = displacementDelegate; - tumbler.model = 6; - compare(tumbler.count, 6); + tumbler.model = data.count; + compare(tumbler.count, data.count); var delegate = findChild(tumbler.contentItem, "delegate" + data.index); verify(delegate); @@ -354,11 +438,10 @@ TestCase { } function test_displacementListView(data) { - tumbler.destroy(); // Sanity check that they're aren't any children at this stage. - tryCompare(testCase.children, "length", 0); + tryCompare(cleanupItem.children, "length", 0); - tumbler = listViewTumblerComponent.createObject(testCase); + tumbler = listViewTumblerComponent.createObject(cleanupItem); verify(tumbler); tumbler.delegate = displacementDelegate; @@ -428,9 +511,7 @@ TestCase { } function test_listViewFlickAboveBounds(data) { - tumbler.destroy(); - - tumbler = listViewTumblerComponent.createObject(testCase); + tumbler = listViewTumblerComponent.createObject(cleanupItem); verify(tumbler); tumbler.delegate = displacementDelegate; @@ -496,6 +577,9 @@ TestCase { } function test_visibleItemCount(data) { + tumbler = tumblerComponent.createObject(cleanupItem); + verify(tumbler); + tumbler.delegate = objectNameDelegate; tumbler.visibleItemCount = data.visibleItemCount; @@ -527,6 +611,9 @@ TestCase { } function test_attachedProperties() { + tumbler = tumblerComponent.createObject(cleanupItem); + verify(tumbler); + // TODO: crashes somewhere in QML's guts // tumbler.model = 5; // tumbler.delegate = wrongDelegateTypeComponent; @@ -538,14 +625,15 @@ TestCase { noParentDelegateComponent.createObject(null); ignoreWarning("Tumbler: attempting to access attached property on item without an \"index\" property"); - var object = noParentDelegateComponent.createObject(testCase); + var object = noParentDelegateComponent.createObject(cleanupItem); + verify(object); object.destroy(); // Should not be any warnings from this, as ListView, for example, doesn't produce warnings for the same code. - var gridView = gridViewComponent.createObject(testCase); + var gridView = gridViewComponent.createObject(cleanupItem); object = simpleDisplacementDelegate.createObject(gridView); + verify(object); object.destroy(); - gridView.destroy(); } property Component paddingDelegate: Text { @@ -592,6 +680,9 @@ TestCase { } function test_padding(data) { + tumbler = tumblerComponent.createObject(cleanupItem); + verify(tumbler); + tumbler.delegate = paddingDelegate; tumbler.model = 5; compare(tumbler.padding, 0); diff --git a/tests/auto/controls/default/default.pro b/tests/auto/controls/default/default.pro new file mode 100644 index 00000000..6ab5b5ff --- /dev/null +++ b/tests/auto/controls/default/default.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = tst_default +CONFIG += qmltestcase + +DEFINES += TST_CONTROLS_DATA=\\\"$$QQC2_SOURCE_TREE/tests/auto/controls/data\\\" + +SOURCES += \ + $$PWD/tst_default.cpp + +OTHER_FILES += \ + $$PWD/../data/* + +TESTDATA += \ + $$PWD/../data/tst_* diff --git a/tests/auto/controls/tst_controls.cpp b/tests/auto/controls/default/tst_default.cpp index 89cc39f0..68c3ab8f 100644 --- a/tests/auto/controls/tst_controls.cpp +++ b/tests/auto/controls/default/tst_default.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -35,4 +35,10 @@ ****************************************************************************/ #include <QtQuickTest/quicktest.h> -QUICK_TEST_MAIN(tst_controls) + +int main(int argc, char *argv[]) +{ + QTEST_ADD_GPU_BLACKLIST_SUPPORT + QTEST_SET_MAIN_SOURCE_PATH + return quick_test_main(argc, argv, "tst_controls::Default", TST_CONTROLS_DATA); +} diff --git a/tests/auto/controls/material/material.pro b/tests/auto/controls/material/material.pro new file mode 100644 index 00000000..1a8260f3 --- /dev/null +++ b/tests/auto/controls/material/material.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +TARGET = tst_material +CONFIG += qmltestcase +QT += quickcontrols2 + +DEFINES += TST_CONTROLS_DATA=\\\"$$QQC2_SOURCE_TREE/tests/auto/controls/data\\\" + +SOURCES += \ + $$PWD/tst_material.cpp + +OTHER_FILES += \ + $$PWD/../data/* + +TESTDATA += \ + $$PWD/../data/tst_* diff --git a/tests/auto/controls/material/tst_material.cpp b/tests/auto/controls/material/tst_material.cpp new file mode 100644 index 00000000..2825b127 --- /dev/null +++ b/tests/auto/controls/material/tst_material.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTest/quicktest.h> +#include <QtQuickControls2/qquickstyle.h> + +int main(int argc, char *argv[]) +{ + QTEST_ADD_GPU_BLACKLIST_SUPPORT + QTEST_SET_MAIN_SOURCE_PATH + QQuickStyle::setStyle("Material"); + return quick_test_main(argc, argv, "tst_controls::Material", TST_CONTROLS_DATA); +} diff --git a/tests/auto/controls/universal/tst_universal.cpp b/tests/auto/controls/universal/tst_universal.cpp new file mode 100644 index 00000000..de4ca85c --- /dev/null +++ b/tests/auto/controls/universal/tst_universal.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTest/quicktest.h> +#include <QtQuickControls2/qquickstyle.h> + +int main(int argc, char *argv[]) +{ + QTEST_ADD_GPU_BLACKLIST_SUPPORT + QTEST_SET_MAIN_SOURCE_PATH + QQuickStyle::setStyle("Universal"); + return quick_test_main(argc, argv, "tst_controls::Universal", TST_CONTROLS_DATA); +} diff --git a/tests/auto/controls/universal/universal.pro b/tests/auto/controls/universal/universal.pro new file mode 100644 index 00000000..7a16cc64 --- /dev/null +++ b/tests/auto/controls/universal/universal.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +TARGET = tst_universal +CONFIG += qmltestcase +QT += quickcontrols2 + +DEFINES += TST_CONTROLS_DATA=\\\"$$QQC2_SOURCE_TREE/tests/auto/controls/data\\\" + +SOURCES += \ + $$PWD/tst_universal.cpp + +OTHER_FILES += \ + $$PWD/../data/* + +TESTDATA += \ + $$PWD/../data/tst_* |