aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/auto.pro7
-rw-r--r--tests/auto/controls/data/tst_abstractbutton.qml23
-rw-r--r--tests/auto/controls/data/tst_button.qml3
-rw-r--r--tests/auto/controls/data/tst_delaybutton.qml3
-rw-r--r--tests/auto/controls/data/tst_swipedelegate.qml3
-rw-r--r--tests/auto/controls/data/tst_tooltip.qml33
-rw-r--r--tests/auto/customization/tst_customization.cpp4
-rw-r--r--tests/auto/qquickcontrol/data/flickable.qml71
-rw-r--r--tests/auto/qquickcontrol/qquickcontrol.pro14
-rw-r--r--tests/auto/qquickcontrol/tst_qquickcontrol.cpp110
-rw-r--r--tests/auto/qquickheaderview/data/Window.qml121
-rw-r--r--tests/auto/qquickheaderview/qquickheaderview.pro15
-rw-r--r--tests/auto/qquickheaderview/tst_qquickheaderview.cpp354
-rw-r--r--tests/auto/qquickpopup/data/invisibleToolTipOpen.qml28
-rw-r--r--tests/auto/qquickpopup/tst_qquickpopup.cpp28
-rw-r--r--tests/auto/sanity/BLACKLIST20
-rw-r--r--tests/auto/sanity/tst_sanity.cpp2
-rw-r--r--tests/auto/translation/data/comboBox.qml65
-rw-r--r--tests/auto/translation/data/dialogButtonBoxWithCustomButtons.qml75
-rw-r--r--tests/auto/translation/qml_jp.qmbin0 -> 135 bytes
-rw-r--r--tests/auto/translation/qml_jp.ts28
-rw-r--r--tests/auto/translation/qtbase_fr.qmbin0 -> 259 bytes
-rw-r--r--tests/auto/translation/qtbase_fr.ts1
-rw-r--r--tests/auto/translation/translation.pro5
-rw-r--r--tests/auto/translation/tst_translation.cpp65
25 files changed, 1059 insertions, 19 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 8612e2c1..6059cf7b 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -14,6 +14,7 @@ SUBDIRS += \
qquickapplicationwindow \
qquickcolor \
qquickdrawer \
+ qquickheaderview \
qquickiconimage \
qquickiconlabel \
qquickimaginestyle \
@@ -29,7 +30,5 @@ SUBDIRS += \
qquickuniversalstyleconf \
revisions \
sanity \
- snippets
-
-# Requires lrelease, which isn't always available in CI.
-qtHaveModule(tools): translation
+ snippets \
+ translation
diff --git a/tests/auto/controls/data/tst_abstractbutton.qml b/tests/auto/controls/data/tst_abstractbutton.qml
index ee26a6d6..da5642cc 100644
--- a/tests/auto/controls/data/tst_abstractbutton.qml
+++ b/tests/auto/controls/data/tst_abstractbutton.qml
@@ -887,4 +887,27 @@ TestCase {
mouseRelease(control)
compare(clickedSpy.count, 1)
}
+
+ function test_doubleClick() {
+ let control = createTemporaryObject(button, testCase, { text: "Hello" })
+ verify(control)
+
+ let pressedSpy = signalSpy.createObject(control, { target: control, signalName: "pressed" })
+ verify(pressedSpy.valid)
+
+ let releasedSpy = signalSpy.createObject(control, { target: control, signalName: "released" })
+ verify(releasedSpy.valid)
+
+ let clickedSpy = signalSpy.createObject(control, { target: control, signalName: "clicked" })
+ verify(clickedSpy.valid)
+
+ let doubleClickedSpy = signalSpy.createObject(control, { target: control, signalName: "doubleClicked" })
+ verify(doubleClickedSpy.valid)
+
+ mouseDoubleClickSequence(control)
+ compare(pressedSpy.count, 2)
+ compare(releasedSpy.count, 2)
+ compare(clickedSpy.count, 1)
+ compare(doubleClickedSpy.count, 1)
+ }
}
diff --git a/tests/auto/controls/data/tst_button.qml b/tests/auto/controls/data/tst_button.qml
index bd4fe80e..83a6ea61 100644
--- a/tests/auto/controls/data/tst_button.qml
+++ b/tests/auto/controls/data/tst_button.qml
@@ -152,8 +152,7 @@ TestCase {
"doubleClicked",
["pressedChanged", { "pressed": false }],
["downChanged", { "down": false }],
- "released",
- "clicked"]
+ "released"]
mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton)
verify(sequenceSpy.success)
}
diff --git a/tests/auto/controls/data/tst_delaybutton.qml b/tests/auto/controls/data/tst_delaybutton.qml
index 2560177d..e965b5ef 100644
--- a/tests/auto/controls/data/tst_delaybutton.qml
+++ b/tests/auto/controls/data/tst_delaybutton.qml
@@ -173,8 +173,7 @@ TestCase {
"doubleClicked",
["pressedChanged", { "pressed": false }],
["downChanged", { "down": false }],
- "released",
- "clicked"]
+ "released"]
mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton)
verify(sequenceSpy.success)
}
diff --git a/tests/auto/controls/data/tst_swipedelegate.qml b/tests/auto/controls/data/tst_swipedelegate.qml
index 3e2ff460..71eb0b99 100644
--- a/tests/auto/controls/data/tst_swipedelegate.qml
+++ b/tests/auto/controls/data/tst_swipedelegate.qml
@@ -654,8 +654,7 @@ TestCase {
"pressed",
"doubleClicked",
["pressedChanged", { "pressed": false }],
- "released",
- "clicked"
+ "released"
];
mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton);
verify(mouseSignalSequenceSpy.success);
diff --git a/tests/auto/controls/data/tst_tooltip.qml b/tests/auto/controls/data/tst_tooltip.qml
index d98a7cc8..6d45b09d 100644
--- a/tests/auto/controls/data/tst_tooltip.qml
+++ b/tests/auto/controls/data/tst_tooltip.qml
@@ -227,15 +227,46 @@ TestCase {
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: 1000 }
+ NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 500 }
}
}
}
+ function test_openDuringExitTransitionWithTimeout() {
+ let control = createTemporaryObject(toolTipWithExitTransition, testCase, { timeout: 250 })
+ verify(control)
+
+ let openedSpy = signalSpy.createObject(control, { target: control, signalName: "opened" })
+ verify(openedSpy.valid)
+
+ control.open()
+ verify(control.visible)
+ // Can't be fully open yet because the enter transition has only just started.
+ compare(control.opened, false)
+ compare(control.enter.running, true)
+ // Wait for it to have opened. We don't check that the opened property is still true
+ // because it can result in hard-to-reproduce flakiness. Instead we just check that
+ // it was opened at some point.
+ tryCompare(openedSpy, "count", 1)
+
+ // Let it timeout and begin the exit transition.
+ tryCompare(control, "opened", false)
+ verify(control.visible)
+ tryCompare(control.exit, "running", true)
+ verify(control.visible)
+
+ // Quickly open it again; it should still timeout eventually.
+ control.open()
+ tryCompare(openedSpy, "count", 2)
+ tryCompare(control.exit, "running", true)
+ }
+
function test_makeVisibleWhileExitTransitionRunning_data() {
return [
{ tag: "imperative", imperative: true },
diff --git a/tests/auto/customization/tst_customization.cpp b/tests/auto/customization/tst_customization.cpp
index cce74b41..498a9e60 100644
--- a/tests/auto/customization/tst_customization.cpp
+++ b/tests/auto/customization/tst_customization.cpp
@@ -311,7 +311,7 @@ void tst_customization::creation()
QVERIFY2(qt_createdQObjects()->removeOne(controlName), qPrintable(controlName + " was not created as expected"));
for (QString delegate : qAsConst(delegates)) {
- QStringList properties = delegate.split(".", QString::SkipEmptyParts);
+ QStringList properties = delegate.split(".", Qt::SkipEmptyParts);
// <control>-<delegate>-<style>(-<override>)
delegate.append("-" + style);
@@ -412,7 +412,7 @@ void tst_customization::override()
QVERIFY2(qt_createdQObjects()->removeOne(controlName), qPrintable(controlName + " was not created as expected"));
for (QString delegate : qAsConst(delegates)) {
- QStringList properties = delegate.split(".", QString::SkipEmptyParts);
+ QStringList properties = delegate.split(".", Qt::SkipEmptyParts);
// <control>-<delegate>-<style>(-override)
delegate.append("-" + style);
diff --git a/tests/auto/qquickcontrol/data/flickable.qml b/tests/auto/qquickcontrol/data/flickable.qml
new file mode 100644
index 00000000..f3a1c381
--- /dev/null
+++ b/tests/auto/qquickcontrol/data/flickable.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 2.14
+import QtQuick.Controls 2.14
+
+ApplicationWindow {
+ width: 400
+ height: 400
+
+ property alias flickable: flickable
+ property alias button: button
+
+ Flickable {
+ id: flickable
+ width: 300
+ height: 400
+ pressDelay: 50
+ Button {
+ id: button
+ text: "This is a test button"
+ }
+ }
+}
diff --git a/tests/auto/qquickcontrol/qquickcontrol.pro b/tests/auto/qquickcontrol/qquickcontrol.pro
new file mode 100644
index 00000000..8641343d
--- /dev/null
+++ b/tests/auto/qquickcontrol/qquickcontrol.pro
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_qquickcontrol
+SOURCES += tst_qquickcontrol.cpp
+
+macos:CONFIG -= app_bundle
+
+QT += core-private gui-private qml-private quick-private testlib quicktemplates2-private
+
+include (../shared/util.pri)
+
+TESTDATA = data/*
+
+OTHER_FILES += \
+ data/*.qml
diff --git a/tests/auto/qquickcontrol/tst_qquickcontrol.cpp b/tests/auto/qquickcontrol/tst_qquickcontrol.cpp
new file mode 100644
index 00000000..c8d34756
--- /dev/null
+++ b/tests/auto/qquickcontrol/tst_qquickcontrol.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 <QtTest/qtest.h>
+#include <QtTest/qsignalspy.h>
+#include "../shared/util.h"
+#include "../shared/visualtestutil.h"
+#include "../shared/qtest_quickcontrols.h"
+#include <QtGui/qpa/qwindowsysteminterface.h>
+#include <QtQuickTemplates2/private/qquickbutton_p.h>
+
+using namespace QQuickVisualTestUtil;
+
+class tst_QQuickControl : public QQmlDataTest
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void flickable();
+
+private:
+ struct TouchDeviceDeleter
+ {
+ static inline void cleanup(QTouchDevice *device)
+ {
+ QWindowSystemInterface::unregisterTouchDevice(device);
+ delete device;
+ }
+ };
+
+ QScopedPointer<QTouchDevice, TouchDeviceDeleter> touchDevice;
+};
+
+
+void tst_QQuickControl::initTestCase()
+{
+ QQmlDataTest::initTestCase();
+ qputenv("QML_NO_TOUCH_COMPRESSION", "1");
+
+ touchDevice.reset(new QTouchDevice);
+ touchDevice->setType(QTouchDevice::TouchScreen);
+ QWindowSystemInterface::registerTouchDevice(touchDevice.data());
+}
+
+void tst_QQuickControl::flickable()
+{
+ // Check that when a Button that is inside a Flickable with a pressDelay
+ // still gets the released and clicked signals sent due to the fact that
+ // Flickable sends a mouse event for the delay and not a touch event
+ QQuickApplicationHelper helper(this, QStringLiteral("flickable.qml"));
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickButton *button = window->property("button").value<QQuickButton *>();
+ QVERIFY(button);
+
+ QSignalSpy buttonPressedSpy(button, SIGNAL(pressed()));
+ QVERIFY(buttonPressedSpy.isValid());
+
+ QSignalSpy buttonReleasedSpy(button, SIGNAL(released()));
+ QVERIFY(buttonReleasedSpy.isValid());
+
+ QSignalSpy buttonClickedSpy(button, SIGNAL(clicked()));
+ QVERIFY(buttonClickedSpy.isValid());
+
+ QTest::touchEvent(window, touchDevice.data()).press(0, QPoint(button->width() / 2, button->height() / 2));
+ QTRY_COMPARE(buttonPressedSpy.count(), 1);
+ QTest::touchEvent(window, touchDevice.data()).release(0, QPoint(button->width() / 2, button->height() / 2));
+ QTRY_COMPARE(buttonReleasedSpy.count(), 1);
+ QTRY_COMPARE(buttonClickedSpy.count(), 1);
+}
+
+QTEST_QUICKCONTROLS_MAIN(tst_QQuickControl)
+
+#include "tst_qquickcontrol.moc"
diff --git a/tests/auto/qquickheaderview/data/Window.qml b/tests/auto/qquickheaderview/data/Window.qml
new file mode 100644
index 00000000..3811904e
--- /dev/null
+++ b/tests/auto/qquickheaderview/data/Window.qml
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 2.15
+import QtQuick.Window 2.15
+import QtQuick.Controls 2.15
+import TestTableModel 0.1
+import TestTableModelWithHeader 0.1
+import HeaderDataProxyModel 0.1
+
+Window {
+ objectName: "window"
+ width: 400
+ height: 400
+ visible: true
+
+ Component {
+ id: cellDelegate
+ Rectangle {
+ implicitHeight: 25
+ implicitWidth: 50
+ color: "red"
+ Text {
+ text: row + "," + column
+ }
+ }
+ }
+
+ HeaderDataProxyModel {
+ id: pm
+ objectName: "proxyModel"
+ }
+
+ TestTableModel {
+ id: tm
+ objectName: "tableModel"
+ rowCount: 5
+ columnCount: 10
+ }
+
+ TestTableModelWithHeader {
+ id: thm
+ objectName: "tableHeaderModel"
+ rowCount: 5
+ columnCount: 10
+ }
+
+ HorizontalHeaderView {
+ id: hhv
+ objectName: "horizontalHeader"
+ width: 200
+ height: 200
+ model: thm
+ delegate: cellDelegate
+ }
+
+ VerticalHeaderView {
+ id: vhv
+ objectName: "verticalHeader"
+ width: 200
+ height: 200
+ model: thm
+ delegate: cellDelegate
+ }
+
+ TableView {
+ id: tv
+ objectName: "tableView"
+ width: 400
+ height: 400
+ model: thm
+ delegate:cellDelegate
+ }
+}
diff --git a/tests/auto/qquickheaderview/qquickheaderview.pro b/tests/auto/qquickheaderview/qquickheaderview.pro
new file mode 100644
index 00000000..4410c888
--- /dev/null
+++ b/tests/auto/qquickheaderview/qquickheaderview.pro
@@ -0,0 +1,15 @@
+CONFIG += testcase
+TARGET = tst_qquickheaderview
+SOURCES += tst_qquickheaderview.cpp
+
+macos:CONFIG -= app_bundle
+
+QT += core-private gui-private qml-private quick-private testlib quickcontrols2 \
+ quickcontrols2-private quicktemplates2-private quicktemplates2
+
+include (../shared/util.pri)
+
+TESTDATA = data/*
+
+OTHER_FILES += \
+ data/*.qml
diff --git a/tests/auto/qquickheaderview/tst_qquickheaderview.cpp b/tests/auto/qquickheaderview/tst_qquickheaderview.cpp
new file mode 100644
index 00000000..5ce5439d
--- /dev/null
+++ b/tests/auto/qquickheaderview/tst_qquickheaderview.cpp
@@ -0,0 +1,354 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 "../shared/qtest_quickcontrols.h"
+#include "../shared/util.h"
+#include <QtTest/qsignalspy.h>
+#include <QtTest/qtest.h>
+
+#include <QAbstractItemModelTester>
+#include <QtQml/QQmlEngine>
+#include <QtQuick/private/qquickwindow_p.h>
+#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
+#include <QtQuickTemplates2/private/qquickheaderview_p.h>
+#include <private/qquickheaderview_p_p.h>
+
+class TestTableModel : public QAbstractTableModel {
+ Q_OBJECT
+ Q_PROPERTY(int rowCount READ rowCount WRITE setRowCount NOTIFY rowCountChanged)
+ Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount NOTIFY columnCountChanged)
+
+public:
+ TestTableModel(QObject *parent = nullptr)
+ : QAbstractTableModel(parent)
+ {
+ }
+
+ int rowCount(const QModelIndex & = QModelIndex()) const override
+ {
+ return m_rows;
+ }
+ virtual void setRowCount(int count)
+ {
+ beginResetModel();
+ m_rows = count;
+ emit rowCountChanged();
+ endResetModel();
+ }
+
+ int columnCount(const QModelIndex & = QModelIndex()) const override
+ {
+ return m_cols;
+ }
+ virtual void setColumnCount(int count)
+ {
+ beginResetModel();
+ m_cols = count;
+ emit columnCountChanged();
+ endResetModel();
+ }
+
+ int indexValue(const QModelIndex &index) const
+ {
+ return index.row() + (index.column() * rowCount());
+ }
+
+ Q_INVOKABLE QModelIndex toQModelIndex(int serialIndex)
+ {
+ return createIndex(serialIndex % rowCount(), serialIndex / rowCount());
+ }
+
+ Q_INVOKABLE QVariant data(int row, int col)
+ {
+ return data(createIndex(row, col), Qt::DisplayRole);
+ }
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ if (!index.isValid())
+ return QVariant();
+
+ switch (role) {
+ case Qt::DisplayRole:
+ return QString("%1, %2, checked: %3 ")
+ .arg(index.row())
+ .arg(index.column())
+ .arg(m_checkedCells.contains(indexValue(index)));
+ case Qt::EditRole:
+ return m_checkedCells.contains(indexValue(index));
+ default:
+ return QVariant();
+ }
+ }
+
+ bool setData(const QModelIndex &index, const QVariant &value,
+ int role = Qt::EditRole) override
+ {
+
+ if (role != Qt::EditRole)
+ return false;
+
+ int i = indexValue(index);
+ bool checked = value.toBool();
+ if (checked == m_checkedCells.contains(i))
+ return false;
+
+ if (checked)
+ m_checkedCells.insert(i);
+ else
+ m_checkedCells.remove(i);
+
+ emit dataChanged(index, index, { role });
+ return true;
+ }
+
+ Q_INVOKABLE QHash<int, QByteArray> roleNames() const override
+ {
+ return {
+ { Qt::DisplayRole, "display" },
+ { Qt::EditRole, "edit" }
+ };
+ }
+
+signals:
+ void rowCountChanged();
+ void columnCountChanged();
+
+private:
+ int m_rows = 0;
+ int m_cols = 0;
+
+ QSet<int> m_checkedCells;
+};
+
+class TestTableModelWithHeader : public TestTableModel {
+
+ Q_OBJECT
+public:
+ void setRowCount(int count) override
+ {
+ vData.resize(count);
+ TestTableModel::setRowCount(count);
+ }
+
+ void setColumnCount(int count) override
+ {
+ hData.resize(count);
+ TestTableModel::setColumnCount(count);
+ }
+ Q_INVOKABLE QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const override
+ {
+ auto sectionCount = orientation == Qt::Horizontal ? columnCount() : rowCount();
+ if (section < 0 || section >= sectionCount)
+ return QVariant();
+ switch (role) {
+ case Qt::DisplayRole:
+ case Qt::EditRole: {
+ auto &data = orientation == Qt::Horizontal ? hData : vData;
+ return data[section].toString();
+ }
+ default:
+ return QVariant();
+ }
+ }
+ Q_INVOKABLE bool setHeaderData(int section, Qt::Orientation orientation,
+ const QVariant &value, int role = Qt::EditRole) override
+ {
+ qDebug() << Q_FUNC_INFO
+ << "section:" << section
+ << "orient:" << orientation
+ << "value:" << value
+ << "role:" << QAbstractItemModel::roleNames()[role];
+ auto sectionCount = orientation == Qt::Horizontal ? columnCount() : rowCount();
+ if (section < 0 || section >= sectionCount)
+ return false;
+ auto &data = orientation == Qt::Horizontal ? hData : vData;
+ data[section] = value;
+ emit headerDataChanged(orientation, section, section);
+ return true;
+ }
+
+private:
+ QVector<QVariant> hData, vData;
+};
+
+class tst_QQuickHeaderView : public QQmlDataTest {
+ Q_OBJECT
+
+private slots:
+ void initTestCase() override;
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+ void defaults();
+ void testHeaderDataProxyModel();
+ void testOrientation();
+ void testModel();
+
+private:
+ QQmlEngine *engine;
+ QString errorString;
+
+ std::unique_ptr<QObject> rootObjectFromQml(const char *file)
+ {
+ auto component = new QQmlComponent(engine);
+ component->loadUrl(testFileUrl(file));
+ auto root = component->create();
+ if (!root)
+ errorString = component->errorString();
+ return std::unique_ptr<QObject>(new QObject(root));
+ }
+};
+
+void tst_QQuickHeaderView::initTestCase()
+{
+ QQmlDataTest::initTestCase();
+ qmlRegisterType<TestTableModel>("TestTableModel", 0, 1, "TestTableModel");
+ qmlRegisterType<TestTableModelWithHeader>("TestTableModelWithHeader", 0, 1, "TestTableModelWithHeader");
+ qmlRegisterType<QHeaderDataProxyModel>("HeaderDataProxyModel", 0, 1, "HeaderDataProxyModel");
+}
+
+void tst_QQuickHeaderView::cleanupTestCase()
+{
+}
+
+void tst_QQuickHeaderView::init()
+{
+ engine = new QQmlEngine(this);
+}
+
+void tst_QQuickHeaderView::cleanup()
+{
+ if (engine) {
+ delete engine;
+ engine = nullptr;
+ }
+}
+
+void tst_QQuickHeaderView::defaults()
+{
+ QQmlComponent component(engine);
+ component.loadUrl(testFileUrl("Window.qml"));
+
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY2(root, qPrintable(component.errorString()));
+
+ auto hhv = root->findChild<QQuickHorizontalHeaderView *>("horizontalHeader");
+ QVERIFY(hhv);
+ auto vhv = root->findChild<QQuickVerticalHeaderView *>("verticalHeader");
+ QVERIFY(vhv);
+ auto tm = root->findChild<TestTableModel *>("tableModel");
+ QVERIFY(tm);
+ auto pm = root->findChild<QHeaderDataProxyModel *>("proxyModel");
+ QVERIFY(pm);
+ auto tv = root->findChild<QQuickTableView *>("tableView");
+ QVERIFY(tv);
+}
+
+void tst_QQuickHeaderView::testHeaderDataProxyModel()
+{
+ TestTableModel model;
+ model.setColumnCount(10);
+ model.setRowCount(7);
+ QHeaderDataProxyModel model2;
+ model2.setSourceModel(&model);
+ QAbstractItemModelTester tester(&model2, QAbstractItemModelTester::FailureReportingMode::QtTest);
+}
+
+void tst_QQuickHeaderView::testOrientation()
+{
+ QQmlComponent component(engine);
+ component.loadUrl(testFileUrl("Window.qml"));
+
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY2(root, qPrintable(component.errorString()));
+
+ auto hhv = root->findChild<QQuickHorizontalHeaderView *>("horizontalHeader");
+ QVERIFY(hhv);
+ QCOMPARE(hhv->columns(), 10);
+ QCOMPARE(hhv->rows(), 1);
+ auto vhv = root->findChild<QQuickVerticalHeaderView *>("verticalHeader");
+ QVERIFY(vhv);
+
+ hhv->setSyncDirection(Qt::Vertical);
+ hhv->flick(10, 20);
+
+ vhv->setSyncDirection(Qt::Horizontal);
+ vhv->flick(20, 10);
+
+ QVERIFY(QTest::qWaitForWindowActive(qobject_cast<QWindow *>(root.data())));
+ // Explicitly setting a different synDirection is ignored
+ QCOMPARE(hhv->syncDirection(), Qt::Horizontal);
+ QCOMPARE(hhv->flickableDirection(), QQuickFlickable::HorizontalFlick);
+ QCOMPARE(vhv->syncDirection(), Qt::Vertical);
+ QCOMPARE(vhv->flickableDirection(), QQuickFlickable::VerticalFlick);
+}
+
+void tst_QQuickHeaderView::testModel()
+{
+ QQmlComponent component(engine);
+ component.loadUrl(testFileUrl("Window.qml"));
+
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY2(root, qPrintable(component.errorString()));
+
+ auto hhv = root->findChild<QQuickHorizontalHeaderView *>("horizontalHeader");
+ QVERIFY(hhv);
+ auto thm = root->findChild<TestTableModel *>("tableHeaderModel");
+ QVERIFY(thm);
+ auto pm = root->findChild<QHeaderDataProxyModel *>("proxyModel");
+ QVERIFY(pm);
+
+ QSignalSpy modelChangedSpy(hhv, SIGNAL(modelChanged()));
+ QVERIFY(modelChangedSpy.isValid());
+
+ hhv->setModel(QVariant::fromValue(thm));
+ QCOMPARE(modelChangedSpy.count(), 0);
+
+ hhv->setModel(QVariant::fromValue(pm));
+ QCOMPARE(modelChangedSpy.count(), 1);
+
+ TestTableModel ttm2;
+ ttm2.setRowCount(100);
+ ttm2.setColumnCount(30);
+ hhv->setModel(QVariant::fromValue(&ttm2));
+ QCOMPARE(modelChangedSpy.count(), 2);
+}
+
+QTEST_MAIN(tst_QQuickHeaderView)
+
+#include "tst_qquickheaderview.moc"
diff --git a/tests/auto/qquickpopup/data/invisibleToolTipOpen.qml b/tests/auto/qquickpopup/data/invisibleToolTipOpen.qml
new file mode 100644
index 00000000..2e58bb97
--- /dev/null
+++ b/tests/auto/qquickpopup/data/invisibleToolTipOpen.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.13
+import QtQuick.Window 2.13
+import QtQuick.Controls 2.13
+
+Window {
+ width: 400
+ height: 400
+ property alias mouseArea: mouseArea
+ property alias loader: loader
+ MouseArea {
+ id: mouseArea
+ property bool isToolTipVisible: false
+ width: 200
+ height: 200
+ hoverEnabled: true
+ ToolTip.text: "static tooltip"
+ ToolTip.visible: containsMouse
+ ToolTip.onVisibleChanged: isToolTipVisible = ToolTip.visible
+ }
+ Loader {
+ id: loader
+ active: false
+ sourceComponent: Rectangle {
+ ToolTip.text: "dynamic tooltip"
+ ToolTip.visible: false
+ }
+ }
+}
diff --git a/tests/auto/qquickpopup/tst_qquickpopup.cpp b/tests/auto/qquickpopup/tst_qquickpopup.cpp
index f0d8b004..d96436de 100644
--- a/tests/auto/qquickpopup/tst_qquickpopup.cpp
+++ b/tests/auto/qquickpopup/tst_qquickpopup.cpp
@@ -94,6 +94,7 @@ private slots:
void toolTipCrashOnClose();
void setOverlayParentToNull();
void tabFence();
+ void invisibleToolTipOpen();
};
void tst_QQuickPopup::initTestCase()
@@ -1358,6 +1359,33 @@ void tst_QQuickPopup::tabFence()
QVERIFY(outsideButton1->hasActiveFocus());
}
+void tst_QQuickPopup::invisibleToolTipOpen()
+{
+ QQuickApplicationHelper helper(this, "invisibleToolTipOpen.qml");
+
+ QQuickWindow *window = helper.window;
+ centerOnScreen(window);
+ moveMouseAway(window);
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ QQuickItem *mouseArea = qvariant_cast<QQuickItem *>(window->property("mouseArea"));
+ QVERIFY(mouseArea);
+ QObject *loader = qvariant_cast<QObject *>(window->property("loader"));
+ QVERIFY(loader);
+
+ QTest::mouseMove(window, QPoint(mouseArea->width() / 2, mouseArea->height() / 2));
+ QTRY_VERIFY(mouseArea->property("isToolTipVisible").toBool());
+
+ QSignalSpy componentLoadedSpy(loader, SIGNAL(loaded()));
+ QVERIFY(componentLoadedSpy.isValid());
+
+ loader->setProperty("active", true);
+ QTRY_COMPARE(componentLoadedSpy.count(), 1);
+
+ QTRY_VERIFY(mouseArea->property("isToolTipVisible").toBool());
+}
+
QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup)
#include "tst_qquickpopup.moc"
diff --git a/tests/auto/sanity/BLACKLIST b/tests/auto/sanity/BLACKLIST
index 42ad3448..2a157b87 100644
--- a/tests/auto/sanity/BLACKLIST
+++ b/tests/auto/sanity/BLACKLIST
@@ -2,3 +2,23 @@
*
[attachedObjects:material/SwitchDelegate.qml]
*
+[ids:controls/HorizontalHeaderView.qml]
+*
+[ids:controls/VerticalHeaderView.qml]
+*
+[ids:fusion/HorizontalHeaderView.qml]
+*
+[ids:fusion/VerticalHeaderView.qml]
+*
+[ids:imagine/HorizontalHeaderView.qml]
+*
+[ids:imagine/VerticalHeaderView.qml]
+*
+[ids:material/HorizontalHeaderView.qml]
+*
+[ids:material/VerticalHeaderView.qml]
+*
+[ids:universal/HorizontalHeaderView.qml]
+*
+[ids:universal/VerticalHeaderView.qml]
+*
diff --git a/tests/auto/sanity/tst_sanity.cpp b/tests/auto/sanity/tst_sanity.cpp
index a801ecaf..78b86f00 100644
--- a/tests/auto/sanity/tst_sanity.cpp
+++ b/tests/auto/sanity/tst_sanity.cpp
@@ -122,7 +122,7 @@ public:
if (!parser.parse()) {
const auto diagnosticMessages = parser.diagnosticMessages();
for (const QQmlJS::DiagnosticMessage &msg : diagnosticMessages)
-#if Q_QML_PRIVATE_API_VERSION < 5
+#if Q_QML_PRIVATE_API_VERSION >= 8
m_errors += QString("%s:%d : %s").arg(m_fileName).arg(msg.loc.startLine).arg(msg.message);
#else
m_errors += QString("%s:%d : %s").arg(m_fileName).arg(msg.line).arg(msg.message);
diff --git a/tests/auto/translation/data/comboBox.qml b/tests/auto/translation/data/comboBox.qml
new file mode 100644
index 00000000..8bb8ed6f
--- /dev/null
+++ b/tests/auto/translation/data/comboBox.qml
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 2.13
+import QtQuick.Controls 2.13
+
+ComboBox {
+ objectName: "comboBox"
+ textRole: "label"
+ model: ListModel {
+ ListElement {
+ label: qsTr("Hello")
+ }
+ ListElement {
+ label: qsTr("ListView")
+ }
+ }
+}
diff --git a/tests/auto/translation/data/dialogButtonBoxWithCustomButtons.qml b/tests/auto/translation/data/dialogButtonBoxWithCustomButtons.qml
new file mode 100644
index 00000000..6f046cf1
--- /dev/null
+++ b/tests/auto/translation/data/dialogButtonBoxWithCustomButtons.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 2.14
+import QtQuick.Controls 2.14
+
+Item {
+ property Dialog dialog: Dialog {
+ width: 300
+ height: 300
+ visible: true
+
+ footer: DialogButtonBox {
+ Button {
+ objectName: "okButton"
+ text: qsTr("OK")
+
+ DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
+ }
+ Button {
+ objectName: "cancelButton"
+ text: qsTr("Cancel")
+
+ DialogButtonBox.buttonRole: DialogButtonBox.RejectRole
+ }
+ }
+ }
+}
diff --git a/tests/auto/translation/qml_jp.qm b/tests/auto/translation/qml_jp.qm
new file mode 100644
index 00000000..a3712e99
--- /dev/null
+++ b/tests/auto/translation/qml_jp.qm
Binary files differ
diff --git a/tests/auto/translation/qml_jp.ts b/tests/auto/translation/qml_jp.ts
new file mode 100644
index 00000000..303c142f
--- /dev/null
+++ b/tests/auto/translation/qml_jp.ts
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ja_JP">
+<context>
+ <name>main</name>
+ <message>
+ <location filename="../main.qml" line="8"/>
+ <source>Hello World</source>
+ <translation>こんにちは世界</translation>
+ </message>
+ <message>
+ <location filename="../main.qml" line="12"/>
+ <source>Hello Text</source>
+ <translation>ハローテキスト</translation>
+ </message>
+ <message>
+ <location filename="../main.qml" line="35"/>
+ <source>Hello</source>
+ <translation>こんにちは</translation>
+ </message>
+ <message>
+ <location filename="../main.qml" line="38"/>
+ <source>ListView</source>
+ <translation>リストビュー</translation>
+ </message>
+</context>
+</TS>
+
diff --git a/tests/auto/translation/qtbase_fr.qm b/tests/auto/translation/qtbase_fr.qm
new file mode 100644
index 00000000..176675a8
--- /dev/null
+++ b/tests/auto/translation/qtbase_fr.qm
Binary files differ
diff --git a/tests/auto/translation/qtbase_fr.ts b/tests/auto/translation/qtbase_fr.ts
index a2a05a07..7aff8bd7 100644
--- a/tests/auto/translation/qtbase_fr.ts
+++ b/tests/auto/translation/qtbase_fr.ts
@@ -20,3 +20,4 @@
</message>
</context>
</TS>
+
diff --git a/tests/auto/translation/translation.pro b/tests/auto/translation/translation.pro
index d2d9d6ee..a33cf56a 100644
--- a/tests/auto/translation/translation.pro
+++ b/tests/auto/translation/translation.pro
@@ -13,7 +13,4 @@ TESTDATA = data/*
OTHER_FILES += \
data/*.qml
-# We only want to run lrelease, which is why we use EXTRA_TRANSLATIONS.
-EXTRA_TRANSLATIONS = qtbase_fr.ts
-# Embed the translations in a qrc file.
-CONFIG += lrelease embed_translations
+RESOURCES += qml_jp.qm qtbase_fr.qm
diff --git a/tests/auto/translation/tst_translation.cpp b/tests/auto/translation/tst_translation.cpp
index 9cbca915..ffb39f96 100644
--- a/tests/auto/translation/tst_translation.cpp
+++ b/tests/auto/translation/tst_translation.cpp
@@ -42,8 +42,10 @@
#include <QtGui/qpa/qplatformtheme.h>
#include <QtQuick/qquickview.h>
#include <QtQuickTemplates2/private/qquickabstractbutton_p.h>
+#include <QtQuickTemplates2/private/qquickcombobox_p.h>
#include <QtQuickTemplates2/private/qquickdialog_p.h>
#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h>
+#include <QtQuickTemplates2/private/qquicktextfield_p.h>
using namespace QQuickVisualTestUtil;
@@ -53,6 +55,8 @@ class tst_translation : public QQmlDataTest
private slots:
void dialogButtonBox();
+ void dialogButtonBoxWithCustomButtons();
+ void comboBox();
};
void tst_translation::dialogButtonBox()
@@ -82,7 +86,7 @@ void tst_translation::dialogButtonBox()
QCOMPARE(discardButton->text(), defaultDiscardText);
QTranslator translator;
- QVERIFY(translator.load(":/i18n/qtbase_fr.qm"));
+ QVERIFY(translator.load("qtbase_fr.qm", ":/"));
QVERIFY(qApp->installTranslator(&translator));
view.engine()->retranslate();
@@ -95,6 +99,65 @@ void tst_translation::dialogButtonBox()
QCOMPARE(discardButton->text(), translatedDiscardText);
}
+// Test that custom buttons with explicitly specified text
+// do not have that text overwritten on language changes.
+void tst_translation::dialogButtonBoxWithCustomButtons()
+{
+ // This is just a way of simulating the translator going out of scope
+ // after the QML has been loaded.
+ QScopedPointer<QTranslator> translator(new QTranslator);
+ // Doesn't matter which language it is, as we won't be using it anyway.
+ QVERIFY(translator->load("qtbase_fr.qm", ":/"));
+ QVERIFY(qApp->installTranslator(translator.data()));
+
+ QQuickView view(testFileUrl("dialogButtonBoxWithCustomButtons.qml"));
+ if (view.status() != QQuickView::Ready)
+ QFAIL("Failed to load QML file");
+ view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ QQuickDialog *dialog = view.rootObject()->property("dialog").value<QQuickDialog*>();
+ QVERIFY(dialog);
+
+ QQuickDialogButtonBox *dialogButtonBox = qobject_cast<QQuickDialogButtonBox*>(dialog->footer());
+ QVERIFY(dialogButtonBox);
+
+ auto okButton = dialogButtonBox->findChild<QQuickAbstractButton*>("okButton");
+ QVERIFY(okButton);
+ QCOMPARE(okButton->text(), QLatin1String("OK"));
+
+ QQuickAbstractButton *cancelButton = dialogButtonBox->findChild<QQuickAbstractButton*>("cancelButton");
+ QVERIFY(cancelButton);
+ QCOMPARE(cancelButton->text(), QLatin1String("Cancel"));
+
+ // Delete the translator and hence cause a LanguageChange event,
+ // but _without_ calling QQmlEngine::retranslate(), which would
+ // restore the original bindings and hence not reproduce the issue.
+ translator.reset();
+ QCOMPARE(okButton->text(), QLatin1String("OK"));
+ QCOMPARE(cancelButton->text(), QLatin1String("Cancel"));
+}
+
+void tst_translation::comboBox()
+{
+ QQuickView view(testFileUrl("comboBox.qml"));
+
+ QQuickComboBox *comboBox = qobject_cast<QQuickComboBox*>(view.rootObject());
+ QVERIFY(comboBox);
+ QCOMPARE(comboBox->displayText(), QLatin1String("Hello"));
+
+ QQuickTextField *contentItem = qobject_cast<QQuickTextField*>(comboBox->contentItem());
+ QVERIFY(contentItem);
+ QCOMPARE(contentItem->text(), QLatin1String("Hello"));
+
+ QTranslator translator;
+ QVERIFY(translator.load("qml_jp.qm", ":/"));
+ QVERIFY(qApp->installTranslator(&translator));
+ view.engine()->retranslate();
+ QTRY_COMPARE(comboBox->displayText(), QString::fromUtf8("こんにちは"));
+ QCOMPARE(contentItem->text(), QString::fromUtf8("こんにちは"));
+}
+
QTEST_MAIN(tst_translation)
#include "tst_translation.moc"