summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/text
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/gui/text')
-rw-r--r--tests/auto/gui/text/CMakeLists.txt5
-rw-r--r--tests/auto/gui/text/qabstracttextdocumentlayout/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp6
-rw-r--r--tests/auto/gui/text/qcssparser/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qcssparser/tst_qcssparser.cpp83
-rw-r--r--tests/auto/gui/text/qfont/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qfont/tst_qfont.cpp90
-rw-r--r--tests/auto/gui/text/qfontcache/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qfontcache/tst_qfontcache.cpp2
-rw-r--r--tests/auto/gui/text/qfontdatabase/CMakeLists.txt12
-rw-r--r--tests/auto/gui/text/qfontdatabase/QtTestFallbackFont-Regular.ttfbin0 -> 5664 bytes
-rw-r--r--tests/auto/gui/text/qfontdatabase/QtTestLimitedFont-Regular.ttfbin0 -> 5280 bytes
-rw-r--r--tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp273
-rw-r--r--tests/auto/gui/text/qfontmetrics/CMakeLists.txt10
-rw-r--r--tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp72
-rw-r--r--tests/auto/gui/text/qglyphrun/BLACKLIST7
-rw-r--r--tests/auto/gui/text/qglyphrun/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp14
-rw-r--r--tests/auto/gui/text/qinputcontrol/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qinputcontrol/tst_qinputcontrol.cpp2
-rw-r--r--tests/auto/gui/text/qrawfont/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qrawfont/tst_qrawfont.cpp24
-rw-r--r--tests/auto/gui/text/qstatictext/CMakeLists.txt8
-rw-r--r--tests/auto/gui/text/qstatictext/tst_qstatictext.cpp61
-rw-r--r--tests/auto/gui/text/qsyntaxhighlighter/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp2
-rw-r--r--tests/auto/gui/text/qtextblock/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextblock/tst_qtextblock.cpp2
-rw-r--r--tests/auto/gui/text/qtextcursor/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp17
-rw-r--r--tests/auto/gui/text/qtextdocument/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextdocument/common.h2
-rw-r--r--tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp310
-rw-r--r--tests/auto/gui/text/qtextdocumentfragment/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp41
-rw-r--r--tests/auto/gui/text/qtextdocumentlayout/BLACKLIST3
-rw-r--r--tests/auto/gui/text/qtextdocumentlayout/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp14
-rw-r--r--tests/auto/gui/text/qtextformat/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextformat/tst_qtextformat.cpp8
-rw-r--r--tests/auto/gui/text/qtextimagehandler/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp74
-rw-r--r--tests/auto/gui/text/qtextlayout/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp29
-rw-r--r--tests/auto/gui/text/qtextlist/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextlist/tst_qtextlist.cpp62
-rw-r--r--tests/auto/gui/text/qtextmarkdownimporter/CMakeLists.txt14
-rw-r--r--tests/auto/gui/text/qtextmarkdownimporter/data/paragraphs.md9
-rw-r--r--tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md1
-rw-r--r--tests/auto/gui/text/qtextmarkdownimporter/data/yaml-only.md6
-rw-r--r--tests/auto/gui/text/qtextmarkdownimporter/data/yaml.md11
-rw-r--r--tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp241
-rw-r--r--tests/auto/gui/text/qtextmarkdownwriter/CMakeLists.txt12
-rw-r--r--tests/auto/gui/text/qtextmarkdownwriter/data/blockquotes.md6
-rw-r--r--tests/auto/gui/text/qtextmarkdownwriter/data/blockquotesWithLists.md14
-rw-r--r--tests/auto/gui/text/qtextmarkdownwriter/data/example.md4
-rw-r--r--tests/auto/gui/text/qtextmarkdownwriter/data/listItemWithBlockquote.md6
-rw-r--r--tests/auto/gui/text/qtextmarkdownwriter/data/longHeadings.md9
-rw-r--r--tests/auto/gui/text/qtextmarkdownwriter/data/yaml.md11
-rw-r--r--tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp502
-rw-r--r--tests/auto/gui/text/qtextobject/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextobject/tst_qtextobject.cpp2
-rw-r--r--tests/auto/gui/text/qtextodfwriter/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextodfwriter/tst_qtextodfwriter.cpp2
-rw-r--r--tests/auto/gui/text/qtextpiecetable/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp136
-rw-r--r--tests/auto/gui/text/qtextscriptengine/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtextscriptengine/generate/main.cpp2
-rw-r--r--tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp50
-rw-r--r--tests/auto/gui/text/qtexttable/CMakeLists.txt6
-rw-r--r--tests/auto/gui/text/qtexttable/tst_qtexttable.cpp76
-rw-r--r--tests/auto/gui/text/qzip/.gitignore1
-rw-r--r--tests/auto/gui/text/qzip/CMakeLists.txt21
-rw-r--r--tests/auto/gui/text/qzip/testdata/symlink.zipbin289 -> 0 bytes
-rw-r--r--tests/auto/gui/text/qzip/testdata/test.zipbin286 -> 0 bytes
-rw-r--r--tests/auto/gui/text/qzip/tst_qzip.cpp116
76 files changed, 2174 insertions, 443 deletions
diff --git a/tests/auto/gui/text/CMakeLists.txt b/tests/auto/gui/text/CMakeLists.txt
index 2ba0a96774..30b35fb10a 100644
--- a/tests/auto/gui/text/CMakeLists.txt
+++ b/tests/auto/gui/text/CMakeLists.txt
@@ -11,7 +11,9 @@ add_subdirectory(qstatictext)
add_subdirectory(qsyntaxhighlighter)
add_subdirectory(qtextblock)
add_subdirectory(qtextcursor)
-add_subdirectory(qtextdocumentfragment)
+if(QT_FEATURE_texthtmlparser)
+ add_subdirectory(qtextdocumentfragment)
+endif()
add_subdirectory(qtextdocumentlayout)
add_subdirectory(qtextformat)
add_subdirectory(qtextimagehandler)
@@ -26,7 +28,6 @@ endif()
if(QT_FEATURE_private_tests)
add_subdirectory(qfontcache)
add_subdirectory(qtextlayout)
- add_subdirectory(qzip)
add_subdirectory(qtextodfwriter)
endif()
if(TARGET Qt::Xml)
diff --git a/tests/auto/gui/text/qabstracttextdocumentlayout/CMakeLists.txt b/tests/auto/gui/text/qabstracttextdocumentlayout/CMakeLists.txt
index 247326253a..316b9cd3c6 100644
--- a/tests/auto/gui/text/qabstracttextdocumentlayout/CMakeLists.txt
+++ b/tests/auto/gui/text/qabstracttextdocumentlayout/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qabstracttextdocumentlayout Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qabstracttextdocumentlayout LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qabstracttextdocumentlayout
SOURCES
tst_qabstracttextdocumentlayout.cpp
diff --git a/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp b/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp
index 037964f42b..3d0fab4603 100644
--- a/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp
+++ b/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.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>
@@ -22,9 +22,11 @@ public:
private slots:
void getSetCheck();
void maximumBlockCount();
+#ifndef QT_NO_TEXTHTMLPARSER
void anchorAt();
void imageAt();
void formatAt();
+#endif
};
tst_QAbstractTextDocumentLayout::tst_QAbstractTextDocumentLayout()
@@ -119,6 +121,7 @@ void tst_QAbstractTextDocumentLayout::maximumBlockCount()
QCOMPARE(layout.blockCount, 10);
}
+#ifndef QT_NO_TEXTHTMLPARSER
void tst_QAbstractTextDocumentLayout::anchorAt()
{
QTextDocument doc;
@@ -204,6 +207,7 @@ void tst_QAbstractTextDocumentLayout::formatAt()
QVERIFY(!format.toCharFormat().fontItalic());
QVERIFY(!format.isImageFormat());
}
+#endif
QTEST_MAIN(tst_QAbstractTextDocumentLayout)
#include "tst_qabstracttextdocumentlayout.moc"
diff --git a/tests/auto/gui/text/qcssparser/CMakeLists.txt b/tests/auto/gui/text/qcssparser/CMakeLists.txt
index 4f9401d8db..e766ec5484 100644
--- a/tests/auto/gui/text/qcssparser/CMakeLists.txt
+++ b/tests/auto/gui/text/qcssparser/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qcssparser Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcssparser LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp
index 5ca983450a..203fe003a0 100644
--- a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp
+++ b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp
@@ -1,5 +1,6 @@
// 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>
#include <QtXml/QtXml>
#include <QtGui/QFontInfo>
@@ -55,6 +56,10 @@ private slots:
void quotedAndUnquotedIdentifiers();
void whitespaceValues_data();
void whitespaceValues();
+ void strokeLineCapValues_data();
+ void strokeLineCapValues();
+ void strokeLineJoinValues_data();
+ void strokeLineJoinValues();
};
void tst_QCssParser::scanner_data()
@@ -69,7 +74,8 @@ void tst_QCssParser::scanner_data()
#endif
d.cd("testdata");
d.cd("scanner");
- foreach (QFileInfo test, d.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) {
+ const auto entries = d.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
+ for (const QFileInfo &test : entries) {
QString dir = test.absoluteFilePath() + QDir::separator();
QTest::newRow(qPrintable(test.baseName()))
<< dir + "input"
@@ -1543,20 +1549,26 @@ void tst_QCssParser::gradient()
QList<QCss::StyleRule> rules = testSelector.styleRulesForNode(n);
QList<QCss::Declaration> decls = rules.at(0).declarations;
QCss::ValueExtractor ve(decls);
- QBrush fg, sfg, pfg;
- QBrush sbg, abg;
- QVERIFY(ve.extractPalette(&fg, &sfg, &sbg, &abg, &pfg));
+ QBrush foreground;
+ QBrush selectedForeground;
+ QBrush selectedBackground;
+ QBrush alternateBackground;
+ QBrush placeHolderTextForeground;
+ QBrush accent;
+ QVERIFY(ve.extractPalette(&foreground, &selectedForeground, &selectedBackground,
+ &alternateBackground, &placeHolderTextForeground, &accent));
+
if (type == "linear") {
- QCOMPARE(sbg.style(), Qt::LinearGradientPattern);
- const QLinearGradient *lg = static_cast<const QLinearGradient *>(sbg.gradient());
+ QCOMPARE(selectedBackground.style(), Qt::LinearGradientPattern);
+ const auto *lg = static_cast<const QLinearGradient *>(selectedBackground.gradient());
QCOMPARE(lg->start(), start);
QCOMPARE(lg->finalStop(), finalStop);
} else if (type == "conical") {
- QCOMPARE(sbg.style(), Qt::ConicalGradientPattern);
- const QConicalGradient *cg = static_cast<const QConicalGradient *>(sbg.gradient());
+ QCOMPARE(selectedBackground.style(), Qt::ConicalGradientPattern);
+ const auto *cg = static_cast<const QConicalGradient *>(selectedBackground.gradient());
QCOMPARE(cg->center(), start);
}
- const QGradient *g = sbg.gradient();
+ const QGradient *g = selectedBackground.gradient();
QCOMPARE(g->spread(), QGradient::Spread(spread));
QCOMPARE(g->stops().at(0).first, stop0);
QCOMPARE(g->stops().at(0).second, color0);
@@ -1751,6 +1763,57 @@ void tst_QCssParser::whitespaceValues()
QCOMPARE(rule.declarations.at(0).d->values.first().toString(), value);
}
+void tst_QCssParser::strokeLineCapValues_data()
+{
+ QTest::addColumn<QString>("value");
+
+ QTest::newRow("flatcap") << "flatcap";
+ QTest::newRow("roundcap") << "roundcap";
+ QTest::newRow("squarecap") << "squarecap";
+}
+
+void tst_QCssParser::strokeLineCapValues()
+{
+ QFETCH(QString, value);
+ QCss::Parser parser(QString("foo { -qt-stroke-linecap: %1 }").arg(value));
+ QCss::StyleSheet sheet;
+ QVERIFY(parser.parse(&sheet));
+
+ QCss::StyleRule rule = (!sheet.styleRules.isEmpty()) ?
+ sheet.styleRules.at(0) : *sheet.nameIndex.begin();
+ QCOMPARE(rule.declarations.size(), 1);
+
+ QCOMPARE(rule.declarations.at(0).d->property, QLatin1String("-qt-stroke-linecap"));
+ QCOMPARE(rule.declarations.at(0).d->values.first().type, QCss::Value::KnownIdentifier);
+ QCOMPARE(rule.declarations.at(0).d->values.first().toString(), value);
+}
+
+void tst_QCssParser::strokeLineJoinValues_data()
+{
+ QTest::addColumn<QString>("value");
+
+ QTest::newRow("beveljoin") << "beveljoin";
+ QTest::newRow("miterjoin") << "miterjoin";
+ QTest::newRow("roundjoin") << "roundjoin";
+ QTest::newRow("svgmiterjoin") << "svgmiterjoin";
+}
+
+void tst_QCssParser::strokeLineJoinValues()
+{
+ QFETCH(QString, value);
+ QCss::Parser parser(QString("foo { -qt-stroke-linejoin: %1 }").arg(value));
+ QCss::StyleSheet sheet;
+ QVERIFY(parser.parse(&sheet));
+
+ QCss::StyleRule rule = (!sheet.styleRules.isEmpty()) ?
+ sheet.styleRules.at(0) : *sheet.nameIndex.begin();
+ QCOMPARE(rule.declarations.size(), 1);
+
+ QCOMPARE(rule.declarations.at(0).d->property, QLatin1String("-qt-stroke-linejoin"));
+ QCOMPARE(rule.declarations.at(0).d->values.first().type, QCss::Value::KnownIdentifier);
+ QCOMPARE(rule.declarations.at(0).d->values.first().toString(), value);
+}
+
QTEST_MAIN(tst_QCssParser)
#include "tst_qcssparser.moc"
diff --git a/tests/auto/gui/text/qfont/CMakeLists.txt b/tests/auto/gui/text/qfont/CMakeLists.txt
index c51df322f9..88ae9959e4 100644
--- a/tests/auto/gui/text/qfont/CMakeLists.txt
+++ b/tests/auto/gui/text/qfont/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qfont Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfont LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Resources:
set(testfont_resource_files
"datastream.515"
diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp
index 76d844b007..5426d7b117 100644
--- a/tests/auto/gui/text/qfont/tst_qfont.cpp
+++ b/tests/auto/gui/text/qfont/tst_qfont.cpp
@@ -1,5 +1,7 @@
// 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
+
+#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
#include <QTest>
#include <QBuffer>
@@ -19,6 +21,9 @@
#endif
#include <qlist.h>
#include <QtTest/private/qemulationdetector_p.h>
+#include <private/qcomparisontesthelper_p.h>
+
+using namespace Qt::StringLiterals;
class tst_QFont : public QObject
{
@@ -54,6 +59,9 @@ private slots:
void setFamilies();
void setFamiliesAndFamily_data();
void setFamiliesAndFamily();
+ void featureAccessors();
+ void tagCompares_data();
+ void tagCompares();
};
// Testing get/set functions
@@ -150,7 +158,7 @@ void tst_QFont::italicOblique()
continue;
}
QFont f = QFontDatabase::font(family, style, 12);
- QVERIFY(f.italic());
+ QVERIFY2(f.italic(), qPrintable(QString::asprintf("Failed for font \"%ls\"", qUtf16Printable(f.family()))));
}
}
}
@@ -841,5 +849,83 @@ void tst_QFont::setFamiliesAndFamily()
QFontDatabase::removeApplicationFont(weirdFontId);
}
+void tst_QFont::featureAccessors()
+{
+ const QFont::Tag abcdTag("abcd");
+ QCOMPARE(abcdTag.toString(), "abcd");
+ QVERIFY(abcdTag.isValid());
+
+ QFont font;
+ QVERIFY(font.featureTags().isEmpty());
+ font.setFeature("abcd", 0xc0ffee);
+
+ QVERIFY(font.isFeatureSet(abcdTag));
+ QVERIFY(!font.isFeatureSet("bcde"));
+ QCOMPARE(font.featureTags().size(), 1);
+ QCOMPARE(font.featureTags().first(), abcdTag);
+ QCOMPARE(font.featureTags().first(), "abcd");
+ QCOMPARE(font.featureValue(abcdTag), 0xc0ffeeU);
+ QCOMPARE(font.featureValue("bcde"), 0U);
+ font.setFeature(abcdTag, 0xf00d);
+ QCOMPARE(font.featureTags().size(), 1);
+ QCOMPARE(font.featureValue(abcdTag), 0xf00dU);
+
+ QFont::Tag invalidTag;
+ QVERIFY(!invalidTag.isValid());
+ font.setFeature(invalidTag, 0xcaca0);
+ QVERIFY(!font.isFeatureSet(invalidTag));
+ QCOMPARE(font.featureTags().size(), 1);
+ QFont font2 = font;
+
+ font.unsetFeature("abcd");
+ QVERIFY(!font.isFeatureSet("abcd"));
+ QVERIFY(font.featureTags().isEmpty());
+
+ QVERIFY(font2.isFeatureSet("abcd"));
+ font2.clearFeatures();
+ QVERIFY(font.featureTags().isEmpty());
+
+ // various constructor compile tests
+ QFont::Tag tag;
+ tag = QFont::Tag("1234");
+ QVERIFY(QFont::Tag::fromString(QByteArray("abcd")));
+ QVERIFY(QFont::Tag::fromString(u"frac"_s));
+
+ // named constructors with invalid input
+ QTest::ignoreMessage(QtWarningMsg, "The tag name must be exactly 4 characters long!");
+ QVERIFY(!QFont::Tag::fromString(u"fraction"_s));
+ QVERIFY(!QFont::Tag::fromValue(0));
+ QVERIFY(QFont::Tag::fromValue(abcdTag.value()));
+
+ enum Features {
+ Frac = QFont::Tag("frac").value()
+ };
+}
+
+void tst_QFont::tagCompares_data()
+{
+ QTestPrivate::testAllComparisonOperatorsCompile<QFont::Tag>();
+
+ QTest::addColumn<QFont::Tag>("lhs");
+ QTest::addColumn<QFont::Tag>("rhs");
+ QTest::addColumn<Qt::strong_ordering>("expectedOrder");
+
+ auto row = [](QFont::Tag left, QFont::Tag right) {
+ QTest::addRow("%s<=>%s", left.toString().constData(), right.toString().constData())
+ << left << right << Qt::compareThreeWay(left.value(), right.value());
+ };
+ row("frac", "wght");
+}
+
+void tst_QFont::tagCompares()
+{
+ QFETCH(QFont::Tag, lhs);
+ QFETCH(QFont::Tag, rhs);
+ QFETCH(Qt::strong_ordering, expectedOrder);
+
+ QVERIFY(comparesEqual(lhs, lhs));
+ QCOMPARE(compareThreeWay(lhs, rhs), expectedOrder);
+}
+
QTEST_MAIN(tst_QFont)
#include "tst_qfont.moc"
diff --git a/tests/auto/gui/text/qfontcache/CMakeLists.txt b/tests/auto/gui/text/qfontcache/CMakeLists.txt
index a95128caba..d9645c115a 100644
--- a/tests/auto/gui/text/qfontcache/CMakeLists.txt
+++ b/tests/auto/gui/text/qfontcache/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qfontcache Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfontcache LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qfontcache
SOURCES
tst_qfontcache.cpp
diff --git a/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp b/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp
index 7d30baf876..79f24a2f0d 100644
--- a/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp
+++ b/tests/auto/gui/text/qfontcache/tst_qfontcache.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>
diff --git a/tests/auto/gui/text/qfontdatabase/CMakeLists.txt b/tests/auto/gui/text/qfontdatabase/CMakeLists.txt
index b1eaf8e3df..0cb6e8d7c8 100644
--- a/tests/auto/gui/text/qfontdatabase/CMakeLists.txt
+++ b/tests/auto/gui/text/qfontdatabase/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qfontdatabase Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfontdatabase LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
list(APPEND test_data "LED_REAL.TTF")
@@ -31,12 +37,18 @@ set_source_files_properties("../../../shared/resources/testfont_italic.ttf"
set_source_files_properties("../../../shared/resources/testfont_open.otf"
PROPERTIES QT_RESOURCE_ALIAS "testfont_open.otf"
)
+set_source_files_properties("../../../shared/resources/testfont_variable.ttf"
+ PROPERTIES QT_RESOURCE_ALIAS "testfont_variable.ttf"
+)
set(testdata_resource_files
"../../../shared/resources/testfont.ttf"
"../../../shared/resources/testfont_condensed.ttf"
"../../../shared/resources/testfont_italic.ttf"
"../../../shared/resources/testfont_open.otf"
+ "../../../shared/resources/testfont_variable.ttf"
"LED_REAL.TTF"
+ "QtTestLimitedFont-Regular.ttf"
+ "QtTestFallbackFont-Regular.ttf"
)
qt_internal_add_resource(tst_qfontdatabase "testdata"
diff --git a/tests/auto/gui/text/qfontdatabase/QtTestFallbackFont-Regular.ttf b/tests/auto/gui/text/qfontdatabase/QtTestFallbackFont-Regular.ttf
new file mode 100644
index 0000000000..ae21fec9a5
--- /dev/null
+++ b/tests/auto/gui/text/qfontdatabase/QtTestFallbackFont-Regular.ttf
Binary files differ
diff --git a/tests/auto/gui/text/qfontdatabase/QtTestLimitedFont-Regular.ttf b/tests/auto/gui/text/qfontdatabase/QtTestLimitedFont-Regular.ttf
new file mode 100644
index 0000000000..2891f8aeff
--- /dev/null
+++ b/tests/auto/gui/text/qfontdatabase/QtTestLimitedFont-Regular.ttf
Binary files differ
diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
index 665ee75a35..8733f64d97 100644
--- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.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>
#include <QSignalSpy>
@@ -12,6 +12,9 @@
#include <private/qfont_p.h>
#include <private/qfontengine_p.h>
#include <qpa/qplatformfontdatabase.h>
+#include <qpa/qplatformintegration.h>
+
+#include <QtGui/private/qguiapplication_p.h>
using namespace Qt::StringLiterals;
@@ -61,15 +64,22 @@ private slots:
void stretchRespected();
+ void variableFont();
+
#ifdef Q_OS_WIN
void findCourier();
#endif
+ void addApplicationFontFallback();
+
private:
QString m_ledFont;
QString m_testFont;
QString m_testFontCondensed;
QString m_testFontItalic;
+ QString m_testFontVariable;
+ QString m_limitedFont;
+ QString m_fallbackFont;
};
tst_QFontDatabase::tst_QFontDatabase()
@@ -82,10 +92,16 @@ void tst_QFontDatabase::initTestCase()
m_testFont = QFINDTESTDATA("testfont.ttf");
m_testFontCondensed = QFINDTESTDATA("testfont_condensed.ttf");
m_testFontItalic = QFINDTESTDATA("testfont_italic.ttf");
+ m_testFontVariable = QFINDTESTDATA("testfont_variable.ttf");
+ m_limitedFont = QFINDTESTDATA("QtTestLimitedFont-Regular.ttf");
+ m_fallbackFont = QFINDTESTDATA("QtTestFallbackFont-Regular.ttf");
QVERIFY(!m_ledFont.isEmpty());
QVERIFY(!m_testFont.isEmpty());
QVERIFY(!m_testFontCondensed.isEmpty());
QVERIFY(!m_testFontItalic.isEmpty());
+ QVERIFY(!m_testFontVariable.isEmpty());
+ QVERIFY(!m_limitedFont.isEmpty());
+ QVERIFY(!m_fallbackFont.isEmpty());
}
void tst_QFontDatabase::styles_data()
@@ -223,7 +239,7 @@ void tst_QFontDatabase::addAppFont()
int id;
if (useMemoryFont) {
QFile fontfile(m_ledFont);
- fontfile.open(QIODevice::ReadOnly);
+ QVERIFY(fontfile.open(QIODevice::ReadOnly));
QByteArray fontdata = fontfile.readAll();
QVERIFY(!fontdata.isEmpty());
id = QFontDatabase::addApplicationFontFromData(fontdata);
@@ -319,8 +335,8 @@ void tst_QFontDatabase::fallbackFonts()
layout.createLine();
layout.endLayout();
- QList<QGlyphRun> runs = layout.glyphRuns(0, 1);
- foreach (QGlyphRun run, runs) {
+ const QList<QGlyphRun> runs = layout.glyphRuns(0, 1);
+ for (QGlyphRun run : runs) {
QRawFont rawFont = run.rawFont();
QVERIFY(rawFont.isValid());
@@ -381,8 +397,14 @@ void tst_QFontDatabase::condensedFontWidthNoFontMerging()
void tst_QFontDatabase::condensedFontWidth()
{
- QFontDatabase::addApplicationFont(m_testFont);
- QFontDatabase::addApplicationFont(m_testFontCondensed);
+ int testFontId = QFontDatabase::addApplicationFont(m_testFont);
+ int testFontCondensedId = QFontDatabase::addApplicationFont(m_testFontCondensed);
+ auto cleanup = qScopeGuard([&testFontId, &testFontCondensedId] {
+ if (testFontId >= 0)
+ QFontDatabase::removeApplicationFont(testFontId);
+ if (testFontCondensedId >= 0)
+ QFontDatabase::removeApplicationFont(testFontCondensedId);
+ });
QVERIFY(QFontDatabase::hasFamily("QtBidiTestFont"));
if (!QFontDatabase::hasFamily("QtBidiTestFontCondensed"))
@@ -400,10 +422,16 @@ void tst_QFontDatabase::condensedFontWidth()
void tst_QFontDatabase::condensedFontMatching()
{
QFontDatabase::removeAllApplicationFonts();
- QFontDatabase::addApplicationFont(m_testFontCondensed);
+ int testFontCondensedId = QFontDatabase::addApplicationFont(m_testFontCondensed);
if (!QFontDatabase::hasFamily("QtBidiTestFont"))
QSKIP("This platform doesn't support preferred font family names (QTBUG-53478)");
- QFontDatabase::addApplicationFont(m_testFont);
+ int testFontId = QFontDatabase::addApplicationFont(m_testFont);
+ auto cleanup = qScopeGuard([&testFontId, &testFontCondensedId] {
+ if (testFontId >= 0)
+ QFontDatabase::removeApplicationFont(testFontId);
+ if (testFontCondensedId >= 0)
+ QFontDatabase::removeApplicationFont(testFontCondensedId);
+ });
// Test we correctly get the condensed font using different font matching methods:
QFont tfcByStretch("QtBidiTestFont");
@@ -415,8 +443,10 @@ void tst_QFontDatabase::condensedFontMatching()
QFont f;
f.setStyleStrategy(QFont::NoFontMerging);
QFontPrivate *font_d = QFontPrivate::get(f);
- if (font_d->engineForScript(QChar::Script_Common)->type() != QFontEngine::Freetype)
+ if (font_d->engineForScript(QChar::Script_Common)->type() != QFontEngine::Freetype
+ && font_d->engineForScript(QChar::Script_Common)->type() != QFontEngine::DirectWrite) {
QEXPECT_FAIL("","No matching of sub-family by stretch on Windows", Continue);
+ }
#endif
QCOMPARE(QFontMetrics(tfcByStretch).horizontalAdvance(testString()),
@@ -505,5 +535,230 @@ void tst_QFontDatabase::findCourier()
}
#endif
+void tst_QFontDatabase::variableFont()
+{
+ {
+ QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
+ if (!pfdb->supportsVariableApplicationFonts())
+ QSKIP("Variable application fonts not supported on this platform");
+ }
+
+ int id = QFontDatabase::addApplicationFont(m_testFontVariable);
+ if (id == -1)
+ QSKIP("Skip the test since app fonts are not supported on this system");
+
+ QString family = QFontDatabase::applicationFontFamilies(id).first();
+ {
+ QFont font(family);
+ QCOMPARE(QFontInfo(font).styleName(), u"Regular"_s);
+ QCOMPARE(QFontInfo(font).weight(), QFont::Normal);
+ }
+
+ {
+ QFont font(family);
+ font.setWeight(QFont::Black);
+ QCOMPARE(QFontInfo(font).styleName(), u"QtExtraBold"_s);
+ QCOMPARE(QFontInfo(font).weight(), int(QFont::Black));
+ }
+
+ {
+ QFont regularFont(family);
+ QFont extraBoldFont(family);
+ extraBoldFont.setStyleName(u"QtExtraBold"_s);
+
+ QFontMetricsF regularFm(regularFont);
+ QFontMetricsF extraBoldFm(extraBoldFont);
+
+ QVERIFY(regularFm.horizontalAdvance(QLatin1Char('1')) < extraBoldFm.horizontalAdvance(QLatin1Char('1')));
+ }
+
+ QFontDatabase::removeApplicationFont(id);
+}
+
+void tst_QFontDatabase::addApplicationFontFallback()
+{
+ int ledId = -1;
+ int id = -1;
+ int limitedId = -1;
+ int fallbackId = -1;
+ auto cleanup = qScopeGuard([&id, &ledId, &limitedId, &fallbackId] {
+ if (id >= 0)
+ QFontDatabase::removeApplicationFont(id);
+ if (ledId >= 0)
+ QFontDatabase::removeApplicationFont(ledId);
+ if (limitedId >= 0)
+ QFontDatabase::removeApplicationFont(limitedId);
+ if (fallbackId >= 0)
+ QFontDatabase::removeApplicationFont(fallbackId);
+ });
+
+ const QChar hebrewChar(0x05D0); // Hebrew 'aleph'
+
+ ledId = QFontDatabase::addApplicationFont(m_ledFont);
+ if (ledId < 0)
+ QSKIP("Skip the test since app fonts are not supported on this system");
+
+ auto getHebrewFont = [&]() {
+ QTextLayout layout;
+ layout.setText(hebrewChar);
+ layout.setFont(QFont(u"LED Real"_s));
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QList<QGlyphRun> glyphRuns = layout.glyphRuns();
+ if (glyphRuns.isEmpty())
+ return QString{};
+
+ return glyphRuns.first().rawFont().familyName();
+ };
+
+ QString defaultHebrewFont = getHebrewFont();
+ if (defaultHebrewFont.isEmpty())
+ QSKIP("Skip the test since Hebrew is not supported on this system");
+
+ QVERIFY(QFontDatabase::applicationFallbackFontFamilies(QChar::Script_Hebrew).isEmpty());
+ QFontDatabase::addApplicationFallbackFontFamily(QChar::Script_Hebrew, u"QtBidiTestFont"_s);
+
+ QCOMPARE(QFontDatabase::applicationFallbackFontFamilies(QChar::Script_Hebrew).size(), 1);
+ QCOMPARE(QFontDatabase::applicationFallbackFontFamilies(QChar::Script_Hebrew).first(), u"QtBidiTestFont"_s);
+
+ {
+ QString hebrewFontNow = getHebrewFont();
+ QCOMPARE(hebrewFontNow, defaultHebrewFont);
+ }
+
+ id = QFontDatabase::addApplicationFont(m_testFont);
+ QVERIFY(id >= 0);
+
+ {
+ QString hebrewFontNow = getHebrewFont();
+ QCOMPARE(hebrewFontNow, u"QtBidiTestFont"_s);
+ }
+
+ QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script_Hebrew, u"QtBidiTestFont"_s);
+
+ {
+ QString hebrewFontNow = getHebrewFont();
+ QCOMPARE(hebrewFontNow, defaultHebrewFont);
+ }
+
+ QFontDatabase::setApplicationFallbackFontFamilies(QChar::Script_Hebrew, QStringList(u"QtBidiTestFont"_s));
+
+ {
+ QString hebrewFontNow = getHebrewFont();
+ QCOMPARE(hebrewFontNow, u"QtBidiTestFont"_s);
+ }
+
+ QFontDatabase::setApplicationFallbackFontFamilies(QChar::Script_Hebrew, QStringList{});
+
+ {
+ QString hebrewFontNow = getHebrewFont();
+ QCOMPARE(hebrewFontNow, defaultHebrewFont);
+ }
+
+ limitedId = QFontDatabase::addApplicationFont(m_limitedFont);
+ QVERIFY(limitedId >= 0);
+
+ fallbackId = QFontDatabase::addApplicationFont(m_fallbackFont);
+ QVERIFY(fallbackId >= 0);
+
+ QFontDatabase::addApplicationFallbackFontFamily(QChar::Script_Common, u"QtTestFallbackFont"_s);
+
+ // The fallback for Common will be used also for Latin, because Latin and Common are
+ // considered the same script by the font matching engine.
+ {
+ QTextLayout layout;
+ layout.setText(u"A'B,"_s);
+ layout.setFont(QFont(u"QtTestLimitedFont"_s));
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QList<QGlyphRun> glyphRuns = layout.glyphRuns();
+ QVERIFY(glyphRuns.size() > 1);
+ for (int i = 0; i < glyphRuns.size(); ++i) {
+ QVERIFY(glyphRuns.at(i).rawFont().familyName() == u"QtTestFallbackFont"_s
+ || glyphRuns.at(i).rawFont().familyName() == u"QtTestLimitedFont"_s);
+ }
+ }
+
+ // When the text only consists of common script characters, the fallback font will also be used.
+ {
+ QTextLayout layout;
+ layout.setText(u"',"_s);
+ layout.setFont(QFont(u"QtTestLimitedFont"_s));
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QList<QGlyphRun> glyphRuns = layout.glyphRuns();
+ QCOMPARE(glyphRuns.size(), 2);
+ for (int i = 0; i < glyphRuns.size(); ++i) {
+ QVERIFY(glyphRuns.at(i).rawFont().familyName() == u"QtTestFallbackFont"_s
+ || glyphRuns.at(i).rawFont().familyName() == u"QtTestLimitedFont"_s);
+ }
+ }
+
+ QVERIFY(QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script_Common, u"QtTestFallbackFont"_s));
+ QFontDatabase::addApplicationFallbackFontFamily(QChar::Script_Latin, u"QtTestFallbackFont"_s);
+
+ // Latin fallback works just the same as Common fallback
+ {
+ QTextLayout layout;
+ layout.setText(u"A'B,"_s);
+ layout.setFont(QFont(u"QtTestLimitedFont"_s));
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QList<QGlyphRun> glyphRuns = layout.glyphRuns();
+ QCOMPARE(glyphRuns.size(), 2);
+ for (int i = 0; i < glyphRuns.size(); ++i) {
+ QVERIFY(glyphRuns.at(i).rawFont().familyName() == u"QtTestFallbackFont"_s
+ || glyphRuns.at(i).rawFont().familyName() == u"QtTestLimitedFont"_s);
+ }
+ }
+
+ // When the common character is placed next to a Cyrillic characters, it gets adapted to this,
+ // so the fallback font will not be selected, even if it supports the character in question
+ {
+ QTextLayout layout;
+ layout.setText(u"A'Б,"_s);
+ layout.setFont(QFont(u"QtTestLimitedFont"_s));
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QList<QGlyphRun> glyphRuns = layout.glyphRuns();
+ QCOMPARE(glyphRuns.size(), 2);
+ for (int i = 0; i < glyphRuns.size(); ++i) {
+ QVERIFY(glyphRuns.at(i).rawFont().familyName() != u"QtTestFallbackFont"_s);
+ }
+ }
+
+ QFontDatabase::addApplicationFallbackFontFamily(QChar::Script_Cyrillic, u"QtTestFallbackFont"_s);
+
+ // When we set the fallback font for Cyrillic as well, it gets selected
+ {
+ QTextLayout layout;
+ layout.setText(u"A'Б,"_s);
+ layout.setFont(QFont(u"QtTestLimitedFont"_s));
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QList<QGlyphRun> glyphRuns = layout.glyphRuns();
+ QCOMPARE(glyphRuns.size(), 2);
+ for (int i = 0; i < glyphRuns.size(); ++i) {
+ QVERIFY(glyphRuns.at(i).rawFont().familyName() == u"QtTestFallbackFont"_s
+ || glyphRuns.at(i).rawFont().familyName() == u"QtTestLimitedFont"_s);
+ }
+ }
+
+ QVERIFY(QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script_Cyrillic, u"QtTestFallbackFont"_s));
+ QVERIFY(QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script_Latin, u"QtTestFallbackFont"_s));
+}
+
QTEST_MAIN(tst_QFontDatabase)
#include "tst_qfontdatabase.moc"
diff --git a/tests/auto/gui/text/qfontmetrics/CMakeLists.txt b/tests/auto/gui/text/qfontmetrics/CMakeLists.txt
index d63ae61a10..ee2f76ef76 100644
--- a/tests/auto/gui/text/qfontmetrics/CMakeLists.txt
+++ b/tests/auto/gui/text/qfontmetrics/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qfontmetrics Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfontmetrics LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qfontmetrics
SOURCES
tst_qfontmetrics.cpp
@@ -18,8 +24,12 @@ qt_internal_add_test(tst_qfontmetrics
set_source_files_properties("../../../shared/resources/testfont.ttf"
PROPERTIES QT_RESOURCE_ALIAS "testfont.ttf"
)
+set_source_files_properties("../../../shared/resources/testfont_linemetrics.otf"
+ PROPERTIES QT_RESOURCE_ALIAS "testfont_linemetrics.otf"
+)
set(testfont_resource_files
"../../../shared/resources/testfont.ttf"
+ "../../../shared/resources/testfont_linemetrics.otf"
"ucs4font.ttf"
)
diff --git a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp
index 5516492365..bad33ab0a4 100644
--- a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp
+++ b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.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>
@@ -34,6 +34,9 @@ private slots:
void zeroWidthMetrics();
void verticalMetrics_data();
void verticalMetrics();
+ void largeText_data();
+ void largeText(); // QTBUG-123339
+ void typoLineMetrics();
};
void tst_QFontMetrics::same()
@@ -261,7 +264,7 @@ void tst_QFontMetrics::inFontUcs4()
glyphs.glyphs[0] = 0;
QVERIFY(engine->stringToCMap(string.constData(), string.size(),
&glyphs, &glyphs.numGlyphs,
- QFontEngine::GlyphIndicesOnly));
+ QFontEngine::GlyphIndicesOnly) > 0);
QCOMPARE(glyphs.numGlyphs, 1);
QCOMPARE(glyphs.glyphs[0], uint(1));
}
@@ -273,7 +276,7 @@ void tst_QFontMetrics::inFontUcs4()
glyphs.glyphs[0] = 0;
QVERIFY(engine->stringToCMap(string.constData(), string.size(),
&glyphs, &glyphs.numGlyphs,
- QFontEngine::GlyphIndicesOnly));
+ QFontEngine::GlyphIndicesOnly) >= 0);
QVERIFY(glyphs.glyphs[0] != 1);
}
}
@@ -388,5 +391,68 @@ void tst_QFontMetrics::verticalMetrics()
QVERIFY(fm.ascent() != 0 || fm.descent() != 0);
}
+void tst_QFontMetrics::largeText_data()
+{
+ QTest::addColumn<qsizetype>("size");
+ for (int i = 1; i < 20; ++i) {
+ qsizetype size = qsizetype(1) << i;
+ QByteArray rowText = QByteArray::number(size);
+ QTest::newRow(rowText.constData()) << size;
+ }
+}
+
+void tst_QFontMetrics::largeText()
+{
+ QFont font;
+ QFontMetrics fm(font);
+ QFETCH(qsizetype, size);
+ QString string(size, QLatin1Char('A'));
+ QRect boundingRect = fm.boundingRect(string);
+ QVERIFY(boundingRect.isValid());
+}
+
+void tst_QFontMetrics::typoLineMetrics()
+{
+ QString testFont = QFINDTESTDATA("fonts/testfont_linemetrics.otf");
+ QVERIFY(!testFont.isEmpty());
+
+ int id = QFontDatabase::addApplicationFont(testFont);
+ QVERIFY(id >= 0);
+
+ {
+ auto cleanup = qScopeGuard([&id] {
+ if (id >= 0)
+ QFontDatabase::removeApplicationFont(id);
+ });
+
+ QImage img(100, 100, QImage::Format_ARGB32);
+ img.setDevicePixelRatio(1.0);
+ QFont font(QFontDatabase::applicationFontFamilies(id).at(0), &img);
+ font.setPixelSize(18);
+
+ const qreal unitsPerEm = 1000.0;
+
+ QFontMetrics defaultFm(font);
+ const int defaultAscent = defaultFm.ascent();
+ const int defaultDescent = defaultFm.descent();
+ const int defaultLeading = defaultFm.leading();
+
+ QCOMPARE(defaultAscent, qRound(1234.0 / unitsPerEm * font.pixelSize()));
+ QCOMPARE(defaultDescent, qRound(5678.0 / unitsPerEm * font.pixelSize()));
+ QCOMPARE(defaultLeading, 0.0);
+
+ font.setStyleStrategy(QFont::PreferTypoLineMetrics);
+ const QFontMetrics typoFm(font);
+
+ const int typoAscent = typoFm.ascent();
+ const int typoDescent = typoFm.descent();
+ const int typoLeading = typoFm.leading();
+
+ QCOMPARE(typoAscent, qRound(2000.0 / unitsPerEm * font.pixelSize()));
+ QCOMPARE(typoDescent, qRound(3000.0 / unitsPerEm * font.pixelSize()));
+ QCOMPARE(typoLeading, qRound(1000.0 / unitsPerEm * font.pixelSize()));
+ }
+}
+
QTEST_MAIN(tst_QFontMetrics)
#include "tst_qfontmetrics.moc"
diff --git a/tests/auto/gui/text/qglyphrun/BLACKLIST b/tests/auto/gui/text/qglyphrun/BLACKLIST
deleted file mode 100644
index 86e857fb23..0000000000
--- a/tests/auto/gui/text/qglyphrun/BLACKLIST
+++ /dev/null
@@ -1,7 +0,0 @@
-# QTBUG-68860
-[mixedScripts]
-ubuntu-18.04
-ubuntu-20.04
-ubuntu-22.04
-# QTBUG-100928
-qnx
diff --git a/tests/auto/gui/text/qglyphrun/CMakeLists.txt b/tests/auto/gui/text/qglyphrun/CMakeLists.txt
index ffee80ea03..a9ffd3729d 100644
--- a/tests/auto/gui/text/qglyphrun/CMakeLists.txt
+++ b/tests/auto/gui/text/qglyphrun/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qglyphrun Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qglyphrun LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Resources:
set_source_files_properties("../../../shared/resources/test.ttf"
PROPERTIES QT_RESOURCE_ALIAS "test.ttf"
diff --git a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
index 9bc9391989..8c0c0324c9 100644
--- a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
+++ b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.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>
@@ -408,7 +408,7 @@ void tst_QGlyphRun::drawMultiScriptText1()
QPixmap drawGlyphs(1000, 1000);
drawGlyphs.fill(Qt::white);
- QList<QGlyphRun> glyphsList = textLayout.glyphRuns();
+ const QList<QGlyphRun> glyphsList = textLayout.glyphRuns();
QCOMPARE(glyphsList.size(), 1);
{
@@ -418,8 +418,7 @@ void tst_QGlyphRun::drawMultiScriptText1()
{
QPainter p(&drawGlyphs);
- foreach (QGlyphRun glyphs, glyphsList)
- p.drawGlyphRun(QPointF(50, 50), glyphs);
+ p.drawGlyphRun(QPointF(50, 50), glyphsList.first());
}
#if defined(DEBUG_SAVE_IMAGE)
@@ -449,7 +448,7 @@ void tst_QGlyphRun::drawMultiScriptText2()
QPixmap drawGlyphs(1000, 1000);
drawGlyphs.fill(Qt::white);
- QList<QGlyphRun> glyphsList = textLayout.glyphRuns();
+ const QList<QGlyphRun> glyphsList = textLayout.glyphRuns();
QCOMPARE(glyphsList.size(), 2);
{
@@ -459,7 +458,7 @@ void tst_QGlyphRun::drawMultiScriptText2()
{
QPainter p(&drawGlyphs);
- foreach (QGlyphRun glyphs, glyphsList)
+ for (const QGlyphRun &glyphs : glyphsList)
p.drawGlyphRun(QPointF(50, 50), glyphs);
}
@@ -564,6 +563,9 @@ void tst_QGlyphRun::boundingRect()
void tst_QGlyphRun::mixedScripts()
{
+ if (QFontDatabase::families(QFontDatabase::Korean).isEmpty())
+ QSKIP("This test requires support for Hangul text");
+
QString s;
s += QChar(0x31); // The character '1'
s += QChar(0xbc14); // Hangul character
diff --git a/tests/auto/gui/text/qinputcontrol/CMakeLists.txt b/tests/auto/gui/text/qinputcontrol/CMakeLists.txt
index 04e99b2c7c..75fc85bc39 100644
--- a/tests/auto/gui/text/qinputcontrol/CMakeLists.txt
+++ b/tests/auto/gui/text/qinputcontrol/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qinputcontrol Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qinputcontrol LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qinputcontrol
SOURCES
tst_qinputcontrol.cpp
diff --git a/tests/auto/gui/text/qinputcontrol/tst_qinputcontrol.cpp b/tests/auto/gui/text/qinputcontrol/tst_qinputcontrol.cpp
index a75975664b..678f4491c4 100644
--- a/tests/auto/gui/text/qinputcontrol/tst_qinputcontrol.cpp
+++ b/tests/auto/gui/text/qinputcontrol/tst_qinputcontrol.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>
diff --git a/tests/auto/gui/text/qrawfont/CMakeLists.txt b/tests/auto/gui/text/qrawfont/CMakeLists.txt
index aebbca15f7..d2a318a2a3 100644
--- a/tests/auto/gui/text/qrawfont/CMakeLists.txt
+++ b/tests/auto/gui/text/qrawfont/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qrawfont Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qrawfont LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Resources:
set_source_files_properties("../../../shared/resources/testfont.ttf"
PROPERTIES QT_RESOURCE_ALIAS "testfont.ttf"
diff --git a/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp b/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp
index 8b203f439e..5ec2536718 100644
--- a/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp
+++ b/tests/auto/gui/text/qrawfont/tst_qrawfont.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>
#include <QtGui/QFontDatabase>
@@ -398,13 +398,13 @@ void tst_QRawFont::textLayout()
void tst_QRawFont::fontTable_data()
{
- QTest::addColumn<QByteArray>("tagName");
+ QTest::addColumn<QFont::Tag>("tag");
QTest::addColumn<QFont::HintingPreference>("hintingPreference");
QTest::addColumn<int>("offset");
QTest::addColumn<quint32>("expectedValue");
QTest::newRow("Head table, magic number, default hinting")
- << QByteArray("head")
+ << QFont::Tag("head")
<< QFont::PreferDefaultHinting
<< 12
<< (QSysInfo::ByteOrder == QSysInfo::BigEndian
@@ -412,7 +412,7 @@ void tst_QRawFont::fontTable_data()
: 0xF53C0F5F);
QTest::newRow("Head table, magic number, no hinting")
- << QByteArray("head")
+ << QFont::Tag("head")
<< QFont::PreferNoHinting
<< 12
<< (QSysInfo::ByteOrder == QSysInfo::BigEndian
@@ -420,7 +420,7 @@ void tst_QRawFont::fontTable_data()
: 0xF53C0F5F);
QTest::newRow("Head table, magic number, vertical hinting")
- << QByteArray("head")
+ << QFont::Tag("head")
<< QFont::PreferVerticalHinting
<< 12
<< (QSysInfo::ByteOrder == QSysInfo::BigEndian
@@ -428,7 +428,7 @@ void tst_QRawFont::fontTable_data()
: 0xF53C0F5F);
QTest::newRow("Head table, magic number, full hinting")
- << QByteArray("head")
+ << QFont::Tag("head")
<< QFont::PreferFullHinting
<< 12
<< (QSysInfo::ByteOrder == QSysInfo::BigEndian
@@ -438,7 +438,7 @@ void tst_QRawFont::fontTable_data()
void tst_QRawFont::fontTable()
{
- QFETCH(QByteArray, tagName);
+ QFETCH(QFont::Tag, tag);
QFETCH(QFont::HintingPreference, hintingPreference);
QFETCH(int, offset);
QFETCH(quint32, expectedValue);
@@ -446,11 +446,13 @@ void tst_QRawFont::fontTable()
QRawFont font(testFont, 10, hintingPreference);
QVERIFY(font.isValid());
- QByteArray table = font.fontTable(tagName);
+ QByteArray table = font.fontTable(tag);
QVERIFY(!table.isEmpty());
const quint32 *value = reinterpret_cast<const quint32 *>(table.constData() + offset);
QCOMPARE(*value, expectedValue);
+
+ QCOMPARE(font.fontTable(tag.toString()), table);
}
typedef QList<QFontDatabase::WritingSystem> WritingSystemList;
@@ -490,7 +492,7 @@ void tst_QRawFont::supportedWritingSystems_data()
void tst_QRawFont::supportedWritingSystems()
{
QFETCH(QString, fileName);
- QFETCH(WritingSystemList, writingSystems);
+ QFETCH(const WritingSystemList, writingSystems);
QFETCH(QFont::HintingPreference, hintingPreference);
QRawFont font(fileName, 10, hintingPreference);
@@ -499,7 +501,7 @@ void tst_QRawFont::supportedWritingSystems()
WritingSystemList actualWritingSystems = font.supportedWritingSystems();
QCOMPARE(actualWritingSystems.size(), writingSystems.size());
- foreach (QFontDatabase::WritingSystem writingSystem, writingSystems)
+ for (QFontDatabase::WritingSystem writingSystem : writingSystems)
QVERIFY(actualWritingSystems.contains(writingSystem));
}
@@ -1052,7 +1054,7 @@ void tst_QRawFont::qtbug65923_partal_clone_data()
void tst_QRawFont::qtbug65923_partal_clone()
{
QFile file(testFont);
- file.open(QIODevice::ReadOnly);
+ QVERIFY(file.open(QIODevice::ReadOnly));
QByteArray fontData = file.readAll();
QRawFont outerFont;
diff --git a/tests/auto/gui/text/qstatictext/CMakeLists.txt b/tests/auto/gui/text/qstatictext/CMakeLists.txt
index 5c0a149c35..bdad2609fe 100644
--- a/tests/auto/gui/text/qstatictext/CMakeLists.txt
+++ b/tests/auto/gui/text/qstatictext/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qstatictext Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstatictext LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qstatictext
SOURCES
tst_qstatictext.cpp
@@ -15,7 +21,7 @@ qt_internal_add_test(tst_qstatictext
## Scopes:
#####################################################################
-qt_internal_extend_target(tst_qstatictext CONDITION QT_FEATURE_private_tests
+qt_internal_extend_target(tst_qstatictext CONDITION QT_FEATURE_developer_build
LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
diff --git a/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp b/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp
index e6e16374d3..add2303199 100644
--- a/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp
+++ b/tests/auto/gui/text/qstatictext/tst_qstatictext.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>
#include <QtCore/QSet>
@@ -50,10 +50,6 @@ private slots:
void rotatedPainter();
void scaledPainter();
void projectedPainter();
-#if 0
- void rotatedScaledAndTranslatedPainter_data();
- void rotatedScaledAndTranslatedPainter();
-#endif
void transformationChanged();
void plainTextVsRichText();
@@ -501,61 +497,6 @@ void tst_QStaticText::projectedPainter()
QCOMPARE(imageDrawStaticText, imageDrawText);
}
-#if 0
-void tst_QStaticText::rotatedScaledAndTranslatedPainter_data()
-{
- QTest::addColumn<qreal>("offset");
-
- for (int i=0; i<100; ++i) {
- qreal offset = 300 + i / 100.;
- QTest::newRow(QByteArray::number(offset).constData()) << offset;
- }
-}
-
-void tst_QStaticText::rotatedScaledAndTranslatedPainter()
-{
- QFETCH(qreal, offset);
-
- QPixmap imageDrawText(1000, 1000);
- imageDrawText.fill(Qt::white);
- {
- QPainter p(&imageDrawText);
- p.translate(offset, 0);
- p.rotate(45.0);
- p.scale(2.0, 2.0);
- p.translate(100, 200);
-
- p.drawText(11, 12, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
- }
-
- QPixmap imageDrawStaticText(1000, 1000);
- imageDrawStaticText.fill(Qt::white);
- {
- QPainter p(&imageDrawStaticText);
- p.translate(offset, 0);
- p.rotate(45.0);
- p.scale(2.0, 2.0);
- p.translate(100, 200);
-
- QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
- text.setTextFormat(Qt::PlainText);
-
- p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
- }
-
-#if defined(DEBUG_SAVE_IMAGE)
- imageDrawText.save("rotatedScaledAndPainter_imageDrawText.png");
- imageDrawStaticText.save("rotatedScaledAndPainter_imageDrawStaticText.png");
-#endif
-
- QVERIFY(imageDrawText.toImage() != m_whiteSquare);
-
- if (!supportsTransformations())
- QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort);
- QCOMPARE(imageDrawStaticText, imageDrawText);
-}
-#endif
-
void tst_QStaticText::transformationChanged()
{
QPixmap imageDrawText(1000, 1000);
diff --git a/tests/auto/gui/text/qsyntaxhighlighter/CMakeLists.txt b/tests/auto/gui/text/qsyntaxhighlighter/CMakeLists.txt
index c4bb65a7ac..f1c9146ce1 100644
--- a/tests/auto/gui/text/qsyntaxhighlighter/CMakeLists.txt
+++ b/tests/auto/gui/text/qsyntaxhighlighter/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qsyntaxhighlighter Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsyntaxhighlighter LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qsyntaxhighlighter
SOURCES
tst_qsyntaxhighlighter.cpp
diff --git a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp
index 2d92d49f4f..748f494a41 100644
--- a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp
+++ b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.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>
diff --git a/tests/auto/gui/text/qtextblock/CMakeLists.txt b/tests/auto/gui/text/qtextblock/CMakeLists.txt
index 4b000a42cd..83cc1ce08e 100644
--- a/tests/auto/gui/text/qtextblock/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextblock/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qtextblock Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextblock LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtextblock
SOURCES
tst_qtextblock.cpp
diff --git a/tests/auto/gui/text/qtextblock/tst_qtextblock.cpp b/tests/auto/gui/text/qtextblock/tst_qtextblock.cpp
index e6400fafb0..50331ddef2 100644
--- a/tests/auto/gui/text/qtextblock/tst_qtextblock.cpp
+++ b/tests/auto/gui/text/qtextblock/tst_qtextblock.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 <QtTest/QTest>
diff --git a/tests/auto/gui/text/qtextcursor/CMakeLists.txt b/tests/auto/gui/text/qtextcursor/CMakeLists.txt
index fef0a84e7d..487965f9f8 100644
--- a/tests/auto/gui/text/qtextcursor/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextcursor/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qtextcursor Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextcursor LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtextcursor
SOURCES
tst_qtextcursor.cpp
diff --git a/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp b/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp
index 639e2e277f..8f5cacae4a 100644
--- a/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp
+++ b/tests/auto/gui/text/qtextcursor/tst_qtextcursor.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>
@@ -39,7 +39,9 @@ private slots:
void navigation7();
void navigation8();
void navigation9();
+#ifndef QT_NO_TEXTHTMLPARSER
void navigation10();
+#endif
void movePositionEndOfLine();
void insertBlock();
void insertWithBlockSeparator1();
@@ -431,6 +433,7 @@ void tst_QTextCursor::navigation9()
QCOMPARE(cursor.position(), 15);
}
+#ifndef QT_NO_TEXTHTMLPARSER
void tst_QTextCursor::navigation10()
{
doc->setHtml("<html><p>just a simple paragraph.</p>"
@@ -542,6 +545,7 @@ void tst_QTextCursor::navigation10()
QVERIFY(ok);
QCOMPARE(cursor.position(), 1); // a
}
+#endif
void tst_QTextCursor::insertBlock()
{
@@ -1545,15 +1549,20 @@ void tst_QTextCursor::insertMarkdown_data()
<< 6 << QString("0) eggs\n1) maple syrup\n")
<< QString("bread\u2029eggs\u2029maple syrup\u2029milk")
<< QString("bread\neggs\nmaple syrup\nmilk")
- << QString("1) bread\n2) eggs\n1) maple syrup\n2) milk\n");
- // renumbering would happen if we re-read the whole document
+ << QString("1) bread\n2) eggs\n0) maple syrup\n1) milk\n");
+ // Renumbering would happen if we re-read the whole document.
+ // Currently insertion only uses the new list format after a paragraph separator.
+ // For that reason "bread" and "eggs" use the original list format, while "maple syrup" and
+ // "milk" use the format from the just inserted list.
QTest::newRow("list after a list")
<< "1) bread\n2) milk\n\n" << 2
<< 13 << QString("\n0) eggs\n1) maple syrup\n")
<< QString("bread\u2029milk\u2029eggs\u2029maple syrup")
<< QString("bread\nmilk\neggs\nmaple syrup")
- << QString("1) bread\n2) milk\n3) eggs\n1) maple syrup\n");
+ << QString("1) bread\n2) milk\n3) eggs\n0) maple syrup\n");
+ // Same behavior as above. "eggs" uses the original list format, but "maple syrup" uses the
+ // format of the inserted list, which means "maple syrup" now has a start of 0.
const QString markdownHeadingString("# Hello\nWorld\n");
diff --git a/tests/auto/gui/text/qtextdocument/CMakeLists.txt b/tests/auto/gui/text/qtextdocument/CMakeLists.txt
index 1dc94ce4b4..62fa1d46ca 100644
--- a/tests/auto/gui/text/qtextdocument/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextdocument/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qtextdocument Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextdocument LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtextdocument
SOURCES
common.h
diff --git a/tests/auto/gui/text/qtextdocument/common.h b/tests/auto/gui/text/qtextdocument/common.h
index 5b45315704..3c05913008 100644
--- a/tests/auto/gui/text/qtextdocument/common.h
+++ b/tests/auto/gui/text/qtextdocument/common.h
@@ -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 <QAbstractTextDocumentLayout>
#include <private/qtextdocument_p.h>
diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
index dc93c86829..600b45575f 100644
--- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
+++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.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>
@@ -181,6 +181,10 @@ private slots:
void insertHtmlWithComments();
void delayedLayout();
+ void undoContentChangeIndices();
+
+ void restoreStrokeFromHtml();
+ void restoreForegroundGradientFromHtml();
private:
void backgroundImage_checkExpectedHtml(const QTextDocument &doc);
@@ -743,6 +747,9 @@ void tst_QTextDocument::mightBeRichText_data()
" PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n"
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">";
QVERIFY(Qt::mightBeRichText(QString::fromLatin1(qtDocuHeader)));
+ QVERIFY(Qt::mightBeRichText(QLatin1StringView(qtDocuHeader)));
+ QVERIFY(QUtf8StringView(qtDocuHeader).isValidUtf8());
+ QVERIFY(Qt::mightBeRichText(QUtf8StringView(qtDocuHeader)));
QTest::addColumn<QString>("input");
QTest::addColumn<bool>("result");
@@ -762,6 +769,10 @@ void tst_QTextDocument::mightBeRichText()
QFETCH(QString, input);
QFETCH(bool, result);
QCOMPARE(result, Qt::mightBeRichText(input));
+ QCOMPARE(result, Qt::mightBeRichText(QStringView(input)));
+ QCOMPARE(result, Qt::mightBeRichText(QUtf8StringView(input.toUtf8())));
+ QVERIFY(QtPrivate::isLatin1(input));
+ QCOMPARE(result, Qt::mightBeRichText(QLatin1StringView(input.toLatin1())));
}
Q_DECLARE_METATYPE(QTextDocumentFragment)
@@ -1161,7 +1172,7 @@ void tst_QTextDocument::toHtml_data()
cursor.insertTable(2, 2);
QTest::newRow("simpletable") << QTextDocumentFragment(&doc)
- << QString("<table border=\"1\" cellspacing=\"2\">"
+ << QString("<table border=\"1\" style=\" border-collapse:collapse;\" cellpadding=\"4\">"
"\n<tr>\n<td></td>\n<td></td></tr>"
"\n<tr>\n<td></td>\n<td></td></tr>"
"</table>");
@@ -1175,7 +1186,7 @@ void tst_QTextDocument::toHtml_data()
table->mergeCells(0, 2, 1, 2);
QTest::newRow("tablespans") << QTextDocumentFragment(&doc)
- << QString("<table border=\"1\" cellspacing=\"2\">"
+ << QString("<table border=\"1\" style=\" border-collapse:collapse;\" cellpadding=\"4\">"
"\n<tr>\n<td colspan=\"2\"></td>\n<td colspan=\"2\"></td></tr>"
"</table>");
}
@@ -1194,7 +1205,7 @@ void tst_QTextDocument::toHtml_data()
cursor.insertTable(2, 2, fmt);
QTest::newRow("tableattrs") << QTextDocumentFragment(&doc)
- << QString("<table border=\"1\" style=\" float: right;\" align=\"center\" width=\"50%\" cellspacing=\"3\" cellpadding=\"3\" bgcolor=\"#ff00ff\">"
+ << QString("<table border=\"1\" style=\" float: right; border-collapse:collapse;\" align=\"center\" width=\"50%\" cellspacing=\"3\" cellpadding=\"3\" bgcolor=\"#ff00ff\">"
"\n<tr>\n<td></td>\n<td></td></tr>"
"\n<tr>\n<td></td>\n<td></td></tr>"
"</table>");
@@ -1216,7 +1227,7 @@ void tst_QTextDocument::toHtml_data()
cursor.insertTable(2, 2, fmt);
QTest::newRow("tableattrs2") << QTextDocumentFragment(&doc)
- << QString("<table border=\"1\" style=\" float: right; margin-top:0px; margin-bottom:35px; margin-left:25px; margin-right:0px;\" align=\"center\" width=\"50%\" cellspacing=\"3\" cellpadding=\"3\" bgcolor=\"#ff00ff\">"
+ << QString("<table border=\"1\" style=\" float: right; margin-top:0px; margin-bottom:35px; margin-left:25px; margin-right:0px; border-collapse:collapse;\" align=\"center\" width=\"50%\" cellspacing=\"3\" cellpadding=\"3\" bgcolor=\"#ff00ff\">"
"\n<tr>\n<td></td>\n<td></td></tr>"
"\n<tr>\n<td></td>\n<td></td></tr>"
"</table>");
@@ -1230,7 +1241,7 @@ void tst_QTextDocument::toHtml_data()
cursor.insertTable(4, 2, fmt);
QTest::newRow("tableheader") << QTextDocumentFragment(&doc)
- << QString("<table border=\"1\" cellspacing=\"2\">"
+ << QString("<table border=\"1\" style=\" border-collapse:collapse;\" cellpadding=\"4\">"
"<thead>\n<tr>\n<td></td>\n<td></td></tr>"
"\n<tr>\n<td></td>\n<td></td></tr></thead>"
"\n<tr>\n<td></td>\n<td></td></tr>"
@@ -1246,8 +1257,8 @@ void tst_QTextDocument::toHtml_data()
subTable->cellAt(0, 0).firstCursorPosition().insertText("Hey");
QTest::newRow("nestedtable") << QTextDocumentFragment(&doc)
- << QString("<table border=\"1\" cellspacing=\"2\">"
- "\n<tr>\n<td></td>\n<td>\n<table border=\"1\" cellspacing=\"2\">\n<tr>\n<td>\n<p DEFAULTBLOCKSTYLE>Hey</p></td></tr></table></td></tr>"
+ << QString("<table border=\"1\" style=\" border-collapse:collapse;\" cellpadding=\"4\">"
+ "\n<tr>\n<td></td>\n<td>\n<table border=\"1\" style=\" border-collapse:collapse;\" cellpadding=\"4\">\n<tr>\n<td>\n<p DEFAULTBLOCKSTYLE>Hey</p></td></tr></table></td></tr>"
"\n<tr>\n<td></td>\n<td></td></tr>"
"</table>");
}
@@ -1264,7 +1275,7 @@ void tst_QTextDocument::toHtml_data()
cursor.insertTable(1, 3, fmt);
QTest::newRow("colwidths") << QTextDocumentFragment(&doc)
- << QString("<table border=\"1\" cellspacing=\"2\">"
+ << QString("<table border=\"1\" style=\" border-collapse:collapse;\" cellpadding=\"4\">"
"\n<tr>\n<td></td>\n<td width=\"30%\"></td>\n<td width=\"40\"></td></tr>"
"</table>");
}
@@ -1281,7 +1292,7 @@ void tst_QTextDocument::toHtml_data()
cellCurs.mergeBlockCharFormat(fmt);
QTest::newRow("cellproperties") << QTextDocumentFragment(&doc)
- << QString("<table border=\"1\" cellspacing=\"2\">"
+ << QString("<table border=\"1\" style=\" border-collapse:collapse;\" cellpadding=\"4\">"
"\n<tr>\n<td bgcolor=\"#ffffff\"></td></tr>"
"</table>");
}
@@ -1548,7 +1559,7 @@ void tst_QTextDocument::toHtml_data()
table->setFormat(fmt);
QTest::newRow("mergedtablecolwidths") << QTextDocumentFragment(&doc)
- << QString("<table border=\"1\" cellspacing=\"2\">"
+ << QString("<table border=\"1\" style=\" border-collapse:collapse;\" cellpadding=\"4\">"
"\n<tr>\n<td colspan=\"2\"></td></tr>"
"\n<tr>\n<td width=\"20\"></td>\n<td width=\"40\"></td></tr>"
"</table>");
@@ -1611,7 +1622,7 @@ void tst_QTextDocument::toHtml_data()
table->cellAt(0, 0).firstCursorPosition().insertText("Blah");
QTest::newRow("table-vertical-alignment") << QTextDocumentFragment(&doc)
- << QString("<table border=\"1\" cellspacing=\"2\">"
+ << QString("<table border=\"1\" style=\" border-collapse:collapse;\" cellpadding=\"4\">"
"\n<tr>\n<td style=\" vertical-align:middle;\">\n"
"<p DEFAULTBLOCKSTYLE>Blah</p></td>"
"\n<td style=\" vertical-align:top;\"></td></tr>"
@@ -1640,7 +1651,7 @@ void tst_QTextDocument::toHtml_data()
table->cellAt(0, 0).firstCursorPosition().insertText("Blah");
QTest::newRow("table-cell-paddings") << QTextDocumentFragment(&doc)
- << QString("<table border=\"1\" cellspacing=\"2\">"
+ << QString("<table border=\"1\" style=\" border-collapse:collapse;\" cellpadding=\"4\">"
"\n<tr>\n<td style=\" padding-left:1;\">\n"
"<p DEFAULTBLOCKSTYLE>Blah</p></td>"
"\n<td style=\" padding-right:1;\"></td></tr>"
@@ -1658,7 +1669,7 @@ void tst_QTextDocument::toHtml_data()
cursor.insertTable(2, 2, fmt);
QTest::newRow("tableborder") << QTextDocumentFragment(&doc)
- << QString("<table border=\"1\" style=\" border-color:#0000ff; border-style:solid;\" cellspacing=\"2\">"
+ << QString("<table border=\"1\" style=\" border-color:#0000ff; border-style:solid; border-collapse:collapse;\" cellpadding=\"4\">"
"\n<tr>\n<td></td>\n<td></td></tr>"
"\n<tr>\n<td></td>\n<td></td></tr>"
"</table>");
@@ -1700,7 +1711,7 @@ void tst_QTextDocument::toHtml_data()
<< QString("EMPTYBLOCK") +
QString("<p OPENDEFAULTBLOCKSTYLE page-break-before:always;\">Foo</p>"
"\n<p OPENDEFAULTBLOCKSTYLE page-break-before:always; page-break-after:always;\">Bar</p>"
- "\n<table border=\"1\" style=\" page-break-after:always;\" cellspacing=\"2\">\n<tr>\n<td></td></tr></table>");
+ "\n<table border=\"1\" style=\" page-break-after:always; border-collapse:collapse;\" cellpadding=\"4\">\n<tr>\n<td></td></tr></table>");
}
{
@@ -1780,6 +1791,22 @@ void tst_QTextDocument::toHtml_data()
"<li class=\"unchecked\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">unchecked item</li>\n"
"<li class=\"checked\" style=\" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">checked item</li></ul>");
}
+
+ {
+ CREATE_DOC_AND_CURSOR();
+
+ QTextListFormat fmt;
+ fmt.setStyle(QTextListFormat::ListDecimal);
+ fmt.setStart(4);
+ cursor.insertList(fmt);
+ cursor.insertText("Blah");
+ cursor.insertBlock();
+ cursor.insertText("Bleh");
+
+ QTest::newRow("ordered list with start") << QTextDocumentFragment(&doc)
+ << QString("EMPTYBLOCK") +
+ QString("<ol start=\"4\" style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;\">\n<li style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Blah</li>\n<li style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Bleh</li></ol>");
+ }
}
void tst_QTextDocument::toHtml()
@@ -3965,5 +3992,258 @@ void tst_QTextDocument::delayedLayout()
QCOMPARE(layout->lineCount(), 1); // layout happened
}
+void tst_QTextDocument::undoContentChangeIndices() // QTBUG-113865
+{
+ QTextDocument doc;
+ QTestDocumentLayout *layout = new QTestDocumentLayout(&doc);
+ QString content = QString("<html><body>"
+ "<ul><li>Undo</li></ul>"
+ "<ul><li>operation</li></ul>"
+ "<ul><li>of</li></ul>"
+ "<ul><li>unnumbered</li></ul>"
+ "<ul><li>lists</li></ul>"
+ "<ul><li>shows</li></ul>"
+ "<ul><li>invalid</li></ul>"
+ "<ul><li>content</li></ul>"
+ "<ul><li>indices</li></ul>"
+ "</body></html>");
+ doc.setDocumentLayout(layout);
+ doc.setHtml(content);
+
+ // Select the entire document content
+ QTextCursor cursor(&doc);
+ cursor.select(QTextCursor::Document);
+ cursor.removeSelectedText();
+
+ // Undo above operation
+ doc.undo();
+
+ // Move the cursor to the end
+ cursor.movePosition(QTextCursor::End);
+ cursor.insertHtml(content);
+
+ // Select the whole document and remove the content
+ cursor.select(QTextCursor::Document);
+ cursor.removeSelectedText();
+
+ int documentLength = 0;
+ int changeRemoved = 0;
+ int changeAdded = 0;
+ int changePos = 0;
+ connect(&doc, &QTextDocument::contentsChange, this, [&](int pos, int removed, int added){
+ documentLength = doc.characterCount();
+ changeRemoved = removed;
+ changeAdded = added;
+ changePos = pos;
+ });
+
+ // Undo above operation
+ doc.undo();
+
+ const int changeEnd = changeAdded + changeRemoved;
+
+ QVERIFY(documentLength > 0);
+ QCOMPARE(changePos, 0);
+ QVERIFY(changeRemoved >= 0);
+ QVERIFY(documentLength >= changeEnd);
+}
+
+void tst_QTextDocument::restoreStrokeFromHtml()
+{
+ QTextDocument document;
+ QTextCursor textCursor(&document);
+ QTextCharFormat textOutline;
+
+ // Set stroke color and width
+ {
+ QPen pen(Qt::red, 2.3, Qt::SolidLine);
+ textOutline.setTextOutline(pen);
+ textCursor.insertText("Outlined text", textOutline);
+ }
+
+ // Set Cap and Join styles
+ {
+ QPen pen;
+ pen.setCapStyle(Qt::FlatCap);
+ pen.setJoinStyle(Qt::RoundJoin);
+ textOutline.setTextOutline(pen);
+ textCursor.insertBlock();
+ textCursor.insertText("Cap and Join Style", textOutline);
+ }
+
+ // Set Miter limit
+ {
+ QPen pen;
+ pen.setJoinStyle(Qt::MiterJoin);
+ pen.setMiterLimit(4);
+ textOutline.setTextOutline(pen);
+ textCursor.insertBlock();
+ textCursor.insertText("Miter Limit", textOutline);
+ }
+
+ // Set Dash Array and Dash Offset
+ {
+ QPen pen;
+ QList<qreal> pattern;
+ const int dash = 2;
+ const int gap = 4;
+ pattern << dash << gap << dash << gap << dash << gap;
+ pen.setDashPattern(pattern);
+ pen.setDashOffset(3);
+ textOutline.setTextOutline(pen);
+ textCursor.insertBlock();
+ textCursor.insertText("Dash Pattern", textOutline);
+ }
+
+ {
+ QTextDocument otherDocument;
+ otherDocument.setHtml(document.toHtml());
+ QCOMPARE(otherDocument.blockCount(), document.blockCount());
+
+ QTextBlock block;
+ QTextFragment fragment;
+ QTextCharFormat fmt;
+ QPen pen;
+
+ {
+ block = otherDocument.findBlockByNumber(0);
+ fragment = block.begin().fragment();
+ QCOMPARE(fragment.text(), QStringLiteral("Outlined text"));
+ fmt = fragment.charFormat();
+ QVERIFY(fmt.hasProperty(QTextCharFormat::TextOutline));
+ pen = fmt.textOutline();
+ QCOMPARE(pen.color(), QColor(Qt::red));
+ QCOMPARE(pen.widthF(), 2.3);
+ }
+
+ {
+ block = otherDocument.findBlockByNumber(1);
+ qDebug() << block.text();
+ fragment = block.begin().fragment();
+ QCOMPARE(fragment.text(), QStringLiteral("Cap and Join Style"));
+ fmt = fragment.charFormat();
+ QVERIFY(fmt.hasProperty(QTextCharFormat::TextOutline));
+ pen = fmt.textOutline();
+ QCOMPARE(pen.capStyle(), Qt::FlatCap);
+ QCOMPARE(pen.joinStyle(), Qt::RoundJoin);
+ }
+
+ {
+ block = otherDocument.findBlockByNumber(2);
+ fragment = block.begin().fragment();
+ QCOMPARE(fragment.text(), QStringLiteral("Miter Limit"));
+ fmt = fragment.charFormat();
+ QVERIFY(fmt.hasProperty(QTextCharFormat::TextOutline));
+ pen = fmt.textOutline();
+ QCOMPARE(pen.joinStyle(), Qt::MiterJoin);
+ QCOMPARE(pen.miterLimit(), 4);
+ }
+
+
+ {
+ block = otherDocument.findBlockByNumber(3);
+ fragment = block.begin().fragment();
+ QCOMPARE(fragment.text(), QStringLiteral("Dash Pattern"));
+ fmt = fragment.charFormat();
+ QVERIFY(fmt.hasProperty(QTextCharFormat::TextOutline));
+ pen = fmt.textOutline();
+ QCOMPARE(pen.dashOffset(), 3);
+ QList<qreal> pattern;
+ const int dash = 2;
+ const int gap = 4;
+ pattern << dash << gap << dash << gap << dash << gap;
+ QCOMPARE(pen.dashPattern(), pattern);
+ }
+ }
+}
+
+void tst_QTextDocument::restoreForegroundGradientFromHtml()
+{
+ QTextDocument document;
+
+ QTextCursor textCursor(&document);
+
+ QTextCharFormat foregroundGradient;
+ QLinearGradient lg;
+ lg.setColorAt(0.0, Qt::green);
+ lg.setColorAt(1.0, Qt::blue);
+ lg.setStart(QPointF(0,0));
+ lg.setFinalStop(QPointF(800, 1000));
+ foregroundGradient.setForeground(QBrush(lg));
+ textCursor.insertText("Linear gradient text\n", foregroundGradient);
+
+ QRadialGradient rg;
+ rg.setCoordinateMode(QGradient::ObjectBoundingMode);
+ rg.setSpread(QGradient::ReflectSpread);
+ rg.setColorAt(0.0, Qt::green);
+ rg.setColorAt(1.0, Qt::blue);
+ QPointF center(0.5, 0.5);
+ rg.setCenter(center);
+ rg.setFocalPoint(center);
+ rg.setRadius(0.5);
+ foregroundGradient.setForeground(QBrush(rg));
+ textCursor.insertText("Radial gradient text\n", foregroundGradient);
+
+ QConicalGradient cg;
+ cg.setCoordinateMode(QGradient::ObjectMode);
+ cg.setSpread(QGradient::RepeatSpread);
+ cg.setColorAt(0.0, Qt::green);
+ cg.setColorAt(1.0, Qt::blue);
+ cg.setCenter(QPointF(0.5, 0.5));
+ cg.setAngle(0.0);
+ foregroundGradient.setForeground(QBrush(cg));
+ textCursor.insertText("Conical gradient text\n", foregroundGradient);
+
+ {
+ QTextDocument otherDocument;
+ otherDocument.setHtml(document.toHtml());
+
+ QCOMPARE(otherDocument.blockCount(), document.blockCount());
+
+ QTextBlock block = otherDocument.firstBlock();
+ QTextFragment fragment = block.begin().fragment();
+
+ QCOMPARE(fragment.text(), QStringLiteral("Linear gradient text"));
+
+ QTextCharFormat fmt = fragment.charFormat();
+ QVERIFY(fmt.hasProperty(QTextCharFormat::ForegroundBrush));
+
+ QBrush brush = fmt.foreground();
+ QCOMPARE(brush.style(), Qt::LinearGradientPattern);
+ QCOMPARE(brush.gradient()->coordinateMode(), lg.coordinateMode());
+ QCOMPARE(brush.gradient()->spread(), lg.spread());
+ QCOMPARE(brush.gradient()->stops().size(), lg.stops().size());
+ QCOMPARE(static_cast<const QLinearGradient *>(brush.gradient())->start(), lg.start());
+ QCOMPARE(static_cast<const QLinearGradient *>(brush.gradient())->finalStop(), lg.finalStop());
+
+ block = block.next();
+ fragment = block.begin().fragment();
+
+ fmt = fragment.charFormat();
+ QVERIFY(fmt.hasProperty(QTextCharFormat::ForegroundBrush));
+
+ brush = fmt.foreground();
+ QCOMPARE(brush.style(), Qt::RadialGradientPattern);
+ QCOMPARE(brush.gradient()->coordinateMode(), rg.coordinateMode());
+ QCOMPARE(brush.gradient()->spread(), rg.spread());
+ QCOMPARE(static_cast<const QRadialGradient *>(brush.gradient())->center(), rg.center());
+ QCOMPARE(static_cast<const QRadialGradient *>(brush.gradient())->focalPoint(), rg.focalPoint());
+ QCOMPARE(static_cast<const QRadialGradient *>(brush.gradient())->radius(), rg.radius());
+
+ block = block.next();
+ fragment = block.begin().fragment();
+
+ fmt = fragment.charFormat();
+ QVERIFY(fmt.hasProperty(QTextCharFormat::ForegroundBrush));
+
+ brush = fmt.foreground();
+ QCOMPARE(brush.style(), Qt::ConicalGradientPattern);
+ QCOMPARE(brush.gradient()->coordinateMode(), cg.coordinateMode());
+ QCOMPARE(brush.gradient()->spread(), cg.spread());
+ QCOMPARE(static_cast<const QConicalGradient *>(brush.gradient())->center(), cg.center());
+ QCOMPARE(static_cast<const QConicalGradient *>(brush.gradient())->angle(), cg.angle());
+ }
+}
+
QTEST_MAIN(tst_QTextDocument)
#include "tst_qtextdocument.moc"
diff --git a/tests/auto/gui/text/qtextdocumentfragment/CMakeLists.txt b/tests/auto/gui/text/qtextdocumentfragment/CMakeLists.txt
index 179b77af3b..4a4075106e 100644
--- a/tests/auto/gui/text/qtextdocumentfragment/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextdocumentfragment/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qtextdocumentfragment Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextdocumentfragment LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtextdocumentfragment
SOURCES
tst_qtextdocumentfragment.cpp
diff --git a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
index 4cc4a253ee..f2c3b36dcd 100644
--- a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
+++ b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.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>
@@ -16,6 +16,8 @@
#include <qtextcursor.h>
+using namespace Qt::StringLiterals;
+
QT_FORWARD_DECLARE_CLASS(QTextDocument)
class tst_QTextDocumentFragment : public QObject
@@ -96,6 +98,7 @@ private slots:
void html_thCentered();
void orderedListNumbering();
void html_blockAfterList();
+ void html_listStartAttribute();
void html_subAndSuperScript();
void html_cssColors();
void obeyFragmentMarkersInImport();
@@ -244,6 +247,7 @@ private slots:
void html_fromFirefox();
void html_emptyInlineInsideBlock();
void css_fontAndWordSpacing();
+ void html_brWithWhitespaceAfterList();
private:
inline void setHtml(const QString &html)
@@ -1471,6 +1475,22 @@ void tst_QTextDocumentFragment::html_blockAfterList()
QCOMPARE(cursor.blockFormat().indent(), 0);
}
+void tst_QTextDocumentFragment::html_listStartAttribute()
+{
+ const char html[] = "<ol start=-1><li>Foo</ol><ol><li>Bar</ol>";
+ cursor.insertFragment(QTextDocumentFragment::fromHtml(html));
+
+ cursor.movePosition(QTextCursor::Start);
+
+ QVERIFY(cursor.currentList());
+ QCOMPARE(cursor.currentList()->format().start(), -1);
+
+ QVERIFY(cursor.movePosition(QTextCursor::NextBlock));
+
+ QVERIFY(cursor.currentList());
+ QCOMPARE(cursor.currentList()->format().start(), 1);
+}
+
void tst_QTextDocumentFragment::html_subAndSuperScript()
{
const char subHtml[] = "<sub>Subby</sub>";
@@ -4303,5 +4323,24 @@ void tst_QTextDocumentFragment::css_fontAndWordSpacing()
}
}
+void tst_QTextDocumentFragment::html_brWithWhitespaceAfterList() // QTBUG-81662
+{
+ setHtml(QString::fromLatin1("<ul><li>one</li><li>two</li></ul>\n <br/>\nhello"));
+
+ QCOMPARE(doc->blockCount(), 3);
+
+ QTextBlock block = doc->begin();
+ QVERIFY(block.textList());
+
+ block = block.next();
+ QVERIFY(block.textList());
+
+ block = block.next();
+ QCOMPARE(block.text(), u"\u2028hello"_s);
+
+ block = block.next();
+ QVERIFY(block.text().isEmpty());
+}
+
QTEST_MAIN(tst_QTextDocumentFragment)
#include "tst_qtextdocumentfragment.moc"
diff --git a/tests/auto/gui/text/qtextdocumentlayout/BLACKLIST b/tests/auto/gui/text/qtextdocumentlayout/BLACKLIST
index 5a2f81c448..ed85376c92 100644
--- a/tests/auto/gui/text/qtextdocumentlayout/BLACKLIST
+++ b/tests/auto/gui/text/qtextdocumentlayout/BLACKLIST
@@ -1,6 +1,3 @@
[imageAtRightAlignedTab]
-rhel-6.6
-rhel-7.4
-rhel-7.6
sles
centos
diff --git a/tests/auto/gui/text/qtextdocumentlayout/CMakeLists.txt b/tests/auto/gui/text/qtextdocumentlayout/CMakeLists.txt
index 4556281b65..07386d4e24 100644
--- a/tests/auto/gui/text/qtextdocumentlayout/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextdocumentlayout/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qtextdocumentlayout Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextdocumentlayout LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtextdocumentlayout
SOURCES
tst_qtextdocumentlayout.cpp
diff --git a/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp b/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp
index 010fe002d4..2ae31849bf 100644
--- a/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp
+++ b/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.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>
@@ -24,18 +24,24 @@ private slots:
void cleanupTestCase();
void defaultPageSizeHandling();
void idealWidth();
+#ifndef QT_NO_TEXTHTMLPARSER
void lineSeparatorFollowingTable();
+#endif
#ifndef QT_NO_WIDGETS
void wrapAtWordBoundaryOrAnywhere();
#endif
void inlineImage();
+#ifndef QT_NO_TEXTHTMLPARSER
void clippedTableCell();
+#endif
void floatingTablePageBreak();
void imageAtRightAlignedTab();
void blockVisibility();
+#ifndef QT_NO_TEXTHTMLPARSER
void testHitTest();
void largeImage();
+#endif
private:
QTextDocument *doc;
@@ -99,6 +105,7 @@ void tst_QTextDocumentLayout::idealWidth()
QVERIFY(doc->idealWidth() > 0);
}
+#ifndef QT_NO_TEXTHTMLPARSER
// none of the QTextLine items in the document should intersect with the margin rect
void tst_QTextDocumentLayout::lineSeparatorFollowingTable()
{
@@ -145,6 +152,7 @@ void tst_QTextDocumentLayout::lineSeparatorFollowingTable()
}
}
}
+#endif
#ifndef QT_NO_WIDGETS
void tst_QTextDocumentLayout::wrapAtWordBoundaryOrAnywhere()
@@ -184,6 +192,7 @@ void tst_QTextDocumentLayout::inlineImage()
QCOMPARE(doc->pageCount(), 1);
}
+#ifndef QT_NO_TEXTHTMLPARSER
void tst_QTextDocumentLayout::clippedTableCell()
{
const char *html =
@@ -224,6 +233,7 @@ void tst_QTextDocumentLayout::clippedTableCell()
expected.save("expected.png");
QCOMPARE(img, expected);
}
+#endif
void tst_QTextDocumentLayout::floatingTablePageBreak()
{
@@ -323,6 +333,7 @@ void tst_QTextDocumentLayout::blockVisibility()
QCOMPARE(doc->size(), halfSize);
}
+#ifndef QT_NO_TEXTHTMLPARSER
void tst_QTextDocumentLayout::largeImage()
{
auto img = QImage(400, 500, QImage::Format_ARGB32_Premultiplied);
@@ -416,6 +427,7 @@ void tst_QTextDocumentLayout::testHitTest()
QVERIFY(positionY - topMargin <= y);
}
}
+#endif
QTEST_MAIN(tst_QTextDocumentLayout)
#include "tst_qtextdocumentlayout.moc"
diff --git a/tests/auto/gui/text/qtextformat/CMakeLists.txt b/tests/auto/gui/text/qtextformat/CMakeLists.txt
index e5b714ad9f..4dea90900e 100644
--- a/tests/auto/gui/text/qtextformat/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextformat/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qtextformat Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextformat LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtextformat
SOURCES
tst_qtextformat.cpp
diff --git a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp b/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp
index 1b28274748..6c6145561d 100644
--- a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp
+++ b/tests/auto/gui/text/qtextformat/tst_qtextformat.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>
@@ -7,7 +7,9 @@
#include <qcoreapplication.h>
#include <qdebug.h>
+#if QT_CONFIG(settings)
#include <qsettings.h>
+#endif
#include <qtextformat.h>
#include <private/qtextformat_p.h>
#include <qtextdocument.h>
@@ -27,7 +29,9 @@ Q_OBJECT
private slots:
void getSetCheck();
void defaultAlignment();
+#if QT_CONFIG(settings)
void testQTextCharFormat() const;
+#endif
void testUnderlinePropertyPrecedence();
void toFormat();
void resolveFont();
@@ -47,6 +51,7 @@ private slots:
#endif
};
+#if QT_CONFIG(settings)
/*! \internal
This (used to) trigger a crash in:
@@ -61,6 +66,7 @@ void tst_QTextFormat::testQTextCharFormat() const
settings.value("test", test);
}
+#endif
// Testing get/set functions
void tst_QTextFormat::getSetCheck()
diff --git a/tests/auto/gui/text/qtextimagehandler/CMakeLists.txt b/tests/auto/gui/text/qtextimagehandler/CMakeLists.txt
index 45feab12f1..8d282b8f2c 100644
--- a/tests/auto/gui/text/qtextimagehandler/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextimagehandler/CMakeLists.txt
@@ -1,6 +1,12 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextimagehandler LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
list(APPEND test_data "data/image.png")
list(APPEND test_data "data/image@2x.png")
diff --git a/tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp b/tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp
index b640efc8e4..0048623d0e 100644
--- a/tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp
+++ b/tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp
@@ -1,11 +1,15 @@
// Copyright (C) 2022 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>
#include <QPainter>
#include <private/qtextimagehandler_p.h>
+using namespace Qt::StringLiterals;
+
+// #define DEBUG_WRITE_HTML
+
class tst_QTextImageHandler : public QObject
{
Q_OBJECT
@@ -18,7 +22,11 @@ private slots:
void cleanup();
void cleanupTestCase();
void loadAtNImages_data();
+#ifndef QT_NO_TEXTHTMLPARSER
void loadAtNImages();
+ void maxWidth_data();
+ void maxWidth();
+#endif
};
tst_QTextImageHandler::tst_QTextImageHandler()
@@ -42,11 +50,12 @@ void tst_QTextImageHandler::loadAtNImages_data()
QTest::addColumn<QString>("imageFile");
QTest::addRow("file") << QFINDTESTDATA("data/image.png");
- QTest::addRow("file_url") << QString("file:/") + QFINDTESTDATA("data/image.png");
+ QTest::addRow("file_url") << QUrl::fromLocalFile(QFINDTESTDATA("data/image.png")).toString();
QTest::addRow("resource") << ":/data/image.png";
QTest::addRow("qrc_url") << "qrc:/data/image.png";
}
+#ifndef QT_NO_TEXTHTMLPARSER
void tst_QTextImageHandler::loadAtNImages()
{
QFETCH(QString, imageFile);
@@ -58,7 +67,7 @@ void tst_QTextImageHandler::loadAtNImages()
const auto it = std::find_if(formats.begin(), formats.end(), [](const auto &format){
return format.objectType() == QTextFormat::ImageObject;
});
- QVERIFY(it != formats.end());
+ QCOMPARE_NE(it, formats.end());
const QTextImageFormat format = (*it).toImageFormat();
QTextImageHandler handler;
@@ -75,5 +84,64 @@ void tst_QTextImageHandler::loadAtNImages()
}
}
+void tst_QTextImageHandler::maxWidth_data()
+{
+ QTest::addColumn<QString>("imageFile");
+ QTest::addColumn<QSizeF>("pageSize");
+ QTest::addColumn<QTextLength>("maxWidth");
+ QTest::addColumn<QSizeF>("expectedSize");
+
+ QTest::addRow("constrained-percentage") << QFINDTESTDATA("data/image.png") << QSizeF(16, 16) << QTextLength(QTextLength::PercentageLength, 100) << QSizeF(12, 12);
+ QTest::addRow("not-constrained-percentage") << QFINDTESTDATA("data/image.png") << QSizeF(200, 200) << QTextLength(QTextLength::PercentageLength, 100) << QSizeF(16, 16);
+ QTest::addRow("constrained-fixed") << QFINDTESTDATA("data/image.png") << QSizeF(16, 16) << QTextLength(QTextLength::FixedLength, 5) << QSizeF(5, 5);
+ QTest::addRow("not-constrained-fixed") << QFINDTESTDATA("data/image.png") << QSizeF(200, 200) << QTextLength(QTextLength::FixedLength, 5) << QSizeF(5, 5);
+ QTest::addRow("not-constrained-default") << QFINDTESTDATA("data/image.png") << QSizeF(200, 200) << QTextLength(QTextLength::VariableLength, 5) << QSizeF(16, 16);
+}
+
+void tst_QTextImageHandler::maxWidth()
+{
+ QFETCH(QString, imageFile);
+ QFETCH(QSizeF, pageSize);
+ QFETCH(QTextLength, maxWidth);
+ QFETCH(QSizeF, expectedSize);
+
+ QTextDocument doc;
+ doc.setPageSize(pageSize);
+ doc.setDocumentMargin(2);
+ QTextCursor c(&doc);
+ QString style;
+ if (maxWidth.type() == QTextLength::PercentageLength)
+ style = " style=\"max-width:"_L1 + QString::number(maxWidth.rawValue()) + "%;\""_L1;
+ else if (maxWidth.type() == QTextLength::FixedLength)
+ style = " style=\"max-width:"_L1 + QString::number(maxWidth.rawValue()) + "px;\""_L1;
+ const QString html = "<img src=\"" + imageFile + u'\"' + style + "\">";
+ c.insertHtml(html);
+
+#ifdef DEBUG_WRITE_HTML
+ {
+ QFile out("/tmp/" + QLatin1String(QTest::currentDataTag()) + ".html");
+ out.open(QFile::WriteOnly);
+ out.write(html.toLatin1());
+ out.close();
+ }
+ {
+ QFile out("/tmp/" + QLatin1String(QTest::currentDataTag()) + "_rewrite.html");
+ out.open(QFile::WriteOnly);
+ out.write(doc.toHtml().toLatin1());
+ out.close();
+ }
+#endif
+ const auto formats = doc.allFormats();
+ const auto it = std::find_if(formats.begin(), formats.end(), [](const auto &format){
+ return format.objectType() == QTextFormat::ImageObject;
+ });
+ QCOMPARE_NE(it, formats.end());
+ const QTextImageFormat format = (*it).toImageFormat();
+ QTextImageHandler handler;
+
+ QCOMPARE(handler.intrinsicSize(&doc, 0, format), expectedSize);
+}
+#endif
+
QTEST_MAIN(tst_QTextImageHandler)
#include "tst_qtextimagehandler.moc"
diff --git a/tests/auto/gui/text/qtextlayout/CMakeLists.txt b/tests/auto/gui/text/qtextlayout/CMakeLists.txt
index 025a3451e8..655c0985a0 100644
--- a/tests/auto/gui/text/qtextlayout/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextlayout/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qtextlayout Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextlayout LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtextlayout
SOURCES
tst_qtextlayout.cpp
diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
index 51bb1a65db..209f5a56e2 100644
--- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
+++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
@@ -1,6 +1,7 @@
// 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
+#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
/*
!!!!!! Warning !!!!!
@@ -2736,13 +2737,25 @@ void tst_QTextLayout::min_maximumWidth()
void tst_QTextLayout::negativeLineWidth()
{
- QTextLayout layout;
- layout.setText("Foo bar");
- layout.beginLayout();
- QTextLine line = layout.createLine();
- line.setLineWidth(-1);
- QVERIFY(line.textLength() > 0);
- layout.endLayout();
+ {
+ QTextLayout layout;
+ layout.setText("Foo bar");
+ layout.beginLayout();
+ QTextLine line = layout.createLine();
+ line.setLineWidth(-1);
+ QVERIFY(line.textLength() > 0);
+ layout.endLayout();
+ }
+
+ {
+ QTextLayout layout;
+ layout.setText("Foo bar");
+ layout.beginLayout();
+ QTextLine line = layout.createLine();
+ line.setNumColumns(2, -1);
+ QVERIFY(line.textLength() > 0);
+ layout.endLayout();
+ }
}
QTEST_MAIN(tst_QTextLayout)
diff --git a/tests/auto/gui/text/qtextlist/CMakeLists.txt b/tests/auto/gui/text/qtextlist/CMakeLists.txt
index d8f8a0ddf4..5764df3e99 100644
--- a/tests/auto/gui/text/qtextlist/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextlist/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qtextlist Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextlist LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtextlist
SOURCES
../qtextdocument/common.h
diff --git a/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp b/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp
index 134249ee83..10d44f6d70 100644
--- a/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp
+++ b/tests/auto/gui/text/qtextlist/tst_qtextlist.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>
@@ -36,6 +36,8 @@ private slots:
void blockUpdate();
void numbering_data();
void numbering();
+ void start_data();
+ void start();
private:
QTextDocument *doc;
@@ -138,6 +140,7 @@ void tst_QTextList::autoNumberingPrefixAndSuffixHtmlExportImport()
QCOMPARE(list->count(), 28);
+#ifndef QT_NO_TEXTHTMLPARSER
QString htmlExport = doc->toHtml();
QTextDocument importDoc;
importDoc.setHtml(htmlExport);
@@ -150,6 +153,7 @@ void tst_QTextList::autoNumberingPrefixAndSuffixHtmlExportImport()
QCOMPARE(importCursor.currentList()->itemNumber(importCursor.block()), 27);
QCOMPARE(importCursor.currentList()->itemText(importCursor.block()), QLatin1String("\"ab#"));
QCOMPARE(importCursor.currentList()->format().indent(), 10);
+#endif
}
void tst_QTextList::autoNumberingRTL()
@@ -400,5 +404,61 @@ void tst_QTextList::numbering()
QCOMPARE(cursor.currentList()->itemText(cursor.block()), result);
}
+void tst_QTextList::start_data()
+{
+ QTest::addColumn<int>("format");
+ QTest::addColumn<int>("start");
+ QTest::addColumn<QStringList>("expectedItemTexts");
+
+ QTest::newRow("-1.") << int(QTextListFormat::ListDecimal) << -1
+ << QStringList{ "-1.", "0.", "1." };
+ QTest::newRow("0.") << int(QTextListFormat::ListDecimal) << 0
+ << QStringList{ "0.", "1.", "2." };
+ QTest::newRow("1.") << int(QTextListFormat::ListDecimal) << 1
+ << QStringList{ "1.", "2.", "3." };
+
+ QTest::newRow("A. -1") << int(QTextListFormat::ListUpperAlpha) << -1
+ << QStringList{ "-1.", "0.", "A." };
+ QTest::newRow("A. 0.") << int(QTextListFormat::ListUpperAlpha) << 0
+ << QStringList{ "0.", "A.", "B." };
+ QTest::newRow("a. -1") << int(QTextListFormat::ListLowerAlpha) << -1
+ << QStringList{ "-1.", "0.", "a." };
+ QTest::newRow("a. 0.") << int(QTextListFormat::ListLowerAlpha) << 0
+ << QStringList{ "0.", "a.", "b." };
+ QTest::newRow("d. 4.") << int(QTextListFormat::ListLowerAlpha) << 4
+ << QStringList{ "d.", "e.", "f." };
+
+ QTest::newRow("I. -1") << int(QTextListFormat::ListUpperRoman) << -1
+ << QStringList{ "-1.", "0.", "I." };
+ QTest::newRow("I. 0.") << int(QTextListFormat::ListUpperRoman) << 0
+ << QStringList{ "0.", "I.", "II." };
+ QTest::newRow("i. -1") << int(QTextListFormat::ListLowerRoman) << -1
+ << QStringList{ "-1.", "0.", "i." };
+ QTest::newRow("i. 0.") << int(QTextListFormat::ListLowerRoman) << 0
+ << QStringList{ "0.", "i.", "ii." };
+}
+
+void tst_QTextList::start()
+{
+ QFETCH(int, format);
+ QFETCH(int, start);
+ QFETCH(QStringList, expectedItemTexts);
+
+ QTextListFormat fmt;
+ fmt.setStyle(QTextListFormat::Style(format));
+ fmt.setStart(start);
+ QTextList *list = cursor.createList(fmt);
+ QVERIFY(list);
+
+ while (list->count() < int(expectedItemTexts.size()))
+ cursor.insertBlock();
+
+ QCOMPARE(list->count(), expectedItemTexts.size());
+
+ for (int i = 0; i < list->count(); ++i)
+ QCOMPARE(cursor.currentList()->itemText(cursor.currentList()->item(i)),
+ expectedItemTexts[i]);
+}
+
QTEST_MAIN(tst_QTextList)
#include "tst_qtextlist.moc"
diff --git a/tests/auto/gui/text/qtextmarkdownimporter/CMakeLists.txt b/tests/auto/gui/text/qtextmarkdownimporter/CMakeLists.txt
index a82d4437db..937dd5bd80 100644
--- a/tests/auto/gui/text/qtextmarkdownimporter/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextmarkdownimporter/CMakeLists.txt
@@ -5,11 +5,17 @@
## tst_qtextmarkdownimporter Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextmarkdownimporter LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
-list(APPEND test_data "data/thematicBreaks.md")
-list(APPEND test_data "data/headingBulletsContinuations.md")
-list(APPEND test_data "data/fuzz20450.md")
-list(APPEND test_data "data/fuzz20580.md")
+file(GLOB_RECURSE test_data
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ data/*
+)
qt_internal_add_test(tst_qtextmarkdownimporter
SOURCES
diff --git a/tests/auto/gui/text/qtextmarkdownimporter/data/paragraphs.md b/tests/auto/gui/text/qtextmarkdownimporter/data/paragraphs.md
new file mode 100644
index 0000000000..3d89536376
--- /dev/null
+++ b/tests/auto/gui/text/qtextmarkdownimporter/data/paragraphs.md
@@ -0,0 +1,9 @@
+This paragraph has enough text to auto-wrap when QTextMarkdownWriter writes it
+to a markdown file. The wrapping should be around 80 columns.
+
+This paragrah has been broken up into shorter lines.
+Each line break is created
+by hitting shift-enter in QTextEdit.
+But it's treated as one QTextBlock.
+
+This paragraph also has short lines.
Each ends with a Unicode LineSeparator.

diff --git a/tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md b/tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md
index 7a0d5388ad..e784879326 100644
--- a/tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md
+++ b/tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md
@@ -11,6 +11,7 @@ stars
stars with tabs between
***
stars with whitespace after
+
---
hyphens with whitespace after
_____
diff --git a/tests/auto/gui/text/qtextmarkdownimporter/data/yaml-only.md b/tests/auto/gui/text/qtextmarkdownimporter/data/yaml-only.md
new file mode 100644
index 0000000000..1eff4db37f
--- /dev/null
+++ b/tests/auto/gui/text/qtextmarkdownimporter/data/yaml-only.md
@@ -0,0 +1,6 @@
+---
+name: "Space"
+title: "Outer space"
+keywords:
+ - astronomy
+---
diff --git a/tests/auto/gui/text/qtextmarkdownimporter/data/yaml.md b/tests/auto/gui/text/qtextmarkdownimporter/data/yaml.md
new file mode 100644
index 0000000000..41303a0187
--- /dev/null
+++ b/tests/auto/gui/text/qtextmarkdownimporter/data/yaml.md
@@ -0,0 +1,11 @@
+---
+name: "Venus"
+discoverer: "Galileo Galilei"
+title: "A description of the planet Venus"
+keywords:
+ - planets
+ - solar system
+ - astronomy
+---
+*Venus* is the second planet from the Sun, orbiting it every 224.7 Earth days.
+
diff --git a/tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp b/tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp
index 686187cc77..d9fe000253 100644
--- a/tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp
+++ b/tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2019 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>
#include <QBuffer>
@@ -29,6 +29,7 @@ class tst_QTextMarkdownImporter : public QObject
Q_OBJECT
private slots:
+ void paragraphs();
void headingBulletsContinuations();
void thematicBreaks();
void lists_data();
@@ -43,6 +44,10 @@ private slots:
void pathological();
void fencedCodeBlocks_data();
void fencedCodeBlocks();
+ void frontMatter_data();
+ void frontMatter();
+ void toRawText_data();
+ void toRawText();
private:
bool isMainFontFixed();
@@ -76,6 +81,43 @@ bool tst_QTextMarkdownImporter::isMainFontFixed()
return ret;
}
+void tst_QTextMarkdownImporter::paragraphs()
+{
+ QFile f(QFINDTESTDATA("data/paragraphs.md"));
+ QVERIFY(f.open(QFile::ReadOnly | QIODevice::Text));
+ QString md = QString::fromUtf8(f.readAll());
+ f.close();
+
+ int lineSeparatorCount = 0;
+ QTextDocument doc;
+ QTextMarkdownImporter(&doc, QTextMarkdownImporter::DialectGitHub).import(md);
+ QTextFrame::iterator iterator = doc.rootFrame()->begin();
+ int i = 0;
+ while (!iterator.atEnd()) {
+ QTextBlock block = iterator.currentBlock();
+ int lineSeparatorPos = block.text().indexOf(QChar::LineSeparator);
+ qCDebug(lcTests) << i << block.text();
+ while (lineSeparatorPos > 0) {
+ ++lineSeparatorCount;
+ qCDebug(lcTests) << " LineSeparator @" << lineSeparatorPos;
+ lineSeparatorPos = block.text().indexOf(QChar::LineSeparator, lineSeparatorPos + 1);
+ }
+ ++iterator;
+ ++i;
+ }
+ QCOMPARE(doc.blockCount(), 3);
+ QCOMPARE(lineSeparatorCount, 2);
+
+#ifdef DEBUG_WRITE_HTML
+ {
+ QFile out("/tmp/paragraphs.html");
+ out.open(QFile::WriteOnly);
+ out.write(doc.toHtml().toLatin1());
+ out.close();
+ }
+#endif
+}
+
void tst_QTextMarkdownImporter::headingBulletsContinuations()
{
const QStringList expectedBlocks = QStringList() <<
@@ -101,7 +143,7 @@ void tst_QTextMarkdownImporter::headingBulletsContinuations()
f.close();
QTextDocument doc;
- QTextMarkdownImporter(QTextMarkdownImporter::DialectGitHub).import(&doc, md);
+ QTextMarkdownImporter(&doc, QTextMarkdownImporter::DialectGitHub).import(md);
QTextFrame::iterator iterator = doc.rootFrame()->begin();
QTextFrame *currentFrame = iterator.currentFrame();
QStringList::const_iterator expectedIt = expectedBlocks.constBegin();
@@ -149,7 +191,7 @@ void tst_QTextMarkdownImporter::thematicBreaks()
f.close();
QTextDocument doc;
- QTextMarkdownImporter(QTextMarkdownImporter::DialectGitHub).import(&doc, md);
+ QTextMarkdownImporter(&doc, QTextMarkdownImporter::DialectGitHub).import(md);
QTextFrame::iterator iterator = doc.rootFrame()->begin();
QTextFrame *currentFrame = iterator.currentFrame();
int i = 0;
@@ -182,36 +224,58 @@ void tst_QTextMarkdownImporter::thematicBreaks()
void tst_QTextMarkdownImporter::lists_data()
{
QTest::addColumn<QString>("input");
+ QTest::addColumn<int>("skipToCheckStart");
+ QTest::addColumn<int>("expectedListStart");
QTest::addColumn<int>("expectedItemCount");
QTest::addColumn<bool>("expectedEmptyItems");
QTest::addColumn<QString>("rewrite");
// Some of these cases show odd behavior, which is subject to change
// as the importer and the writer are tweaked to fix bugs over time.
- QTest::newRow("dot newline") << ".\n" << 0 << true << ".\n\n";
- QTest::newRow("number dot newline") << "1.\n" << 1 << true << "1. \n";
- QTest::newRow("star newline") << "*\n" << 1 << true << "* \n";
- QTest::newRow("hyphen newline") << "-\n" << 1 << true << "- \n";
- QTest::newRow("hyphen space newline") << "- \n" << 1 << true << "- \n";
- QTest::newRow("hyphen space letter newline") << "- a\n" << 1 << false << "- a\n";
+ QTest::newRow("dot newline") << ".\n" << 0 << 1 << 0 << true << ".\n\n";
+ QTest::newRow("number dot newline") << "1.\n" << 0 << 1 << 1 << true << "1. \n";
+ QTest::newRow("number offset start") << "2. text\n" << 0 << 2 << 1 << false << "2. text\n";
+ QTest::newRow("second list offset start")
+ << "1. text\n\nintervening paragraph\n\n4. second list item"
+ << 2 << 4 << 2 << false
+ << "1. text\n\nintervening paragraph\n\n4. second list item\n";
+ QTest::newRow("list continuation offset start")
+ << "3. text\n\n next paragraph in item 1\n10. second list item"
+ << 2 << 3 << 2 << false
+ << "3. text\n\n next paragraph in item 1\n\n4. second list item\n";
+ QTest::newRow("nested list offset start")
+ << "1. text\n\n 0. indented list item\n\n4. second item in first list"
+ << 1 << 0 << 3 << false
+ << "1. text\n 0. indented list item\n2. second item in first list\n";
+ QTest::newRow("offset start after nested list")
+ << "1. text\n\n 0. indented list item\n\n4. second item in first list"
+ << 2 << 1 << 3 << false
+ << "1. text\n 0. indented list item\n2. second item in first list\n";
+ QTest::newRow("star newline") << "*\n" << 0 << 1 << 1 << true << "* \n";
+ QTest::newRow("hyphen newline") << "-\n" << 0 << 1 << 1 << true << "- \n";
+ QTest::newRow("hyphen space newline") << "- \n" << 0 << 1 << 1 << true << "- \n";
+ QTest::newRow("hyphen space letter newline") << "- a\n" << 0 << 1 << 1 << false << "- a\n";
QTest::newRow("hyphen nbsp newline") <<
- QString::fromUtf8("-\u00A0\n") << 0 << true << "-\u00A0\n\n";
- QTest::newRow("nested empty lists") << "*\n *\n *\n" << 1 << true << " * \n";
- QTest::newRow("list nested in empty list") << "-\n * a\n" << 2 << false << "- \n * a\n";
+ QString::fromUtf8("-\u00A0\n") << 0 << 1 << 0 << true << "\\-\u00A0\n\n";
+ QTest::newRow("nested empty lists") << "*\n *\n *\n" << 0 << 1 << 1 << true << " * \n";
+ QTest::newRow("list nested in empty list") << "-\n * a\n" << 0 << 1 << 2 << false << "- \n * a\n";
QTest::newRow("lists nested in empty lists")
- << "-\n * a\n * b\n- c\n *\n + d\n" << 5 << false
+ << "-\n * a\n * b\n- c\n *\n + d\n" << 0 << 1 << 5 << false
<< "- \n * a\n * b\n- c *\n + d\n";
QTest::newRow("numeric lists nested in empty lists")
- << "- \n 1. a\n 2. b\n- c\n 1.\n + d\n" << 4 << false
+ << "- \n 1. a\n 2. b\n- c\n 1.\n + d\n" << 0 << 1 << 4 << false
<< "- \n 1. a\n 2. b\n- c 1. + d\n";
QTest::newRow("styled spans in list items")
- << "1. normal text\n2. **bold** text\n3. `code` in the item\n4. *italic* text\n5. _underlined_ text\n" << 5 << false
+ << "1. normal text\n2. **bold** text\n3. `code` in the item\n4. *italic* text\n5. _underlined_ text\n"
+ << 0 << 1 << 5 << false
<< "1. normal text\n2. **bold** text\n3. `code` in the item\n4. *italic* text\n5. _underlined_ text\n";
}
void tst_QTextMarkdownImporter::lists()
{
QFETCH(QString, input);
+ QFETCH(int, skipToCheckStart);
+ QFETCH(int, expectedListStart);
QFETCH(int, expectedItemCount);
QFETCH(bool, expectedEmptyItems);
QFETCH(QString, rewrite);
@@ -227,6 +291,8 @@ void tst_QTextMarkdownImporter::lists()
out.close();
}
#endif
+ qCDebug(lcTests) << " original:" << input;
+ qCDebug(lcTests) << "rewritten:" << doc.toMarkdown();
QTextFrame::iterator iterator = doc.rootFrame()->begin();
QTextFrame *currentFrame = iterator.currentFrame();
@@ -239,10 +305,12 @@ void tst_QTextMarkdownImporter::lists()
QCOMPARE(iterator.currentFrame(), currentFrame);
// Check whether the block is text or a horizontal rule
QTextBlock block = iterator.currentBlock();
+ QTextListFormat listFmt;
if (block.textList()) {
++itemCount;
if (!block.text().isEmpty())
emptyItems = false;
+ listFmt = block.textList()->format();
}
qCDebug(lcTests, "%d %s%s", i,
(block.textList() ? "<li>" : "<p>"), qPrintable(block.text()));
@@ -261,6 +329,11 @@ void tst_QTextMarkdownImporter::lists()
QCOMPARE(listItemFmt.fontItalic(), false);
QCOMPARE(listItemFmt.fontUnderline(), false);
QCOMPARE(listItemFmt.fontFixedPitch(), false);
+ if (i == skipToCheckStart) {
+ qCDebug(lcTests) << "skipped to list item" << i << block.text()
+ << "start" << listFmt.start() << "expected" << expectedListStart;
+ QCOMPARE(listFmt.start(), expectedListStart);
+ }
++iterator;
++i;
}
@@ -392,7 +465,7 @@ void tst_QTextMarkdownImporter::avoidBlankLineAtBeginning() // QTBUG-81060
QFETCH(int, expectedNumberOfParagraphs);
QTextDocument doc;
- QTextMarkdownImporter(QTextMarkdownImporter::DialectGitHub).import(&doc, input);
+ QTextMarkdownImporter(&doc, QTextMarkdownImporter::DialectGitHub).import(input);
QTextFrame::iterator iterator = doc.rootFrame()->begin();
int i = 0;
while (!iterator.atEnd()) {
@@ -437,7 +510,7 @@ void tst_QTextMarkdownImporter::fragmentsAndProperties()
QFETCH(int, expectedNumberOfFragments);
QTextDocument doc;
- QTextMarkdownImporter(QTextMarkdownImporter::DialectGitHub).import(&doc, input);
+ QTextMarkdownImporter(&doc, QTextMarkdownImporter::DialectGitHub).import(input);
#ifdef DEBUG_WRITE_HTML
{
QFile out("/tmp/" + QLatin1String(QTest::currentDataTag()) + ".html");
@@ -505,6 +578,10 @@ void tst_QTextMarkdownImporter::fencedCodeBlocks_data()
<< "```pseudocode\nprint('hello world\\n')\n```\n"
<< 1 << 0 << "pseudocode" << "`"
<< "```pseudocode\nprint('hello world\\n')\n```\n\n";
+ QTest::newRow("backtick fence with punctuated language")
+ << "```html+js\n<html><head><script>function hi() { console.log('\\\"hello world') }</script></head>blah</html>\n```\n"
+ << 1 << 0 << "html+js" << "`"
+ << "```html+js\n<html><head><script>function hi() { console.log('\\\"hello world') }</script></head>blah</html>\n```\n\n";
QTest::newRow("tilde fence with language")
<< "~~~pseudocode\nprint('hello world\\n')\n~~~\n"
<< 1 << 0 << "pseudocode" << "~"
@@ -564,5 +641,135 @@ void tst_QTextMarkdownImporter::fencedCodeBlocks()
QCOMPARE(doc.toMarkdown(), rewrite);
}
+void tst_QTextMarkdownImporter::frontMatter_data()
+{
+ QTest::addColumn<QString>("inputFile");
+ QTest::addColumn<int>("expectedBlockCount");
+
+ QTest::newRow("yaml + markdown") << QFINDTESTDATA("data/yaml.md") << 1;
+ QTest::newRow("yaml only") << QFINDTESTDATA("data/yaml-only.md") << 0;
+}
+
+void tst_QTextMarkdownImporter::frontMatter()
+{
+ QFETCH(QString, inputFile);
+ QFETCH(int, expectedBlockCount);
+
+ QFile f(inputFile);
+ QVERIFY(f.open(QFile::ReadOnly | QIODevice::Text));
+ QString md = QString::fromUtf8(f.readAll());
+ f.close();
+ const int yamlBegin = md.indexOf("name:");
+ const int yamlEnd = md.indexOf("---", yamlBegin);
+ const QString yaml = md.sliced(yamlBegin, yamlEnd - yamlBegin);
+
+ QTextDocument doc;
+ QTextMarkdownImporter(&doc, QTextMarkdownImporter::DialectGitHub).import(md);
+ int blockCount = 0;
+ for (QTextFrame::iterator iterator = doc.rootFrame()->begin(); !iterator.atEnd(); ++iterator) {
+ // Check whether the block is text or a horizontal rule
+ if (!iterator.currentBlock().text().isEmpty())
+ ++blockCount;
+ }
+ QCOMPARE(blockCount, expectedBlockCount); // yaml is not part of the markdown text
+ QCOMPARE(doc.metaInformation(QTextDocument::FrontMatter), yaml); // without fences
+}
+
+void tst_QTextMarkdownImporter::toRawText_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("expectedRawText");
+
+ // tests to verify that fixing QTBUG-122083 is safe
+ // https://spec.commonmark.org/0.31.2/#example-12
+ QTest::newRow("punctuation backslash escapes") <<
+ R"(\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~)" <<
+ R"(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)";
+ // https://spec.commonmark.org/0.31.2/#example-13
+ QTest::newRow("literal backslashes") <<
+ QString(uR"(\→\A\a\ \3\φ\«)") <<
+ QString(uR"(\→\A\a\ \3\φ\«)");
+ // https://spec.commonmark.org/0.31.2/#example-14
+ QTest::newRow("escape to avoid em") <<
+ R"(\*not emphasized*)" <<
+ R"(*not emphasized*)";
+ QTest::newRow("escape to avoid html") <<
+ R"(\<br/> not a tag)" <<
+ R"(<br/> not a tag)";
+ QTest::newRow("escape to avoid link") <<
+ R"(\[not a link](/foo))" <<
+ R"([not a link](/foo))";
+ QTest::newRow("escape to avoid mono") <<
+ R"(\`not code`)" <<
+ R"(`not code`)";
+ QTest::newRow("escape to avoid num list") <<
+ R"(1\. not a list)" <<
+ R"(1. not a list)";
+ QTest::newRow("escape to avoid list") <<
+ R"(\* not a list)" <<
+ R"(* not a list)";
+ QTest::newRow("escape to avoid heading") <<
+ R"(\# not a heading)" <<
+ R"(# not a heading)";
+ QTest::newRow("escape to avoid reflink") <<
+ R"(\[foo]: /url "not a reference")" <<
+ R"([foo]: /url "not a reference")";
+ QTest::newRow("escape to avoid entity") <<
+ R"(\&ouml; not a character entity)" <<
+ R"(&ouml; not a character entity)";
+ // https://spec.commonmark.org/0.31.2/#example-15
+ QTest::newRow("escape backslash only") <<
+ R"(\\*emphasis*)" <<
+ R"(\emphasis)";
+ // https://spec.commonmark.org/0.31.2/#example-16
+ QTest::newRow("backslash line break") <<
+ "foo\\\nbar" <<
+ "foo\u2029bar";
+ // https://spec.commonmark.org/0.31.2/#example-17
+ QTest::newRow("backslash in mono span") <<
+ R"(`` \[\` ``)" <<
+ R"(\[\`)";
+ // https://spec.commonmark.org/0.31.2/#example-18
+ QTest::newRow("backslash in indented code") <<
+ R"( \[\])" <<
+ R"(\[\])";
+ // https://spec.commonmark.org/0.31.2/#example-19
+ QTest::newRow("backslash in fenced code") <<
+ "~~~\n\\[\\]\n~~~" <<
+ R"(\[\])";
+ // https://spec.commonmark.org/0.31.2/#example-20
+ QTest::newRow("backslash in autolink") <<
+ R"(<https://example.com?find=\*>)" <<
+ R"(https://example.com?find=\*)";
+ // https://spec.commonmark.org/0.31.2/#example-21
+ QTest::newRow("backslash in autolink") <<
+ "<a href=\"/bar\\/)\"" <<
+ "<a href=\"/bar/)\"";
+ // https://spec.commonmark.org/0.31.2/#example-22
+ QTest::newRow("escapes in link") <<
+ R"([foo](/bar\* "ti\*tle"))" <<
+ R"(foo)";
+ // https://spec.commonmark.org/0.31.2/#example-24
+ QTest::newRow("backslash in code lang") <<
+ "```\nfoo\\+bar\nfoo\n```" <<
+ "foo\\+bar\u2029foo";
+ // end of tests to verify that fixing QTBUG-122083 is safe
+ // (it's ok to add unrelated markdown-to-rawtext cases later)
+}
+
+void tst_QTextMarkdownImporter::toRawText()
+{
+ QFETCH(QString, input);
+ QFETCH(QString, expectedRawText);
+
+ QTextDocument doc;
+ doc.setMarkdown(input);
+
+ // These are testing md4c more than Qt, so any change may be an md4c bug, or a fix
+ QCOMPARE(doc.toRawText(), expectedRawText);
+ if (doc.blockCount() == 1)
+ QCOMPARE(doc.firstBlock().text(), expectedRawText);
+}
+
QTEST_MAIN(tst_QTextMarkdownImporter)
#include "tst_qtextmarkdownimporter.moc"
diff --git a/tests/auto/gui/text/qtextmarkdownwriter/CMakeLists.txt b/tests/auto/gui/text/qtextmarkdownwriter/CMakeLists.txt
index 7779ee4267..0cdf1d9225 100644
--- a/tests/auto/gui/text/qtextmarkdownwriter/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextmarkdownwriter/CMakeLists.txt
@@ -5,9 +5,17 @@
## tst_qtextmarkdownwriter Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextmarkdownwriter LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
-list(APPEND test_data "data/example.md")
-list(APPEND test_data "data/blockquotes.md")
+file(GLOB_RECURSE test_data
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ data/*
+)
qt_internal_add_test(tst_qtextmarkdownwriter
SOURCES
diff --git a/tests/auto/gui/text/qtextmarkdownwriter/data/blockquotes.md b/tests/auto/gui/text/qtextmarkdownwriter/data/blockquotes.md
index a021f15aba..8e605ef7e6 100644
--- a/tests/auto/gui/text/qtextmarkdownwriter/data/blockquotes.md
+++ b/tests/auto/gui/text/qtextmarkdownwriter/data/blockquotes.md
@@ -8,17 +8,17 @@ MacFarlane writes:
> What distinguishes Markdown from many other lightweight markup syntaxes,
> which are often easier to write, is its readability. As Gruber writes:
-
+>
> > The overriding design goal for Markdown's formatting syntax is to make it
> > as readable as possible. The idea is that a Markdown-formatted document should
> > be publishable as-is, as plain text, without looking like it's been marked up
> > with tags or formatting instructions. (
> > <http://daringfireball.net/projects/markdown/> )
-
+>
> The point can be illustrated by comparing a sample of AsciiDoc with an
> equivalent sample of Markdown. Here is a sample of AsciiDoc from the AsciiDoc
> manual:
-
+>
> ```AsciiDoc
> 1. List item one.
> +
diff --git a/tests/auto/gui/text/qtextmarkdownwriter/data/blockquotesWithLists.md b/tests/auto/gui/text/qtextmarkdownwriter/data/blockquotesWithLists.md
new file mode 100644
index 0000000000..1728889adc
--- /dev/null
+++ b/tests/auto/gui/text/qtextmarkdownwriter/data/blockquotesWithLists.md
@@ -0,0 +1,14 @@
+What if we have a quotation containing a list?
+
+> First some quoted text, and then a list:
+>
+> - one
+> - two is longer and has enough words to form a paragraph with text continuing
+> onto the next line
+>
+> enough of that, let's try a numbered list
+>
+> 1. List item one
+> 2. List item two is longer and has enough words to form a paragraph with
+> text continuing onto the next line.
+> \ No newline at end of file
diff --git a/tests/auto/gui/text/qtextmarkdownwriter/data/example.md b/tests/auto/gui/text/qtextmarkdownwriter/data/example.md
index 15b30598e6..8fdad207ae 100644
--- a/tests/auto/gui/text/qtextmarkdownwriter/data/example.md
+++ b/tests/auto/gui/text/qtextmarkdownwriter/data/example.md
@@ -40,7 +40,7 @@ numerals in the same list structure:
1. Introduction
2. Qt Tools
1) Qt Assistant
- 2) Qt Designer
+ 2) Qt Widgets Designer
1. Form Editor
2. Component Architecture
3) Qt Linguist
@@ -70,7 +70,7 @@ column spans, text formatting within cells, and size constraints for columns.
|-------------|------------------------------------|---------------------------|-------------------------|
|9:00 - 11:00 |Introduction to Qt |||
|11:00 - 13:00|Using qmake |Object-oriented Programming|Layouts in Qt |
-|13:00 - 15:00|Qt Designer Tutorial |Extreme Programming |Writing Custom Styles |
+|13:00 - 15:00|Qt Widgets Designer Tutorial |Extreme Programming |Writing Custom Styles |
|15:00 - 17:00|Qt Linguist and Internationalization|Test-Driven Development | |
*Try adding text to the cells in the table and experiment with the alignment of
diff --git a/tests/auto/gui/text/qtextmarkdownwriter/data/listItemWithBlockquote.md b/tests/auto/gui/text/qtextmarkdownwriter/data/listItemWithBlockquote.md
new file mode 100644
index 0000000000..c417125fea
--- /dev/null
+++ b/tests/auto/gui/text/qtextmarkdownwriter/data/listItemWithBlockquote.md
@@ -0,0 +1,6 @@
+What if we have a list item containing a block quote?
+
+- one
+- > two is longer and has enough words to form a paragraph with text continuing
+ > onto the next line
+
diff --git a/tests/auto/gui/text/qtextmarkdownwriter/data/longHeadings.md b/tests/auto/gui/text/qtextmarkdownwriter/data/longHeadings.md
new file mode 100644
index 0000000000..72692b4845
--- /dev/null
+++ b/tests/auto/gui/text/qtextmarkdownwriter/data/longHeadings.md
@@ -0,0 +1,9 @@
+# The quick brown fox jumped over the lazy dog while the cat played the fiddle and the cow jumped over the moon
+
+Hey diddle diddle
+
+## This document has a verbose subheading too, which we do not expect to wrap in the output
+
+Qt can write it right. Long text here in this paragraph will actually wrap,
+even though its heading doesn't.
+
diff --git a/tests/auto/gui/text/qtextmarkdownwriter/data/yaml.md b/tests/auto/gui/text/qtextmarkdownwriter/data/yaml.md
new file mode 100644
index 0000000000..41303a0187
--- /dev/null
+++ b/tests/auto/gui/text/qtextmarkdownwriter/data/yaml.md
@@ -0,0 +1,11 @@
+---
+name: "Venus"
+discoverer: "Galileo Galilei"
+title: "A description of the planet Venus"
+keywords:
+ - planets
+ - solar system
+ - astronomy
+---
+*Venus* is the second planet from the Sun, orbiting it every 224.7 Earth days.
+
diff --git a/tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp b/tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp
index 2b6b1ecca5..0d261bc27e 100644
--- a/tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp
+++ b/tests/auto/gui/text/qtextmarkdownwriter/tst_qtextmarkdownwriter.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2019 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>
#include <QTextDocument>
@@ -34,11 +34,21 @@ private slots:
void testWriteNestedBulletLists_data();
void testWriteNestedBulletLists();
void testWriteNestedNumericLists();
+ void testWriteNumericListWithStart();
void testWriteTable();
+ void frontMatter();
+ void charFormatWrapping_data();
+ void charFormatWrapping();
+ void charFormat_data();
+ void charFormat();
void rewriteDocument_data();
void rewriteDocument();
void fromHtml_data();
void fromHtml();
+ void fromPlainTextAndBack_data();
+ void fromPlainTextAndBack();
+ void escapeSpecialCharacters_data();
+ void escapeSpecialCharacters();
private:
bool isMainFontFixed();
@@ -47,6 +57,8 @@ private:
private:
QTextDocument *document;
+ QFont m_monoFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
+ QFont m_defaultFont;
};
void tst_QTextMarkdownWriter::init()
@@ -284,6 +296,7 @@ void tst_QTextMarkdownWriter::testWriteNestedNumericLists()
list1->add(cursor.block());
QTextListFormat fmt2;
+ // Alpha "numbering" is not supported in markdown, so we'll actually get decimal.
fmt2.setStyle(QTextListFormat::ListLowerAlpha);
fmt2.setNumberSuffix(QLatin1String(")"));
fmt2.setIndent(2);
@@ -305,7 +318,24 @@ void tst_QTextMarkdownWriter::testWriteNestedNumericLists()
list2->add(cursor.block());
const QString output = documentToUnixMarkdown();
- // There's no QTextList API to set the starting number so we hard-coded all lists to start at 1 (QTBUG-65384)
+
+ #ifdef DEBUG_WRITE_OUTPUT
+ {
+ QFile out(QDir::temp().filePath(QLatin1String(QTest::currentTestFunction()) + ".md"));
+ out.open(QFile::WriteOnly);
+ out.write(output.toUtf8());
+ out.close();
+ }
+ {
+ QFile out(QDir::temp().filePath(QLatin1String(QTest::currentTestFunction()) + ".html"));
+ out.open(QFile::WriteOnly);
+ out.write(document->toHtml().toUtf8());
+ out.close();
+ }
+#endif
+
+ // While we can set the start index for a block, if list items intersect each other, they will
+ // still use the list numbering.
const QString expected = QString::fromLatin1(
"1. ListItem 1\n 1) ListItem 2\n 1. ListItem 3\n2. ListItem 4\n 2) ListItem 5\n");
if (output != expected && isMainFontFixed())
@@ -313,6 +343,92 @@ void tst_QTextMarkdownWriter::testWriteNestedNumericLists()
QCOMPARE(output, expected);
}
+void tst_QTextMarkdownWriter::testWriteNumericListWithStart()
+{
+ QTextCursor cursor(document);
+
+ // The first list will start at 2.
+ QTextListFormat fmt1;
+ fmt1.setStyle(QTextListFormat::ListDecimal);
+ fmt1.setStart(2);
+ QTextList *list1 = cursor.createList(fmt1);
+ cursor.insertText("ListItem 1");
+ list1->add(cursor.block());
+
+ // This list uses the default start (1) again.
+ QTextListFormat fmt2;
+ // Alpha "numbering" is not supported in markdown, so we'll actually get decimal.
+ fmt2.setStyle(QTextListFormat::ListLowerAlpha);
+ fmt2.setNumberSuffix(QLatin1String(")"));
+ fmt2.setIndent(2);
+ QTextList *list2 = cursor.insertList(fmt2);
+ cursor.insertText("ListItem 2");
+
+ // Negative list numbers are disallowed by most Markdown implementations. This list will start
+ // at 1 for that reason.
+ QTextListFormat fmt3;
+ fmt3.setStyle(QTextListFormat::ListDecimal);
+ fmt3.setIndent(3);
+ fmt3.setStart(-1);
+ cursor.insertList(fmt3);
+ cursor.insertText("ListItem 3");
+
+ // Continuing list1, so the second item will have the number 3.
+ cursor.insertBlock();
+ cursor.insertText("ListItem 4");
+ list1->add(cursor.block());
+
+ // This will look out of place: it's in a different position than its list would suggest.
+ // Generates invalid markdown numbering (OK for humans, but md4c will parse it differently than we "meant").
+ // TODO QTBUG-111707: the writer needs to add newlines, otherwise ListItem 5 becomes part of the text for ListItem 4.
+ cursor.insertBlock();
+ cursor.insertText("ListItem 5");
+ list2->add(cursor.block());
+
+ // 0 indexed lists are fine.
+ QTextListFormat fmt4;
+ fmt4.setStyle(QTextListFormat::ListDecimal);
+ fmt4.setStart(0);
+ QTextList *list4 = cursor.insertList(fmt4);
+ cursor.insertText("SecondList Item 0");
+ list4->add(cursor.block());
+
+ // Ensure list numbers are incremented properly.
+ cursor.insertBlock();
+ cursor.insertText("SecondList Item 1");
+ list4->add(cursor.block());
+
+ const QString output = documentToUnixMarkdown();
+ const QString expected = QString::fromLatin1(
+ R"(2. ListItem 1
+ 1) ListItem 2
+ 1. ListItem 3
+3. ListItem 4
+ 2) ListItem 5
+0. SecondList Item 0
+1. SecondList Item 1
+)");
+
+#ifdef DEBUG_WRITE_OUTPUT
+ {
+ QFile out(QDir::temp().filePath(QLatin1String(QTest::currentTestFunction()) + ".md"));
+ out.open(QFile::WriteOnly);
+ out.write(output.toUtf8());
+ out.close();
+ }
+ {
+ QFile out(QDir::temp().filePath(QLatin1String(QTest::currentTestFunction()) + ".html"));
+ out.open(QFile::WriteOnly);
+ out.write(document->toHtml().toUtf8());
+ out.close();
+ }
+#endif
+
+ if (output != expected && isMainFontFixed())
+ QEXPECT_FAIL("", "fixed-pitch main font (QTBUG-103484)", Continue);
+ QCOMPARE(output, expected);
+}
+
void tst_QTextMarkdownWriter::testWriteTable()
{
QTextCursor cursor(document);
@@ -420,16 +536,231 @@ void tst_QTextMarkdownWriter::testWriteTable()
QCOMPARE(md, expected);
}
+void tst_QTextMarkdownWriter::frontMatter()
+{
+ QTextCursor cursor(document);
+ cursor.insertText("bar");
+ document->setMetaInformation(QTextDocument::FrontMatter, "foo");
+
+ const QString output = documentToUnixMarkdown();
+ const QString expectedOutput("---\nfoo\n---\nbar\n\n");
+ if (output != expectedOutput && isMainFontFixed())
+ QEXPECT_FAIL("", "fixed-pitch main font (QTBUG-103484)", Continue);
+ QCOMPARE(output, expectedOutput);
+}
+
+void tst_QTextMarkdownWriter::charFormatWrapping_data()
+{
+ QTest::addColumn<QTextFormat::Property>("property");
+ QTest::addColumn<QVariant>("propertyValue");
+ QTest::addColumn<QString>("followingText");
+ QTest::addColumn<QString>("expectedIndicator");
+
+ const QString spaced = " after";
+ const QString unspaced = ", and some more after";
+
+ QTest::newRow("FontFixedPitch-spaced")
+ << QTextFormat::FontFixedPitch << QVariant(true) << spaced << "`";
+ QTest::newRow("FontFixedPitch-unspaced")
+ << QTextFormat::FontFixedPitch << QVariant(true) << unspaced << "`";
+ QTest::newRow("FontItalic")
+ << QTextFormat::FontItalic << QVariant(true) << spaced << "*";
+ QTest::newRow("FontUnderline")
+ << QTextFormat::FontUnderline << QVariant(true) << spaced << "_";
+ QTest::newRow("FontStrikeOut")
+ << QTextFormat::FontStrikeOut << QVariant(true) << spaced << "~~";
+ QTest::newRow("FontWeight-spaced")
+ << QTextFormat::FontWeight << QVariant(700) << spaced << "**";
+ QTest::newRow("FontWeight-unspaced")
+ << QTextFormat::FontWeight << QVariant(700) << unspaced << "**";
+}
+
+void tst_QTextMarkdownWriter::charFormatWrapping() // QTBUG-116927
+{
+ QFETCH(QTextFormat::Property, property);
+ QFETCH(QVariant, propertyValue);
+ QFETCH(QString, expectedIndicator);
+ QFETCH(QString, followingText);
+
+ const QString newLine("\n");
+ QTextCursor cursor(document);
+ cursor.insertText("around sixty-four characters to go before some formatted words ");
+ QTextCharFormat fmt;
+ fmt.setProperty(property, propertyValue);
+ cursor.setCharFormat(fmt);
+ cursor.insertText("formatted text");
+
+ cursor.setCharFormat({});
+ cursor.insertText(followingText);
+ qsizetype lastNewLineIndex = 100;
+
+ for (int push = 0; push < 10; ++push) {
+ if (push > 0) {
+ cursor.movePosition(QTextCursor::StartOfBlock);
+ cursor.insertText("a");
+ }
+
+ const QString output = documentToUnixMarkdown().trimmed(); // get rid of trailing newlines
+ const auto nlIdx = output.indexOf(newLine);
+ qCDebug(lcTests) << "push" << push << ":" << output << "newline @" << nlIdx;
+ // we're always wrapping in this test: expect to find a newline
+ QCOMPARE_GT(nlIdx, 70);
+ // don't expect the newline to be more than one character to the right of where we found it last time
+ // i.e. if we already started breaking in the middle: "`formatted\ntext`",
+ // then we would not expect that prepending one more character would make it go
+ // back to breaking afterwards: "`formatted text`\n" (because then the line becomes longer than necessary)
+ QCOMPARE_LE(nlIdx, lastNewLineIndex + 1);
+ lastNewLineIndex = nlIdx;
+ const QString nextChars = output.sliced(nlIdx + newLine.size(), expectedIndicator.size());
+ const auto startingIndicatorIdx = output.indexOf(expectedIndicator);
+ // the starting indicator always exists, except in case of font problems on some CI platforms
+ if (startingIndicatorIdx <= 0)
+ QSKIP("starting indicator not found, probably due to platform font problems (QTBUG-103484 etc.)");
+ const auto endingIndicatorIdx = output.indexOf(expectedIndicator, startingIndicatorIdx + 5);
+ qCDebug(lcTests) << "next chars past newline" << nextChars
+ << "indicators @" << startingIndicatorIdx << endingIndicatorIdx;
+ // the closing indicator must exist
+ QCOMPARE_GT(endingIndicatorIdx, startingIndicatorIdx);
+ // don't start a new line with an ending indicator:
+ // we can have "**formatted\ntext**" or "**formatted text**\n" or "\n**formatted text**"
+ // but not "**formatted text\n**"
+ if (startingIndicatorIdx < nlIdx)
+ QCOMPARE_NE(nextChars, expectedIndicator);
+ }
+}
+
+void tst_QTextMarkdownWriter::charFormat_data()
+{
+ QTest::addColumn<QTextFormat::Property>("property");
+ QTest::addColumn<QVariant>("propertyValue");
+ QTest::addColumn<QFont>("explicitFont");
+ QTest::addColumn<QString>("expectedOutput");
+
+ const QTextFormat::Property NoProperty = QTextFormat::ObjectIndex;
+
+ QTest::newRow("FontFixedPitch")
+ << QTextFormat::FontFixedPitch << QVariant(true) << m_defaultFont
+ << "before `formatted` after";
+ if (!isFixedFontProportional()) {
+ // QTBUG-54623 QTBUG-75649 QTBUG-79900 QTBUG-103484 etc.
+ QTest::newRow("mono font") << NoProperty << QVariant() << m_monoFont
+ << "before `formatted` after";
+ }
+
+ {
+ QFont font;
+ font.setItalic(true);
+ QTest::newRow("italic font")
+ << NoProperty << QVariant() << font
+ << "before *formatted* after";
+ }
+ QTest::newRow("FontItalic")
+ << QTextFormat::FontItalic << QVariant(true) << m_defaultFont
+ << "before *formatted* after";
+
+ {
+ QFont font;
+ font.setUnderline(true);
+ QTest::newRow("underline font")
+ << NoProperty << QVariant() << font
+ << "before _formatted_ after";
+ }
+ QTest::newRow("FontUnderline")
+ << QTextFormat::FontUnderline << QVariant(true) << m_defaultFont
+ << "before _formatted_ after";
+
+ {
+ QFont font;
+ font.setStrikeOut(true);
+ QTest::newRow("strikeout font")
+ << NoProperty << QVariant() << font
+ << "before ~~formatted~~ after";
+ }
+ QTest::newRow("FontStrikeOut")
+ << QTextFormat::FontStrikeOut << QVariant(true) << m_defaultFont
+ << "before ~~formatted~~ after";
+
+ {
+ QFont font;
+ font.setBold(true);
+ QTest::newRow("bold font")
+ << NoProperty << QVariant() << font
+ << "before **formatted** after";
+ }
+ {
+ QFont font;
+ font.setWeight(QFont::Black);
+ QTest::newRow("black font")
+ << NoProperty << QVariant() << font
+ << "before **formatted** after";
+ }
+ QTest::newRow("FontWeight")
+ << QTextFormat::FontWeight << QVariant(700) << m_defaultFont
+ << "before **formatted** after";
+
+ QTest::newRow("AnchorHref")
+ << QTextFormat::AnchorHref << QVariant("linky linky") << m_defaultFont
+ << "before [formatted](linky linky) after";
+
+ QTest::newRow("TextToolTip") // no effect without AnchorHref
+ << QTextFormat::TextToolTip << QVariant("such a tool") << m_defaultFont
+ << "before formatted after";
+}
+
+void tst_QTextMarkdownWriter::charFormat()
+{
+ if (isMainFontFixed())
+ QSKIP("QTextMarkdownWriter would generate bogus backticks");
+
+ QFETCH(QTextFormat::Property, property);
+ QFETCH(QVariant, propertyValue);
+ QFETCH(QFont, explicitFont);
+ QFETCH(QString, expectedOutput);
+
+ QTextCursor cursor(document);
+ cursor.insertText("before ");
+
+ QTextCharFormat fmt;
+ if (explicitFont != m_defaultFont)
+ fmt.setFont(explicitFont);
+ if (property != QTextFormat::ObjectIndex) // != 0
+ fmt.setProperty(property, propertyValue);
+ if (explicitFont == m_monoFont) {
+ QFontInfo fontInfo(fmt.font());
+ qCDebug(lcTests) << "mono font" << explicitFont << "fontInfo fixedPitch" << fontInfo.fixedPitch() << "fmt fixedPitch" << fmt.fontFixedPitch();
+ }
+ cursor.setCharFormat(fmt);
+ cursor.insertText("formatted");
+
+ cursor.setCharFormat({});
+ cursor.insertText(" after");
+
+ const QString output = documentToUnixMarkdown();
+#ifdef DEBUG_WRITE_OUTPUT
+ {
+ QFile out(QDir::temp().filePath(QLatin1String(QTest::currentDataTag()) + ".md"));
+ out.open(QFile::WriteOnly);
+ out.write(output.toUtf8());
+ out.close();
+ }
+#endif
+ QCOMPARE(output.trimmed(), expectedOutput);
+}
+
void tst_QTextMarkdownWriter::rewriteDocument_data()
{
QTest::addColumn<QString>("inputFile");
QTest::newRow("block quotes") << "blockquotes.md";
+ QTest::newRow("block quotes with lists") << "blockquotesWithLists.md";
+ // QTest::newRow("list item with block quote") << "listItemWithBlockquote.md"; // not supported for now
QTest::newRow("example") << "example.md";
QTest::newRow("list items after headings") << "headingsAndLists.md";
QTest::newRow("word wrap") << "wordWrap.md";
QTest::newRow("links") << "links.md";
QTest::newRow("lists and code blocks") << "listsAndCodeBlocks.md";
+ QTest::newRow("front matter") << "yaml.md";
+ QTest::newRow("long headings") << "longHeadings.md";
}
void tst_QTextMarkdownWriter::rewriteDocument()
@@ -462,7 +793,7 @@ void tst_QTextMarkdownWriter::fromHtml_data()
QTest::newRow("long URL") <<
"<span style=\"font-style:italic;\">https://www.example.com/dir/subdir/subsubdir/subsubsubdir/subsubsubsubdir/subsubsubsubsubdir/</span>" <<
- "*https://www.example.com/dir/subdir/subsubdir/subsubsubdir/subsubsubsubdir/subsubsubsubsubdir/*\n\n";
+ "\n*https://www.example.com/dir/subdir/subsubdir/subsubsubdir/subsubsubsubdir/subsubsubsubsubdir/*\n\n";
QTest::newRow("non-emphasis inline asterisk") << "3 * 4" << "3 * 4\n\n";
QTest::newRow("arithmetic") << "(2 * a * x + b)^2 = b^2 - 4 * a * c" << "(2 * a * x + b)^2 = b^2 - 4 * a * c\n\n";
QTest::newRow("escaped asterisk after newline") <<
@@ -495,16 +826,42 @@ void tst_QTextMarkdownWriter::fromHtml_data()
QTest::newRow("code") <<
"<pre class=\"language-pseudocode\">\n#include \"foo.h\"\n\nblock {\n statement();\n}\n\n</pre>" <<
"```pseudocode\n#include \"foo.h\"\n\nblock {\n statement();\n}\n\n```\n\n";
- // TODO
-// QTest::newRow("escaped number and paren after double newline") <<
-// "<p>(The first sentence of this paragraph is a line, the next paragraph has a number</p>13) but that's not part of an ordered list" <<
-// "(The first sentence of this paragraph is a line, the next paragraph has a number\n\n13\\) but that's not part of an ordered list\n\n";
+ QTest::newRow("escaped number and paren after single newline") <<
+ "<p>(The first sentence of this paragraph is a line, next paragraph has a number 13) but that's not part of an ordered list</p>" <<
+ "(The first sentence of this paragraph is a line, next paragraph has a number\n13\\) but that's not part of an ordered list\n\n";
+ QTest::newRow("escaped number and paren after double newline") <<
+ "<p>(The first sentence of this paragraph is a line, the next paragraph has a number</p>13) but that's not part of an ordered list" <<
+ "(The first sentence of this paragraph is a line, the next paragraph has a number\n\n13\\) but that's not part of an ordered list\n\n";
QTest::newRow("preformats with embedded backticks") <<
"<pre>none `one` ``two``</pre>plain<pre>```three``` ````four````</pre>plain" <<
"```\nnone `one` ``two``\n\n```\nplain\n\n```\n```three``` ````four````\n\n```\nplain\n\n";
QTest::newRow("list items with and without checkboxes") <<
"<ul><li>bullet</li><li class=\"unchecked\">unchecked item</li><li class=\"checked\">checked item</li></ul>" <<
"- bullet\n- [ ] unchecked item\n- [x] checked item\n";
+ QTest::newRow("table with backslash in cell") << // QTBUG-96051
+ "<table><tr><td>1011011 [</td><td>1011100 backslash \\</td></tr></table>" <<
+ "|1011011 [|1011100 backslash \\\\|";
+ // https://spec.commonmark.org/0.31.2/#example-12
+ // escaping punctuation is ok, but QTextMarkdownWriter currently doesn't do that (which is also ok)
+ QTest::newRow("punctuation") <<
+ R"(<p>!&quot;#$%&amp;'()*+,-./:;&lt;=&gt;?@[\]^_`{|}~</p>)" <<
+ R"(!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~)";
+ // https://spec.commonmark.org/0.31.2/#example-14
+ QTest::newRow("backslash asterisk no emphasis") << // QTBUG-122083
+ R"(\*no emphasis*)" <<
+ R"(\\\*no emphasis*)";
+ // https://spec.commonmark.org/0.31.2/#example-15
+ QTest::newRow("backslash before emphasis") <<
+ R"(\<em>emphasis</em>)" <<
+ R"(\\*emphasis*)";
+ // https://spec.commonmark.org/0.31.2/#example-20
+ QTest::newRow("backslash-asterisk in autolink") <<
+ R"(<p><a href="https://example.com?find=\\*">https://example.com?find=\*</a></p>)" <<
+ R"(<https://example.com?find=\\*>)";
+ // https://spec.commonmark.org/0.31.2/#example-24
+ QTest::newRow("plus in fenced code lang") <<
+ "<pre class=\"language-foo+bar\">foo</pre>" <<
+ "```foo+bar\nfoo\n```";
}
void tst_QTextMarkdownWriter::fromHtml()
@@ -524,6 +881,137 @@ void tst_QTextMarkdownWriter::fromHtml()
}
#endif
+ output = output.trimmed();
+ expectedOutput = expectedOutput.trimmed();
+ if (output != expectedOutput && (isMainFontFixed() || isFixedFontProportional()))
+ QEXPECT_FAIL("", "fixed main font or proportional fixed font (QTBUG-103484)", Continue);
+ QCOMPARE(output, expectedOutput);
+}
+
+void tst_QTextMarkdownWriter::fromPlainTextAndBack_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("expectedMarkdown");
+
+ // tests to verify that fixing QTBUG-122083 is safe
+ QTest::newRow("single backslashes") <<
+ R"(\ again: \ not esc: \* \-\-\ \*abc*)" <<
+ R"(\\ again: \\ not esc: \\* \\-\\-\\ \\\*abc*)";
+ // https://spec.commonmark.org/0.31.2/#example-12
+ QTest::newRow("punctuation") <<
+ R"(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)" <<
+ R"(!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~)";
+ // https://spec.commonmark.org/0.31.2/#example-13
+ QTest::newRow("literal backslashes") <<
+ QString(uR"(\→\A\a\ \3\φ\«)") <<
+ "\\\\\u2192\\\\A\\\\a\\\\ \\\\3\\\\\u03C6\\\\\u00AB";
+ // https://spec.commonmark.org/0.31.2/#example-14
+ QTest::newRow("escape to avoid em") <<
+ R"(*not emphasized*)" <<
+ R"(\*not emphasized*)";
+ QTest::newRow("escape to avoid html") <<
+ R"(<br/> not a tag)" <<
+ R"(\<br/> not a tag)";
+ QTest::newRow("escape to avoid link") <<
+ R"([not a link](/foo))" <<
+ R"(\[not a link](/foo))";
+ QTest::newRow("escape to avoid mono") <<
+ R"(`not code`)" <<
+ R"(\`not code`)";
+ QTest::newRow("escape to avoid num list") <<
+ R"(1. not a list)" <<
+ R"(1\. not a list)";
+ QTest::newRow("escape to avoid list") <<
+ R"(* not a list)" <<
+ R"(\* not a list)";
+ QTest::newRow("escape to avoid heading") <<
+ R"(# not a heading)" <<
+ R"(\# not a heading)";
+ QTest::newRow("escape to avoid reflink") <<
+ R"([foo]: /url "not a reference")" <<
+ R"(\[foo]: /url "not a reference")";
+ QTest::newRow("escape to avoid entity") <<
+ R"(&ouml; not a character entity)" <<
+ R"(\&ouml; not a character entity)";
+ // end of tests to verify that fixing QTBUG-122083 is safe
+ // (it's ok to add unrelated plain-to-markdown-to-plaintext cases later)
+}
+
+void tst_QTextMarkdownWriter::fromPlainTextAndBack()
+{
+ QFETCH(QString, input);
+ QFETCH(QString, expectedMarkdown);
+
+ document->setPlainText(input);
+ QString output = documentToUnixMarkdown();
+
+#ifdef DEBUG_WRITE_OUTPUT
+ {
+ QFile out("/tmp/" + QLatin1String(QTest::currentDataTag()) + ".md");
+ out.open(QFile::WriteOnly);
+ out.write(output.toUtf8());
+ out.close();
+ }
+#endif
+
+ output = output.trimmed();
+ expectedMarkdown = expectedMarkdown.trimmed();
+ if (output != expectedMarkdown && (isMainFontFixed() || isFixedFontProportional()))
+ QSKIP("", "fixed main font or proportional fixed font (QTBUG-103484)");
+ QCOMPARE(output, expectedMarkdown);
+ QCOMPARE(document->toPlainText(), input);
+ document->setMarkdown(output);
+ QCOMPARE(document->toPlainText(), input);
+ if (document->blockCount() == 1)
+ QCOMPARE(document->firstBlock().text(), input);
+}
+
+void tst_QTextMarkdownWriter::escapeSpecialCharacters_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("expectedOutput");
+
+ QTest::newRow("backslash") << "foo \\ bar \\\\ baz \\" << "foo \\\\ bar \\\\\\\\ baz \\\\";
+ QTest::newRow("not emphasized") << "*normal* **normal too**" << "\\*normal* \\**normal too**";
+ QTest::newRow("not code") << "`normal` `normal too`" << "\\`normal` \\`normal too`";
+ QTest::newRow("code fence") << "```not a fence; ``` no risk here; ```not a fence" // TODO slightly inconsistent
+ << "\\```not a fence; ``` no risk here; \\```not a fence";
+ QTest::newRow("not html") << "<p>not a tag: <br/> nope</p>" << "\\<p>not a tag: \\<br/> nope\\</p>";
+ QTest::newRow("not a link") << "text [not a link](/foo)" << "text \\[not a link](/foo)";
+ QTest::newRow("not a circle") << "* polaris" << "\\* polaris";
+ QTest::newRow("not a square") << "+ groovy" << "\\+ groovy";
+ QTest::newRow("not a bullet") << "- stayin alive" << "\\- stayin alive";
+ QTest::newRow("arithmetic") << "1 + 2 - 3 * 4" << "1 + 2 - 3 * 4";
+ QTest::newRow("not a list") << "1. not a list" << "1\\. not a list";
+ QTest::newRow("not a list either") << "Jupiter and 10." << "Jupiter and 10.";
+ QTest::newRow("not a heading") << "# not a heading" << "\\# not a heading";
+ QTest::newRow("a non-entity") << "&ouml; not a character entity" << "\\&ouml; not a character entity";
+}
+
+/*! \internal
+ If the user types into a Qt-based editor plain text that the
+ markdown parser would misinterpret, escape it when we save to markdown
+ to clarify that it's plain text.
+ https://spec.commonmark.org/0.31.2/#backslash-escapes
+*/
+void tst_QTextMarkdownWriter::escapeSpecialCharacters() // QTBUG-96051, QTBUG-122083
+{
+ QFETCH(QString, input);
+ QFETCH(QString, expectedOutput);
+
+ document->setPlainText(input);
+ QString output = documentToUnixMarkdown();
+
+#ifdef DEBUG_WRITE_OUTPUT
+ {
+ QFile out("/tmp/" + QLatin1String(QTest::currentDataTag()) + ".md");
+ out.open(QFile::WriteOnly);
+ out.write(output.toUtf8());
+ out.close();
+ }
+#endif
+
+ output = output.trimmed();
if (output != expectedOutput && (isMainFontFixed() || isFixedFontProportional()))
QEXPECT_FAIL("", "fixed main font or proportional fixed font (QTBUG-103484)", Continue);
QCOMPARE(output, expectedOutput);
diff --git a/tests/auto/gui/text/qtextobject/CMakeLists.txt b/tests/auto/gui/text/qtextobject/CMakeLists.txt
index a5d10f3d4f..dd7aeae60e 100644
--- a/tests/auto/gui/text/qtextobject/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextobject/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qtextobject Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextobject LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtextobject
SOURCES
tst_qtextobject.cpp
diff --git a/tests/auto/gui/text/qtextobject/tst_qtextobject.cpp b/tests/auto/gui/text/qtextobject/tst_qtextobject.cpp
index 8a84dfd40c..e75dfcb270 100644
--- a/tests/auto/gui/text/qtextobject/tst_qtextobject.cpp
+++ b/tests/auto/gui/text/qtextobject/tst_qtextobject.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>
diff --git a/tests/auto/gui/text/qtextodfwriter/CMakeLists.txt b/tests/auto/gui/text/qtextodfwriter/CMakeLists.txt
index 86134f02eb..d371fe2ee1 100644
--- a/tests/auto/gui/text/qtextodfwriter/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextodfwriter/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qtextodfwriter Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextodfwriter LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtextodfwriter
SOURCES
tst_qtextodfwriter.cpp
diff --git a/tests/auto/gui/text/qtextodfwriter/tst_qtextodfwriter.cpp b/tests/auto/gui/text/qtextodfwriter/tst_qtextodfwriter.cpp
index 3ae6046bdb..6b56e7c727 100644
--- a/tests/auto/gui/text/qtextodfwriter/tst_qtextodfwriter.cpp
+++ b/tests/auto/gui/text/qtextodfwriter/tst_qtextodfwriter.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>
#include <QTextDocument>
diff --git a/tests/auto/gui/text/qtextpiecetable/CMakeLists.txt b/tests/auto/gui/text/qtextpiecetable/CMakeLists.txt
index 27c803ca5b..8bdf17890c 100644
--- a/tests/auto/gui/text/qtextpiecetable/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextpiecetable/CMakeLists.txt
@@ -1,6 +1,12 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextpiecetable LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
if(WIN32)
return()
endif()
diff --git a/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp b/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp
index cac84de7e2..f47d5dc0d6 100644
--- a/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp
+++ b/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.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>
@@ -99,21 +99,21 @@ void tst_QTextPieceTable::cleanup()
void tst_QTextPieceTable::insertion1()
{
- table->insert(0, "aacc", charFormatIndex);
+ table->insert(0, u"aacc", charFormatIndex);
QCOMPARE(table->plainText(), QString("aacc"));
- table->insert(2, "bb", charFormatIndex);
+ table->insert(2, u"bb", charFormatIndex);
QCOMPARE(table->plainText(), QString("aabbcc"));
- table->insert(1, "1", charFormatIndex);
+ table->insert(1, u"1", charFormatIndex);
QCOMPARE(table->plainText(), QString("a1abbcc"));
- table->insert(6, "d", charFormatIndex);
+ table->insert(6, u"d", charFormatIndex);
QCOMPARE(table->plainText(), QString("a1abbcdc"));
- table->insert(8, "z", charFormatIndex);
+ table->insert(8, u"z", charFormatIndex);
QCOMPARE(table->plainText(), QString("a1abbcdcz"));
}
void tst_QTextPieceTable::insertion2()
{
- table->insert(0, "bb", charFormatIndex);
+ table->insert(0, u"bb", charFormatIndex);
QCOMPARE(table->plainText(), QString("bb"));
}
@@ -176,21 +176,21 @@ void tst_QTextPieceTable::insertion5()
void tst_QTextPieceTable::removal1()
{
- table->insert(0, "abbccc", charFormatIndex);
+ table->insert(0, u"abbccc", charFormatIndex);
QCOMPARE(table->plainText(), QString("abbccc"));
table->remove(1, 2);
QCOMPARE(table->plainText(), QString("accc"));
- table->insert(1, "1", charFormatIndex);
+ table->insert(1, u"1", charFormatIndex);
QCOMPARE(table->plainText(), QString("a1ccc"));
table->remove(4, 1);
QCOMPARE(table->plainText(), QString("a1cc"));
- table->insert(4, "z", charFormatIndex);
+ table->insert(4, u"z", charFormatIndex);
QCOMPARE(table->plainText(), QString("a1ccz"));
}
void tst_QTextPieceTable::removal2()
{
- table->insert(0, "bb", charFormatIndex);
+ table->insert(0, u"bb", charFormatIndex);
QCOMPARE(table->plainText(), QString("bb"));
table->remove(0, 2);
QCOMPARE(table->plainText(), QString(""));
@@ -199,7 +199,7 @@ void tst_QTextPieceTable::removal2()
table->remove(0, 1);
QCOMPARE(table->plainText(), QString(""));
- table->insert(0, "bb", charFormatIndex);
+ table->insert(0, u"bb", charFormatIndex);
QCOMPARE(table->plainText(), QString("bb"));
table->insertBlock(1, blockFormatIndex, charFormatIndex);
QCOMPARE(table->plainText(), QString("b") + QString(QChar(QChar::ParagraphSeparator)) + QString("b"));
@@ -270,16 +270,16 @@ void tst_QTextPieceTable::removal4()
void tst_QTextPieceTable::undoRedo1()
{
- table->insert(0, "01234567", charFormatIndex);
- table->insert(0, "a", charFormatIndex);
- table->insert(1, "b", charFormatIndex);
+ table->insert(0, u"01234567", charFormatIndex);
+ table->insert(0, u"a", charFormatIndex);
+ table->insert(1, u"b", charFormatIndex);
QCOMPARE(table->plainText(), QString("ab01234567"));
table->undo();
QCOMPARE(table->plainText(), QString("01234567"));
table->redo();
QCOMPARE(table->plainText(), QString("ab01234567"));
table->undo();
- table->insert(1, "c", charFormatIndex);
+ table->insert(1, u"c", charFormatIndex);
QCOMPARE(table->plainText(), QString("0c1234567"));
table->undo();
QCOMPARE(table->plainText(), QString("01234567"));
@@ -289,8 +289,8 @@ void tst_QTextPieceTable::undoRedo1()
void tst_QTextPieceTable::undoRedo2()
{
- table->insert(0, "01", charFormatIndex);
- table->insert(1, "a", charFormatIndex);
+ table->insert(0, u"01", charFormatIndex);
+ table->insert(1, u"a", charFormatIndex);
QCOMPARE(table->plainText(), QString("0a1"));
table->undo();
QCOMPARE(table->plainText(), QString("01"));
@@ -304,8 +304,8 @@ void tst_QTextPieceTable::undoRedo2()
void tst_QTextPieceTable::undoRedo3()
{
- table->insert(0, "01", charFormatIndex);
- table->insert(2, "ab", charFormatIndex);
+ table->insert(0, u"01", charFormatIndex);
+ table->insert(2, u"ab", charFormatIndex);
table->remove(2, 1);
QCOMPARE(table->plainText(), QString("01b"));
table->undo();
@@ -320,8 +320,8 @@ void tst_QTextPieceTable::undoRedo3()
void tst_QTextPieceTable::undoRedo4()
{
- table->insert(0, "01", charFormatIndex);
- table->insert(0, "ab", charFormatIndex);
+ table->insert(0, u"01", charFormatIndex);
+ table->insert(0, u"ab", charFormatIndex);
table->remove(0, 1);
QCOMPARE(table->plainText(), QString("b01"));
table->undo();
@@ -341,7 +341,7 @@ void tst_QTextPieceTable::undoRedo4()
void tst_QTextPieceTable::undoRedo5()
{
table->beginEditBlock();
- table->insert(0, "01", charFormatIndex);
+ table->insert(0, u"01", charFormatIndex);
table->remove(1, 1);
table->endEditBlock();
QCOMPARE(table->plainText(), QString("0"));
@@ -384,8 +384,8 @@ void tst_QTextPieceTable::undoRedo6()
void tst_QTextPieceTable::undoRedo7()
{
- table->insert(0, "a", charFormatIndex);
- table->insert(1, "b", charFormatIndex);
+ table->insert(0, u"a", charFormatIndex);
+ table->insert(1, u"b", charFormatIndex);
QCOMPARE(table->plainText(), QString("ab"));
table->undo();
@@ -394,8 +394,8 @@ void tst_QTextPieceTable::undoRedo7()
void tst_QTextPieceTable::undoRedo8()
{
- table->insert(0, "a", charFormatIndex);
- table->insert(1, "b", charFormatIndex);
+ table->insert(0, u"a", charFormatIndex);
+ table->insert(1, u"b", charFormatIndex);
QCOMPARE(table->plainText(), QString("ab"));
table->remove(0, 1);
@@ -408,8 +408,8 @@ void tst_QTextPieceTable::undoRedo8()
void tst_QTextPieceTable::undoRedo9()
{
- table->insert(0, "a", charFormatIndex);
- table->insert(1, "b", charFormatIndex);
+ table->insert(0, u"a", charFormatIndex);
+ table->insert(1, u"b", charFormatIndex);
QCOMPARE(table->plainText(), QString("ab"));
table->remove(1, 1);
@@ -430,9 +430,9 @@ void tst_QTextPieceTable::undoRedo10()
QTextBlockFormat f;
int idx = table->formatCollection()->indexForFormat(f);
- table->insert(0, "a", cfIdx);
+ table->insert(0, u"a", cfIdx);
table->insertBlock(1, idx, cfIdx);
- table->insert(1, "b", cfIdx);
+ table->insert(1, u"b", cfIdx);
cf.setForeground(Qt::red);
int newCfIdx = table->formatCollection()->indexForFormat(cf);
@@ -485,7 +485,7 @@ void tst_QTextPieceTable::checkDocumentChanged()
// single insert
layout->expect(0, 0, 15);
- table->insert(0, "012345678901234", charFormatIndex);
+ table->insert(0, u"012345678901234", charFormatIndex);
QVERIFY(!layout->error);
// single remove
@@ -496,7 +496,7 @@ void tst_QTextPieceTable::checkDocumentChanged()
// symmetric insert/remove
layout->expect(0, 0, 0);
table->beginEditBlock();
- table->insert(0, "01234", charFormatIndex);
+ table->insert(0, u"01234", charFormatIndex);
table->remove(0, 5);
table->endEditBlock();
QVERIFY(!layout->error);
@@ -504,7 +504,7 @@ void tst_QTextPieceTable::checkDocumentChanged()
layout->expect(0, 5, 5);
table->beginEditBlock();
table->remove(0, 5);
- table->insert(0, "01234", charFormatIndex);
+ table->insert(0, u"01234", charFormatIndex);
table->endEditBlock();
QVERIFY(!layout->error);
@@ -512,13 +512,13 @@ void tst_QTextPieceTable::checkDocumentChanged()
layout->expect(0, 3, 5);
table->beginEditBlock();
table->remove(0, 3);
- table->insert(0, "01234", charFormatIndex);
+ table->insert(0, u"01234", charFormatIndex);
table->endEditBlock();
QVERIFY(!layout->error);
layout->expect(0, 0, 2);
table->beginEditBlock();
- table->insert(0, "01234", charFormatIndex);
+ table->insert(0, u"01234", charFormatIndex);
table->remove(0, 3);
table->endEditBlock();
QVERIFY(!layout->error);
@@ -526,14 +526,14 @@ void tst_QTextPieceTable::checkDocumentChanged()
// insert + remove inside insert block
layout->expect(0, 0, 2);
table->beginEditBlock();
- table->insert(0, "01234", charFormatIndex);
+ table->insert(0, u"01234", charFormatIndex);
table->remove(1, 3);
table->endEditBlock();
QVERIFY(!layout->error);
layout->expect(0, 0, 2);
table->beginEditBlock();
- table->insert(0, "01234", charFormatIndex);
+ table->insert(0, u"01234", charFormatIndex);
table->remove(2, 3);
table->endEditBlock();
QVERIFY(!layout->error);
@@ -541,42 +541,42 @@ void tst_QTextPieceTable::checkDocumentChanged()
// insert + remove partly outside
layout->expect(0, 1, 0);
table->beginEditBlock();
- table->insert(1, "0", charFormatIndex);
+ table->insert(1, u"0", charFormatIndex);
table->remove(0, 2);
table->endEditBlock();
QVERIFY(!layout->error);
layout->expect(0, 1, 1);
table->beginEditBlock();
- table->insert(1, "01", charFormatIndex);
+ table->insert(1, u"01", charFormatIndex);
table->remove(0, 2);
table->endEditBlock();
QVERIFY(!layout->error);
layout->expect(0, 1, 2);
table->beginEditBlock();
- table->insert(1, "012", charFormatIndex);
+ table->insert(1, u"012", charFormatIndex);
table->remove(0, 2);
table->endEditBlock();
QVERIFY(!layout->error);
layout->expect(1, 1, 0);
table->beginEditBlock();
- table->insert(1, "0", charFormatIndex);
+ table->insert(1, u"0", charFormatIndex);
table->remove(1, 2);
table->endEditBlock();
QVERIFY(!layout->error);
layout->expect(1, 1, 1);
table->beginEditBlock();
- table->insert(1, "01", charFormatIndex);
+ table->insert(1, u"01", charFormatIndex);
table->remove(2, 2);
table->endEditBlock();
QVERIFY(!layout->error);
layout->expect(1, 1, 2);
table->beginEditBlock();
- table->insert(1, "012", charFormatIndex);
+ table->insert(1, u"012", charFormatIndex);
table->remove(3, 2);
table->endEditBlock();
QVERIFY(!layout->error);
@@ -584,14 +584,14 @@ void tst_QTextPieceTable::checkDocumentChanged()
// insert + remove non overlapping
layout->expect(0, 1, 1);
table->beginEditBlock();
- table->insert(1, "0", charFormatIndex);
+ table->insert(1, u"0", charFormatIndex);
table->remove(0, 1);
table->endEditBlock();
QVERIFY(!layout->error);
layout->expect(0, 2, 2);
table->beginEditBlock();
- table->insert(2, "1", charFormatIndex);
+ table->insert(2, u"1", charFormatIndex);
table->remove(0, 1);
table->endEditBlock();
QVERIFY(!layout->error);
@@ -599,14 +599,14 @@ void tst_QTextPieceTable::checkDocumentChanged()
layout->expect(0, 2, 2);
table->beginEditBlock();
table->remove(0, 1);
- table->insert(1, "0", charFormatIndex);
+ table->insert(1, u"0", charFormatIndex);
table->endEditBlock();
QVERIFY(!layout->error);
layout->expect(0, 3, 3);
table->beginEditBlock();
table->remove(0, 1);
- table->insert(2, "1", charFormatIndex);
+ table->insert(2, u"1", charFormatIndex);
table->endEditBlock();
@@ -631,9 +631,9 @@ void tst_QTextPieceTable::checkDocumentChanged2()
layout->expect(0, 0, 12);
table->beginEditBlock();
- table->insert(0, "0123", charFormatIndex);
- table->insert(4, "4567", anotherCharFormatIndex);
- table->insert(8, "8901", charFormatIndex);
+ table->insert(0, u"0123", charFormatIndex);
+ table->insert(4, u"4567", anotherCharFormatIndex);
+ table->insert(8, u"8901", charFormatIndex);
table->endEditBlock();
QVERIFY(!layout->error);
@@ -696,7 +696,7 @@ void tst_QTextPieceTable::blockInsertion2()
int pos = 0;
table->insertBlock(pos, blockFormatIndex, charFormatIndex);
pos += 1;
- table->insert(pos, "a", charFormatIndex);
+ table->insert(pos, u"a", charFormatIndex);
pos += 1;
pos -= 1;
@@ -719,11 +719,11 @@ void tst_QTextPieceTable::blockRemoval1()
int idx1 = table->formatCollection()->indexForFormat(fmt1);
int idx2 = table->formatCollection()->indexForFormat(fmt2);
- table->insert(0, "0123", charFormatIndex);
+ table->insert(0, u"0123", charFormatIndex);
table->insertBlock(4, idx1, charFormatIndex);
- table->insert(5, "5678", charFormatIndex);
+ table->insert(5, u"5678", charFormatIndex);
table->insertBlock(9, idx2, charFormatIndex);
- table->insert(10, "0123", charFormatIndex);
+ table->insert(10, u"0123", charFormatIndex);
QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat());
QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat());
@@ -767,11 +767,11 @@ void tst_QTextPieceTable::blockRemoval2()
int idx1 = table->formatCollection()->indexForFormat(fmt1);
int idx2 = table->formatCollection()->indexForFormat(fmt2);
- table->insert(0, "0123", charFormatIndex);
+ table->insert(0, u"0123", charFormatIndex);
table->insertBlock(4, idx1, charFormatIndex);
- table->insert(5, "5678", charFormatIndex);
+ table->insert(5, u"5678", charFormatIndex);
table->insertBlock(9, idx2, charFormatIndex);
- table->insert(10, "0123", charFormatIndex);
+ table->insert(10, u"0123", charFormatIndex);
QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat());
QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat());
@@ -813,11 +813,11 @@ void tst_QTextPieceTable::blockRemoval3()
int idx1 = table->formatCollection()->indexForFormat(fmt1);
int idx2 = table->formatCollection()->indexForFormat(fmt2);
- table->insert(0, "0123", charFormatIndex);
+ table->insert(0, u"0123", charFormatIndex);
table->insertBlock(4, idx1, charFormatIndex);
- table->insert(5, "5678", charFormatIndex);
+ table->insert(5, u"5678", charFormatIndex);
table->insertBlock(9, idx2, charFormatIndex);
- table->insert(10, "0123", charFormatIndex);
+ table->insert(10, u"0123", charFormatIndex);
QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat());
QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat());
@@ -910,11 +910,11 @@ void tst_QTextPieceTable::blockRemoval5()
int idx1 = table->formatCollection()->indexForFormat(fmt1);
int idx2 = table->formatCollection()->indexForFormat(fmt2);
- table->insert(0, "0123", charFormatIndex);
+ table->insert(0, u"0123", charFormatIndex);
table->insertBlock(4, idx1, charFormatIndex);
- table->insert(5, "5678", charFormatIndex);
+ table->insert(5, u"5678", charFormatIndex);
table->insertBlock(9, idx2, charFormatIndex);
- table->insert(10, "0123", charFormatIndex);
+ table->insert(10, u"0123", charFormatIndex);
QCOMPARE(table->blocksFind(0).blockFormat(), QTextBlockFormat());
QCOMPARE(table->blocksFind(4).blockFormat(), QTextBlockFormat());
@@ -962,7 +962,7 @@ void tst_QTextPieceTable::checkBlockSeparation()
void tst_QTextPieceTable::checkFrames1()
{
QTextFrameFormat ffmt;
- table->insert(0, "Hello", charFormatIndex);
+ table->insert(0, u"Hello", charFormatIndex);
QPointer<QTextFrame> frame = table->insertFrame(1, 3, ffmt);
QTextFrame *root = table->rootFrame();
@@ -1031,7 +1031,7 @@ void tst_QTextPieceTable::checkFrames1()
void tst_QTextPieceTable::removeFrameDirect()
{
QTextFrameFormat ffmt;
- table->insert(0, "Hello", charFormatIndex);
+ table->insert(0, u"Hello", charFormatIndex);
QTextFrame *frame = table->insertFrame(1, 5, ffmt);
@@ -1065,7 +1065,7 @@ void tst_QTextPieceTable::removeWithChildFrame()
In this case frameAt(2) != frameAt(6), so the assertion in remove() needed an adjustement.
*/
QTextFrameFormat ffmt;
- table->insert(0, "Hello World", charFormatIndex);
+ table->insert(0, u"Hello World", charFormatIndex);
QTextFrame *frame = table->insertFrame(1, 6, ffmt);
QTextFrame *childFrame = table->insertFrame(3, 5, ffmt);
@@ -1095,7 +1095,7 @@ void tst_QTextPieceTable::clearWithFrames()
The idea is to remove from [1] until [7].
*/
QTextFrameFormat ffmt;
- table->insert(0, "Hello World", charFormatIndex);
+ table->insert(0, u"Hello World", charFormatIndex);
QTextFrame *firstFrame = table->insertFrame(1, 2, ffmt);
QTextFrame *secondFrame = table->insertFrame(4, 6, ffmt);
diff --git a/tests/auto/gui/text/qtextscriptengine/CMakeLists.txt b/tests/auto/gui/text/qtextscriptengine/CMakeLists.txt
index 9307e01b85..9bb9e4c13b 100644
--- a/tests/auto/gui/text/qtextscriptengine/CMakeLists.txt
+++ b/tests/auto/gui/text/qtextscriptengine/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qtextscriptengine Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextscriptengine LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtextscriptengine
SOURCES
tst_qtextscriptengine.cpp
diff --git a/tests/auto/gui/text/qtextscriptengine/generate/main.cpp b/tests/auto/gui/text/qtextscriptengine/generate/main.cpp
index fa0512fb50..5082c2b406 100644
--- a/tests/auto/gui/text/qtextscriptengine/generate/main.cpp
+++ b/tests/auto/gui/text/qtextscriptengine/generate/main.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 <QApplication>
diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
index d3267d024b..975658005e 100644
--- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
+++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.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>
#include <private/qfontengine_p.h>
@@ -56,9 +56,6 @@ private slots:
void shapingDisabledDevanagari();
void shapingDisabledLatin();
-
- void privateUseArea();
-
private:
bool haveTestFonts;
};
@@ -1097,11 +1094,12 @@ void tst_QTextScriptEngine::combiningMarks_qtbug15675_data()
bool hasTests = false;
- QStringList families;
- families << QStringLiteral("Monaco");
- families << QStringLiteral("DejaVu Sans Mono");
+ const QString families[] = {
+ QStringLiteral("Monaco"),
+ QStringLiteral("DejaVu Sans Mono"),
+ };
- foreach (const QString &family, families) {
+ for (const QString &family : families) {
QFont font(family);
font.setStyleStrategy(QFont::NoFontMerging);
if (QFontInfo(font).family() != family)
@@ -1315,41 +1313,5 @@ void tst_QTextScriptEngine::shapingDisabledDevanagari()
QCOMPARE(noShapingRuns.first().glyphIndexes().size(), normalRuns.first().glyphIndexes().size());
}
-void tst_QTextScriptEngine::privateUseArea()
-{
- QString privateUseAreaString = QString::fromUtf8("");
-
- QFont font;
- QList<QGlyphRun> withFontMerging;
- {
- QTextLayout layout;
- layout.setText(privateUseAreaString);
- layout.setFont(font);
- layout.beginLayout();
- layout.createLine();
- layout.endLayout();
-
- withFontMerging = layout.glyphRuns();
- }
-
- font.setStyleStrategy(QFont::NoFontMerging);
- QList<QGlyphRun> withoutFontMerging;
- {
- QTextLayout layout;
- layout.setText(privateUseAreaString);
- layout.setFont(font);
- layout.beginLayout();
- layout.createLine();
- layout.endLayout();
-
- withoutFontMerging = layout.glyphRuns();
- }
-
- QCOMPARE(withFontMerging.size(), withoutFontMerging.size());
-
- for (int i = 0; i < withFontMerging.size(); ++i)
- QCOMPARE(withFontMerging.at(i).glyphIndexes(), withoutFontMerging.at(i).glyphIndexes());
-}
-
QTEST_MAIN(tst_QTextScriptEngine)
#include "tst_qtextscriptengine.moc"
diff --git a/tests/auto/gui/text/qtexttable/CMakeLists.txt b/tests/auto/gui/text/qtexttable/CMakeLists.txt
index 5b23903ffc..e83a38f087 100644
--- a/tests/auto/gui/text/qtexttable/CMakeLists.txt
+++ b/tests/auto/gui/text/qtexttable/CMakeLists.txt
@@ -5,6 +5,12 @@
## tst_qtexttable Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtexttable LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtexttable
SOURCES
tst_qtexttable.cpp
diff --git a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
index ae5502852c..a7e319ef62 100644
--- a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
+++ b/tests/auto/gui/text/qtexttable/tst_qtexttable.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>
@@ -75,6 +75,8 @@ private slots:
#endif
void checkBorderAttributes_data();
void checkBorderAttributes();
+ void checkTableBorderAttributes_data();
+ void checkTableBorderAttributes();
#ifndef QT_NO_WIDGETS
void columnWidthWithSpans();
@@ -1234,6 +1236,7 @@ void tst_QTextTable::checkBorderAttributes()
QFETCH(QBrush, leftBorderBrush);
QFETCH(QBrush, rightBorderBrush);
+#ifndef QT_NO_TEXTHTMLPARSER
QTextDocument doc;
doc.setHtml(html);
QTextCursor cursor(doc.firstBlock());
@@ -1259,6 +1262,75 @@ void tst_QTextTable::checkBorderAttributes()
QCOMPARE(cellFormat.brushProperty(QTextFormat::TableCellRightBorderBrush), rightBorderBrush);
}
}
+#endif
+}
+
+void tst_QTextTable::checkTableBorderAttributes_data()
+{
+ QTest::addColumn<QString>("html");
+ QTest::addColumn<qreal>("tableBorderWidth");
+ QTest::addColumn<QTextFrameFormat::BorderStyle>("tableBorderStyle");
+ QTest::addColumn<QBrush>("tableBorderBrush");
+
+ const QString tableHtmlStart = QStringLiteral("<html><head><style>");
+ const QString tableHtmlEnd1 = QStringLiteral("</style></head><body>"
+ "<table><tr><td>One</td><td>Two</td></tr></table>"
+ "</body></html>");
+ const QString tableHtmlEnd2 = QStringLiteral("</style></head><body>"
+ "<table border=10><tr><td>One</td><td>Two</td></tr></table>"
+ "</body></html>");
+
+ QTest::newRow("table-border-attributes-shorthand")
+ << QString("%1"
+ "table {"
+ "border: 2px solid red;"
+ "}"
+ "%2").arg(tableHtmlStart).arg(tableHtmlEnd1)
+ << 2.0 << QTextFrameFormat::BorderStyle_Solid << QBrush(Qt::red);
+
+ QTest::newRow("table-border-attributes-explicit")
+ << QString("%1"
+ "table {"
+ "border-width: 2px;"
+ "border-color: red;"
+ "border-style: dashed;"
+ "}"
+ "%2").arg(tableHtmlStart).arg(tableHtmlEnd1)
+ << 2.0 << QTextFrameFormat::BorderStyle_Dashed << QBrush(Qt::red);
+
+ QTest::newRow("table-border-override")
+ << QString("%1"
+ "table {"
+ "border: 2px solid red;"
+ "}"
+ "%2").arg(tableHtmlStart).arg(tableHtmlEnd2)
+ << 2.0 << QTextFrameFormat::BorderStyle_Solid << QBrush(Qt::red);
+
+ QTest::newRow("table-border-default")
+ << QString("%1"
+ "%2").arg(tableHtmlStart).arg(tableHtmlEnd2)
+ << 10.0 << QTextFrameFormat::BorderStyle_Outset << QBrush(Qt::darkGray);
+}
+
+void tst_QTextTable::checkTableBorderAttributes()
+{
+ QFETCH(QString, html);
+ QFETCH(qreal, tableBorderWidth);
+ QFETCH(QTextFrameFormat::BorderStyle, tableBorderStyle);
+ QFETCH(QBrush, tableBorderBrush);
+
+#ifndef QT_NO_TEXTHTMLPARSER
+ QTextDocument doc;
+ doc.setHtml(html);
+ QTextCursor cursor(doc.firstBlock());
+ cursor.movePosition(QTextCursor::Right);
+
+ QTextTable *currentTable = cursor.currentTable();
+ QVERIFY(currentTable);
+ QCOMPARE(currentTable->format().border(), tableBorderWidth);
+ QCOMPARE(currentTable->format().borderStyle(), tableBorderStyle);
+ QCOMPARE(currentTable->format().borderBrush(), tableBorderBrush);
+#endif
}
#ifndef QT_NO_WIDGETS
@@ -1317,6 +1389,7 @@ void tst_QTextTable::columnWidthWithImage()
QFETCH(QString, rightHtml);
QFETCH(QSize, imageSize);
+#ifndef QT_NO_TEXTHTMLPARSER
QTextDocument doc;
doc.setHtml(tableTemplate.arg(leftHtml).arg(rightHtml));
QTextEdit textEdit;
@@ -1336,6 +1409,7 @@ void tst_QTextTable::columnWidthWithImage()
const QRectF rightRect = currentTable->document()->documentLayout()->blockBoundingRect(block);
QCOMPARE(leftRect.size().toSize(), imageSize);
QVERIFY(rightRect.left() > leftRect.right());
+#endif
}
#endif
diff --git a/tests/auto/gui/text/qzip/.gitignore b/tests/auto/gui/text/qzip/.gitignore
deleted file mode 100644
index 2d7dfbe70c..0000000000
--- a/tests/auto/gui/text/qzip/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-tst_qzip
diff --git a/tests/auto/gui/text/qzip/CMakeLists.txt b/tests/auto/gui/text/qzip/CMakeLists.txt
deleted file mode 100644
index 73bf0fda7f..0000000000
--- a/tests/auto/gui/text/qzip/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
-
-#####################################################################
-## tst_qzip Test:
-#####################################################################
-
-# Collect test data
-file(GLOB_RECURSE test_data
- RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
- testdata/*
-)
-
-qt_internal_add_test(tst_qzip
- SOURCES
- tst_qzip.cpp
- LIBRARIES
- Qt::Gui
- Qt::GuiPrivate
- TESTDATA ${test_data}
-)
diff --git a/tests/auto/gui/text/qzip/testdata/symlink.zip b/tests/auto/gui/text/qzip/testdata/symlink.zip
deleted file mode 100644
index 027f96477a..0000000000
--- a/tests/auto/gui/text/qzip/testdata/symlink.zip
+++ /dev/null
Binary files differ
diff --git a/tests/auto/gui/text/qzip/testdata/test.zip b/tests/auto/gui/text/qzip/testdata/test.zip
deleted file mode 100644
index a57ba4e2a9..0000000000
--- a/tests/auto/gui/text/qzip/testdata/test.zip
+++ /dev/null
Binary files differ
diff --git a/tests/auto/gui/text/qzip/tst_qzip.cpp b/tests/auto/gui/text/qzip/tst_qzip.cpp
deleted file mode 100644
index 3e2dc39983..0000000000
--- a/tests/auto/gui/text/qzip/tst_qzip.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include <QTest>
-#include <QDebug>
-#include <QBuffer>
-
-#include <private/qzipwriter_p.h>
-#include <private/qzipreader_p.h>
-
-class tst_QZip : public QObject
-{
- Q_OBJECT
-
-private slots:
- void basicUnpack();
- void symlinks();
- void readTest();
- void createArchive();
-};
-
-void tst_QZip::basicUnpack()
-{
- QZipReader zip(QFINDTESTDATA("/testdata/test.zip"), QIODevice::ReadOnly);
- QList<QZipReader::FileInfo> files = zip.fileInfoList();
- QCOMPARE(files.size(), 2);
-
- QZipReader::FileInfo fi = files.at(0);
- QVERIFY(fi.isValid());
- QCOMPARE(fi.filePath, QString("test"));
- QCOMPARE(uint(fi.isDir), (uint) 1);
- QCOMPARE(uint(fi.isFile), (uint) 0);
- QCOMPARE(uint(fi.isSymLink), (uint) 0);
-
- QCOMPARE(fi.permissions,QFile::Permissions( QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner
- | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser ));
-
- QCOMPARE(fi.lastModified, QDateTime::fromString("2005.11.11 13:08:02", "yyyy.MM.dd HH:mm:ss"));
-
- fi = files.at(1);
- QVERIFY(fi.isValid());
- QCOMPARE(fi.filePath, QString("test/test.txt"));
- QCOMPARE(uint(fi.isDir), (uint) 0);
- QCOMPARE(uint(fi.isFile), (uint) 1);
- QCOMPARE(uint(fi.isSymLink), (uint) 0);
-
- QVERIFY(fi.permissions == QFile::Permissions( QFile::ReadOwner | QFile::WriteOwner
- | QFile::ReadUser | QFile::WriteUser ));
-
- QCOMPARE(fi.lastModified, QDateTime::fromString("2005.11.11 13:08:02", "yyyy.MM.dd HH:mm:ss"));
-
- QCOMPARE(zip.fileData("test/test.txt"), QByteArray("content\n"));
-
- fi = zip.entryInfoAt(-1);
- QVERIFY(!fi.isValid());
-}
-
-void tst_QZip::symlinks()
-{
- QZipReader zip(QFINDTESTDATA("/testdata/symlink.zip"), QIODevice::ReadOnly);
- QList<QZipReader::FileInfo> files = zip.fileInfoList();
- QCOMPARE(files.size(), 2);
-
- QZipReader::FileInfo fi = files.at(0);
- QVERIFY(fi.isValid());
- QCOMPARE(fi.filePath, QString("symlink"));
- QVERIFY(!fi.isDir);
- QVERIFY(!fi.isFile);
- QVERIFY(fi.isSymLink);
-
- QCOMPARE(zip.fileData("symlink"), QByteArray("destination"));
-
- fi = files.at(1);
- QVERIFY(fi.isValid());
- QCOMPARE(fi.filePath, QString("destination"));
- QVERIFY(!fi.isDir);
- QVERIFY(fi.isFile);
- QVERIFY(!fi.isSymLink);
-}
-
-void tst_QZip::readTest()
-{
- QZipReader zip("foobar.zip", QIODevice::ReadOnly); // non existing file.
- QList<QZipReader::FileInfo> files = zip.fileInfoList();
- QCOMPARE(files.size(), 0);
- QByteArray b = zip.fileData("foobar");
- QCOMPARE(b.size(), 0);
-}
-
-void tst_QZip::createArchive()
-{
- QBuffer buffer;
- QZipWriter zip(&buffer);
- QByteArray fileContents("simple file contents\nline2\n");
- zip.addFile("My Filename", fileContents);
- zip.close();
- QByteArray zipFile = buffer.buffer();
-
- // QFile f("createArchiveTest.zip"); f.open(QIODevice::WriteOnly); f.write(zipFile); f.close();
-
- QBuffer buffer2(&zipFile);
- QZipReader zip2(&buffer2);
- QList<QZipReader::FileInfo> files = zip2.fileInfoList();
- QCOMPARE(files.size(), 1);
- QZipReader::FileInfo file = files.at(0);
- QCOMPARE(file.filePath, QString("My Filename"));
- QCOMPARE(uint(file.isDir), (uint) 0);
- QCOMPARE(uint(file.isFile), (uint) 1);
- QCOMPARE(uint(file.isSymLink), (uint) 0);
- QCOMPARE(file.permissions, QFile::Permissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser) );
- QCOMPARE(file.size, (long long) 27);
- QCOMPARE(zip2.fileData("My Filename"), fileContents);
-}
-
-QTEST_MAIN(tst_QZip)
-#include "tst_qzip.moc"