diff options
Diffstat (limited to 'tests/auto/quickcontrols/translation')
-rw-r--r-- | tests/auto/quickcontrols/translation/CMakeLists.txt | 71 | ||||
-rw-r--r-- | tests/auto/quickcontrols/translation/data/comboBox.qml | 18 | ||||
-rw-r--r-- | tests/auto/quickcontrols/translation/data/dialogButtonBox.qml | 14 | ||||
-rw-r--r-- | tests/auto/quickcontrols/translation/data/dialogButtonBoxWithCustomButtons.qml | 28 | ||||
-rw-r--r-- | tests/auto/quickcontrols/translation/data/stackView.qml | 100 | ||||
-rw-r--r-- | tests/auto/quickcontrols/translation/qml_jp.qm | bin | 0 -> 135 bytes | |||
-rw-r--r-- | tests/auto/quickcontrols/translation/qml_jp.ts | 28 | ||||
-rw-r--r-- | tests/auto/quickcontrols/translation/qtbase_fr.qm | bin | 0 -> 259 bytes | |||
-rw-r--r-- | tests/auto/quickcontrols/translation/qtbase_fr.ts | 23 | ||||
-rw-r--r-- | tests/auto/quickcontrols/translation/tst_translation.cpp | 165 |
10 files changed, 447 insertions, 0 deletions
diff --git a/tests/auto/quickcontrols/translation/CMakeLists.txt b/tests/auto/quickcontrols/translation/CMakeLists.txt new file mode 100644 index 0000000000..c1c47e139d --- /dev/null +++ b/tests/auto/quickcontrols/translation/CMakeLists.txt @@ -0,0 +1,71 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +# Generated from translation.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_translation LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## tst_translation Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_translation + SOURCES + tst_translation.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols\\\" + LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +# Resources: +set(qmake_immediate_resource_files + "qml_jp.qm" + "qtbase_fr.qm" +) + +qt_internal_add_resource(tst_translation "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + + +#### Keys ignored in scope 1:.:.:translation.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_translation CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_translation CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols/translation/data/comboBox.qml b/tests/auto/quickcontrols/translation/data/comboBox.qml new file mode 100644 index 0000000000..e6a58787ae --- /dev/null +++ b/tests/auto/quickcontrols/translation/data/comboBox.qml @@ -0,0 +1,18 @@ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ComboBox { + objectName: "comboBox" + textRole: "label" + model: ListModel { + ListElement { + label: qsTr("Hello") + } + ListElement { + label: qsTr("ListView") + } + } +} diff --git a/tests/auto/quickcontrols/translation/data/dialogButtonBox.qml b/tests/auto/quickcontrols/translation/data/dialogButtonBox.qml new file mode 100644 index 0000000000..ababa65019 --- /dev/null +++ b/tests/auto/quickcontrols/translation/data/dialogButtonBox.qml @@ -0,0 +1,14 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +Item { + property Dialog dialog: Dialog { + width: 300 + height: 300 + visible: true + standardButtons: DialogButtonBox.Save | DialogButtonBox.Discard + } +} diff --git a/tests/auto/quickcontrols/translation/data/dialogButtonBoxWithCustomButtons.qml b/tests/auto/quickcontrols/translation/data/dialogButtonBoxWithCustomButtons.qml new file mode 100644 index 0000000000..6e8dca8ad5 --- /dev/null +++ b/tests/auto/quickcontrols/translation/data/dialogButtonBoxWithCustomButtons.qml @@ -0,0 +1,28 @@ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +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/quickcontrols/translation/data/stackView.qml b/tests/auto/quickcontrols/translation/data/stackView.qml new file mode 100644 index 0000000000..44d85c2ea1 --- /dev/null +++ b/tests/auto/quickcontrols/translation/data/stackView.qml @@ -0,0 +1,100 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls +import QtQuick.Window + +Window { + id: window + width: 640 + height: 480 + + property var engine + + signal calledTranslate + + property int pagesCreated: 0 + + Component { + id: translatePageComponent + Item { + id: root + + Component.onCompleted: objectName = "translatePageRootItem" + pagesCreated++ + + StackView.onActivating: { + retranslateTimer.start() + } + + Timer { + id: retranslateTimer + objectName: "retranslateTimer" + interval: 100 + repeat: true + + property int count: 0 + + onTriggered: { + + // This triggers the crash without retranslate(). + // retranslate() got cleverer in 6.2, sidestepping the issue. + replaceExit.animations[0].target = null; + replaceExit.animations[0].target = replaceExit.ViewTransition.item + + console.log("timer within", root, "is about to call retranslate") + window.engine.retranslate() + window.calledTranslate() + count++ + if(count >= 10) { + stop() + count = 0 + } + } + } + + Button { + objectName: "button" + text: qsTr("Push") + onClicked: root.StackView.view.replace(translatePageComponent) + } + } + } + + StackView { + id: stack + objectName: "stackView" + anchors.fill: parent + initialItem: translatePageComponent + + replaceEnter: Transition { + id: replaceEnter + objectName: "enterTransition" + + PropertyAnimation { + objectName: replaceEnter.objectName + "PropertyAnimation" + target: replaceEnter.ViewTransition.item + property: "opacity" + from: 0 + to: 1 + duration: 10 + } + + } + + replaceExit: Transition { + id: replaceExit + objectName: "exitTransition" + + PropertyAnimation { + objectName: replaceExit.objectName + "PropertyAnimation" + target: replaceExit.ViewTransition.item + property: "opacity" + from: 1 + to: 0 + duration: 10 + } + } + } +} + diff --git a/tests/auto/quickcontrols/translation/qml_jp.qm b/tests/auto/quickcontrols/translation/qml_jp.qm Binary files differnew file mode 100644 index 0000000000..a3712e9964 --- /dev/null +++ b/tests/auto/quickcontrols/translation/qml_jp.qm diff --git a/tests/auto/quickcontrols/translation/qml_jp.ts b/tests/auto/quickcontrols/translation/qml_jp.ts new file mode 100644 index 0000000000..303c142fd8 --- /dev/null +++ b/tests/auto/quickcontrols/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/quickcontrols/translation/qtbase_fr.qm b/tests/auto/quickcontrols/translation/qtbase_fr.qm Binary files differnew file mode 100644 index 0000000000..176675a820 --- /dev/null +++ b/tests/auto/quickcontrols/translation/qtbase_fr.qm diff --git a/tests/auto/quickcontrols/translation/qtbase_fr.ts b/tests/auto/quickcontrols/translation/qtbase_fr.ts new file mode 100644 index 0000000000..7aff8bd760 --- /dev/null +++ b/tests/auto/quickcontrols/translation/qtbase_fr.ts @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="fr_FR"> +<context> + <name>QPlatformTheme</name> + <message> + <source>Save</source> + <translation>Enregistrer</translation> + </message> + <message> + <source>Discard</source> + <translation>Ne pas tenir compte</translation> + </message> +</context> +<context> + <name>QGnomeTheme</name> + <message> + <source>&Save</source> + <translation>&Enregistrer</translation> + </message> +</context> +</TS> + diff --git a/tests/auto/quickcontrols/translation/tst_translation.cpp b/tests/auto/quickcontrols/translation/tst_translation.cpp new file mode 100644 index 0000000000..f0798d0367 --- /dev/null +++ b/tests/auto/quickcontrols/translation/tst_translation.cpp @@ -0,0 +1,165 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include <QtTest/qsignalspy.h> +#include <QtTest/qtest.h> +#include <QtCore/qtranslator.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtQuick/qquickview.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.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> +#include <QtQuickControls2/qquickstyle.h> + +using namespace QQuickControlsTestUtils; +using namespace QQuickVisualTestUtils; + +class tst_translation : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_translation(); + +private slots: + void dialogButtonBox(); + void dialogButtonBoxWithCustomButtons(); + void comboBox(); + void stackView(); +}; + +tst_translation::tst_translation() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ + QQuickStyle::setStyle("Basic"); +} + +void tst_translation::dialogButtonBox() +{ + QQuickView view(testFileUrl("dialogButtonBox.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); + + QQuickAbstractButton *saveButton = dialogButtonBox->standardButton(QPlatformDialogHelper::Save); + QVERIFY(saveButton); + QString defaultSaveText = QGuiApplicationPrivate::platformTheme()->standardButtonText(QPlatformDialogHelper::Save); + defaultSaveText = QPlatformTheme::removeMnemonics(defaultSaveText); + QCOMPARE(saveButton->text(), defaultSaveText); + + QQuickAbstractButton *discardButton = dialogButtonBox->standardButton(QPlatformDialogHelper::Discard); + QVERIFY(discardButton); + QString defaultDiscardText = QGuiApplicationPrivate::platformTheme()->standardButtonText(QPlatformDialogHelper::Discard); + defaultDiscardText = QPlatformTheme::removeMnemonics(defaultDiscardText); + QCOMPARE(discardButton->text(), defaultDiscardText); + + QTranslator translator; + QVERIFY(translator.load("qtbase_fr.qm", ":/")); + QVERIFY(qApp->installTranslator(&translator)); + qApp->sendPostedEvents(); + view.engine()->retranslate(); + + QString translatedSaveText = QGuiApplicationPrivate::platformTheme()->standardButtonText(QPlatformDialogHelper::Save); + translatedSaveText = QPlatformTheme::removeMnemonics(translatedSaveText); + QCOMPARE(saveButton->text(), translatedSaveText); + + QString translatedDiscardText = QGuiApplicationPrivate::platformTheme()->standardButtonText(QPlatformDialogHelper::Discard); + translatedDiscardText = QPlatformTheme::removeMnemonics(translatedDiscardText); + 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("こんにちは")); +} + +void tst_translation::stackView() +{ + QQuickControlsApplicationHelper helper(this, "stackView.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + QVERIFY(window->setProperty("engine", QVariant::fromValue(&helper.engine))); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QSignalSpy calledTranslateSpy(window, SIGNAL(calledTranslate())); + QVERIFY(calledTranslateSpy.isValid()); + + QQuickAbstractButton *button = window->findChild<QQuickAbstractButton*>("button"); + QVERIFY(button); + // Shouldn't crash when calling retranslate. + QVERIFY(clickButton(button)); + QTRY_COMPARE(calledTranslateSpy.size(), 1); +} + +QTEST_MAIN(tst_translation) + +#include "tst_translation.moc" |