diff options
Diffstat (limited to 'tests/auto/gui/text')
76 files changed, 2554 insertions, 709 deletions
diff --git a/tests/auto/gui/text/CMakeLists.txt b/tests/auto/gui/text/CMakeLists.txt index 5040060a33..bad13de7dc 100644 --- a/tests/auto/gui/text/CMakeLists.txt +++ b/tests/auto/gui/text/CMakeLists.txt @@ -1,4 +1,5 @@ -# Generated from text.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause add_subdirectory(qabstracttextdocumentlayout) add_subdirectory(qfont) @@ -13,9 +14,10 @@ add_subdirectory(qtextcursor) add_subdirectory(qtextdocumentfragment) add_subdirectory(qtextdocumentlayout) add_subdirectory(qtextformat) +add_subdirectory(qtextimagehandler) add_subdirectory(qtextlist) add_subdirectory(qtextobject) -# add_subdirectory(qtextscriptengine) # disable until system_harfbuzz feature is available # special case +# add_subdirectory(qtextscriptengine) # disable until system_harfbuzz feature is available add_subdirectory(qtexttable) add_subdirectory(qinputcontrol) if(QT_FEATURE_private_tests AND TARGET Qt::Xml) @@ -24,7 +26,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 f78e1d81c7..316b9cd3c6 100644 --- a/tests/auto/gui/text/qabstracttextdocumentlayout/CMakeLists.txt +++ b/tests/auto/gui/text/qabstracttextdocumentlayout/CMakeLists.txt @@ -1,12 +1,19 @@ -# Generated from qabstracttextdocumentlayout.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui ) diff --git a/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp b/tests/auto/gui/text/qabstracttextdocumentlayout/tst_qabstracttextdocumentlayout.cpp index 4ab2d1adb3..2ae2ccda0a 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> @@ -126,7 +126,7 @@ void tst_QAbstractTextDocumentLayout::anchorAt() QAbstractTextDocumentLayout *documentLayout = doc.documentLayout(); QTextBlock firstBlock = doc.begin(); QTextLayout *layout = firstBlock.layout(); - layout->setPreeditArea(doc.toPlainText().length(), "xxx"); + layout->setPreeditArea(doc.toPlainText().size(), "xxx"); doc.setPageSize(QSizeF(1000, 1000)); QFontMetrics metrics(layout->font()); @@ -156,7 +156,7 @@ void tst_QAbstractTextDocumentLayout::imageAt() QAbstractTextDocumentLayout *documentLayout = doc.documentLayout(); QTextBlock firstBlock = doc.begin(); QTextLayout *layout = firstBlock.layout(); - layout->setPreeditArea(doc.toPlainText().length(), "xxx"); + layout->setPreeditArea(doc.toPlainText().size(), "xxx"); doc.setPageSize(QSizeF(1000, 1000)); QFontMetrics metrics(layout->font()); @@ -181,7 +181,7 @@ void tst_QAbstractTextDocumentLayout::formatAt() QAbstractTextDocumentLayout *documentLayout = doc.documentLayout(); QTextBlock firstBlock = doc.begin(); QTextLayout *layout = firstBlock.layout(); - layout->setPreeditArea(doc.toPlainText().length(), "xxx"); + layout->setPreeditArea(doc.toPlainText().size(), "xxx"); doc.setPageSize(QSizeF(1000, 1000)); QFontMetrics metrics(layout->font()); diff --git a/tests/auto/gui/text/qcssparser/CMakeLists.txt b/tests/auto/gui/text/qcssparser/CMakeLists.txt index bd9ca00d60..e766ec5484 100644 --- a/tests/auto/gui/text/qcssparser/CMakeLists.txt +++ b/tests/auto/gui/text/qcssparser/CMakeLists.txt @@ -1,9 +1,16 @@ -# Generated from qcssparser.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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} @@ -13,7 +20,7 @@ file(GLOB_RECURSE test_data qt_internal_add_test(tst_qcssparser SOURCES tst_qcssparser.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui Qt::GuiPrivate Qt::Xml diff --git a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp index 3b20068f17..a438d7ebc8 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> @@ -69,7 +70,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" @@ -126,7 +128,7 @@ static const char *tokenName(QCss::TokenType t) static void debug(const QList<QCss::Symbol> &symbols, int index = -1) { qDebug() << "all symbols:"; - for (int i = 0; i < symbols.count(); ++i) + for (int i = 0; i < symbols.size(); ++i) qDebug() << '(' << i << "); Token:" << tokenName(symbols.at(i).token) << "; Lexem:" << symbols.at(i).lexem(); if (index != -1) qDebug() << "failure at index" << index; @@ -144,10 +146,10 @@ void tst_QCssParser::scanner() QList<QCss::Symbol> symbols; QCss::Scanner::scan(QCss::Scanner::preprocess(QString::fromUtf8(inputFile.readAll())), &symbols); - QVERIFY(symbols.count() > 1); + QVERIFY(symbols.size() > 1); QCOMPARE(symbols.last().token, QCss::S); QCOMPARE(symbols.last().lexem(), QLatin1String("\n")); - symbols.remove(symbols.count() - 1, 1); + symbols.remove(symbols.size() - 1, 1); QFile outputFile(output); QVERIFY(outputFile.open(QIODevice::ReadOnly|QIODevice::Text)); @@ -159,14 +161,14 @@ void tst_QCssParser::scanner() lines.append(line); } - if (lines.count() != symbols.count()) { + if (lines.size() != symbols.size()) { debug(symbols); - QCOMPARE(lines.count(), symbols.count()); + QCOMPARE(lines.size(), symbols.size()); } - for (int i = 0; i < lines.count(); ++i) { + for (int i = 0; i < lines.size(); ++i) { QStringList l = lines.at(i).split(QChar::fromLatin1('|')); - QCOMPARE(l.count(), 2); + QCOMPARE(l.size(), 2); const QString expectedToken = l.at(0); const QString expectedLexem = l.at(1); QString actualToken = QString::fromLatin1(tokenName(symbols.at(i).token)); @@ -350,9 +352,9 @@ void tst_QCssParser::expr() QVERIFY(parser.testExpr()); QCOMPARE(parser.parseExpr(&values), parseSuccess); if (parseSuccess) { - QCOMPARE(values.count(), expectedValues.count()); + QCOMPARE(values.size(), expectedValues.size()); - for (int i = 0; i < values.count(); ++i) { + for (int i = 0; i < values.size(); ++i) { QCOMPARE(int(values.at(i).type), int(expectedValues.at(i).type)); QCOMPARE(values.at(i).variant, expectedValues.at(i).variant); } @@ -371,7 +373,7 @@ void tst_QCssParser::import() QVERIFY(parser.testImport()); QVERIFY(parser.parseImport(&rule)); QCOMPARE(rule.href, QString("www.kde.org")); - QCOMPARE(rule.media.count(), 2); + QCOMPARE(rule.media.size(), 2); QCOMPARE(rule.media.at(0), QString("print")); QCOMPARE(rule.media.at(1), QString("screen")); } @@ -382,7 +384,7 @@ void tst_QCssParser::media() QVERIFY(parser.testMedia()); QCss::MediaRule rule; QVERIFY(parser.parseMedia(&rule)); - QCOMPARE(rule.media.count(), 2); + QCOMPARE(rule.media.size(), 2); QCOMPARE(rule.media.at(0), QString("print")); QCOMPARE(rule.media.at(1), QString("screen")); QVERIFY(rule.styleRules.isEmpty()); @@ -405,8 +407,8 @@ void tst_QCssParser::ruleset() QVERIFY(parser.testRuleset()); QCss::StyleRule rule; QVERIFY(parser.parseRuleset(&rule)); - QCOMPARE(rule.selectors.count(), 1); - QCOMPARE(rule.selectors.at(0).basicSelectors.count(), 1); + QCOMPARE(rule.selectors.size(), 1); + QCOMPARE(rule.selectors.at(0).basicSelectors.size(), 1); QCOMPARE(rule.selectors.at(0).basicSelectors.at(0).elementName, QString("p")); QVERIFY(rule.declarations.isEmpty()); } @@ -416,10 +418,10 @@ void tst_QCssParser::ruleset() QVERIFY(parser.testRuleset()); QCss::StyleRule rule; QVERIFY(parser.parseRuleset(&rule)); - QCOMPARE(rule.selectors.count(), 2); - QCOMPARE(rule.selectors.at(0).basicSelectors.count(), 1); + QCOMPARE(rule.selectors.size(), 2); + QCOMPARE(rule.selectors.at(0).basicSelectors.size(), 1); QCOMPARE(rule.selectors.at(0).basicSelectors.at(0).elementName, QString("p")); - QCOMPARE(rule.selectors.at(1).basicSelectors.count(), 1); + QCOMPARE(rule.selectors.at(1).basicSelectors.size(), 1); QCOMPARE(rule.selectors.at(1).basicSelectors.at(0).elementName, QString("div")); QVERIFY(rule.declarations.isEmpty()); } @@ -429,14 +431,14 @@ void tst_QCssParser::ruleset() QVERIFY(parser.testRuleset()); QCss::StyleRule rule; QVERIFY(parser.parseRuleset(&rule)); - QCOMPARE(rule.selectors.count(), 2); + QCOMPARE(rule.selectors.size(), 2); - QCOMPARE(rule.selectors.at(0).basicSelectors.count(), 1); - QCOMPARE(rule.selectors.at(0).basicSelectors.at(0).pseudos.count(), 1); + QCOMPARE(rule.selectors.at(0).basicSelectors.size(), 1); + QCOMPARE(rule.selectors.at(0).basicSelectors.at(0).pseudos.size(), 1); QCOMPARE(rule.selectors.at(0).basicSelectors.at(0).pseudos.at(0).name, QString("before")); - QCOMPARE(rule.selectors.at(1).basicSelectors.count(), 1); - QCOMPARE(rule.selectors.at(1).basicSelectors.at(0).pseudos.count(), 1); + QCOMPARE(rule.selectors.at(1).basicSelectors.size(), 1); + QCOMPARE(rule.selectors.at(1).basicSelectors.at(0).pseudos.size(), 1); QCOMPARE(rule.selectors.at(1).basicSelectors.at(0).pseudos.at(0).name, QString("after")); QVERIFY(rule.declarations.isEmpty()); @@ -688,21 +690,21 @@ void tst_QCssParser::selector() QCss::Selector selector; QVERIFY(parser.parseSelector(&selector)); - QCOMPARE(selector.basicSelectors.count(), expectedSelector.basicSelectors.count()); - for (int i = 0; i < selector.basicSelectors.count(); ++i) { + QCOMPARE(selector.basicSelectors.size(), expectedSelector.basicSelectors.size()); + for (int i = 0; i < selector.basicSelectors.size(); ++i) { const QCss::BasicSelector sel = selector.basicSelectors.at(i); const QCss::BasicSelector expectedSel = expectedSelector.basicSelectors.at(i); QCOMPARE(sel.elementName, expectedSel.elementName); QCOMPARE(int(sel.relationToNext), int(expectedSel.relationToNext)); - QCOMPARE(sel.pseudos.count(), expectedSel.pseudos.count()); - for (int i = 0; i < sel.pseudos.count(); ++i) { + QCOMPARE(sel.pseudos.size(), expectedSel.pseudos.size()); + for (int i = 0; i < sel.pseudos.size(); ++i) { QCOMPARE(sel.pseudos.at(i).name, expectedSel.pseudos.at(i).name); QCOMPARE(sel.pseudos.at(i).function, expectedSel.pseudos.at(i).function); } - QCOMPARE(sel.attributeSelectors.count(), expectedSel.attributeSelectors.count()); - for (int i = 0; i < sel.attributeSelectors.count(); ++i) { + QCOMPARE(sel.attributeSelectors.size(), expectedSel.attributeSelectors.size()); + for (int i = 0; i < sel.attributeSelectors.size(); ++i) { QCOMPARE(sel.attributeSelectors.at(i).name, expectedSel.attributeSelectors.at(i).name); QCOMPARE(sel.attributeSelectors.at(i).value, expectedSel.attributeSelectors.at(i).value); QCOMPARE(int(sel.attributeSelectors.at(i).valueMatchCriterium), int(expectedSel.attributeSelectors.at(i).valueMatchCriterium)); @@ -760,13 +762,13 @@ void tst_QCssParser::malformedDeclarations() QCss::StyleRule rule; QVERIFY(parser.parseRuleset(&rule)); - QCOMPARE(rule.selectors.count(), 1); - QCOMPARE(rule.selectors.at(0).basicSelectors.count(), 1); + QCOMPARE(rule.selectors.size(), 1); + QCOMPARE(rule.selectors.at(0).basicSelectors.size(), 1); QCOMPARE(rule.selectors.at(0).basicSelectors.at(0).elementName, QString("p")); - QVERIFY(rule.declarations.count() >= 1); + QVERIFY(rule.declarations.size() >= 1); QCOMPARE(int(rule.declarations.last().d->propertyId), int(QCss::Color)); - QCOMPARE(rule.declarations.last().d->values.count(), 1); + QCOMPARE(rule.declarations.last().d->values.size(), 1); QCOMPARE(int(rule.declarations.last().d->values.at(0).type), int(QCss::Value::Identifier)); QCOMPARE(rule.declarations.last().d->values.at(0).variant.toString(), QString("green")); } @@ -786,17 +788,17 @@ void tst_QCssParser::invalidAtKeywords() QCss::StyleSheet sheet; QVERIFY(parser.parse(&sheet)); - QCOMPARE(sheet.styleRules.count() + sheet.nameIndex.count(), 1); + QCOMPARE(sheet.styleRules.size() + sheet.nameIndex.size(), 1); QCss::StyleRule rule = (!sheet.styleRules.isEmpty()) ? sheet.styleRules.at(0) : *sheet.nameIndex.begin(); - QCOMPARE(rule.selectors.count(), 1); - QCOMPARE(rule.selectors.at(0).basicSelectors.count(), 1); + QCOMPARE(rule.selectors.size(), 1); + QCOMPARE(rule.selectors.at(0).basicSelectors.size(), 1); QCOMPARE(rule.selectors.at(0).basicSelectors.at(0).elementName, QString("h1")); - QCOMPARE(rule.declarations.count(), 1); + QCOMPARE(rule.declarations.size(), 1); QCOMPARE(int(rule.declarations.at(0).d->propertyId), int(QCss::Color)); - QCOMPARE(rule.declarations.at(0).d->values.count(), 1); + QCOMPARE(rule.declarations.at(0).d->values.size(), 1); QCOMPARE(int(rule.declarations.at(0).d->values.at(0).type), int(QCss::Value::Identifier)); QCOMPARE(rule.declarations.at(0).d->values.at(0).variant.toString(), QString("blue")); } @@ -1141,9 +1143,9 @@ void tst_QCssParser::styleSelector() QList<QCss::Declaration> decls = testSelector.declarationsForNode(n); if (match) { - QCOMPARE(decls.count(), 1); + QCOMPARE(decls.size(), 1); QCOMPARE(int(decls.at(0).d->propertyId), int(QCss::BackgroundColor)); - QCOMPARE(decls.at(0).d->values.count(), 1); + QCOMPARE(decls.at(0).d->values.size(), 1); QCOMPARE(int(decls.at(0).d->values.at(0).type), int(QCss::Value::Identifier)); QCOMPARE(decls.at(0).d->values.at(0).variant.toString(), QString("green")); } else { @@ -1183,11 +1185,11 @@ void tst_QCssParser::specificity() QCss::StyleSheet sheet; QVERIFY(parser.parse(&sheet)); - QCOMPARE(sheet.styleRules.count() + sheet.nameIndex.count() + sheet.idIndex.count() , 1); + QCOMPARE(sheet.styleRules.size() + sheet.nameIndex.size() + sheet.idIndex.size() , 1); QCss::StyleRule rule = (!sheet.styleRules.isEmpty()) ? sheet.styleRules.at(0) : (!sheet.nameIndex.isEmpty()) ? *sheet.nameIndex.begin() : *sheet.idIndex.begin(); - QCOMPARE(rule.selectors.count(), 1); + QCOMPARE(rule.selectors.size(), 1); QTEST(rule.selectors.at(0).specificity(), "specificity"); } @@ -1236,15 +1238,15 @@ void tst_QCssParser::specificitySort() n.ptr = &e; QList<QCss::Declaration> decls = testSelector.declarationsForNode(n); - QCOMPARE(decls.count(), 2); + QCOMPARE(decls.size(), 2); QCOMPARE(int(decls.at(0).d->propertyId), int(QCss::Color)); - QCOMPARE(decls.at(0).d->values.count(), 1); + QCOMPARE(decls.at(0).d->values.size(), 1); QCOMPARE(int(decls.at(0).d->values.at(0).type), int(QCss::Value::Identifier)); QCOMPARE(decls.at(0).d->values.at(0).variant.toString(), QString("green")); QCOMPARE(int(decls.at(1).d->propertyId), int(QCss::Color)); - QCOMPARE(decls.at(1).d->values.count(), 1); + QCOMPARE(decls.at(1).d->values.size(), 1); QCOMPARE(int(decls.at(1).d->values.at(0).type), int(QCss::Value::Identifier)); QCOMPARE(decls.at(1).d->values.at(0).variant.toString(), QString("red")); } @@ -1319,7 +1321,7 @@ void tst_QCssParser::rulesForNode() QList<QCss::StyleRule> rules = testSelector.styleRulesForNode(n); QList<QCss::Declaration> decls; - for (int i = 0; i < rules.count(); i++) { + for (int i = 0; i < rules.size(); i++) { const QCss::Selector &selector = rules.at(i).selectors.at(0); quint64 negated = 0; quint64 cssClass = selector.pseudoClass(&negated); @@ -1328,7 +1330,7 @@ void tst_QCssParser::rulesForNode() decls += rules.at(i).declarations; } - QCOMPARE(decls.count(), declCount); + QCOMPARE(decls.size(), declCount); if (declCount > 0) QCOMPARE(decls.at(0).d->values.at(0).variant.toString(), value0); @@ -1455,14 +1457,14 @@ void tst_QCssParser::pseudoElement() n.ptr = &e; QList<QCss::StyleRule> rules = testSelector.styleRulesForNode(n); QList<QCss::Declaration> decls; - for (int i = 0; i < rules.count(); i++) { + for (int i = 0; i < rules.size(); i++) { const QCss::Selector& selector = rules.at(i).selectors.at(0); if (pseudoElement.compare(selector.pseudoElement(), Qt::CaseInsensitive) != 0) continue; decls += rules.at(i).declarations; } - QCOMPARE(decls.count(), declCount); + QCOMPARE(decls.size(), declCount); } void tst_QCssParser::gradient_data() @@ -1543,20 +1545,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; - QBrush sbg, abg; - QVERIFY(ve.extractPalette(&fg, &sfg, &sbg, &abg)); + 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); @@ -1596,7 +1604,7 @@ void tst_QCssParser::extractFontFamily() QCss::StyleSheet sheet; QVERIFY(parser.parse(&sheet)); - QCOMPARE(sheet.styleRules.count() + sheet.nameIndex.count(), 1); + QCOMPARE(sheet.styleRules.size() + sheet.nameIndex.size(), 1); QCss::StyleRule rule = (!sheet.styleRules.isEmpty()) ? sheet.styleRules.at(0) : *sheet.nameIndex.begin(); @@ -1654,7 +1662,7 @@ void tst_QCssParser::extractBorder() QCss::StyleSheet sheet; QVERIFY(parser.parse(&sheet)); - QCOMPARE(sheet.styleRules.count() + sheet.nameIndex.count(), 1); + QCOMPARE(sheet.styleRules.size() + sheet.nameIndex.size(), 1); QCss::StyleRule rule = (!sheet.styleRules.isEmpty()) ? sheet.styleRules.at(0) : *sheet.nameIndex.begin(); const QList<QCss::Declaration> decls = rule.declarations; @@ -1684,7 +1692,7 @@ void tst_QCssParser::noTextDecoration() QCss::StyleSheet sheet; QVERIFY(parser.parse(&sheet)); - QCOMPARE(sheet.styleRules.count() + sheet.nameIndex.count(), 1); + QCOMPARE(sheet.styleRules.size() + sheet.nameIndex.size(), 1); QCss::StyleRule rule = (!sheet.styleRules.isEmpty()) ? sheet.styleRules.at(0) : *sheet.nameIndex.begin(); const QList<QCss::Declaration> decls = rule.declarations; @@ -1709,7 +1717,7 @@ void tst_QCssParser::quotedAndUnquotedIdentifiers() QCss::StyleSheet sheet; QVERIFY(parser.parse(&sheet)); - QCOMPARE(sheet.styleRules.count() + sheet.nameIndex.count(), 1); + QCOMPARE(sheet.styleRules.size() + sheet.nameIndex.size(), 1); QCss::StyleRule rule = (!sheet.styleRules.isEmpty()) ? sheet.styleRules.at(0) : *sheet.nameIndex.begin(); const QList<QCss::Declaration> decls = rule.declarations; diff --git a/tests/auto/gui/text/qfont/BLACKLIST b/tests/auto/gui/text/qfont/BLACKLIST index e914a7e533..f85d8ceebb 100644 --- a/tests/auto/gui/text/qfont/BLACKLIST +++ b/tests/auto/gui/text/qfont/BLACKLIST @@ -1,12 +1,8 @@ [defaultFamily:cursive] -ubuntu-20.04 -ubuntu-22.04 centos b2qt rhel [defaultFamily:fantasy] -ubuntu-20.04 -ubuntu-22.04 centos b2qt rhel diff --git a/tests/auto/gui/text/qfont/CMakeLists.txt b/tests/auto/gui/text/qfont/CMakeLists.txt index 048416495b..88ae9959e4 100644 --- a/tests/auto/gui/text/qfont/CMakeLists.txt +++ b/tests/auto/gui/text/qfont/CMakeLists.txt @@ -1,9 +1,16 @@ -# Generated from qfont.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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" @@ -13,7 +20,7 @@ set(testfont_resource_files qt_internal_add_test(tst_qfont SOURCES tst_qfont.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate @@ -26,6 +33,6 @@ qt_internal_add_test(tst_qfont ##################################################################### qt_internal_extend_target(tst_qfont CONDITION TARGET Qt::Widgets - PUBLIC_LIBRARIES + LIBRARIES Qt::Widgets ) diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp index a663468d0f..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())))); } } } @@ -357,15 +365,15 @@ void tst_QFont::insertAndRemoveSubstitutions() // inserting Foo QFont::insertSubstitution("BogusFontFamily", "Foo"); - QCOMPARE(QFont::substitutes("BogusFontFamily").count(), 1); - QCOMPARE(QFont::substitutes("bogusfontfamily").count(), 1); + QCOMPARE(QFont::substitutes("BogusFontFamily").size(), 1); + QCOMPARE(QFont::substitutes("bogusfontfamily").size(), 1); // inserting Bar and Baz QStringList moreFonts; moreFonts << "Bar" << "Baz"; QFont::insertSubstitutions("BogusFontFamily", moreFonts); - QCOMPARE(QFont::substitutes("BogusFontFamily").count(), 3); - QCOMPARE(QFont::substitutes("bogusfontfamily").count(), 3); + QCOMPARE(QFont::substitutes("BogusFontFamily").size(), 3); + QCOMPARE(QFont::substitutes("bogusfontfamily").size(), 3); QFont::removeSubstitutions("BogusFontFamily"); // make sure it is empty again @@ -392,7 +400,7 @@ void tst_QFont::serialize_data() QTest::newRow("defaultConstructed") << font << QDataStream::Qt_1_0; font.setLetterSpacing(QFont::AbsoluteSpacing, 105); - QTest::newRow("letterSpacing") << font << QDataStream::Qt_4_5; + QTest::newRow("letterSpacing=105") << font << QDataStream::Qt_4_5; font = basicFont; font.setWordSpacing(50.0); @@ -436,7 +444,7 @@ void tst_QFont::serialize_data() font = basicFont; font.setLetterSpacing(QFont::AbsoluteSpacing, 10); // Fails for 4.4 because letterSpacing wasn't read until 4.5. - QTest::newRow("letterSpacing") << font << QDataStream::Qt_4_5; + QTest::newRow("letterSpacing=10") << font << QDataStream::Qt_4_5; font = basicFont; font.setKerning(false); @@ -589,6 +597,11 @@ void tst_QFont::defaultFamily() break; } } + +#if defined(Q_OS_UNIX) && defined(QT_NO_FONTCONFIG) + QSKIP("This platform does not support checking for default font acceptability"); +#endif + #ifdef Q_PROCESSOR_ARM_32 if (QTestPrivate::isRunningArmOnX86()) QEXPECT_FAIL("", "Fails on ARMv7 QEMU (QTQAINFRA-4127)", Continue); @@ -836,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 fb93c91e0c..d9645c115a 100644 --- a/tests/auto/gui/text/qfontcache/CMakeLists.txt +++ b/tests/auto/gui/text/qfontcache/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qfontcache.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate 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 73ab56d49f..18b96ded5d 100644 --- a/tests/auto/gui/text/qfontdatabase/CMakeLists.txt +++ b/tests/auto/gui/text/qfontdatabase/CMakeLists.txt @@ -1,16 +1,23 @@ -# Generated from qfontdatabase.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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") qt_internal_add_test(tst_qfontdatabase SOURCES tst_qfontdatabase.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate @@ -30,11 +37,15 @@ 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" ) diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp index 9c56d9b2d2..849e7432d1 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,20 @@ 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; }; tst_QFontDatabase::tst_QFontDatabase() @@ -82,10 +90,12 @@ 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"); QVERIFY(!m_ledFont.isEmpty()); QVERIFY(!m_testFont.isEmpty()); QVERIFY(!m_testFontCondensed.isEmpty()); QVERIFY(!m_testFontItalic.isEmpty()); + QVERIFY(!m_testFontVariable.isEmpty()); } void tst_QFontDatabase::styles_data() @@ -223,7 +233,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); @@ -236,7 +246,7 @@ void tst_QFontDatabase::addAppFont() QCOMPARE(id, -1); return; #endif - QCOMPARE(fontDbChangedSpy.count(), 1); + QCOMPARE(fontDbChangedSpy.size(), 1); if (id == -1) QSKIP("Skip the test since app fonts are not supported on this system"); @@ -245,9 +255,9 @@ void tst_QFontDatabase::addAppFont() const QStringList newFamilies = QFontDatabase::families(); QVERIFY(!newFamilies.isEmpty()); - QVERIFY(newFamilies.count() >= oldFamilies.count()); + QVERIFY(newFamilies.size() >= oldFamilies.size()); - for (int i = 0; i < addedFamilies.count(); ++i) { + for (int i = 0; i < addedFamilies.size(); ++i) { QString family = addedFamilies.at(i); QVERIFY(newFamilies.contains(family)); QFont qfont(family); @@ -256,9 +266,9 @@ void tst_QFontDatabase::addAppFont() } QVERIFY(QFontDatabase::removeApplicationFont(id)); - QCOMPARE(fontDbChangedSpy.count(), 2); + QCOMPARE(fontDbChangedSpy.size(), 2); - QVERIFY(QFontDatabase::families().count() <= oldFamilies.count()); + QVERIFY(QFontDatabase::families().size() <= oldFamilies.size()); } void tst_QFontDatabase::addTwoAppFontsFromFamily() @@ -319,8 +329,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()); @@ -415,8 +425,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 +517,123 @@ 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; + auto cleanup = qScopeGuard([&id, &ledId] { + if (id >= 0) + QFontDatabase::removeApplicationFont(id); + if (ledId >= 0) + QFontDatabase::removeApplicationFont(ledId); + }); + + 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); + } + +} + 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 d7a22671d6..d014d27d46 100644 --- a/tests/auto/gui/text/qfontmetrics/CMakeLists.txt +++ b/tests/auto/gui/text/qfontmetrics/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qfontmetrics.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate diff --git a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp index 5516492365..9471c1d93f 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,8 @@ private slots: void zeroWidthMetrics(); void verticalMetrics_data(); void verticalMetrics(); + void largeText_data(); + void largeText(); // QTBUG-123339 }; void tst_QFontMetrics::same() @@ -261,7 +263,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 +275,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 +390,25 @@ 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()); +} + 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 4c5a7c44c0..a9ffd3729d 100644 --- a/tests/auto/gui/text/qglyphrun/CMakeLists.txt +++ b/tests/auto/gui/text/qglyphrun/CMakeLists.txt @@ -1,21 +1,29 @@ -# Generated from qglyphrun.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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" ) set(testdata_resource_files "../../../shared/resources/test.ttf" + "Ligatures.otf" ) qt_internal_add_test(tst_qglyphrun SOURCES tst_qglyphrun.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui TESTDATA ${testdata_resource_files} BUILTIN_TESTDATA diff --git a/tests/auto/gui/text/qglyphrun/Ligatures.otf b/tests/auto/gui/text/qglyphrun/Ligatures.otf Binary files differnew file mode 100644 index 0000000000..194218a0f6 --- /dev/null +++ b/tests/auto/gui/text/qglyphrun/Ligatures.otf diff --git a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp index 1569a4bf84..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> @@ -39,6 +39,10 @@ private slots: void mixedScripts(); void multiLineBoundingRect(); void defaultIgnorables(); + void stringIndexes(); + void retrievalFlags_data(); + void retrievalFlags(); + void objectReplacementCharacter(); private: int m_testFontId; @@ -404,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); { @@ -414,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) @@ -445,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); { @@ -455,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); } @@ -560,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 @@ -605,17 +611,365 @@ void tst_QGlyphRun::multiLineBoundingRect() void tst_QGlyphRun::defaultIgnorables() { + { + QTextLayout layout; + layout.setFont(QFont("QtsSpecialTestFont")); + layout.setText(QChar(0x200D)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> runs = layout.glyphRuns(); + QCOMPARE(runs.size(), 0); + } + + { + QTextLayout layout; + layout.setFont(QFont("QtsSpecialTestFont")); + layout.setText(QStringLiteral("AAA") + QChar(0xFE0F) + QStringLiteral("111")); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> runs = layout.glyphRuns(); + QVERIFY(!runs.isEmpty()); + + bool hasFullMainFontRun = false; + for (const QGlyphRun &run : runs) { + // QtsSpecialFont will be used for at least five characters: AA[...]111 + // Depending on the font selected for the 0xFE0F variant selector, the + // third 'A' may be in QtsSpecialFont or in the fallback. This is platform-specific, + // so we accept either. + if (run.rawFont().familyName() == QStringLiteral("QtsSpecialTestFont") + && run.glyphIndexes().size() >= 5) { + hasFullMainFontRun = true; + break; + } + } + QVERIFY(hasFullMainFontRun); + } +} + +void tst_QGlyphRun::stringIndexes() +{ + int ligatureFontId = QFontDatabase::addApplicationFont(QFINDTESTDATA("Ligatures.otf")); + QVERIFY(ligatureFontId >= 0); + + QFont ligatureFont = QFont("QtLigatures"); + QCOMPARE(QFontInfo(ligatureFont).family(), QString::fromLatin1("QtLigatures")); + + QTextLayout::GlyphRunRetrievalFlags retrievalFlags + = QTextLayout::RetrieveGlyphIndexes | QTextLayout::RetrieveStringIndexes; + + // Three characters -> three glyphs + { + QTextLayout layout; + layout.setText("f i"); + layout.setFont(ligatureFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 3); + QCOMPARE(stringIndexes.at(0), 0); + QCOMPARE(stringIndexes.at(1), 1); + QCOMPARE(stringIndexes.at(2), 2); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(2, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 1); + QCOMPARE(stringIndexes.at(0), 2); + } + } + + // Two characters -> one glyph + { + QTextLayout layout; + layout.setText("fi"); + layout.setFont(ligatureFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 1); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(233)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 1); + QCOMPARE(stringIndexes.at(0), 0); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 1); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(233)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 1); + QCOMPARE(stringIndexes.at(0), 1); + } + } + + // Four characters -> three glyphs + { + QTextLayout layout; + layout.setText("ffii"); + layout.setFont(ligatureFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 3); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(71)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(233)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(2), uint(74)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 3); + QCOMPARE(stringIndexes.at(0), uint(0)); + QCOMPARE(stringIndexes.at(1), uint(1)); + QCOMPARE(stringIndexes.at(2), uint(3)); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(1, 1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 1); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(233)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 1); + QCOMPARE(stringIndexes.at(0), uint(1)); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(1, 2, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 1); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(233)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 1); + QCOMPARE(stringIndexes.at(0), uint(1)); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(1, 3, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 2); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(233)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(74)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 2); + QCOMPARE(stringIndexes.at(0), 1); + QCOMPARE(stringIndexes.at(1), 3); + } + + } + + // One character -> two glyphs + { + QTextLayout layout; + layout.setText(QChar(0xe6)); // LATIN SMALL LETTER AE + layout.setFont(ligatureFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 2); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(66)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(70)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 2); + QCOMPARE(stringIndexes.at(0), uint(0)); + QCOMPARE(stringIndexes.at(1), uint(0)); + } + + // Three characters -> four glyphs + { + QTextLayout layout; + layout.setText(QString('f') + QChar(0xe6) + QChar('i')); + layout.setFont(ligatureFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 4); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(71)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(66)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(2), uint(70)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(3), uint(74)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 4); + QCOMPARE(stringIndexes.at(0), 0); + QCOMPARE(stringIndexes.at(1), 1); + QCOMPARE(stringIndexes.at(2), 1); + QCOMPARE(stringIndexes.at(3), 2); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 3); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(66)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(70)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(2), uint(74)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 3); + QCOMPARE(stringIndexes.at(0), 1); + QCOMPARE(stringIndexes.at(1), 1); + QCOMPARE(stringIndexes.at(2), 2); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(0, 2, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 3); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(71)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(66)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(2), uint(70)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 3); + QCOMPARE(stringIndexes.at(0), 0); + QCOMPARE(stringIndexes.at(1), 1); + QCOMPARE(stringIndexes.at(2), 1); + } + + + } + + // Five characters -> five glyphs + { + QTextLayout layout; + layout.setText(QLatin1String("ffi") + QChar(0xe6) + QLatin1Char('i')); + layout.setFont(ligatureFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 5); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(71)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(233)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(2), uint(66)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(3), uint(70)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(4), uint(74)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 5); + QCOMPARE(stringIndexes.at(0), 0); + QCOMPARE(stringIndexes.at(1), 1); + QCOMPARE(stringIndexes.at(2), 3); + QCOMPARE(stringIndexes.at(3), 3); + QCOMPARE(stringIndexes.at(4), 4); + } + +} + +void tst_QGlyphRun::retrievalFlags_data() +{ + QTest::addColumn<QTextLayout::GlyphRunRetrievalFlags>("flags"); + QTest::addColumn<bool>("expectedGlyphIndexes"); + QTest::addColumn<bool>("expectedStringIndexes"); + QTest::addColumn<bool>("expectedString"); + QTest::addColumn<bool>("expectedGlyphPositions"); + + QTest::newRow("Glyph indexes") + << QTextLayout::GlyphRunRetrievalFlags(QTextLayout::RetrieveGlyphIndexes) + << true << false << false << false; + QTest::newRow("Glyph Positions") + << QTextLayout::GlyphRunRetrievalFlags(QTextLayout::RetrieveGlyphPositions) + << false << false << false << true; + QTest::newRow("String indexes") + << QTextLayout::GlyphRunRetrievalFlags(QTextLayout::RetrieveStringIndexes) + << false << true << false << false; + QTest::newRow("String") + << QTextLayout::GlyphRunRetrievalFlags(QTextLayout::RetrieveString) + << false << false << true << false; + + QTest::newRow("Default") + << QTextLayout::GlyphRunRetrievalFlags(QTextLayout::DefaultRetrievalFlags) + << true << false << false << true; + QTest::newRow("All") + << QTextLayout::GlyphRunRetrievalFlags(QTextLayout::RetrieveAll) + << true << true << true << true; +} + +void tst_QGlyphRun::retrievalFlags() +{ + QFETCH(QTextLayout::GlyphRunRetrievalFlags, flags); + QFETCH(bool, expectedGlyphIndexes); + QFETCH(bool, expectedStringIndexes); + QFETCH(bool, expectedString); + QFETCH(bool, expectedGlyphPositions); + QTextLayout layout; - layout.setFont(QFont("QtsSpecialTestFont")); - layout.setText(QChar(0x200D)); + layout.setText(QLatin1String("abc")); layout.beginLayout(); layout.createLine(); layout.endLayout(); - QList<QGlyphRun> runs = layout.glyphRuns(); - QCOMPARE(runs.size(), 1); - QCOMPARE(runs.at(0).glyphIndexes().size(), 1); - QCOMPARE(runs.at(0).glyphIndexes()[0], uint(0)); + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, flags); + QVERIFY(!glyphRuns.isEmpty()); + + QGlyphRun firstGlyphRun = glyphRuns.first(); + QCOMPARE(firstGlyphRun.glyphIndexes().isEmpty(), !expectedGlyphIndexes); + QCOMPARE(firstGlyphRun.stringIndexes().isEmpty(), !expectedStringIndexes); + QCOMPARE(firstGlyphRun.sourceString().isEmpty(), !expectedString); + QCOMPARE(firstGlyphRun.positions().isEmpty(), !expectedGlyphPositions); +} + +void tst_QGlyphRun::objectReplacementCharacter() +{ + QTextLayout layout; + layout.setFont(m_testFont); + layout.setText(QStringLiteral("\uFFFC")); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 1); + QCOMPARE(glyphRuns.first().glyphIndexes().size(), 1); + QCOMPARE(glyphRuns.first().glyphIndexes().first(), uint(5)); } #endif // QT_NO_RAWFONT diff --git a/tests/auto/gui/text/qinputcontrol/CMakeLists.txt b/tests/auto/gui/text/qinputcontrol/CMakeLists.txt index 048a96ef77..75fc85bc39 100644 --- a/tests/auto/gui/text/qinputcontrol/CMakeLists.txt +++ b/tests/auto/gui/text/qinputcontrol/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qinputcontrol.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui Qt::GuiPrivate ) 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 c7a883d9ce..d2a318a2a3 100644 --- a/tests/auto/gui/text/qrawfont/CMakeLists.txt +++ b/tests/auto/gui/text/qrawfont/CMakeLists.txt @@ -1,9 +1,16 @@ -# Generated from qrawfont.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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" @@ -17,7 +24,7 @@ set(testdata_resource_files qt_internal_add_test(tst_qrawfont SOURCES tst_qrawfont.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate diff --git a/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp b/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp index 0e90572709..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> @@ -96,7 +96,7 @@ void tst_QRawFont::initTestCase() if (testFont.isEmpty() || testFontBoldItalic.isEmpty()) QFAIL("qrawfont unittest font files not found!"); - if (QFontDatabase::families().count() == 0) + if (QFontDatabase::families().size() == 0) QSKIP("No fonts available!!!"); } @@ -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 a7ba4e392a..bdad2609fe 100644 --- a/tests/auto/gui/text/qstatictext/CMakeLists.txt +++ b/tests/auto/gui/text/qstatictext/CMakeLists.txt @@ -1,21 +1,28 @@ -# Generated from qstatictext.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui ) ## Scopes: ##################################################################### -qt_internal_extend_target(tst_qstatictext CONDITION QT_FEATURE_private_tests - PUBLIC_LIBRARIES +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 397a116a73..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(); @@ -82,11 +78,6 @@ private: Q_DECLARE_METATYPE(QImage::Format); -static bool isPlatformWayland() -{ - return QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive); -} - void tst_QStaticText::constructionAndDestruction() { QStaticText text("My text"); @@ -148,8 +139,6 @@ void tst_QStaticText::drawToPoint() } QVERIFY(imageDrawText.toImage() != m_whiteSquare); - if (isPlatformWayland()) - QEXPECT_FAIL("", "Wayland: This fails. See QTBUG-100982.", Abort); QCOMPARE(imageDrawStaticText, imageDrawText); } @@ -190,8 +179,6 @@ void tst_QStaticText::drawToRect() #endif QVERIFY(imageDrawText.toImage() != m_whiteSquare); - if (isPlatformWayland()) - QEXPECT_FAIL("", "Wayland: This fails. See QTBUG-100982.", Abort); QCOMPARE(imageDrawStaticText, imageDrawText); } @@ -246,13 +233,11 @@ void tst_QStaticText::compareToDrawText() #if defined(DEBUG_SAVE_IMAGE) imageDrawText.save("compareToDrawText_imageDrawText.png"); - imageDrawStaticText.save("compareToDrawText_imageDrawStaticPlainText.png"); - imageDrawStaticText.save("compareToDrawText_imageDrawStaticRichText.png"); + imageDrawStaticPlainText.save("compareToDrawText_imageDrawStaticPlainText.png"); + imageDrawStaticRichText.save("compareToDrawText_imageDrawStaticRichText.png"); #endif QVERIFY(imageDrawText.toImage() != m_whiteSquare); - if (isPlatformWayland() && font == QFont()) - QEXPECT_FAIL("", "Wayland: This fails. See QTBUG-100982.", Abort); QCOMPARE(imageDrawStaticPlainText, imageDrawText); QCOMPARE(imageDrawStaticRichText, imageDrawText); } @@ -360,8 +345,6 @@ void tst_QStaticText::setFont() #endif QVERIFY(imageDrawText.toImage() != m_whiteSquare); - if (isPlatformWayland()) - QEXPECT_FAIL("", "Wayland: This fails. See QTBUG-100982.", Abort); QCOMPARE(imageDrawStaticText, imageDrawText); } @@ -385,8 +368,6 @@ void tst_QStaticText::setTextWidth() } QVERIFY(imageDrawText.toImage() != m_whiteSquare); - if (isPlatformWayland()) - QEXPECT_FAIL("", "Wayland: This fails. See QTBUG-100982.", Abort); QCOMPARE(imageDrawStaticText, imageDrawText); } @@ -414,8 +395,6 @@ void tst_QStaticText::translatedPainter() } QVERIFY(imageDrawText.toImage() != m_whiteSquare); - if (isPlatformWayland()) - QEXPECT_FAIL("", "Wayland: This fails. See QTBUG-100982.", Abort); QCOMPARE(imageDrawStaticText, imageDrawText); } @@ -456,8 +435,6 @@ void tst_QStaticText::rotatedPainter() if (!supportsTransformations()) QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort); - if (isPlatformWayland()) - QEXPECT_FAIL("", "Wayland: This fails. See QTBUG-100982.", Abort); QCOMPARE(imageDrawStaticText, imageDrawText); } @@ -488,8 +465,6 @@ void tst_QStaticText::scaledPainter() if (!supportsTransformations()) QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort); - if (isPlatformWayland()) - QEXPECT_FAIL("", "Wayland: This fails. See QTBUG-100982.", Abort); QCOMPARE(imageDrawStaticText, imageDrawText); } @@ -522,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); @@ -617,8 +537,6 @@ void tst_QStaticText::transformationChanged() if (!supportsTransformations()) QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort); - if (isPlatformWayland()) - QEXPECT_FAIL("", "Wayland: This fails. See QTBUG-100982.", Abort); QCOMPARE(imageDrawStaticText, imageDrawText); } diff --git a/tests/auto/gui/text/qsyntaxhighlighter/CMakeLists.txt b/tests/auto/gui/text/qsyntaxhighlighter/CMakeLists.txt index 9ac732cee0..f1c9146ce1 100644 --- a/tests/auto/gui/text/qsyntaxhighlighter/CMakeLists.txt +++ b/tests/auto/gui/text/qsyntaxhighlighter/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qsyntaxhighlighter.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui ) @@ -15,6 +22,6 @@ qt_internal_add_test(tst_qsyntaxhighlighter ##################################################################### qt_internal_extend_target(tst_qsyntaxhighlighter CONDITION TARGET Qt::Widgets - PUBLIC_LIBRARIES + LIBRARIES Qt::Widgets ) diff --git a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp index 202d07ea1e..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> @@ -100,7 +100,7 @@ public: virtual void highlightBlock(const QString &text) override { - for (int i = 0; i < formats.count(); ++i) { + for (int i = 0; i < formats.size(); ++i) { const QTextLayout::FormatRange &range = formats.at(i); setFormat(range.start, range.length, range.format); } @@ -161,7 +161,7 @@ public: commentFormat.setForeground(Qt::darkGreen); commentFormat.setFontWeight(QFont::StyleItalic); commentFormat.setFontFixedPitch(true); - int textLength = text.length(); + int textLength = text.size(); if (text.startsWith(QLatin1Char(';'))){ // The entire line is a comment @@ -414,7 +414,7 @@ void tst_QSyntaxHighlighter::preservePreeditArea() QCOMPARE(hl->callCount, 1); formats = layout->formats(); - QCOMPARE(formats.count(), 3); + QCOMPARE(formats.size(), 3); range = formats.at(0); @@ -493,7 +493,7 @@ void tst_QSyntaxHighlighter::noContentsChangedDuringHighlight() QSignalSpy contentsChangedSpy(doc, SIGNAL(contentsChanged())); cursor.insertText("Hello World"); - QCOMPARE(contentsChangedSpy.count(), 1); + QCOMPARE(contentsChangedSpy.size(), 1); QVERIFY(hl->highlighted); QVERIFY(lout->documentChangedCalled); } diff --git a/tests/auto/gui/text/qtextblock/CMakeLists.txt b/tests/auto/gui/text/qtextblock/CMakeLists.txt index aedd6c27a3..83cc1ce08e 100644 --- a/tests/auto/gui/text/qtextblock/CMakeLists.txt +++ b/tests/auto/gui/text/qtextblock/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qtextblock.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate 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 a82dc928e9..487965f9f8 100644 --- a/tests/auto/gui/text/qtextcursor/CMakeLists.txt +++ b/tests/auto/gui/text/qtextcursor/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qtextcursor.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate diff --git a/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp b/tests/auto/gui/text/qtextcursor/tst_qtextcursor.cpp index cc6722af40..6984cd1bd2 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> @@ -1545,15 +1545,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"); @@ -1754,26 +1759,26 @@ void tst_QTextCursor::update_data() QTest::newRow("removeInsideSelection") << text << /*position*/ 0 - << /*anchor*/ int(text.length()) + << /*anchor*/ int(text.size()) // delete 'big' << 6 << 6 + charsToDelete << QString() // don't insert anything, just remove << /*expectedPosition*/ 0 - << /*expectedAnchor*/ int(text.length() - charsToDelete) + << /*expectedAnchor*/ int(text.size() - charsToDelete) ; text = "Hello big world"; charsToDelete = 3; QTest::newRow("removeInsideSelectionWithSwappedAnchorAndPosition") << text - << /*position*/ int(text.length()) + << /*position*/ int(text.size()) << /*anchor*/ 0 // delete 'big' << 6 << 6 + charsToDelete << QString() // don't insert anything, just remove - << /*expectedPosition*/ int(text.length() - charsToDelete) + << /*expectedPosition*/ int(text.size() - charsToDelete) << /*expectedAnchor*/ 0 ; @@ -1784,13 +1789,13 @@ void tst_QTextCursor::update_data() QTest::newRow("replaceInsideSelection") << text << /*position*/ 0 - << /*anchor*/ int(text.length()) + << /*anchor*/ int(text.size()) // delete 'big' ... << 6 << 6 + charsToDelete << textToInsert // ... and replace 'big' with 'small' << /*expectedPosition*/ 0 - << /*expectedAnchor*/ int(text.length() - charsToDelete + textToInsert.length()) + << /*expectedAnchor*/ int(text.size() - charsToDelete + textToInsert.size()) ; text = "Hello big world"; @@ -1798,13 +1803,13 @@ void tst_QTextCursor::update_data() textToInsert = "small"; QTest::newRow("replaceInsideSelectionWithSwappedAnchorAndPosition") << text - << /*position*/ int(text.length()) + << /*position*/ int(text.size()) << /*anchor*/ 0 // delete 'big' ... << 6 << 6 + charsToDelete << textToInsert // ... and replace 'big' with 'small' - << /*expectedPosition*/ int(text.length() - charsToDelete + textToInsert.length()) + << /*expectedPosition*/ int(text.size() - charsToDelete + textToInsert.size()) << /*expectedAnchor*/ 0 ; @@ -1813,14 +1818,14 @@ void tst_QTextCursor::update_data() charsToDelete = 3; QTest::newRow("removeBeforeSelection") << text - << /*position*/ int(text.length() - 5) - << /*anchor*/ int(text.length()) + << /*position*/ int(text.size() - 5) + << /*anchor*/ int(text.size()) // delete 'big' << 6 << 6 + charsToDelete << QString() // don't insert anything, just remove - << /*expectedPosition*/ int(text.length() - 5 - charsToDelete) - << /*expectedAnchor*/ int(text.length() - charsToDelete) + << /*expectedPosition*/ int(text.size() - 5 - charsToDelete) + << /*expectedAnchor*/ int(text.size() - charsToDelete) ; text = "Hello big world"; diff --git a/tests/auto/gui/text/qtextdocument/CMakeLists.txt b/tests/auto/gui/text/qtextdocument/CMakeLists.txt index bff5cabfb7..62fa1d46ca 100644 --- a/tests/auto/gui/text/qtextdocument/CMakeLists.txt +++ b/tests/auto/gui/text/qtextdocument/CMakeLists.txt @@ -1,14 +1,21 @@ -# Generated from qtextdocument.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 tst_qtextdocument.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate 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 d10027b7a0..335ee06e2f 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); @@ -465,17 +469,17 @@ void tst_QTextDocument::basicIsModifiedChecks() QVERIFY(!doc->isModified()); cursor.insertText("Hello World"); QVERIFY(doc->isModified()); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QVERIFY(spy.takeFirst().at(0).toBool()); doc->undo(); QVERIFY(!doc->isModified()); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QVERIFY(!spy.takeFirst().at(0).toBool()); doc->redo(); QVERIFY(doc->isModified()); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QVERIFY(spy.takeFirst().at(0).toBool()); } @@ -566,16 +570,16 @@ void tst_QTextDocument::noundo_basicIsModifiedChecks() QVERIFY(!doc->isModified()); cursor.insertText("Hello World"); QVERIFY(doc->isModified()); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QVERIFY(spy.takeFirst().at(0).toBool()); doc->undo(); QVERIFY(doc->isModified()); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); doc->redo(); QVERIFY(doc->isModified()); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); } void tst_QTextDocument::task240325() @@ -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() @@ -1945,7 +1972,7 @@ void tst_QTextDocument::toHtmlBodyBgColor() doc.rootFrame()->setFrameFormat(fmt); QString expectedHtml = htmlHead; - expectedHtml.insert(htmlHead.length() - 2, " bgcolor=\"#0000ff\""); + expectedHtml.insert(htmlHead.size() - 2, " bgcolor=\"#0000ff\""); expectedHtml += "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Blah</p>" + htmlTail; @@ -1965,7 +1992,7 @@ void tst_QTextDocument::toHtmlBodyBgColorRgba() doc.rootFrame()->setFrameFormat(fmt); QString expectedHtml = htmlHead; - expectedHtml.insert(htmlHead.length() - 2, " bgcolor=\"rgba(255,0,0,0.2)\""); + expectedHtml.insert(htmlHead.size() - 2, " bgcolor=\"rgba(255,0,0,0.2)\""); expectedHtml += "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Blah</p>" + htmlTail; @@ -1985,7 +2012,7 @@ void tst_QTextDocument::toHtmlBodyBgColorTransparent() doc.rootFrame()->setFrameFormat(fmt); QString expectedHtml = htmlHead; - expectedHtml.insert(htmlHead.length() - 2, " bgcolor=\"transparent\""); + expectedHtml.insert(htmlHead.size() - 2, " bgcolor=\"transparent\""); expectedHtml += "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Blah</p>" + htmlTail; @@ -2051,7 +2078,7 @@ void tst_QTextDocument::toHtmlDefaultFontSpacingProperties() doc.setDefaultFont(fnt); QString expectedOutput = htmlHead; - expectedOutput.insert(htmlHead.length() - 3, " letter-spacing:13px; word-spacing:15px;"); + expectedOutput.insert(htmlHead.size() - 3, " letter-spacing:13px; word-spacing:15px;"); expectedOutput += "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Blah</p>" + htmlTail; @@ -2071,7 +2098,7 @@ void tst_QTextDocument::toHtmlTextDecorationUnderline() doc.setDefaultFont(fnt); QString expectedOutput = htmlHead; - expectedOutput.insert(htmlHead.length() - 3, " text-decoration: underline;"); + expectedOutput.insert(htmlHead.size() - 3, " text-decoration: underline;"); expectedOutput += "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Some text</p>" + htmlTail; @@ -2086,7 +2113,7 @@ void tst_QTextDocument::toHtmlTextDecorationUnderline() cursor.mergeCharFormat(format); expectedOutput = htmlHead; - expectedOutput.insert(htmlHead.length() - 3, " text-decoration: underline;"); + expectedOutput.insert(htmlHead.size() - 3, " text-decoration: underline;"); expectedOutput += "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; " "margin-right:0px; -qt-block-indent:0; text-indent:0px;\">" @@ -2740,11 +2767,11 @@ void tst_QTextDocument::defaultTableStyle() brushes << sideProperty.value<QBrush>(); } auto errorDetails = qScopeGuard([&]{ - if (brushes.count() != borderBrushes.count()) { - qWarning("Different count: %lld vs %lld", brushes.count(), borderBrushes.count()); + if (brushes.size() != borderBrushes.size()) { + qWarning("Different count: %lld vs %lld", brushes.size(), borderBrushes.size()); return; } - for (int i = 0; i < brushes.count(); ++i) { + for (int i = 0; i < brushes.size(); ++i) { QString side; QDebug(&side) << QTextFormat::Property(QTextFormat::TableCellTopBorderBrush + i); QString actual; @@ -2868,13 +2895,13 @@ void tst_QTextDocument::blockCountChanged() doc->setPlainText("Foo"); QCOMPARE(doc->blockCount(), 1); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); spy.clear(); doc->setPlainText("Foo\nBar"); QCOMPARE(doc->blockCount(), 2); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QCOMPARE(spy.at(0).value(0).toInt(), 2); spy.clear(); @@ -2882,16 +2909,16 @@ void tst_QTextDocument::blockCountChanged() cursor.movePosition(QTextCursor::End); cursor.insertText("Blahblah"); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); cursor.insertBlock(); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QCOMPARE(spy.at(0).value(0).toInt(), 3); spy.clear(); doc->undo(); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QCOMPARE(spy.at(0).value(0).toInt(), 2); } @@ -3070,12 +3097,12 @@ void tst_QTextDocument::characterAt() QString text("12345\n67890"); cursor.insertText(text); int length = doc.characterCount(); - QCOMPARE(length, text.length() + 1); + QCOMPARE(length, text.size() + 1); QCOMPARE(doc.characterAt(length-1), QChar(QChar::ParagraphSeparator)); QCOMPARE(doc.characterAt(-1), QChar()); QCOMPARE(doc.characterAt(length), QChar()); QCOMPARE(doc.characterAt(length + 1), QChar()); - for (int i = 0; i < text.length(); ++i) { + for (int i = 0; i < text.size(); ++i) { QChar c = text.at(i); if (c == QLatin1Char('\n')) c = QChar(QChar::ParagraphSeparator); @@ -3155,11 +3182,11 @@ void tst_QTextDocument::testUndoCommandAdded() QVERIFY(spy.isEmpty()); cursor.insertText("a"); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); cursor.insertText("b"); // should be merged - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); cursor.insertText("c"); // should be merged - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); QCOMPARE(doc->toPlainText(), QString("abc")); doc->undo(); QCOMPARE(doc->toPlainText(), QString("")); @@ -3167,11 +3194,11 @@ void tst_QTextDocument::testUndoCommandAdded() doc->clear(); spy.clear(); cursor.insertText("aaa"); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); spy.clear(); cursor.insertText("aaaa\nbcd"); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); spy.clear(); cursor.beginEditBlock(); @@ -3181,11 +3208,11 @@ void tst_QTextDocument::testUndoCommandAdded() cursor.insertText("\nccc"); QVERIFY(spy.isEmpty()); cursor.endEditBlock(); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); spy.clear(); cursor.insertBlock(); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); spy.clear(); cursor.setPosition(5); @@ -3197,18 +3224,18 @@ void tst_QTextDocument::testUndoCommandAdded() QTextCharFormat cf; cf.setFontItalic(true); cursor.mergeCharFormat(cf); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); spy.clear(); doc->undo(); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); doc->undo(); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); spy.clear(); doc->redo(); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); doc->redo(); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); } void tst_QTextDocument::testUndoBlocks() @@ -3788,7 +3815,7 @@ void tst_QTextDocument::mergeFontFamilies() QTextCursor cursor = QTextCursor(&td); cursor.setPosition(0); - cursor.setPosition(QByteArray("Hello World").length(), QTextCursor::KeepAnchor); + cursor.setPosition(QByteArray("Hello World").size(), QTextCursor::KeepAnchor); cursor.mergeCharFormat(newFormat); QVERIFY(td.toHtml().contains(QLatin1String("font-family:'Jokerman';"))); @@ -3934,7 +3961,7 @@ void tst_QTextDocument::insertHtmlWithComments() QTextDocument doc; doc.setHtml(html); - QCOMPARE(doc.blockCount(), expectedBlocks.count()); + QCOMPARE(doc.blockCount(), expectedBlocks.size()); QStringList blockContent; auto currentBlock = doc.begin(); @@ -3965,5 +3992,171 @@ 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; + textOutline.setTextOutline(QPen(Qt::red, 2.3)); + textCursor.insertText("Outlined text", textOutline); + { + QTextDocument otherDocument; + otherDocument.setHtml(document.toHtml()); + QCOMPARE(otherDocument.blockCount(), 1); + QTextBlock block = otherDocument.firstBlock(); + QTextFragment fragment = block.begin().fragment(); + QCOMPARE(fragment.text(), QStringLiteral("Outlined text")); + QTextCharFormat fmt = fragment.charFormat(); + QVERIFY(fmt.hasProperty(QTextCharFormat::TextOutline)); + QPen pen = fmt.textOutline(); + QCOMPARE(pen.color(), QColor(Qt::red)); + QCOMPARE(pen.widthF(), 2.3); + } +} + +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 6f1207c49a..4a4075106e 100644 --- a/tests/auto/gui/text/qtextdocumentfragment/CMakeLists.txt +++ b/tests/auto/gui/text/qtextdocumentfragment/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qtextdocumentfragment.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate diff --git a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp index 52708e1b14..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) @@ -1175,7 +1179,7 @@ void tst_QTextDocumentFragment::copySubTable() table->cellAt(row, col).firstCursorPosition().insertText(rowS + QString::number(col)); } - QCOMPARE(table->format().columnWidthConstraints().count(), table->columns()); + QCOMPARE(table->format().columnWidthConstraints().size(), table->columns()); // select 2x2 subtable cursor = table->cellAt(1, 1).firstCursorPosition(); @@ -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>"; @@ -2235,7 +2255,7 @@ void tst_QTextDocumentFragment::html_frameImport() cursor.insertFragment(frag); QList<QTextFrame *> childFrames = doc->rootFrame()->childFrames(); - QCOMPARE(childFrames.count(), 1); + QCOMPARE(childFrames.size(), 1); QTextFrame *frame = childFrames.first(); QCOMPARE(frame->frameFormat().margin(), ffmt.margin()); QCOMPARE(frame->frameFormat().border(), ffmt.border()); @@ -2263,7 +2283,7 @@ void tst_QTextDocumentFragment::html_frameImport2() cursor.insertFragment(frag); QList<QTextFrame *> childFrames = doc->rootFrame()->childFrames(); - QCOMPARE(childFrames.count(), 1); + QCOMPARE(childFrames.size(), 1); QTextFrame *frame = childFrames.first(); QCOMPARE(frame->frameFormat().topMargin(), ffmt.topMargin()); QCOMPARE(frame->frameFormat().bottomMargin(), ffmt.bottomMargin()); @@ -2278,7 +2298,7 @@ void tst_QTextDocumentFragment::html_dontAddMarginsAcrossTableCells() cursor.insertFragment(QTextDocumentFragment::fromHtml(QString::fromLatin1(html))); QList<QTextFrame *> childFrames = doc->rootFrame()->childFrames(); - QCOMPARE(childFrames.count(), 1); + QCOMPARE(childFrames.size(), 1); QTextFrame *frame = childFrames.first(); cursor = frame->firstCursorPosition(); QCOMPARE(cursor.blockFormat().leftMargin(), qreal(50.0)); @@ -2760,7 +2780,7 @@ void tst_QTextDocumentFragment::html_columnWidths() QTextTableFormat fmt = table->format(); const QList<QTextLength> columnWidths = fmt.columnWidthConstraints(); - QCOMPARE(columnWidths.count(), 2); + QCOMPARE(columnWidths.size(), 2); QCOMPARE(columnWidths.at(0).type(), QTextLength::VariableLength); QCOMPARE(columnWidths.at(1).type(), QTextLength::PercentageLength); QCOMPARE(columnWidths.at(1).rawValue(), qreal(1)); @@ -4168,7 +4188,7 @@ void tst_QTextDocumentFragment::html_entities() setHtml(html); QCOMPARE(doc->blockCount(), 1); QString txt = doc->begin().text(); - QCOMPARE(txt.length(), 1); + QCOMPARE(txt.size(), 1); QCOMPARE(txt.at(0).unicode(), code); } @@ -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 da41073962..07386d4e24 100644 --- a/tests/auto/gui/text/qtextdocumentlayout/CMakeLists.txt +++ b/tests/auto/gui/text/qtextdocumentlayout/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qtextdocumentlayout.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui ) @@ -15,6 +22,6 @@ qt_internal_add_test(tst_qtextdocumentlayout ##################################################################### qt_internal_extend_target(tst_qtextdocumentlayout CONDITION TARGET Qt::Widgets - PUBLIC_LIBRARIES + LIBRARIES Qt::Widgets ) diff --git a/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp b/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp index 01c4005bfe..2a279682ca 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> @@ -33,6 +33,7 @@ private slots: void floatingTablePageBreak(); void imageAtRightAlignedTab(); void blockVisibility(); + void testHitTest(); void largeImage(); @@ -380,5 +381,41 @@ void tst_QTextDocumentLayout::largeImage() } } +void tst_QTextDocumentLayout::testHitTest() +{ + QTextDocument document; + QTextCursor cur(&document); + int topMargin = 20; + + //insert 500 blocks into textedit + for (int i = 0; i < 500; i++) { + cur.insertBlock(); + cur.insertHtml(QString("block %1").arg(i)); + } + + //randomly set half the blocks invisible + QTextBlock blk=document.begin(); + for (int i = 0; i < 500; i++) { + if (i % 7) + blk.setVisible(0); + blk = blk.next(); + } + + //set margin for all blocks (not strictly necessary, but makes easier to click in between blocks) + QTextBlockFormat blkfmt; + blkfmt.setTopMargin(topMargin); + cur.movePosition(QTextCursor::Start); + cur.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + cur.mergeBlockFormat(blkfmt); + + for (int y = cur.selectionStart(); y < cur.selectionEnd(); y += 10) { + QPoint mousePoint(1, y); + int cursorPos = document.documentLayout()->hitTest(mousePoint, Qt::FuzzyHit); + int positionY = document.findBlock(cursorPos).layout()->position().toPoint().y(); + //mousePoint is in the rect of the current Block + QVERIFY(positionY - topMargin <= y); + } +} + 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 cacd7fbd18..4dea90900e 100644 --- a/tests/auto/gui/text/qtextformat/CMakeLists.txt +++ b/tests/auto/gui/text/qtextformat/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qtextformat.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate diff --git a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp b/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp index a998bbd482..d20a2f1ea5 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> @@ -187,7 +187,7 @@ void tst_QTextFormat::resolveFont() QTextCursor(&doc).insertText("Test", fmt); QList<QTextFormat> formats = doc.allFormats(); - QCOMPARE(formats.count(), 3); + QCOMPARE(formats.size(), 3); QCOMPARE(formats.at(2).type(), int(QTextFormat::CharFormat)); fmt = formats.at(2).toCharFormat(); @@ -312,8 +312,8 @@ void tst_QTextFormat::getSetTabs() public: Comparator(const QList<QTextOption::Tab> &tabs, const QList<QTextOption::Tab> &tabs2) { - QCOMPARE(tabs.count(), tabs2.count()); - for(int i=0; i < tabs.count(); i++) { + QCOMPARE(tabs.size(), tabs2.size()); + for(int i=0; i < tabs.size(); i++) { QTextOption::Tab t1 = tabs[i]; QTextOption::Tab t2 = tabs2[i]; QCOMPARE(t1.position, t2.position); @@ -364,7 +364,7 @@ void tst_QTextFormat::testTabsUsed() QCOMPARE(line.cursorToX(4), 100.); QTextOption option = layout->textOption(); - QCOMPARE(option.tabs().count(), tabs.count()); + QCOMPARE(option.tabs().size(), tabs.size()); } @@ -648,16 +648,16 @@ void tst_QTextFormat::clearCollection() charFormat2.setUnderlineStyle(QTextCharFormat::SingleUnderline); int formatIndex2 = collection.indexForFormat(charFormat2); QCOMPARE(formatIndex2, 1); - QCOMPARE(collection.formats.count(), 2); - QCOMPARE(collection.hashes.count(), 2); + QCOMPARE(collection.formats.size(), 2); + QCOMPARE(collection.hashes.size(), 2); QCOMPARE(collection.defaultFont(), f); collection.clear(); - QCOMPARE(collection.formats.count(), 0); - QCOMPARE(collection.hashes.count(), 0); + QCOMPARE(collection.formats.size(), 0); + QCOMPARE(collection.hashes.size(), 0); QCOMPARE(collection.indexForFormat(charFormat2), 0); - QCOMPARE(collection.formats.count(), 1); - QCOMPARE(collection.hashes.count(), 1); + QCOMPARE(collection.formats.size(), 1); + QCOMPARE(collection.hashes.size(), 1); QCOMPARE(collection.defaultFont(), f); // kept, QTextDocument::clear or setPlainText should not reset the font set by setDefaultFont } @@ -679,7 +679,7 @@ void tst_QTextFormat::dataStreamCompatibility() QVERIFY(properties.contains(QTextFormat::FontFamilies)); QVERIFY(!properties.contains(QTextFormat::OldFontLetterSpacingType)); QVERIFY(!properties.contains(QTextFormat::OldFontStretch)); - QVERIFY(!properties.contains(QTextFormat::FontFamily)); + QVERIFY(!properties.contains(QTextFormat::OldFontFamily)); } QByteArray memory; @@ -710,7 +710,7 @@ void tst_QTextFormat::dataStreamCompatibility() QVERIFY(properties.contains(QTextFormat::FontFamilies)); QVERIFY(!properties.contains(QTextFormat::OldFontLetterSpacingType)); QVERIFY(!properties.contains(QTextFormat::OldFontStretch)); - QVERIFY(!properties.contains(QTextFormat::FontFamily)); + QVERIFY(!properties.contains(QTextFormat::OldFontFamily)); } } @@ -730,7 +730,7 @@ void tst_QTextFormat::dataStreamCompatibility() QVERIFY(properties.contains(QTextFormat::FontFamilies)); QVERIFY(!properties.contains(QTextFormat::OldFontLetterSpacingType)); QVERIFY(!properties.contains(QTextFormat::OldFontStretch)); - QVERIFY(!properties.contains(QTextFormat::FontFamily)); + QVERIFY(!properties.contains(QTextFormat::OldFontFamily)); } } @@ -763,7 +763,7 @@ void tst_QTextFormat::dataStreamCompatibility() QVERIFY(properties.contains(QTextFormat::FontFamilies)); QVERIFY(!properties.contains(QTextFormat::OldFontLetterSpacingType)); QVERIFY(!properties.contains(QTextFormat::OldFontStretch)); - QVERIFY(!properties.contains(QTextFormat::FontFamily)); + QVERIFY(!properties.contains(QTextFormat::OldFontFamily)); } } @@ -785,7 +785,7 @@ void tst_QTextFormat::dataStreamCompatibility() QVERIFY(!properties.contains(QTextFormat::FontFamilies)); QVERIFY(properties.contains(QTextFormat::OldFontLetterSpacingType)); QVERIFY(properties.contains(QTextFormat::OldFontStretch)); - QVERIFY(properties.contains(QTextFormat::FontFamily)); + QVERIFY(properties.contains(QTextFormat::OldFontFamily)); } } diff --git a/tests/auto/gui/text/qtextimagehandler/CMakeLists.txt b/tests/auto/gui/text/qtextimagehandler/CMakeLists.txt new file mode 100644 index 0000000000..8d282b8f2c --- /dev/null +++ b/tests/auto/gui/text/qtextimagehandler/CMakeLists.txt @@ -0,0 +1,29 @@ +# 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") + +qt_internal_add_test(tst_qtextimagehandler + SOURCES + tst_qtextimagehandler.cpp + LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + TESTDATA + ${test_data} +) + +qt_internal_add_resource(tst_qtextimagehandler "qtextimagehandler" + PREFIX + "/" + FILES + ${test_data} +) diff --git a/tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp b/tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp index a1d9b2c6cf..5311aa6f2b 100644 --- a/tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp +++ b/tests/auto/gui/text/qtextimagehandler/tst_qtextimagehandler.cpp @@ -1,5 +1,5 @@ -// Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> @@ -17,6 +17,7 @@ private slots: void init(); void cleanup(); void cleanupTestCase(); + void loadAtNImages_data(); void loadAtNImages(); }; @@ -36,24 +37,40 @@ void tst_QTextImageHandler::cleanupTestCase() { } +void tst_QTextImageHandler::loadAtNImages_data() +{ + QTest::addColumn<QString>("imageFile"); + + QTest::addRow("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"; +} + void tst_QTextImageHandler::loadAtNImages() { + QFETCH(QString, imageFile); + QTextDocument doc; QTextCursor c(&doc); - c.insertHtml("<img src=\"data/image.png\">"); + c.insertHtml("<img src=\"" + imageFile + "\">"); + const auto formats = doc.allFormats(); + const auto it = std::find_if(formats.begin(), formats.end(), [](const auto &format){ + return format.objectType() == QTextFormat::ImageObject; + }); + QVERIFY(it != formats.end()); + const QTextImageFormat format = (*it).toImageFormat(); QTextImageHandler handler; - QTextImageFormat fmt; - fmt.setName("data/image.png"); - for (int i = 1; i < 3; ++i) { + for (const auto &dpr : {1, 2}) { QImage img(20, 20, QImage::Format_ARGB32_Premultiplied); img.fill(Qt::white); - img.setDevicePixelRatio(i); + img.setDevicePixelRatio(dpr); QPainter p(&img); - handler.drawObject(&p, QRect(0, 0, 20, 20), &doc, 0, fmt); + handler.drawObject(&p, QRect(0, 0, 20, 20), &doc, 0, format); p.end(); QVERIFY(!img.isNull()); - const auto expectedColor = i == 1 ? Qt::red : Qt::green; + const auto expectedColor = dpr == 1 ? Qt::red : Qt::green; QCOMPARE(img.pixelColor(0, 0), expectedColor); } } diff --git a/tests/auto/gui/text/qtextlayout/CMakeLists.txt b/tests/auto/gui/text/qtextlayout/CMakeLists.txt index 3fb5dea8b9..655c0985a0 100644 --- a/tests/auto/gui/text/qtextlayout/CMakeLists.txt +++ b/tests/auto/gui/text/qtextlayout/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qtextlayout.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index def7c88593..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 !!!!! @@ -124,7 +125,9 @@ private slots: void tooManyDirectionalCharctersCrash_qtbug77819(); void softHyphens_data(); void softHyphens(); + void min_maximumWidth_data(); void min_maximumWidth(); + void negativeLineWidth(); private: QFont testFont; @@ -289,14 +292,14 @@ void tst_QTextLayout::simpleBoundingRect() QString hello("hello world"); - const int width = hello.length() * testFont.pixelSize(); + const int width = hello.size() * testFont.pixelSize(); QTextLayout layout(hello, testFont); layout.beginLayout(); QTextLine line = layout.createLine(); line.setLineWidth(width); - QCOMPARE(line.textLength(), hello.length()); + QCOMPARE(line.textLength(), hello.size()); QCOMPARE(layout.boundingRect(), QRectF(0, 0, width, QFontMetrics(testFont).height())); } @@ -331,18 +334,18 @@ void tst_QTextLayout::threeLineBoundingRect() QString thirdWord("world"); QString text(firstWord + wordBoundary1 + secondWord + wordBoundary2 + thirdWord); - int firstLineWidth = firstWord.length() * testFont.pixelSize(); - int secondLineWidth = secondWord.length() * testFont.pixelSize(); - int thirdLineWidth = thirdWord.length() * testFont.pixelSize(); + int firstLineWidth = firstWord.size() * testFont.pixelSize(); + int secondLineWidth = secondWord.size() * testFont.pixelSize(); + int thirdLineWidth = thirdWord.size() * testFont.pixelSize(); // Trailing spaces do not count to line width: if (!wordBoundary1.isSpace()) firstLineWidth += testFont.pixelSize(); if (!wordBoundary2.isSpace()) secondLineWidth += testFont.pixelSize(); // But trailing spaces do count to line length: - const int firstLineLength = firstWord.length() + 1; - const int secondLineLength = secondWord.length() + 1; - const int thirdLineLength = thirdWord.length(); + const int firstLineLength = firstWord.size() + 1; + const int secondLineLength = secondWord.size() + 1; + const int thirdLineLength = thirdWord.size(); const int longestLine = qMax(firstLineWidth, qMax(secondLineWidth, thirdLineWidth)); @@ -386,7 +389,7 @@ void tst_QTextLayout::boundingRectWithLongLineAndNoWrap() { QString longString("thisisaverylongstringthatcannotbewrappedatallitjustgoesonandonlikeonebigword"); - const int width = longString.length() * testFont.pixelSize() / 20; // very small widthx + const int width = longString.size() * testFont.pixelSize() / 20; // very small widthx QTextLayout layout(longString, testFont); layout.beginLayout(); @@ -511,18 +514,24 @@ void tst_QTextLayout::noWrap() void tst_QTextLayout::cursorToXForInlineObjects() { - QChar ch(QChar::ObjectReplacementCharacter); - QString text(ch); - QTextLayout layout(text, testFont); - layout.beginLayout(); + QString text = QStringLiteral("<html><body><img src=\"\" width=\"32\" height=\"32\" /></body></html>"); - QTextEngine *engine = layout.engine(); - const int item = engine->findItem(0); - engine->layoutData->items[item].width = 32; + QTextDocument document; + document.setHtml(text); + QCOMPARE(document.blockCount(), 1); - QTextLine line = layout.createLine(); - line.setLineWidth(0x10000); + // Trigger layout + { + QImage img(1, 1, QImage::Format_ARGB32_Premultiplied); + QPainter p(&img); + document.drawContents(&p); + } + QTextLayout *layout = document.firstBlock().layout(); + QVERIFY(layout != nullptr); + QCOMPARE(layout->lineCount(), 1); + + QTextLine line = layout->lineAt(0); QCOMPARE(line.cursorToX(0), qreal(0)); QCOMPARE(line.cursorToX(1), qreal(32)); } @@ -720,29 +729,29 @@ void tst_QTextLayout::cursorToXForBidiBoundaries_data() QTest::addColumn<Qt::LayoutDirection>("textDirection"); QTest::addColumn<QString>("text"); QTest::addColumn<int>("cursorPosition"); - QTest::addColumn<int>("expectedX"); + QTest::addColumn<int>("runsToInclude"); QTest::addRow("LTR, abcشزذabc, 0") << Qt::LeftToRight << "abcشزذabc" << 0 << 0; QTest::addRow("RTL, abcشزذabc, 9") << Qt::RightToLeft << "abcشزذabc" - << 9 << TESTFONT_SIZE * 3; + << 9 << 1; QTest::addRow("LTR, abcشزذabc, 3") << Qt::LeftToRight << "abcشزذabc" << 0 << 0; QTest::addRow("RTL, abcشزذabc, 6") << Qt::RightToLeft << "abcشزذabc" - << 9 << TESTFONT_SIZE * 3; + << 9 << 1; QTest::addRow("LTR, شزذabcشزذ, 0") << Qt::LeftToRight << "شزذabcشزذ" - << 0 << TESTFONT_SIZE * 2; + << 0 << 1; QTest::addRow("RTL, شزذabcشزذ, 9") << Qt::RightToLeft << "شزذabcشزذ" << 9 << 0; QTest::addRow("LTR, شزذabcشزذ, 3") << Qt::LeftToRight << "شزذabcشزذ" - << 3 << TESTFONT_SIZE * 2; + << 3 << 1; QTest::addRow("RTL, شزذabcشزذ, 3") << Qt::RightToLeft << "شزذabcشزذ" - << 3 << TESTFONT_SIZE * 5; + << 3 << 2; QTest::addRow("LTR, شزذabcشزذ, 6") << Qt::LeftToRight << "شزذabcشزذ" - << 6 << TESTFONT_SIZE * 5; + << 6 << 2; QTest::addRow("RTL, شزذabcشزذ, 6") << Qt::RightToLeft << "شزذabcشزذ" - << 6 << TESTFONT_SIZE * 2; + << 6 << 1; } void tst_QTextLayout::cursorToXForBidiBoundaries() @@ -750,7 +759,7 @@ void tst_QTextLayout::cursorToXForBidiBoundaries() QFETCH(Qt::LayoutDirection, textDirection); QFETCH(QString, text); QFETCH(int, cursorPosition); - QFETCH(int, expectedX); + QFETCH(int, runsToInclude); QTextOption option; option.setTextDirection(textDirection); @@ -759,12 +768,30 @@ void tst_QTextLayout::cursorToXForBidiBoundaries() layout.setTextOption(option); layout.beginLayout(); - QTextLine line = layout.createLine(); - line.setLineWidth(0x10000); + { + QTextLine line = layout.createLine(); + line.setLineWidth(0x10000); + } + layout.endLayout(); - QCOMPARE(line.cursorToX(cursorPosition), expectedX); + QTextLine line = layout.lineAt(0); + QList<QGlyphRun> glyphRuns = line.glyphRuns(-1, + -1, + QTextLayout::RetrieveStringIndexes + | QTextLayout::RetrieveGlyphIndexes); + QVERIFY(runsToInclude <= glyphRuns.size()); + + std::sort(glyphRuns.begin(), glyphRuns.end(), + [](const QGlyphRun &first, const QGlyphRun &second) { + return first.stringIndexes().first() < second.stringIndexes().first(); + }); + + qreal expectedX = 0.0; + for (int i = 0; i < runsToInclude; ++i) { + expectedX += glyphRuns.at(i).boundingRect().width(); + } - layout.endLayout(); + QCOMPARE(line.cursorToX(cursorPosition), expectedX); } void tst_QTextLayout::horizontalAlignment_data() @@ -1139,7 +1166,7 @@ void tst_QTextLayout::xToCursorAtEndOfLine() QString text = "FirstLine SecondLine"; text.replace('\n', QChar::LineSeparator); - const qreal firstLineWidth = QString("FirstLine").length() * testFont.pixelSize(); + const qreal firstLineWidth = QString("FirstLine").size() * testFont.pixelSize(); QTextLayout layout(text, testFont); layout.setCacheEnabled(true); @@ -1282,7 +1309,7 @@ void tst_QTextLayout::integerOverflow() QVERIFY(line.isValid()); line.setLineWidth(INT_MAX); - QCOMPARE(line.textLength(), txt.length()); + QCOMPARE(line.textLength(), txt.size()); QVERIFY(!layout.createLine().isValid()); @@ -1857,7 +1884,7 @@ void tst_QTextLayout::capitalization_allUpperCase() QTextEngine *engine = layout.engine(); engine->itemize(); - QCOMPARE(engine->layoutData->items.count(), 1); + QCOMPARE(engine->layoutData->items.size(), 1); QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::Uppercase)); } @@ -1877,7 +1904,7 @@ void tst_QTextLayout::capitalization_allUpperCase_newline() QTextEngine *engine = layout.engine(); engine->itemize(); - QCOMPARE(engine->layoutData->items.count(), 3); + QCOMPARE(engine->layoutData->items.size(), 3); QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::Uppercase)); QCOMPARE(engine->layoutData->items.at(1).analysis.flags, ushort(QScriptAnalysis::LineOrParagraphSeparator)); QCOMPARE(engine->layoutData->items.at(2).analysis.flags, ushort(QScriptAnalysis::Uppercase)); @@ -1895,7 +1922,7 @@ void tst_QTextLayout::capitalization_allLowerCase() QTextEngine *engine = layout.engine(); engine->itemize(); - QCOMPARE(engine->layoutData->items.count(), 1); + QCOMPARE(engine->layoutData->items.size(), 1); QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::Lowercase)); } @@ -1911,7 +1938,7 @@ void tst_QTextLayout::capitalization_smallCaps() QTextEngine *engine = layout.engine(); engine->itemize(); - QCOMPARE(engine->layoutData->items.count(), 2); + QCOMPARE(engine->layoutData->items.size(), 2); QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::None)); QCOMPARE(engine->layoutData->items.at(1).analysis.flags, ushort(QScriptAnalysis::SmallCaps)); } @@ -1928,7 +1955,7 @@ void tst_QTextLayout::capitalization_capitalize() QTextEngine *engine = layout.engine(); engine->itemize(); - QCOMPARE(engine->layoutData->items.count(), 5); + QCOMPARE(engine->layoutData->items.size(), 5); QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::Uppercase)); QCOMPARE(engine->layoutData->items.at(1).analysis.flags, ushort(QScriptAnalysis::None)); QCOMPARE(engine->layoutData->items.at(2).analysis.flags, ushort(QScriptAnalysis::Tab)); @@ -2039,7 +2066,7 @@ void tst_QTextLayout::columnWrapWithTabs() textLayout.beginLayout(); QTextLine line = textLayout.createLine(); line.setNumColumns(30); - QCOMPARE(line.textLength(), text.length()); + QCOMPARE(line.textLength(), text.size()); textLayout.endLayout(); } @@ -2050,7 +2077,7 @@ void tst_QTextLayout::columnWrapWithTabs() textLayout.beginLayout(); QTextLine line = textLayout.createLine(); line.setNumColumns(30); - QVERIFY(line.textLength() < text.length()); + QVERIFY(line.textLength() < text.size()); textLayout.endLayout(); } @@ -2454,7 +2481,7 @@ void tst_QTextLayout::nbspWithFormat() layout.setText(s1 + s2 + nbsp + s3); QTextLayout::FormatRange formatRange; - formatRange.start = s1.length() + s2.length(); + formatRange.start = s1.size() + s2.size(); formatRange.length = 1; formatRange.format.setFontUnderline(true); @@ -2471,9 +2498,9 @@ void tst_QTextLayout::nbspWithFormat() QCOMPARE(layout.lineCount(), 2); QCOMPARE(layout.lineAt(0).textStart(), 0); - QCOMPARE(layout.lineAt(0).textLength(), s1.length()); - QCOMPARE(layout.lineAt(1).textStart(), s1.length()); - QCOMPARE(layout.lineAt(1).textLength(), s2.length() + 1 + s3.length()); + QCOMPARE(layout.lineAt(0).textLength(), s1.size()); + QCOMPARE(layout.lineAt(1).textStart(), s1.size()); + QCOMPARE(layout.lineAt(1).textLength(), s2.size() + 1 + s3.size()); } void tst_QTextLayout::koreanWordWrap() @@ -2647,13 +2674,35 @@ void tst_QTextLayout::softHyphens() } } +void tst_QTextLayout::min_maximumWidth_data() +{ + QTest::addColumn<QString>("text"); + + QTest::newRow("long string") << QStringLiteral("lmong_long_crazy_87235982735_23857239682376923876923876-fuwhfhfw-names-AAAA-deeaois2019-03-03.and.more"); + QTest::newRow("QTBUG-106947") << QStringLiteral("text text"); + QTest::newRow("spaces") << QStringLiteral(" text text "); + QTest::newRow("QTBUG-104986") << QStringLiteral("text\ntext\ntext"); + QTest::newRow("spaces + line breaks") << QStringLiteral(" \n text\n \ntext \n "); +} + void tst_QTextLayout::min_maximumWidth() { - QString longString("lmong_long_crazy_87235982735_23857239682376923876923876-fuwhfhfw-names-AAAA-deeaois2019-03-03.and.more"); - QTextLayout layout(longString, testFont); + QFETCH(QString, text); + text.replace('\n', QChar::LineSeparator); + + QTextLayout layout(text, testFont); + layout.setCacheEnabled(true); + + QTextOption opt; + opt.setWrapMode(QTextOption::NoWrap); + layout.setTextOption(opt); + layout.beginLayout(); + while (layout.createLine().isValid()) { } + layout.endLayout(); + + const qreal nonWrappedMaxWidth = layout.maximumWidth(); for (int wrapMode = QTextOption::NoWrap; wrapMode <= QTextOption::WrapAtWordBoundaryOrAnywhere; ++wrapMode) { - QTextOption opt; opt.setWrapMode((QTextOption::WrapMode)wrapMode); layout.setTextOption(opt); layout.beginLayout(); @@ -2662,6 +2711,9 @@ void tst_QTextLayout::min_maximumWidth() const qreal minWidth = layout.minimumWidth(); const qreal maxWidth = layout.maximumWidth(); + QCOMPARE_LE(minWidth, maxWidth); + QCOMPARE_LE(maxWidth, nonWrappedMaxWidth); // maxWidth for wrapped text shouldn't exceed maxWidth for the text without wrapping. + // Try the layout from slightly wider than the widest (maxWidth) // and narrow it down to slighly narrower than minWidth // layout.maximumWidth() should return the same regardless @@ -2683,5 +2735,28 @@ 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.setNumColumns(2, -1); + QVERIFY(line.textLength() > 0); + layout.endLayout(); + } +} + QTEST_MAIN(tst_QTextLayout) #include "tst_qtextlayout.moc" diff --git a/tests/auto/gui/text/qtextlist/CMakeLists.txt b/tests/auto/gui/text/qtextlist/CMakeLists.txt index 2f325d5e17..5764df3e99 100644 --- a/tests/auto/gui/text/qtextlist/CMakeLists.txt +++ b/tests/auto/gui/text/qtextlist/CMakeLists.txt @@ -1,14 +1,21 @@ -# Generated from qtextlist.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 tst_qtextlist.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate diff --git a/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp b/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp index 134249ee83..28eae93f6a 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; @@ -400,5 +402,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 3f23f03c3d..937dd5bd80 100644 --- a/tests/auto/gui/text/qtextmarkdownimporter/CMakeLists.txt +++ b/tests/auto/gui/text/qtextmarkdownimporter/CMakeLists.txt @@ -1,19 +1,26 @@ -# Generated from qtextmarkdownimporter.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 tst_qtextmarkdownimporter.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate 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"(\ö not a character entity)" << + R"(ö 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 884195345c..0cdf1d9225 100644 --- a/tests/auto/gui/text/qtextmarkdownwriter/CMakeLists.txt +++ b/tests/auto/gui/text/qtextmarkdownwriter/CMakeLists.txt @@ -1,17 +1,26 @@ -# Generated from qtextmarkdownwriter.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 tst_qtextmarkdownwriter.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate 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/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>!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~</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"(ö not a character entity)" << + R"(\ö 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") << "ö not a character entity" << "\\ö 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 07ea132de0..dd7aeae60e 100644 --- a/tests/auto/gui/text/qtextobject/CMakeLists.txt +++ b/tests/auto/gui/text/qtextobject/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qtextobject.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui ) @@ -15,6 +22,6 @@ qt_internal_add_test(tst_qtextobject ##################################################################### qt_internal_extend_target(tst_qtextobject CONDITION TARGET Qt::Widgets - PUBLIC_LIBRARIES + LIBRARIES Qt::Widgets ) 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 2a468b0c5e..d371fe2ee1 100644 --- a/tests/auto/gui/text/qtextodfwriter/CMakeLists.txt +++ b/tests/auto/gui/text/qtextodfwriter/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qtextodfwriter.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate diff --git a/tests/auto/gui/text/qtextodfwriter/tst_qtextodfwriter.cpp b/tests/auto/gui/text/qtextodfwriter/tst_qtextodfwriter.cpp index 30185e83b9..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> @@ -79,7 +79,7 @@ QString tst_QTextOdfWriter::getContentFromXml() if (index > 0) { index = stringContent.indexOf('>', index); if (index > 0) - ret = stringContent.mid(index+1, stringContent.length() - index - 10); + ret = stringContent.mid(index+1, stringContent.size() - index - 10); } return ret; } @@ -279,7 +279,7 @@ file.open(QIODevice::WriteOnly); file.write(buffer->data()); file.close(); */ - QVERIFY(buffer->data().length() > 80); + QVERIFY(buffer->data().size() > 80); QCOMPARE(buffer->data()[0], 'P'); // its a zip :) QCOMPARE(buffer->data()[1], 'K'); QString mimetype(buffer->data().mid(38, 39)); diff --git a/tests/auto/gui/text/qtextpiecetable/CMakeLists.txt b/tests/auto/gui/text/qtextpiecetable/CMakeLists.txt index 49cfcfab6a..8bdf17890c 100644 --- a/tests/auto/gui/text/qtextpiecetable/CMakeLists.txt +++ b/tests/auto/gui/text/qtextpiecetable/CMakeLists.txt @@ -1,4 +1,11 @@ -# Generated from qtextpiecetable.pro. +# 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() @@ -15,11 +22,8 @@ qt_internal_add_test(tst_qtextpiecetable SOURCES ../qtextdocument/common.h tst_qtextpiecetable.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate ) - -#### Keys ignored in scope 1:.:.:qtextpiecetable.pro:<TRUE>: -# _REQUIREMENTS = "!win32" "qtConfig(private_tests)" diff --git a/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp b/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp index 71afd31574..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(); @@ -971,7 +971,7 @@ void tst_QTextPieceTable::checkFrames1() QVERIFY(root); QVERIFY(!root->parentFrame()); - QCOMPARE(root->childFrames().count(), 1); + QCOMPARE(root->childFrames().size(), 1); QVERIFY(frame->format() == ffmt); QCOMPARE(frame->firstPosition(), 2); QCOMPARE(frame->lastPosition(), 4); @@ -979,10 +979,10 @@ void tst_QTextPieceTable::checkFrames1() QPointer<QTextFrame> frame2 = table->insertFrame(2, 3, ffmt); - QCOMPARE(root->childFrames().count(), 1); + QCOMPARE(root->childFrames().size(), 1); QCOMPARE(root->childFrames().at(0), frame.data()); - QCOMPARE(frame->childFrames().count(), 1); - QCOMPARE(frame2->childFrames().count(), 0); + QCOMPARE(frame->childFrames().size(), 1); + QCOMPARE(frame2->childFrames().size(), 0); QCOMPARE(frame2->parentFrame(), frame.data()); QCOMPARE(frame2->firstPosition(), 3); QCOMPARE(frame2->lastPosition(), 4); @@ -993,10 +993,10 @@ void tst_QTextPieceTable::checkFrames1() table->removeFrame(frame); - QCOMPARE(root->childFrames().count(), 1); + QCOMPARE(root->childFrames().size(), 1); QCOMPARE(root->childFrames().at(0), frame2.data()); QVERIFY(!frame); - QCOMPARE(frame2->childFrames().count(), 0); + QCOMPARE(frame2->childFrames().size(), 0); QCOMPARE(frame2->parentFrame(), root); QCOMPARE(frame2->firstPosition(), 2); QCOMPARE(frame2->lastPosition(), 3); @@ -1005,11 +1005,11 @@ void tst_QTextPieceTable::checkFrames1() frame = table->frameAt(2); - QCOMPARE(root->childFrames().count(), 1); + QCOMPARE(root->childFrames().size(), 1); QCOMPARE(root->childFrames().at(0), frame.data()); - QCOMPARE(frame->childFrames().count(), 1); + QCOMPARE(frame->childFrames().size(), 1); QCOMPARE(frame->childFrames().at(0), frame2.data()); - QCOMPARE(frame2->childFrames().count(), 0); + QCOMPARE(frame2->childFrames().size(), 0); QCOMPARE(frame2->parentFrame(), frame.data()); QCOMPARE(frame2->firstPosition(), 3); QCOMPARE(frame2->lastPosition(), 4); @@ -1019,9 +1019,9 @@ void tst_QTextPieceTable::checkFrames1() table->undo(); - QCOMPARE(root->childFrames().count(), 1); + QCOMPARE(root->childFrames().size(), 1); QCOMPARE(root->childFrames().at(0), frame.data()); - QCOMPARE(frame->childFrames().count(), 0); + QCOMPARE(frame->childFrames().size(), 0); QVERIFY(!frame2); QCOMPARE(frame->firstPosition(), 2); @@ -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 01d418ebd4..9bb9e4c13b 100644 --- a/tests/auto/gui/text/qtextscriptengine/CMakeLists.txt +++ b/tests/auto/gui/text/qtextscriptengine/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qtextscriptengine.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate diff --git a/tests/auto/gui/text/qtextscriptengine/generate/CMakeLists.txt b/tests/auto/gui/text/qtextscriptengine/generate/CMakeLists.txt index d3b6b1dc6d..db284b2e1c 100644 --- a/tests/auto/gui/text/qtextscriptengine/generate/CMakeLists.txt +++ b/tests/auto/gui/text/qtextscriptengine/generate/CMakeLists.txt @@ -1,4 +1,5 @@ -# Generated from generate.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## generate Binary: @@ -9,9 +10,8 @@ qt_internal_add_executable(generate SOURCES main.cpp INCLUDE_DIRECTORIES - . /usr/include/freetype2 - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui ) 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 f28478dafd..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> @@ -1094,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) diff --git a/tests/auto/gui/text/qtexttable/CMakeLists.txt b/tests/auto/gui/text/qtexttable/CMakeLists.txt index 94d33d3530..e83a38f087 100644 --- a/tests/auto/gui/text/qtexttable/CMakeLists.txt +++ b/tests/auto/gui/text/qtexttable/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qtexttable.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## 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 - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui Qt::GuiPrivate ) @@ -16,6 +23,6 @@ qt_internal_add_test(tst_qtexttable ##################################################################### qt_internal_extend_target(tst_qtexttable CONDITION TARGET Qt::Widgets - PUBLIC_LIBRARIES + LIBRARIES Qt::Widgets ) diff --git a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp index bfead23d4d..d0e1e1cd74 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(); @@ -121,7 +123,7 @@ void tst_QTextTable::variousTableModifications() QTextTableFormat tableFmt; QTextTable *tab = cursor.insertTable(2, 2, tableFmt); - QCOMPARE(doc->toPlainText().length(), 5); + QCOMPARE(doc->toPlainText().size(), 5); QCOMPARE(tab, cursor.currentTable()); QCOMPARE(tab->columns(), 2); QCOMPARE(tab->rows(), 2); @@ -176,14 +178,14 @@ void tst_QTextTable::variousTableModifications() cursor.movePosition(QTextCursor::NextBlock); QCOMPARE(cursor.position(), 1); cursor.deleteChar(); - QCOMPARE(doc->toPlainText().length(), 5); + QCOMPARE(doc->toPlainText().size(), 5); cursor.movePosition(QTextCursor::NextBlock); QCOMPARE(cursor.position(), 2); cursor.deleteChar(); - QCOMPARE(doc->toPlainText().length(), 5); + QCOMPARE(doc->toPlainText().size(), 5); cursor.deletePreviousChar(); QCOMPARE(cursor.position(), 2); - QCOMPARE(doc->toPlainText().length(), 5); + QCOMPARE(doc->toPlainText().size(), 5); QTextTable *table = cursor.currentTable(); QCOMPARE(table->rows(), 2); @@ -192,16 +194,16 @@ void tst_QTextTable::variousTableModifications() table->insertRows(2, 1); QCOMPARE(table->rows(), 3); QCOMPARE(table->columns(), 2); - QCOMPARE(doc->toPlainText().length(), 7); + QCOMPARE(doc->toPlainText().size(), 7); table->insertColumns(2, 2); QCOMPARE(table->rows(), 3); QCOMPARE(table->columns(), 4); - QCOMPARE(doc->toPlainText().length(), 13); + QCOMPARE(doc->toPlainText().size(), 13); table->resize(4, 5); QCOMPARE(table->rows(), 4); QCOMPARE(table->columns(), 5); - QCOMPARE(doc->toPlainText().length(), 21); + QCOMPARE(doc->toPlainText().size(), 21); } void tst_QTextTable::tableShrinking() @@ -209,7 +211,7 @@ void tst_QTextTable::tableShrinking() QTextTableFormat tableFmt; cursor.insertTable(3, 4, tableFmt); - QCOMPARE(doc->toPlainText().length(), 13); + QCOMPARE(doc->toPlainText().size(), 13); QTextTable *table = cursor.currentTable(); QCOMPARE(table->rows(), 3); @@ -218,16 +220,16 @@ void tst_QTextTable::tableShrinking() table->removeRows(1, 1); QCOMPARE(table->rows(), 2); QCOMPARE(table->columns(), 4); - QCOMPARE(doc->toPlainText().length(), 9); + QCOMPARE(doc->toPlainText().size(), 9); table->removeColumns(1, 2); QCOMPARE(table->rows(), 2); QCOMPARE(table->columns(), 2); - QCOMPARE(doc->toPlainText().length(), 5); + QCOMPARE(doc->toPlainText().size(), 5); table->resize(1, 1); QCOMPARE(table->rows(), 1); QCOMPARE(table->columns(), 1); - QCOMPARE(doc->toPlainText().length(), 2); + QCOMPARE(doc->toPlainText().size(), 2); } void tst_QTextTable::spans() @@ -252,7 +254,7 @@ void tst_QTextTable::variousModifications2() QTextTableFormat tableFmt; cursor.insertTable(2, 5, tableFmt); - QCOMPARE(doc->toPlainText().length(), 11); + QCOMPARE(doc->toPlainText().size(), 11); QTextTable *table = cursor.currentTable(); QCOMPARE(cursor.position(), 1); QCOMPARE(table->rows(), 2); @@ -1148,8 +1150,8 @@ void tst_QTextTable::QTBUG31330_renderBackground() doc.print(&paintDevice); QVERIFY(paintDevice.pages >= 2); - QCOMPARE(engine.rects.count(), paintDevice.pages); - for (int i = 0; i < engine.rects.count(); ++i) { + QCOMPARE(engine.rects.size(), paintDevice.pages); + for (int i = 0; i < engine.rects.size(); ++i) { QRectF rect = engine.rects[i]; QVERIFY(rect.top() > 0); QVERIFY(rect.bottom() < 1000); @@ -1261,6 +1263,72 @@ void tst_QTextTable::checkBorderAttributes() } } +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); + + 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); +} + #ifndef QT_NO_WIDGETS void tst_QTextTable::columnWidthWithSpans() { 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 dceda50251..0000000000 --- a/tests/auto/gui/text/qzip/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Generated from qzip.pro. - -##################################################################### -## 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 - PUBLIC_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 Binary files differdeleted file mode 100644 index 027f96477a..0000000000 --- a/tests/auto/gui/text/qzip/testdata/symlink.zip +++ /dev/null diff --git a/tests/auto/gui/text/qzip/testdata/test.zip b/tests/auto/gui/text/qzip/testdata/test.zip Binary files differdeleted file mode 100644 index a57ba4e2a9..0000000000 --- a/tests/auto/gui/text/qzip/testdata/test.zip +++ /dev/null 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 128f0b3200..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.count(), 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.count(), 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.count(), 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.count(), 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" |