diff options
Diffstat (limited to 'tests/auto/quickcontrols2/controls/data/tst_tooltip.qml')
-rw-r--r-- | tests/auto/quickcontrols2/controls/data/tst_tooltip.qml | 477 |
1 files changed, 477 insertions, 0 deletions
diff --git a/tests/auto/quickcontrols2/controls/data/tst_tooltip.qml b/tests/auto/quickcontrols2/controls/data/tst_tooltip.qml new file mode 100644 index 0000000000..2f98a5f3d2 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_tooltip.qml @@ -0,0 +1,477 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 +import QtTest +import QtQuick.Controls + +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 { } + } + + Component { + id: itemComponent + Item {} + } + + QtObject { + id: object + } + + SignalSpy { + id: sharedSpy + target: ToolTip.toolTip + } + + 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 = createTemporaryObject(toolTip, testCase) + verify(control) + + compare(control[data.property], data.defaultValue) + + var spy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: data.signalName}) + verify(spy.valid) + + control[data.property] = data.setValue + compare(control[data.property], data.setValue) + compare(spy.count, 1) + } + + 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 = createTemporaryObject(mouseArea, testCase) + verify(item1) + + var item2 = createTemporaryObject(mouseArea, testCase) + verify(item2) + + // Reset the properties to the expected default values, in case + // we're not the first test that uses attached properties to be run. + var sharedTip = ToolTip.toolTip + sharedTip[data.property] = data.defaultValue + + 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) + + sharedSpy.signalName = data.signalName + verify(sharedSpy.valid) + sharedSpy.clear() + + // 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) + } + + 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 = createTemporaryObject(toolTip, 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) + } + + function test_timeout_data() { + return [ + {tag: "imperative", imperative: true}, + {tag: "declarative", imperative: false} + ] + } + + function test_timeout(data) { + var control = createTemporaryObject(toolTip, testCase, {timeout: 100}) + + compare(control.visible, false) + if (data.imperative) + control.open() + else + control.visible = true + compare(control.visible, true) + // wait a bit to make sure that it's still visible + wait(50) + compare(control.visible, true) + // re-arm for another 200 ms + control.timeout = 200 + compare(control.visible, true) + // ensure that it's still visible after 150 ms (where old timeout < 150 < new timeout) + wait(150) + compare(control.visible, true) + tryCompare(control, "visible", false) + } + + function test_warning() { + ignoreWarning(new RegExp(".*QML QtObject: ToolTip must be attached to an Item")) + ignoreWarning(new RegExp(".*: QML ToolTip: cannot find any window to open popup in.")) + object.ToolTip.show("") // don't crash (QTBUG-56243) + } + + Component { + id: toolTipWithExitTransition + + ToolTip { + Component.onCompleted: contentItem.objectName = "contentItem" + + 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: 500 } + } + } + } + + function test_makeVisibleWhileExitTransitionRunning_data() { + return [ + { tag: "imperative", imperative: true }, + { tag: "declarative", imperative: false } + ] + } + + function test_makeVisibleWhileExitTransitionRunning(data) { + var control = createTemporaryObject(toolTipWithExitTransition, 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) + tryVerify(function() { return control.opacity < 1; }) + + if (data.imperative) + control.open() + else + control.visible = true + tryCompare(control, "opacity", 1) + } + + Component { + id: buttonAndShortcutComponent + + Item { + property alias shortcut: shortcut + property alias button: button + + Shortcut { + id: shortcut + sequence: "A" + } + + Button { + id: button + text: "Just a button" + focusPolicy: Qt.NoFocus + + ToolTip.visible: button.hovered + ToolTip.text: qsTr("Some helpful text") + } + } + } + + function test_activateShortcutWhileToolTipVisible() { + if ((Qt.platform.pluginName === "offscreen") + || (Qt.platform.pluginName === "minimal")) + skip("Mouse hoovering not functional on offscreen/minimal platforms") + + var root = createTemporaryObject(buttonAndShortcutComponent, testCase) + verify(root) + + mouseMove(root.button, root.button.width / 2, root.button.height / 2) + tryCompare(root.button.ToolTip.toolTip, "visible", true) + + var shortcutActivatedSpy = signalSpy.createObject(root, { target: root.shortcut, signalName: "activated" }) + verify(shortcutActivatedSpy.valid) + keyPress(Qt.Key_A) + compare(shortcutActivatedSpy.count, 1) + } + + Component { + id: hoverComponent + MouseArea { + id: hoverArea + property alias tooltip: tooltip + hoverEnabled: true + width: testCase.width + height: testCase.height + ToolTip { + id: tooltip + x: 10; y: 10 + width: 10; height: 10 + visible: hoverArea.containsMouse + } + } + } + + // QTBUG-63644 + function test_hover() { + var root = createTemporaryObject(hoverComponent, testCase) + verify(root) + + var tooltip = root.tooltip + verify(tooltip) + + for (var pos = 0; pos <= 25; pos += 5) { + mouseMove(root, pos, pos) + verify(tooltip.visible) + } + } + + Component { + id: nonAttachedToolTipComponent + ToolTip { } + } + + function test_nonAttachedToolTipShowAndHide() { + var tip = createTemporaryObject(nonAttachedToolTipComponent, testCase) + verify(tip) + tip.show("hello"); + verify(tip.visible) + verify(tip.text === "hello") + tip.hide() + tryCompare(tip, "visible", false) + tip.show("delay", 200) + verify(tip.visible) + tryCompare(tip, "visible", false) + } + + Component { + id: timeoutButtonRowComponent + + Row { + Button { + text: "Timeout: 1" + ToolTip.text: text + ToolTip.visible: down + ToolTip.timeout: 1 + } + + Button { + text: "Timeout: -1" + ToolTip.text: text + ToolTip.visible: down + } + } + } + + // QTBUG-74226 + function test_attachedTimeout() { + var row = createTemporaryObject(timeoutButtonRowComponent, testCase) + verify(row) + + // Press the button that has no timeout; it should stay visible. + var button2 = row.children[1] + mousePress(button2) + compare(button2.down, true) + tryCompare(button2.ToolTip.toolTip, "opened", true) + + // Wait a bit to make sure that it's still visible. + wait(50) + compare(button2.ToolTip.toolTip.opened, true) + + // Release and should close. + mouseRelease(button2) + compare(button2.down, false) + tryCompare(button2.ToolTip, "visible", false) + + // Now, press the first button that does have a timeout; it should close on its own eventually. + var button1 = row.children[0] + mousePress(button1) + compare(button1.down, true) + // We use a short timeout to speed up the test, but tryCompare(...opened, true) then + // fails because the dialog has already been hidden by that point, so just check that it's + // immediately visible, which is more or less the same thing. + compare(button1.ToolTip.visible, true) + tryCompare(button1.ToolTip, "visible", false) + mouseRelease(button2) + + // Now, hover over the second button again. It should still stay visible until the mouse is released. + mousePress(button2) + compare(button2.down, true) + tryCompare(button2.ToolTip.toolTip, "opened", true) + + // Wait a bit to make sure that it's still visible. + wait(50) + compare(button2.ToolTip.toolTip.opened, true) + + // Release and should close. + mouseRelease(button2) + compare(button2.down, false) + tryCompare(button2.ToolTip, "visible", false) + } + + Component { + id: wrapComponent + + Item { + ToolTip.text: "This is some very very very very very very very very very very very very" + + " very very very very very very very very very very very very very very" + + " very very very very very very very very very very very very long text" + } + } + + // QTBUG-62350 + function test_wrap() { + var item = createTemporaryObject(wrapComponent, testCase) + verify(item) + + // Avoid "cannot find window to popup in" warning that can occur if it's made visible too early. + item.ToolTip.visible = true + tryCompare(item.ToolTip.toolTip, "opened", true) + compare(item.ToolTip.toolTip.contentItem.wrapMode, Text.Wrap) + verify(item.ToolTip.toolTip.contentItem.width < item.ToolTip.toolTip.contentItem.implicitWidth) + } + + // QTBUG-83630: Test that newlines are accounted for in the implicit contentWidth. + function test_newLines() { + var item = createTemporaryObject(itemComponent, testCase) + verify(item) + + item.ToolTip.show("This is one line of text\nThis is another line of text") + + // The implicitWidth of the Text item for the text above will be larger than + // its contentWidth. ToolTip's implicitWidth uses contentWidth in its calculation, + // so we check that it's less than the Text's implicitWidth. + verify(item.ToolTip.toolTip.implicitWidth < item.ToolTip.toolTip.contentItem.implicitWidth) + } + + function test_timeoutAfterOpened() { + let control = createTemporaryObject(toolTipWithExitTransition, testCase, { timeout: 1, exit: null }) + verify(control) + + let openedSpy = createTemporaryObject(signalSpy, testCase, { target: control, signalName: "opened" }) + verify(openedSpy.valid) + + control.show("Test") + tryCompare(openedSpy, "count", 1) + } +} |