diff options
Diffstat (limited to 'tests/auto/quick/qquicktext/tst_qquicktext.cpp')
-rw-r--r-- | tests/auto/quick/qquicktext/tst_qquicktext.cpp | 508 |
1 files changed, 280 insertions, 228 deletions
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index c8d9561803..b731f1b069 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <qtest.h> #include <QtTest/QSignalSpy> #include <QTextDocument> @@ -7,11 +7,12 @@ #include <QtQml/qqmlcomponent.h> #include <QtQml/qjsvalue.h> #include <QtQuick/private/qquicktext_p.h> +#include <QtQuick/private/qquickflickable_p.h> #include <QtQuick/private/qquickmousearea_p.h> +#include <QtQuick/private/qquickpixmapcache_p.h> #include <QtQuickTest/QtQuickTest> #include <private/qquicktext_p_p.h> -#include <private/qquicktextnode_p.h> -#include <private/qquicktextdocument_p.h> +#include <private/qsginternaltextnode_p.h> #include <private/qquickvaluetypes_p.h> #include <QFontMetrics> #include <qmath.h> @@ -28,12 +29,17 @@ DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) Q_DECLARE_METATYPE(QQuickText::TextFormat) -QT_BEGIN_NAMESPACE -extern void qt_setQtEnableTestFont(bool value); -QT_END_NAMESPACE +typedef QVector<QPointF> PointVector; +Q_DECLARE_METATYPE(PointVector); + +typedef qreal (*ExpectedBaseline)(QQuickText *item); +Q_DECLARE_METATYPE(ExpectedBaseline) Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") +QT_BEGIN_NAMESPACE +extern void qt_setQtEnableTestFont(bool value); + class tst_qquicktext : public QQmlDataTest { Q_OBJECT @@ -47,12 +53,14 @@ private slots: void wrap(); void elide(); void elideParentChanged(); + void elideRelayoutAfterZeroWidth_data(); void elideRelayoutAfterZeroWidth(); void multilineElide_data(); void multilineElide(); void implicitElide_data(); void implicitElide(); void textFormat(); + void clipRectOutsideViewportDynamicallyChanged(); void baseUrl(); void embeddedImages_data(); @@ -100,8 +108,10 @@ private slots: void clipRect(); void largeTextObservesViewport_data(); void largeTextObservesViewport(); + void largeTextInDelayedLoader(); void lineLaidOut(); void lineLaidOutRelayout(); + void lineLaidOutFontUpdate(); void lineLaidOutHAlign(); void lineLaidOutImplicitWidth(); @@ -248,13 +258,12 @@ void tst_qquicktext::text() { QQmlComponent textComponent(&engine); textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->text(), QString("")); QCOMPARE(textObject->width(), qreal(0)); - - delete textObject; } for (int i = 0; i < standard.size(); i++) @@ -262,14 +271,12 @@ void tst_qquicktext::text() QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->text(), standard.at(i)); QVERIFY(textObject->width() > 0); - - delete textObject; } for (int i = 0; i < richText.size(); i++) @@ -277,14 +284,13 @@ void tst_qquicktext::text() QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QString expected = richText.at(i); QCOMPARE(textObject->text(), expected.replace("\\\"", "\"")); QVERIFY(textObject->width() > 0); - - delete textObject; } } @@ -294,12 +300,11 @@ void tst_qquicktext::width() { QQmlComponent textComponent(&engine); textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->width(), 0.); - - delete textObject; } bool requiresUnhintedMetrics = !qmlDisableDistanceField(); @@ -341,14 +346,13 @@ void tst_qquicktext::width() QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QVERIFY(textObject->boundingRect().width() > 0); QCOMPARE(textObject->width(), qreal(metricWidth)); QVERIFY(textObject->textFormat() == QQuickText::AutoText); // setting text doesn't change format - - delete textObject; } for (int i = 0; i < richText.size(); i++) @@ -358,7 +362,8 @@ void tst_qquicktext::width() QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\"; textFormat: Text.RichText }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); @@ -370,8 +375,6 @@ void tst_qquicktext::width() QCOMPARE(int(textObject->width()), int(doc->idealWidth())); QCOMPARE(textObject->textFormat(), QQuickText::RichText); - - delete textObject; } } @@ -382,14 +385,13 @@ void tst_qquicktext::wrap() { QQmlComponent textComponent(&engine); textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; wrapMode: Text.WordWrap; width: 300 }", QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); textHeight = textObject->height(); - QVERIFY(textObject != nullptr); QCOMPARE(textObject->wrapMode(), QQuickText::WordWrap); QCOMPARE(textObject->width(), 300.); - - delete textObject; } for (int i = 0; i < standard.size(); i++) @@ -397,7 +399,8 @@ void tst_qquicktext::wrap() QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + standard.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->width(), 30.); @@ -406,8 +409,6 @@ void tst_qquicktext::wrap() int oldHeight = textObject->height(); textObject->setWidth(100); QVERIFY(textObject->height() < oldHeight); - - delete textObject; } for (int i = 0; i < richText.size(); i++) @@ -415,7 +416,8 @@ void tst_qquicktext::wrap() QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + richText.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->width(), 30.); @@ -424,8 +426,6 @@ void tst_qquicktext::wrap() qreal oldHeight = textObject->height(); textObject->setWidth(100); QVERIFY(textObject->height() < oldHeight); - - delete textObject; } // Check that increasing width from idealWidth will cause a relayout @@ -434,7 +434,8 @@ void tst_qquicktext::wrap() QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; textFormat: Text.RichText; width: 30; text: \"" + richText.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->width(), 30.); @@ -453,8 +454,6 @@ void tst_qquicktext::wrap() qreal oldHeight = textObject->height(); textObject->setWidth(100); QVERIFY(textObject->height() < oldHeight); - - delete textObject; } // richtext again with a fixed height @@ -463,7 +462,8 @@ void tst_qquicktext::wrap() QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; height: 50; text: \"" + richText.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->width(), 30.); @@ -472,8 +472,6 @@ void tst_qquicktext::wrap() qreal oldHeight = textObject->implicitHeight(); textObject->setWidth(100); QVERIFY(textObject->implicitHeight() < oldHeight); - - delete textObject; } { @@ -511,12 +509,12 @@ void tst_qquicktext::elide() { QQmlComponent textComponent(&engine); textComponent.setData(("import QtQuick 2.0\nText { text: \"\"; "+elide+" width: 100 }").toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject, qPrintable(textComponent.errorString())); QCOMPARE(textObject->elideMode(), m); QCOMPARE(textObject->width(), 100.); - - delete textObject; } for (int i = 0; i < standard.size(); i++) @@ -524,15 +522,15 @@ void tst_qquicktext::elide() QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + standard.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject, qPrintable(textComponent.errorString())); QCOMPARE(textObject->elideMode(), m); QCOMPARE(textObject->width(), 100.); if (m != QQuickText::ElideNone && !standard.at(i).contains('\n')) QVERIFY(textObject->contentWidth() <= textObject->width()); - - delete textObject; } for (int i = 0; i < richText.size(); i++) @@ -540,15 +538,15 @@ void tst_qquicktext::elide() QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + richText.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject, qPrintable(textComponent.errorString())); QCOMPARE(textObject->elideMode(), m); QCOMPARE(textObject->width(), 100.); if (m != QQuickText::ElideNone && standard.at(i).contains("<br>")) QVERIFY(textObject->contentWidth() <= textObject->width()); - - delete textObject; } } } @@ -592,10 +590,19 @@ void tst_qquicktext::elideParentChanged() QCOMPARE(actualItemImageGrab, expectedItemImageGrab); } +void tst_qquicktext::elideRelayoutAfterZeroWidth_data() +{ + QTest::addColumn<QByteArray>("fileName"); + + QTest::newRow("no_margins") << QByteArray("elideZeroWidth.qml"); + QTest::newRow("with_margins") << QByteArray("elideZeroWidthWithMargins.qml"); +} + void tst_qquicktext::elideRelayoutAfterZeroWidth() { + QFETCH(const QByteArray, fileName); QQmlEngine engine; - QQmlComponent component(&engine, testFileUrl("elideZeroWidth.qml")); + QQmlComponent component(&engine, testFileUrl(fileName.constData())); QScopedPointer<QObject> root(component.create()); QVERIFY2(root, qPrintable(component.errorString())); QVERIFY(root->property("ok").toBool()); @@ -699,6 +706,7 @@ void tst_qquicktext::implicitElide() textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QVERIFY2(textObject, qPrintable(textComponent.errorString())); QVERIFY(textObject->contentWidth() <= textObject->width()); textObject->setText("the quick brown fox jumped over"); @@ -712,7 +720,8 @@ void tst_qquicktext::textFormat() { QQmlComponent textComponent(&engine); textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->textFormat(), QQuickText::RichText); @@ -720,13 +729,12 @@ void tst_qquicktext::textFormat() QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); QVERIFY(textPrivate != nullptr); QVERIFY(textPrivate->richText); - - delete textObject; } { QQmlComponent textComponent(&engine); textComponent.setData("import QtQuick 2.0\nText { text: \"<b>Hello</b>\" }", QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->textFormat(), QQuickText::AutoText); @@ -734,18 +742,15 @@ void tst_qquicktext::textFormat() QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); QVERIFY(textPrivate != nullptr); QVERIFY(textPrivate->styledText); - - delete textObject; } { QQmlComponent textComponent(&engine); textComponent.setData("import QtQuick 2.0\nText { text: \"<b>Hello</b>\"; textFormat: Text.PlainText }", QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->textFormat(), QQuickText::PlainText); - - delete textObject; } { @@ -827,6 +832,28 @@ void tst_qquicktext::textFormat() } } +void tst_qquicktext::clipRectOutsideViewportDynamicallyChanged() +{ + // QTBUG-106205 + QScopedPointer<QQuickView> view(createView(testFile("qtbug_106205.qml"))); + view->setWidth(100); + view->setHeight(200); + view->showNormal(); + QQuickItem *root = view->rootObject(); + QVERIFY(root); + QVERIFY(QTest::qWaitForWindowExposed(view.get())); + + auto clipRectMatches = [&]() -> bool { + auto *textOutsideInitialViewport = root->findChild<QQuickText *>("textOutsideViewport"); + if (!textOutsideInitialViewport) + return false; + auto *clipNode = QQuickItemPrivate::get(textOutsideInitialViewport)->clipNode(); + + return textOutsideInitialViewport->clipRect() == clipNode->clipRect(); + }; + QTRY_VERIFY(clipRectMatches()); +} + //the alignment tests may be trivial o.oa void tst_qquicktext::horizontalAlignment() { @@ -839,11 +866,11 @@ void tst_qquicktext::horizontalAlignment() QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject, qPrintable(textComponent.errorString())); QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j)); - - delete textObject; } } @@ -854,11 +881,11 @@ void tst_qquicktext::horizontalAlignment() QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject, qPrintable(textComponent.errorString())); QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j)); - - delete textObject; } } @@ -975,10 +1002,11 @@ void tst_qquicktext::horizontalAlignment_RightToLeft() QString componentStr = "import QtQuick 2.0\nText {}"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject, qPrintable(textComponent.errorString())); QCOMPARE(textObject->hAlign(), qApp->inputMethod()->inputDirection() == Qt::LeftToRight ? QQuickText::AlignLeft : QQuickText::AlignRight); - delete textObject; } int tst_qquicktext::numberOfNonWhitePixels(int fromX, int toX, const QImage &image) @@ -1076,12 +1104,11 @@ void tst_qquicktext::verticalAlignment() QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j)); - - delete textObject; } } @@ -1092,12 +1119,11 @@ void tst_qquicktext::verticalAlignment() QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j)); - - delete textObject; } } @@ -1110,74 +1136,74 @@ void tst_qquicktext::font() QString componentStr = "import QtQuick 2.0\nText { font.pointSize: 40; text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->font().pointSize(), 40); QCOMPARE(textObject->font().bold(), false); QCOMPARE(textObject->font().italic(), false); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { font.pixelSize: 40; text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->font().pixelSize(), 40); QCOMPARE(textObject->font().bold(), false); QCOMPARE(textObject->font().italic(), false); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { font.bold: true; text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->font().bold(), true); QCOMPARE(textObject->font().italic(), false); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { font.italic: true; text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->font().italic(), true); QCOMPARE(textObject->font().bold(), false); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { font.family: \"Helvetica\"; text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->font().family(), QString("Helvetica")); QCOMPARE(textObject->font().bold(), false); QCOMPARE(textObject->font().italic(), false); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { font.family: \"\"; text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->font().family(), QString("")); - - delete textObject; } } @@ -1189,17 +1215,19 @@ void tst_qquicktext::style() QString componentStr = "import QtQuick 2.0\nText { style: \"" + styleStrings.at(i) + "\"; styleColor: \"white\"; text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE((int)textObject->style(), (int)styles.at(i)); QCOMPARE(textObject->styleColor(), QColor("white")); - - delete textObject; } QString componentStr = "import QtQuick 2.0\nText { text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QRectF brPre = textObject->boundingRect(); textObject->setStyle(QQuickText::Outline); @@ -1207,8 +1235,6 @@ void tst_qquicktext::style() QVERIFY(brPre.width() < brPost.width()); QVERIFY(brPre.height() < brPost.height()); - - delete textObject; } void tst_qquicktext::color() @@ -1219,13 +1245,13 @@ void tst_qquicktext::color() QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->color(), QColor(colorStrings.at(i))); QCOMPARE(textObject->styleColor(), QColor("black")); QCOMPARE(textObject->linkColor(), QColor("blue")); - - delete textObject; } for (int i = 0; i < colorStrings.size(); i++) @@ -1233,7 +1259,9 @@ void tst_qquicktext::color() QString componentStr = "import QtQuick 2.0\nText { styleColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(i))); // default color to black? @@ -1264,8 +1292,6 @@ void tst_qquicktext::color() textObject->setLinkColor(QColor("blue")); QCOMPARE(textObject->linkColor(), QColor("blue")); QCOMPARE(linkColorSpy.size(), 2); - - delete textObject; } for (int i = 0; i < colorStrings.size(); i++) @@ -1273,13 +1299,13 @@ void tst_qquicktext::color() QString componentStr = "import QtQuick 2.0\nText { linkColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->styleColor(), QColor("black")); QCOMPARE(textObject->color(), QColor("black")); QCOMPARE(textObject->linkColor(), QColor(colorStrings.at(i))); - - delete textObject; } for (int i = 0; i < colorStrings.size(); i++) @@ -1293,13 +1319,13 @@ void tst_qquicktext::color() "text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->color(), QColor(colorStrings.at(i))); QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(j))); QCOMPARE(textObject->linkColor(), QColor(colorStrings.at(j))); - - delete textObject; } } { @@ -1310,11 +1336,11 @@ void tst_qquicktext::color() QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStr + "\"; text: \"Hello World\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->color(), testColor); - - delete textObject; } { QString colorStr = "#001234"; QColor testColor(colorStr); @@ -1324,6 +1350,7 @@ void tst_qquicktext::color() textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QScopedPointer<QObject> object(textComponent.create()); QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QSignalSpy spy(textObject, SIGNAL(colorChanged())); @@ -1345,6 +1372,7 @@ void tst_qquicktext::color() textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QScopedPointer<QObject> object(textComponent.create()); QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QSignalSpy spy(textObject, SIGNAL(styleColorChanged())); @@ -1366,6 +1394,7 @@ void tst_qquicktext::color() textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QScopedPointer<QObject> object(textComponent.create()); QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QSignalSpy spy(textObject, SIGNAL(linkColorChanged())); @@ -1389,19 +1418,19 @@ void tst_qquicktext::smooth() QString componentStr = "import QtQuick 2.0\nText { smooth: false; text: \"" + standard.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->smooth(), false); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->smooth(), true); - - delete textObject; } } for (int i = 0; i < richText.size(); i++) @@ -1410,19 +1439,19 @@ void tst_qquicktext::smooth() QString componentStr = "import QtQuick 2.0\nText { smooth: false; text: \"" + richText.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->smooth(), false); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject != nullptr, qPrintable(textComponent.errorString())); QCOMPARE(textObject->smooth(), true); - - delete textObject; } } } @@ -1488,23 +1517,21 @@ void tst_qquicktext::weight() QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE((int)textObject->font().weight(), int(QQuickFontEnums::Normal)); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { font.weight: Font.Bold; text: \"Hello world!\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE((int)textObject->font().weight(), int(QQuickFontEnums::Bold)); - - delete textObject; } } @@ -1553,56 +1580,51 @@ void tst_qquicktext::capitalization() QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE((int)textObject->font().capitalization(), int(QQuickFontEnums::MixedCase)); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllUppercase\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE((int)textObject->font().capitalization(), int(QQuickFontEnums::AllUppercase)); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllLowercase\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE((int)textObject->font().capitalization(), int(QQuickFontEnums::AllLowercase)); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"SmallCaps\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE((int)textObject->font().capitalization(), int(QQuickFontEnums::SmallCaps)); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"Capitalize\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE((int)textObject->font().capitalization(), int(QQuickFontEnums::Capitalize)); - - delete textObject; } } @@ -1612,34 +1634,31 @@ void tst_qquicktext::letterSpacing() QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->font().letterSpacing(), 0.0); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: -2 }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->font().letterSpacing(), -2.); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: 3 }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->font().letterSpacing(), 3.); - - delete textObject; } } @@ -1649,34 +1668,31 @@ void tst_qquicktext::wordSpacing() QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->font().wordSpacing(), 0.0); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: -50 }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->font().wordSpacing(), -50.); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: 200 }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->font().wordSpacing(), 200.); - - delete textObject; } } @@ -1803,10 +1819,6 @@ public: QTextLayout layout; }; - -typedef QVector<QPointF> PointVector; -Q_DECLARE_METATYPE(PointVector); - void tst_qquicktext::linkInteraction_data() { QTest::addColumn<QString>("text"); @@ -2068,7 +2080,8 @@ void tst_qquicktext::linkInteraction() "}"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); @@ -2119,8 +2132,6 @@ void tst_qquicktext::linkInteraction() QCOMPARE(test.hoveredLink, QString()); QCOMPARE(textObject->hoveredLink(), QString()); QCOMPARE(textObject->linkAt(-1, -1), QString()); - - delete textObject; } void tst_qquicktext::baseUrl() @@ -2131,6 +2142,7 @@ void tst_qquicktext::baseUrl() QQmlComponent textComponent(&engine); textComponent.setData("import QtQuick 2.0\n Text {}", localUrl); QQuickText *textObject = qobject_cast<QQuickText *>(textComponent.create()); + QVERIFY2(textObject, qPrintable(textComponent.errorString())); QCOMPARE(textObject->baseUrl(), localUrl); @@ -2151,12 +2163,15 @@ void tst_qquicktext::baseUrl() void tst_qquicktext::embeddedImages_data() { + // Cancel some mess left by clipRectOutsideViewportDynamicallyChanged(): + qmlClearTypeRegistrations(); + QTest::addColumn<QUrl>("qmlfile"); QTest::addColumn<QString>("error"); QTest::newRow("local") << testFileUrl("embeddedImagesLocal.qml") << ""; QTest::newRow("local-error") << testFileUrl("embeddedImagesLocalError.qml") << testFileUrl("embeddedImagesLocalError.qml").toString()+":3:1: QML Text: Cannot open: " + testFileUrl("http/notexists.png").toString(); - QTest::newRow("local") << testFileUrl("embeddedImagesLocalRelative.qml") << ""; + QTest::newRow("local-relative") << testFileUrl("embeddedImagesLocalRelative.qml") << ""; QTest::newRow("remote") << testFileUrl("embeddedImagesRemote.qml") << ""; QTest::newRow("remote-error") << testFileUrl("embeddedImagesRemoteError.qml") << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML Text: Error transferring {{ServerBaseUrl}}/notexists.png - server replied: Not found"; @@ -2178,13 +2193,10 @@ void tst_qquicktext::embeddedImages() if (!error.isEmpty()) QTest::ignoreMessage(QtWarningMsg, error.toLatin1()); - QQuickView *view = new QQuickView; - view->rootContext()->setContextProperty(QStringLiteral("serverBaseUrl"), server.baseUrl()); - view->setSource(qmlfile); - view->show(); - view->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(view)); - QQuickText *textObject = qobject_cast<QQuickText*>(view->rootObject()); + QQuickView view; + view.rootContext()->setContextProperty(QStringLiteral("serverBaseUrl"), server.baseUrl()); + QVERIFY(QQuickTest::showView(view, qmlfile)); + QQuickText *textObject = qobject_cast<QQuickText*>(view.rootObject()); QVERIFY(textObject != nullptr); QTRY_COMPARE(textObject->resourcesLoading(), 0); @@ -2199,7 +2211,9 @@ void tst_qquicktext::embeddedImages() QCOMPARE(textObject->height(), 16.0); } - delete view; + // QTextDocument images are cached in QTextDocumentPrivate::cachedResources, + // so verify that we don't redundantly cache them in QQuickPixmapCache + QCOMPARE(QQuickPixmapCache::instance()->m_cache.size(), 0); } void tst_qquicktext::lineCount() @@ -2357,7 +2371,9 @@ void tst_qquicktext::implicitSize() "maximumLineCount: 2 }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); + QVERIFY2(textObject, qPrintable(textComponent.errorString())); QVERIFY(textObject->width() < textObject->implicitWidth()); QCOMPARE(textObject->height(), textObject->implicitHeight()); @@ -2366,8 +2382,6 @@ void tst_qquicktext::implicitSize() textObject->resetWidth(); QCOMPARE(textObject->width(), textObject->implicitWidth()); QCOMPARE(textObject->height(), textObject->implicitHeight()); - - delete textObject; } void tst_qquicktext::implicitSizeMaxLineCount() @@ -2447,6 +2461,7 @@ void tst_qquicktext::contentSize() textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QScopedPointer<QObject> object(textComponent.create()); QQuickText *textObject = qobject_cast<QQuickText *>(object.data()); + QVERIFY2(textObject, qPrintable(textComponent.errorString())); QSignalSpy spySize(textObject, SIGNAL(contentSizeChanged())); QSignalSpy spyWidth(textObject, SIGNAL(contentWidthChanged(qreal))); @@ -2504,6 +2519,7 @@ void tst_qquicktext::geometryChanged() textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QScopedPointer<QObject> object(textComponent.create()); QQuickText *textObject = qobject_cast<QQuickText *>(object.data()); + QVERIFY2(textObject, qPrintable(textComponent.errorString())); const qreal implicitHeight = textObject->implicitHeight(); @@ -2763,6 +2779,7 @@ void tst_qquicktext::implicitSizeBinding() textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QScopedPointer<QObject> object(textComponent.create()); QQuickText *textObject = qobject_cast<QQuickText *>(object.data()); + QVERIFY2(textObject, qPrintable(textComponent.errorString())); QCOMPARE(textObject->width(), textObject->implicitWidth()); QCOMPARE(textObject->height(), textObject->implicitHeight()); @@ -2951,10 +2968,10 @@ void tst_qquicktext::largeTextObservesViewport_data() Q_ASSERT(text.size() > QQuickTextPrivate::largeTextSizeThreshold); // by default, the root item acts as the viewport: - // QQuickTextNode doesn't populate lines of text beyond the bottom of the window + // QSGInternalTextNode doesn't populate lines of text beyond the bottom of the window QTest::newRow("default plain text") << text << QQuickText::PlainText << 0 << false; // make the rectangle into a viewport item, and move the text upwards: - // QQuickTextNode doesn't populate lines of text beyond the bottom of the viewport rectangle + // QSGInternalTextNode doesn't populate lines of text beyond the bottom of the viewport rectangle QTest::newRow("clipped plain text") << text << QQuickText::PlainText << 10 << true; { @@ -2998,13 +3015,13 @@ void tst_qquicktext::largeTextObservesViewport() QVERIFY(textItem); QQuickItem *viewportItem = textItem->parentItem(); QQuickTextPrivate *textPriv = QQuickTextPrivate::get(textItem); - QQuickTextNode *node = static_cast<QQuickTextNode *>(textPriv->paintNode); + QSGInternalTextNode *node = static_cast<QSGInternalTextNode *>(textPriv->paintNode); QFontMetricsF fm(textItem->font()); const qreal expectedTextHeight = (parentIsViewport ? viewportItem->height() : window.height() - viewportItem->y()); const qreal lineSpacing = qCeil(fm.height()); // A paragraph break is the same as an extra line break; so since our "lines" are paragraphs in StyledText, // visually, with StyledText we skip down 10 "lines", but the first paragraph you see says "line 5". - // It's OK anyway for the test, because QQuickTextNode::addTextLayout() treats the paragraph breaks like lines of text. + // It's OK anyway for the test, because QSGTextNode::addTextLayout() treats the paragraph breaks like lines of text. const int expectedLastLine = linesAboveViewport + int(expectedTextHeight / lineSpacing); viewportItem->setFlag(QQuickItem::ItemIsViewport, parentIsViewport); @@ -3029,6 +3046,29 @@ void tst_qquicktext::largeTextObservesViewport() QVERIFY(qAbs(renderedLineRange.second - (expectedLastLine + 1)) < (linesAboveViewport > 80 ? 4 : 2)); } +void tst_qquicktext::largeTextInDelayedLoader() // QTBUG-115687 +{ + QQuickView view; + QVERIFY(QQuickTest::showView(view, testFileUrl("loaderActiveOnVisible.qml"))); + auto flick = view.rootObject()->findChild<QQuickFlickable*>(); + QVERIFY(flick); + auto textItem = view.rootObject()->findChild<QQuickText*>(); + QVERIFY(textItem); + QQuickTextPrivate *textPriv = QQuickTextPrivate::get(textItem); + QSGInternalTextNode *node = static_cast<QSGInternalTextNode *>(textPriv->paintNode); + const auto initialLineRange = node->renderedLineRange(); + qCDebug(lcTests) << "first line rendered" << initialLineRange.first + << "; first line past viewport" << initialLineRange.second; + flick->setContentY(500); + QTRY_COMPARE_NE(node->renderedLineRange(), initialLineRange); + const auto scrolledLineRange = node->renderedLineRange(); + qCDebug(lcTests) << "after scroll: first line rendered" << scrolledLineRange.first + << "; first line past viewport" << scrolledLineRange.second; + // We scrolled a good bit more than one window-height, so we must render a + // non-overlapping range of text some distance past the initial blocks. + QCOMPARE_GT(scrolledLineRange.first, initialLineRange.second); +} + void tst_qquicktext::lineLaidOut() { QScopedPointer<QQuickView> window(createView(testFile("lineLayout.qml"))); @@ -3043,11 +3083,11 @@ void tst_qquicktext::lineLaidOut() for (int i = 0; i < textPrivate->layout.lineCount(); ++i) { QRectF r = textPrivate->layout.lineAt(i).rect(); - QVERIFY(r.width() == i * 15); + QCOMPARE(r.width(), i * 15); if (i >= 30) - QVERIFY(r.x() == r.width() + 30); + QCOMPARE(r.x(), r.width() + 30); if (i >= 60) { - QVERIFY(r.x() == r.width() * 2 + 60); + QCOMPARE(r.x(), r.width() * 2 + 60); QCOMPARE(r.height(), qreal(20)); } } @@ -3092,6 +3132,29 @@ void tst_qquicktext::lineLaidOutRelayout() } } +void tst_qquicktext::lineLaidOutFontUpdate() +{ + QScopedPointer<QQuickView> window(createView(testFile("lineLayoutFontUpdate.qml"))); + + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + auto *myText = window->rootObject()->findChild<QQuickText*>("exampleText"); + QVERIFY(myText != nullptr); + + QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText); + QVERIFY(textPrivate != nullptr); + + QCOMPARE(textPrivate->layout.lineCount(), 2); + + QTextLine firstLine = textPrivate->layout.lineAt(0); + QTextLine secondLine = textPrivate->layout.lineAt(1); + + QCOMPARE(firstLine.rect().x(), secondLine.rect().x() + 40); + QCOMPARE(firstLine.rect().width(), secondLine.rect().width() - 40); +} + void tst_qquicktext::lineLaidOutHAlign() { QScopedPointer<QQuickView> window(createView(testFile("lineLayoutHAlign.qml"))); @@ -3272,7 +3335,8 @@ void tst_qquicktext::imgTagsAlign() QString componentStr = "import QtQuick 2.0\nText { text: \"This is a test <img src=\\\"" + src + "\\\" align=\\\"" + align + "\\\"> of image.\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), testFileUrl(".")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->height(), qreal(imgHeight)); @@ -3287,8 +3351,6 @@ void tst_qquicktext::imgTagsAlign() QVERIFY(br.y() == imgHeight / 2.0 - br.height() / 2.0); else if (align == "top") QCOMPARE(br.y(), qreal(0)); - - delete textObject; } void tst_qquicktext::imgTagsMultipleImages() @@ -3297,7 +3359,8 @@ void tst_qquicktext::imgTagsMultipleImages() QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), testFileUrl(".")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE(textObject->height(), qreal(85)); @@ -3305,34 +3368,30 @@ void tst_qquicktext::imgTagsMultipleImages() QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); QVERIFY(textPrivate != nullptr); QCOMPARE(textPrivate->extra->visibleImgTags.size(), 2); - - delete textObject; } void tst_qquicktext::imgTagsElide() { QScopedPointer<QQuickView> window(createView(testFile("imgTagsElide.qml"))); - QQuickText *myText = window->rootObject()->findChild<QQuickText*>("myText"); - QVERIFY(myText != nullptr); + QScopedPointer<QQuickText> myText(window->rootObject()->findChild<QQuickText*>("myText")); + QVERIFY(myText); - QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText); + QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText.data()); QVERIFY(textPrivate != nullptr); QCOMPARE(textPrivate->extra->visibleImgTags.size(), 0); myText->setMaximumLineCount(20); QTRY_COMPARE(textPrivate->extra->visibleImgTags.size(), 1); - - delete myText; } void tst_qquicktext::imgTagsUpdates() { QScopedPointer<QQuickView> window(createView(testFile("imgTagsUpdates.qml"))); - QQuickText *myText = window->rootObject()->findChild<QQuickText*>("myText"); - QVERIFY(myText != nullptr); + QScopedPointer<QQuickText> myText(window->rootObject()->findChild<QQuickText*>("myText")); + QVERIFY(myText); - QSignalSpy spy(myText, SIGNAL(contentSizeChanged())); + QSignalSpy spy(myText.data(), SIGNAL(contentSizeChanged())); - QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText); + QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText.data()); QVERIFY(textPrivate != nullptr); myText->setText("This is a heart<img src=\"images/heart200.png\">."); @@ -3346,8 +3405,6 @@ void tst_qquicktext::imgTagsUpdates() // if maximumLineCount is set and the img tag doesn't have an explicit size // we relayout twice. QCOMPARE(spy.size(), 3); - - delete myText; } void tst_qquicktext::imgTagsError() @@ -3361,10 +3418,10 @@ void tst_qquicktext::imgTagsError() + testFileUrl("images/starfish_2.pn").toString()); QTest::ignoreMessage(QtWarningMsg, expectedMessage.toLatin1()); textComponent.setData(componentStr.toLatin1(), testFileUrl(".")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); - delete textObject; } void tst_qquicktext::fontSizeMode_data() @@ -4027,9 +4084,6 @@ void tst_qquicktext::fontFormatSizes() } } -typedef qreal (*ExpectedBaseline)(QQuickText *item); -Q_DECLARE_METATYPE(ExpectedBaseline) - static qreal expectedBaselineTop(QQuickText *item) { QFontMetricsF fm(item->font()); @@ -4194,7 +4248,7 @@ void tst_qquicktext::baselineOffset_data() QTest::newRow("customLine") << "hello world" << "hello\nworld" - << QByteArray("height: 200; onLineLaidOut: line.y += 16") + << QByteArray("height: 200; onLineLaidOut: (line) => { line.y += 16; }") << &expectedBaselineCustom << &expectedBaselineCustom; @@ -4290,7 +4344,8 @@ void tst_qquicktext::baselineOffset_data() QTest::newRow("customLine with padding") << "hello world" << "hello\nworld" - << QByteArray("height: 200; topPadding: 10; bottomPadding: 20; onLineLaidOut: line.y += 16") + << QByteArray("height: 200; topPadding: 10; bottomPadding: 20; " + "onLineLaidOut: (line) => { line.y += 16; }") << &expectedBaselineCustom << &expectedBaselineCustom; @@ -4388,7 +4443,7 @@ void tst_qquicktext::htmlLists() QFETCH(QString, text); QFETCH(int, nbLines); - QQuickView *view = createView(testFile("htmlLists.qml")); + QScopedPointer<QQuickView>view(createView(testFile("htmlLists.qml"))); QQuickText *textObject = view->rootObject()->findChild<QQuickText*>("myText"); QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); @@ -4400,11 +4455,9 @@ void tst_qquicktext::htmlLists() view->show(); view->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(view)); + QVERIFY(QTest::qWaitForWindowActive(view.get())); QCOMPARE(textPrivate->extra->doc->lineCount(), nbLines); - - delete view; } void tst_qquicktext::htmlLists_data() @@ -4489,9 +4542,9 @@ void tst_qquicktext::padding() QTRY_COMPARE(window->status(), QQuickView::Ready); window->show(); QVERIFY(QTest::qWaitForWindowExposed(window.data())); - QQuickItem *root = window->rootObject(); + QScopedPointer<QQuickItem> root(window->rootObject()); QVERIFY(root); - QQuickText *obj = qobject_cast<QQuickText*>(root); + QQuickText *obj = qobject_cast<QQuickText*>(root.data()); QVERIFY(obj != nullptr); qreal cw = obj->contentWidth(); @@ -4582,8 +4635,6 @@ void tst_qquicktext::padding() QCOMPARE(obj->leftPadding(), 0.0); QCOMPARE(obj->rightPadding(), 0.0); QCOMPARE(obj->bottomPadding(), 0.0); - - delete root; } void tst_qquicktext::paddingInLoader() // QTBUG-83413 @@ -4618,23 +4669,21 @@ void tst_qquicktext::hintingPreference() QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE((int)textObject->font().hintingPreference(), (int)QFont::PreferDefaultHinting); - - delete textObject; } { QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.hintingPreference: Font.PreferNoHinting }"; QQmlComponent textComponent(&engine); textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + QScopedPointer<QObject> object(textComponent.create()); + QQuickText *textObject = qobject_cast<QQuickText*>(object.data()); QVERIFY(textObject != nullptr); QCOMPARE((int)textObject->font().hintingPreference(), (int)QFont::PreferNoHinting); - - delete textObject; } } @@ -4710,6 +4759,7 @@ void tst_qquicktext::fontInfo() QScopedPointer<QObject> object(component.create()); QObject *root = object.data(); + QVERIFY2(root, qPrintable(component.errorString())); QQuickText *main = root->findChild<QQuickText *>("main"); QVERIFY(main); @@ -4806,6 +4856,8 @@ void tst_qquicktext::displaySuperscriptedTag() QCOMPARE(color.green(), 255); } +QT_END_NAMESPACE + QTEST_MAIN(tst_qquicktext) #include "tst_qquicktext.moc" |