diff options
Diffstat (limited to 'tests/auto')
15 files changed, 347 insertions, 44 deletions
diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index 4bb3518..484fbef 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -24,6 +24,7 @@ SUBDIRS += \ qdeclarativeecmascript \ qdeclarativeengine \ qdeclarativeerror \ + qdeclarativefolderlistmodel \ qdeclarativefontloader \ qdeclarativeflickable \ qdeclarativeflipable \ diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/groupedPropertyCrash.qml b/tests/auto/declarative/qdeclarativebehaviors/data/groupedPropertyCrash.qml new file mode 100644 index 0000000..c052366 --- /dev/null +++ b/tests/auto/declarative/qdeclarativebehaviors/data/groupedPropertyCrash.qml @@ -0,0 +1,10 @@ +import Qt 4.7 + +Rectangle { + width: 200 + height: 200 + Text { + Behavior on anchors.verticalCenterOffset { NumberAnimation { duration: 300; } } + text: "Hello World" + } +} diff --git a/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp b/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp index 1dc4b53..45e5304 100644 --- a/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp +++ b/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp @@ -72,6 +72,7 @@ private slots: void disabled(); void dontStart(); void startup(); + void groupedPropertyCrash(); }; void tst_qdeclarativebehaviors::simpleBehavior() @@ -351,6 +352,15 @@ void tst_qdeclarativebehaviors::startup() } } +//QTBUG-10799 +void tst_qdeclarativebehaviors::groupedPropertyCrash() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/groupedPropertyCrash.qml")); + QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(c.create()); + QVERIFY(rect); //don't crash +} + QTEST_MAIN(tst_qdeclarativebehaviors) #include "tst_qdeclarativebehaviors.moc" diff --git a/tests/auto/declarative/qdeclarativecomponent/data/createObject.qml b/tests/auto/declarative/qdeclarativecomponent/data/createObject.qml new file mode 100644 index 0000000..4ee1e75 --- /dev/null +++ b/tests/auto/declarative/qdeclarativecomponent/data/createObject.qml @@ -0,0 +1,16 @@ +import Qt 4.7 + +Item{ + id: root + property QtObject qobject : null + property QtObject declarativeitem : null + property QtObject graphicswidget: null + Component{id: a; QtObject{} } + Component{id: b; Item{} } + Component{id: c; QGraphicsWidget{} } + Component.onCompleted: { + root.qobject = a.createObject(root); + root.declarativeitem = b.createObject(root); + root.graphicswidget = c.createObject(root); + } +} diff --git a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp index c9e304c..faa1c21 100644 --- a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp +++ b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp @@ -39,7 +39,9 @@ ** ****************************************************************************/ #include <qtest.h> +#include <QDebug> +#include <QtGui/qgraphicsitem.h> #include <QtDeclarative/qdeclarativeengine.h> #include <QtDeclarative/qdeclarativecomponent.h> @@ -51,6 +53,7 @@ public: private slots: void loadEmptyUrl(); + void qmlCreateObject(); private: QDeclarativeEngine engine; @@ -70,6 +73,31 @@ void tst_qdeclarativecomponent::loadEmptyUrl() QCOMPARE(error.description(), QLatin1String("Invalid empty URL")); } +void tst_qdeclarativecomponent::qmlCreateObject() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/createObject.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QObject *testObject1 = object->property("qobject").value<QObject*>(); + QVERIFY(testObject1); + QVERIFY(testObject1->parent() == object); + + QObject *testObject2 = object->property("declarativeitem").value<QObject*>(); + QVERIFY(testObject2); + QVERIFY(testObject2->parent() == object); + QCOMPARE(testObject2->metaObject()->className(), "QDeclarativeItem"); + + //Note that QGraphicsObjects are not exposed to QML for instantiation, and so can't be used in a component directly + //Also this is actually the extended type QDeclarativeGraphicsWidget, but it still doesn't inherit QDeclarativeItem + QGraphicsObject *testObject3 = qobject_cast<QGraphicsObject*>(object->property("graphicswidget").value<QObject*>()); + QVERIFY(testObject3); + QVERIFY(testObject3->parent() == object); + QVERIFY(testObject3->parentItem() == qobject_cast<QGraphicsObject*>(object)); + QCOMPARE(testObject3->metaObject()->className(), "QDeclarativeGraphicsWidget"); +} + QTEST_MAIN(tst_qdeclarativecomponent) #include "tst_qdeclarativecomponent.moc" diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 9a8ad64..e75abac 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -564,7 +564,7 @@ void tst_qdeclarativeecmascript::deferredPropertiesErrors() QVERIFY(object->objectProperty() == 0); QVERIFY(object->objectProperty2() == 0); - QString warning = component.url().toString() + ":6: Unable to assign [undefined] to QObject*"; + QString warning = component.url().toString() + ":6: Unable to assign [undefined] to QObject* objectProperty"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); qmlExecuteDeferred(object); @@ -642,8 +642,8 @@ void tst_qdeclarativeecmascript::enums() { QDeclarativeComponent component(&engine, TEST_FILE("enums.2.qml")); - QString warning1 = component.url().toString() + ":5: Unable to assign [undefined] to int"; - QString warning2 = component.url().toString() + ":6: Unable to assign [undefined] to int"; + QString warning1 = component.url().toString() + ":5: Unable to assign [undefined] to int a"; + QString warning2 = component.url().toString() + ":6: Unable to assign [undefined] to int b"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); @@ -754,7 +754,7 @@ void tst_qdeclarativeecmascript::nonExistantAttachedObject() { QDeclarativeComponent component(&engine, TEST_FILE("nonExistantAttachedObject.qml")); - QString warning = component.url().toString() + ":4: Unable to assign [undefined] to QString"; + QString warning = component.url().toString() + ":4: Unable to assign [undefined] to QString stringProperty"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); QObject *object = component.create(); @@ -1001,7 +1001,7 @@ void tst_qdeclarativeecmascript::scriptErrors() QString warning3 = url.left(url.length() - 3) + "js:4: Error: Invalid write to global property \"a\""; QString warning4 = url + ":10: TypeError: Result of expression 'a' [undefined] is not an object."; QString warning5 = url + ":8: TypeError: Result of expression 'a' [undefined] is not an object."; - QString warning6 = url + ":7: Unable to assign [undefined] to int"; + QString warning6 = url + ":7: Unable to assign [undefined] to int x"; QString warning7 = url + ":12: Error: Cannot assign to read-only property \"trueProperty\""; QString warning8 = url + ":13: Error: Cannot assign to non-existent property \"fakeProperty\""; diff --git a/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp b/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp index b0db771..0aebea1 100644 --- a/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp +++ b/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp @@ -266,7 +266,7 @@ void tst_qdeclarativeengine::outputWarningsToStandardError() delete o; QCOMPARE(warnings.count(), 1); - QCOMPARE(warnings.at(0), QLatin1String("<Unknown File>:1: Unable to assign [undefined] to int")); + QCOMPARE(warnings.at(0), QLatin1String("<Unknown File>:1: Unable to assign [undefined] to int a")); warnings.clear(); diff --git a/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp b/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp index 8a8bfe7..3cf9613 100644 --- a/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp +++ b/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp @@ -93,7 +93,6 @@ void tst_qdeclarativefolderlistmodel::basicProperties() QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(component.create()); QVERIFY(flm != 0); - flm->setProperty("folder",QUrl::fromLocalFile(SRCDIR "/data")); QTRY_COMPARE(flm->property("count").toInt(),2); // wait for refresh QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile(SRCDIR "/data")); @@ -105,7 +104,10 @@ void tst_qdeclarativefolderlistmodel::basicProperties() QCOMPARE(flm->property("showDotAndDotDot").toBool(), false); QCOMPARE(flm->property("showOnlyReadable").toBool(), false); QCOMPARE(flm->data(flm->index(0),FileNameRole).toString(), QLatin1String("basic.qml")); - QCOMPARE(flm->data(flm->index(1),FileNameRole).toString(), QLatin1String("dummy.qml")); + QCOMPARE(flm->data(flm->index(1),FileNameRole).toString(), QLatin1String("dummy.qml")); + + flm->setProperty("folder",QUrl::fromLocalFile("")); + QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile("")); } QTEST_MAIN(tst_qdeclarativefolderlistmodel) diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro index 1bf1c58..7c006f1 100644 --- a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro +++ b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro @@ -1,5 +1,5 @@ load(qttest_p4) -contains(QT_CONFIG,declarative): QT += declarative gui +contains(QT_CONFIG,declarative): QT += declarative script gui contains(QT_CONFIG,xmlpatterns) { QT += xmlpatterns DEFINES += QTEST_XMLPATTERNS diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp index 7769979..35790e4 100644 --- a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp +++ b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp @@ -81,6 +81,7 @@ private slots: void source(); void source_data(); void data(); + void get(); void reload(); void useKeys(); void useKeys_data(); @@ -223,6 +224,8 @@ void tst_qdeclarativexmllistmodel::roleErrors() { QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/roleErrors.qml")); QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(SRCDIR "/data/roleErrors.qml").toString() + ":6:5: QML XmlRole: An XmlRole query must not start with '/'").toUtf8().constData()); + QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(SRCDIR "/data/roleErrors.qml").toString() + ":9:5: QML XmlRole: invalid query: \"age/\"").toUtf8().constData()); + //### make sure we receive all expected warning messages. QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create()); QVERIFY(model != 0); @@ -388,6 +391,46 @@ void tst_qdeclarativexmllistmodel::data() delete model; } +void tst_qdeclarativexmllistmodel::get() +{ + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/model.qml")); + QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create()); + QVERIFY(model != 0); + QVERIFY(model->get(0).isUndefined()); + + QTRY_COMPARE(model->count(), 9); + QVERIFY(model->get(-1).isUndefined()); + + QScriptValue sv = model->get(0); + QCOMPARE(sv.property("name").toString(), QLatin1String("Polly")); + QCOMPARE(sv.property("type").toString(), QLatin1String("Parrot")); + QCOMPARE(sv.property("age").toNumber(), qsreal(12)); + QCOMPARE(sv.property("size").toString(), QLatin1String("Small")); + + sv = model->get(1); + QCOMPARE(sv.property("name").toString(), QLatin1String("Penny")); + QCOMPARE(sv.property("type").toString(), QLatin1String("Turtle")); + QCOMPARE(sv.property("age").toNumber(), qsreal(4)); + QCOMPARE(sv.property("size").toString(), QLatin1String("Small")); + + sv = model->get(7); + QCOMPARE(sv.property("name").toString(), QLatin1String("Rover")); + QCOMPARE(sv.property("type").toString(), QLatin1String("Dog")); + QCOMPARE(sv.property("age").toNumber(), qsreal(0)); + QCOMPARE(sv.property("size").toString(), QLatin1String("Large")); + + sv = model->get(8); + QCOMPARE(sv.property("name").toString(), QLatin1String("Tiny")); + QCOMPARE(sv.property("type").toString(), QLatin1String("Elephant")); + QCOMPARE(sv.property("age").toNumber(), qsreal(15)); + QCOMPARE(sv.property("size").toString(), QLatin1String("Large")); + + sv = model->get(9); + QVERIFY(sv.isUndefined()); + + delete model; +} + void tst_qdeclarativexmllistmodel::reload() { // If no keys are used, the model should be rebuilt from scratch when diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index f105692..71dc451 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -81,11 +81,11 @@ QString tst_qmlvisual::viewer() QString qmlruntime; #if defined(Q_WS_MAC) - qmlruntime = QDir(binaries).absoluteFilePath("qml.app/Contents/MacOS/qml"); + qmlruntime = QDir(binaries).absoluteFilePath("QMLViewer.app/Contents/MacOS/QMLViewer"); #elif defined(Q_WS_WIN) || defined(Q_WS_S60) - qmlruntime = QDir(binaries).absoluteFilePath("qml.exe"); + qmlruntime = QDir(binaries).absoluteFilePath("qmlviewer.exe"); #else - qmlruntime = QDir(binaries).absoluteFilePath("qml"); + qmlruntime = QDir(binaries).absoluteFilePath("qmlviewer"); #endif return qmlruntime; diff --git a/tests/auto/headers/tst_headers.cpp b/tests/auto/headers/tst_headers.cpp index 12c5843..0538607 100644 --- a/tests/auto/headers/tst_headers.cpp +++ b/tests/auto/headers/tst_headers.cpp @@ -64,7 +64,8 @@ private: const QStringList dirFilters, const QRegExp &exclude); static QStringList getHeaders(const QString &path); - static QStringList getSourceFiles(const QString &path); + static QStringList getQmlFiles(const QString &path); + static QStringList getCppFiles(const QString &path); static QStringList getQDocFiles(const QString &path); void allSourceFilesData(); @@ -107,11 +108,16 @@ QStringList tst_Headers::getHeaders(const QString &path) return getFiles(path, QStringList("*.h"), QRegExp("^(?!ui_)")); } -QStringList tst_Headers::getSourceFiles(const QString &path) +QStringList tst_Headers::getCppFiles(const QString &path) { return getFiles(path, QStringList("*.cpp"), QRegExp("^(?!(moc_|qrc_))")); } +QStringList tst_Headers::getQmlFiles(const QString &path) +{ + return getFiles(path, QStringList("*.qml"), QRegExp(".")); +} + QStringList tst_Headers::getQDocFiles(const QString &path) { return getFiles(path, QStringList("*.qdoc"), QRegExp(".")); @@ -153,7 +159,9 @@ void tst_Headers::allSourceFilesData() }; for (int i = 0; i < sizeof(subdirs) / sizeof(subdirs[0]); ++i) { - sourceFiles << getSourceFiles(qtSrcDir + subdirs[i]); + sourceFiles << getCppFiles(qtSrcDir + subdirs[i]); + if (subdirs[i] != QLatin1String("/tests")) + sourceFiles << getQmlFiles(qtSrcDir + subdirs[i]); sourceFiles << getHeaders(qtSrcDir + subdirs[i]); sourceFiles << getQDocFiles(qtSrcDir + subdirs[i]); } diff --git a/tests/auto/qchar/tst_qchar.cpp b/tests/auto/qchar/tst_qchar.cpp index 5ca2255..93aaf96 100644 --- a/tests/auto/qchar/tst_qchar.cpp +++ b/tests/auto/qchar/tst_qchar.cpp @@ -43,6 +43,7 @@ #include <QtTest/QtTest> #include <qchar.h> #include <qfile.h> +#include <qstringlist.h> #include <private/qunicodetables_p.h> #if defined(Q_OS_WINCE) #include <qcoreapplication.h> @@ -75,6 +76,7 @@ private slots: void isPrint(); void isUpper(); void isLower(); + void isTitle(); void category(); void direction(); void joining(); @@ -83,7 +85,9 @@ private slots: void decomposition(); // void ligature(); void lineBreakClass(); + void normalization_data(); void normalization(); + void normalization_manual(); void normalizationCorrections(); void unicodeVersion(); #if defined(Q_OS_WINCE) @@ -234,6 +238,11 @@ void tst_QChar::isUpper() QVERIFY(!QChar('?').isUpper()); QVERIFY(QChar(0xC2).isUpper()); // A with ^ QVERIFY(!QChar(0xE2).isUpper()); // a with ^ + + for (uint codepoint = 0; codepoint <= UNICODE_LAST_CODEPOINT; ++codepoint) { + if (QChar::category(codepoint) == QChar::Letter_Uppercase) + QVERIFY(codepoint == QChar::toUpper(codepoint)); + } } void tst_QChar::isLower() @@ -245,6 +254,19 @@ void tst_QChar::isLower() QVERIFY(!QChar('?').isLower()); QVERIFY(!QChar(0xC2).isLower()); // A with ^ QVERIFY(QChar(0xE2).isLower()); // a with ^ + + for (uint codepoint = 0; codepoint <= UNICODE_LAST_CODEPOINT; ++codepoint) { + if (QChar::category(codepoint) == QChar::Letter_Lowercase) + QVERIFY(codepoint == QChar::toLower(codepoint)); + } +} + +void tst_QChar::isTitle() +{ + for (uint codepoint = 0; codepoint <= UNICODE_LAST_CODEPOINT; ++codepoint) { + if (QChar::category(codepoint) == QChar::Letter_Titlecase) + QVERIFY(codepoint == QChar::toTitleCase(codepoint)); + } } void tst_QChar::category() @@ -486,31 +508,13 @@ void tst_QChar::lineBreakClass() QVERIFY(QUnicodeTables::lineBreakClass(0x0fffdu) == QUnicodeTables::LineBreak_AL); } -void tst_QChar::normalization() +void tst_QChar::normalization_data() { - { - QString composed; - composed += QChar(0xc0); - QString decomposed; - decomposed += QChar(0x41); - decomposed += QChar(0x300); + QTest::addColumn<QStringList>("columns"); + QTest::addColumn<int>("part"); - QVERIFY(composed.normalized(QString::NormalizationForm_D) == decomposed); - QVERIFY(composed.normalized(QString::NormalizationForm_C) == composed); - QVERIFY(composed.normalized(QString::NormalizationForm_KD) == decomposed); - QVERIFY(composed.normalized(QString::NormalizationForm_KC) == composed); - } - { - QString composed; - composed += QChar(0xa0); - QString decomposed; - decomposed += QChar(0x20); - - QVERIFY(composed.normalized(QString::NormalizationForm_D) == composed); - QVERIFY(composed.normalized(QString::NormalizationForm_C) == composed); - QVERIFY(composed.normalized(QString::NormalizationForm_KD) == decomposed); - QVERIFY(composed.normalized(QString::NormalizationForm_KC) == decomposed); - } + int linenum = 0; + int part = 0; QFile f(SRCDIR "NormalizationTest.txt"); QVERIFY(f.exists()); @@ -518,6 +522,8 @@ void tst_QChar::normalization() f.open(QIODevice::ReadOnly); while (!f.atEnd()) { + linenum++; + QByteArray line; line.resize(1024); int len = f.readLine(line.data(), 1024); @@ -527,8 +533,11 @@ void tst_QChar::normalization() if (comment >= 0) line = line.left(comment); - if (line.startsWith("@")) + if (line.startsWith("@")) { + if (line.startsWith("@Part") && line.size() > 5 && QChar(line.at(5)).isDigit()) + part = QChar(line.at(5)).digitValue(); continue; + } if (line.isEmpty()) continue; @@ -541,8 +550,10 @@ void tst_QChar::normalization() Q_ASSERT(l.size() == 5); - QString columns[5]; + QStringList columns; for (int i = 0; i < 5; ++i) { + columns.append(QString()); + QList<QByteArray> c = l.at(i).split(' '); Q_ASSERT(!c.isEmpty()); @@ -553,15 +564,26 @@ void tst_QChar::normalization() columns[i].append(QChar(uc)); else { // convert to utf16 - uc -= 0x10000; - ushort high = uc/0x400 + 0xd800; - ushort low = uc%0x400 + 0xdc00; + ushort high = QChar::highSurrogate(uc); + ushort low = QChar::lowSurrogate(uc); columns[i].append(QChar(high)); columns[i].append(QChar(low)); } } } + QString nm = QString("line #%1:").arg(linenum); + QTest::newRow(nm.toLatin1()) << columns << part; + } +} + +void tst_QChar::normalization() +{ + QFETCH(QStringList, columns); + QFETCH(int, part); + + Q_UNUSED(part) + // CONFORMANCE: // 1. The following invariants must be true for all conformant implementations // @@ -611,6 +633,32 @@ void tst_QChar::normalization() // ################# +} + +void tst_QChar::normalization_manual() +{ + { + QString composed; + composed += QChar(0xc0); + QString decomposed; + decomposed += QChar(0x41); + decomposed += QChar(0x300); + + QVERIFY(composed.normalized(QString::NormalizationForm_D) == decomposed); + QVERIFY(composed.normalized(QString::NormalizationForm_C) == composed); + QVERIFY(composed.normalized(QString::NormalizationForm_KD) == decomposed); + QVERIFY(composed.normalized(QString::NormalizationForm_KC) == composed); + } + { + QString composed; + composed += QChar(0xa0); + QString decomposed; + decomposed += QChar(0x20); + + QVERIFY(composed.normalized(QString::NormalizationForm_D) == composed); + QVERIFY(composed.normalized(QString::NormalizationForm_C) == composed); + QVERIFY(composed.normalized(QString::NormalizationForm_KD) == decomposed); + QVERIFY(composed.normalized(QString::NormalizationForm_KC) == decomposed); } } diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 5a5a821..300afc3 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -236,11 +236,12 @@ public: QRectF boundingRect() const { return br; } - void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) + void paint(QPainter *painter, const QStyleOptionGraphicsItem *o, QWidget *) { hints = painter->renderHints(); painter->setBrush(brush); painter->drawRect(boundingRect()); + lastExposedRect = o->exposedRect; ++repaints; } @@ -250,10 +251,19 @@ public: return QGraphicsItem::sceneEvent(event); } + void reset() + { + events.clear(); + hints = QPainter::RenderHints(0); + repaints = 0; + lastExposedRect = QRectF(); + } + QList<QEvent::Type> events; QPainter::RenderHints hints; int repaints; QRectF br; + QRectF lastExposedRect; QBrush brush; }; @@ -430,6 +440,7 @@ private slots: void scenePosChange(); void updateMicroFocus(); void textItem_shortcuts(); + void scroll(); // task specific tests below me void task141694_textItemEnsureVisible(); @@ -10155,6 +10166,78 @@ void tst_QGraphicsItem::textItem_shortcuts() QTRY_COMPARE(item->textCursor().selectedText(), item->toPlainText()); } +void tst_QGraphicsItem::scroll() +{ + // Create two overlapping rectangles in the scene: + // +-------+ + // | | <- item1 + // | +-------+ + // | | | + // +---| | <- item2 + // | | + // +-------+ + + EventTester *item1 = new EventTester; + item1->br = QRectF(0, 0, 200, 200); + item1->brush = Qt::red; + item1->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption); + + EventTester *item2 = new EventTester; + item2->br = QRectF(0, 0, 200, 200); + item2->brush = Qt::blue; + item2->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption); + item2->setPos(100, 100); + + QGraphicsScene scene(0, 0, 300, 300); + scene.addItem(item1); + scene.addItem(item2); + + MyGraphicsView view(&scene); + view.setFrameStyle(0); + view.show(); + QTest::qWaitForWindowShown(&view); + QTRY_VERIFY(view.repaints > 0); + + view.reset(); + item1->reset(); + item2->reset(); + + const QRectF item1BoundingRect = item1->boundingRect(); + const QRectF item2BoundingRect = item2->boundingRect(); + + // Scroll item1: + // Item1 should get full exposure + // Item2 should get exposure for the part that overlaps item1. + item1->scroll(0, -10); + QTRY_VERIFY(view.repaints > 0); + QCOMPARE(item1->lastExposedRect, item1BoundingRect); + + QRectF expectedItem2Expose = item2BoundingRect; + // NB! Adjusted by 2 pixels for antialiasing + expectedItem2Expose &= item1->mapRectToItem(item2, item1BoundingRect.adjusted(-2, -2, 2, 2)); + QCOMPARE(item2->lastExposedRect, expectedItem2Expose); + + // Enable ItemCoordinateCache on item1. + view.reset(); + item1->setCacheMode(QGraphicsItem::ItemCoordinateCache); + QTRY_VERIFY(view.repaints > 0); + view.reset(); + item1->reset(); + item2->reset(); + + // Scroll item1: + // Item1 should only get expose for the newly exposed area (accelerated scroll). + // Item2 should get exposure for the part that overlaps item1. + item1->scroll(0, -10, QRectF(50, 50, 100, 100)); + QTRY_VERIFY(view.repaints > 0); + QCOMPARE(item1->lastExposedRect, QRectF(50, 140, 100, 10)); + + expectedItem2Expose = item2BoundingRect; + // NB! Adjusted by 2 pixels for antialiasing + expectedItem2Expose &= item1->mapRectToItem(item2, QRectF(50, 50, 100, 100).adjusted(-2, -2, 2, 2)); + QCOMPARE(item2->lastExposedRect, expectedItem2Expose); +} + void tst_QGraphicsItem::QTBUG_5418_textItemSetDefaultColor() { struct Item : public QGraphicsTextItem diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp index e10d7ee..b6bdb36 100644 --- a/tests/auto/qmenu/tst_qmenu.cpp +++ b/tests/auto/qmenu/tst_qmenu.cpp @@ -51,6 +51,7 @@ #include <QListWidget> #include <QWidgetAction> #include <QDesktopWidget> +#include <qdialog.h> #include <qmenu.h> #include <qstyle.h> @@ -106,6 +107,7 @@ private slots: void pushButtonPopulateOnAboutToShow(); void QTBUG7907_submenus_autoselect(); void QTBUG7411_submenus_activate(); + void QTBUG_10735_crashWithDialog(); protected slots: void onActivated(QAction*); void onHighlighted(QAction*); @@ -969,5 +971,57 @@ void tst_QMenu::QTBUG7411_submenus_activate() +class MyMenu : public QMenu +{ + Q_OBJECT +public: + MyMenu() : m_currentIndex(0) + { + for (int i = 0; i < 2; ++i) + dialogActions[i] = addAction( QString("dialog %1").arg(i), dialogs + i, SLOT(exec())); + } + + + void activateAction(int index) + { + m_currentIndex = index; + popup(QPoint()); + QTest::qWaitForWindowShown(this); + setActiveAction(dialogActions[index]); + QTimer::singleShot(500, this, SLOT(checkVisibility())); + QTest::keyClick(this, Qt::Key_Enter); //activation + } + +public slots: + void activateLastAction() + { + activateAction(1); + } + + void checkVisibility() + { + QTRY_VERIFY(dialogs[m_currentIndex].isVisible()); + if (m_currentIndex == 1) { + QApplication::closeAllWindows(); //this is the end of the test + } + } + + +private: + QAction *dialogActions[2]; + QDialog dialogs[2]; + int m_currentIndex; +}; + +void tst_QMenu::QTBUG_10735_crashWithDialog() +{ + MyMenu menu; + + QTimer::singleShot(1000, &menu, SLOT(activateLastAction())); + menu.activateAction(0); + +} + + QTEST_MAIN(tst_QMenu) #include "tst_qmenu.moc" |