diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-06-08 18:47:57 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-06-08 18:47:57 (GMT) |
commit | d7d55ab51381f5805d52523d98623e63a99db2cf (patch) | |
tree | 5b760b92f84bdb2137fe7d53e16d78c0693fd2f4 /tests/auto | |
parent | c5de4176dac960d8f7c6d2d77b0d8bf3c7311da9 (diff) | |
parent | 2ae808a23ce05bf9768ad9df107c16bb0c555ee7 (diff) | |
download | Qt-d7d55ab51381f5805d52523d98623e63a99db2cf.zip Qt-d7d55ab51381f5805d52523d98623e63a99db2cf.tar.gz Qt-d7d55ab51381f5805d52523d98623e63a99db2cf.tar.bz2 |
Merge remote branch 'origin/4.7' into qt-master-from-4.7
Conflicts:
tools/qdoc3/test/qt-html-templates.qdocconf
Diffstat (limited to 'tests/auto')
29 files changed, 1100 insertions, 77 deletions
diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index 47c5b63..fbab30e 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -50,6 +50,7 @@ #include <QtDeclarative/qdeclarativeexpression.h> #include <QtDeclarative/qdeclarativecomponent.h> #include <private/qdeclarativetextedit_p.h> +#include <private/qdeclarativetextedit_p_p.h> #include <QFontMetrics> #include <QDeclarativeView> #include <QStyle> @@ -86,7 +87,8 @@ private slots: void delegateLoading(); void navigation(); void readOnly(); - void sendRequestSoftwareInputPanelEvent(); + void openInputPanelOnClick(); + void openInputPanelOnFocus(); void geometrySignals(); private: void simulateKey(QDeclarativeView *, int key); @@ -817,14 +819,14 @@ public: bool closeInputPanelReceived; }; -void tst_qdeclarativetextedit::sendRequestSoftwareInputPanelEvent() +void tst_qdeclarativetextedit::openInputPanelOnClick() { QGraphicsScene scene; QGraphicsView view(&scene); MyInputContext ic; view.setInputContext(&ic); QDeclarativeTextEdit edit; - QSignalSpy inputPanelonFocusSpy(&edit, SIGNAL(showInputPanelOnFocusChanged(bool))); + QSignalSpy focusOnPressSpy(&edit, SIGNAL(focusOnPressChanged(bool))); edit.setText("Hello world"); edit.setPos(0, 0); scene.addItem(&edit); @@ -834,7 +836,58 @@ void tst_qdeclarativetextedit::sendRequestSoftwareInputPanelEvent() QTest::qWaitForWindowShown(&view); QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); - QVERIFY(edit.showInputPanelOnFocus()); + QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(&edit); + QDeclarativeTextEditPrivate *editPrivate = static_cast<QDeclarativeTextEditPrivate*>(pri); + + // input panel on click + editPrivate->showInputPanelOnFocus = false; + + QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel( + view.style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos())); + QApplication::processEvents(); + if (behavior == QStyle::RSIP_OnMouseClickAndAlreadyFocused) { + QCOMPARE(ic.openInputPanelReceived, false); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos())); + QApplication::processEvents(); + QCOMPARE(ic.openInputPanelReceived, true); + } else if (behavior == QStyle::RSIP_OnMouseClick) { + QCOMPARE(ic.openInputPanelReceived, true); + } + ic.openInputPanelReceived = false; + + // focus should not cause input panels to open or close + edit.setFocus(false); + edit.setFocus(true); + edit.setFocus(false); + edit.setFocus(true); + edit.setFocus(false); + QCOMPARE(ic.openInputPanelReceived, false); + QCOMPARE(ic.closeInputPanelReceived, false); +} + +void tst_qdeclarativetextedit::openInputPanelOnFocus() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + MyInputContext ic; + view.setInputContext(&ic); + QDeclarativeTextEdit edit; + QSignalSpy focusOnPressSpy(&edit, SIGNAL(focusOnPressChanged(bool))); + edit.setText("Hello world"); + edit.setPos(0, 0); + scene.addItem(&edit); + view.show(); + qApp->setAutoSipEnabled(true); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); + + QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(&edit); + QDeclarativeTextEditPrivate *editPrivate = static_cast<QDeclarativeTextEditPrivate*>(pri); + editPrivate->showInputPanelOnFocus = true; + + QVERIFY(edit.focusOnPress()); QCOMPARE(ic.openInputPanelReceived, false); QCOMPARE(ic.closeInputPanelReceived, false); @@ -867,9 +920,9 @@ void tst_qdeclarativetextedit::sendRequestSoftwareInputPanelEvent() QCOMPARE(ic.closeInputPanelReceived, true); ic.closeInputPanelReceived = false; - // no input panel events if showInputPanelOnFocus is false - edit.setShowInputPanelOnFocus(false); - QCOMPARE(inputPanelonFocusSpy.count(),1); + // no automatic input panel events if focusOnPress is false + edit.setFocusOnPress(false); + QCOMPARE(focusOnPressSpy.count(),1); QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos())); QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(edit.scenePos())); edit.setFocus(false); @@ -877,8 +930,8 @@ void tst_qdeclarativetextedit::sendRequestSoftwareInputPanelEvent() QCOMPARE(ic.openInputPanelReceived, false); QCOMPARE(ic.closeInputPanelReceived, false); - edit.setShowInputPanelOnFocus(false); - QCOMPARE(inputPanelonFocusSpy.count(),1); + edit.setFocusOnPress(false); + QCOMPARE(focusOnPressSpy.count(),1); // one show input panel event when openSoftwareInputPanel is called edit.openSoftwareInputPanel(); @@ -892,14 +945,17 @@ void tst_qdeclarativetextedit::sendRequestSoftwareInputPanelEvent() QCOMPARE(ic.closeInputPanelReceived, true); ic.openInputPanelReceived = false; - // set showInputPanelOnFocus back to true - edit.setShowInputPanelOnFocus(true); - QCOMPARE(inputPanelonFocusSpy.count(),2); + // set focusOnPress back to true + edit.setFocusOnPress(true); + QCOMPARE(focusOnPressSpy.count(),2); edit.setFocus(false); QCOMPARE(ic.openInputPanelReceived, false); QCOMPARE(ic.closeInputPanelReceived, true); ic.closeInputPanelReceived = false; + edit.setFocusOnPress(true); + QCOMPARE(focusOnPressSpy.count(),2); + // active window focus reason should not cause input panel to open QGraphicsObject * editObject = qobject_cast<QGraphicsObject*>(&edit); editObject->setFocus(Qt::ActiveWindowFocusReason); @@ -910,9 +966,6 @@ void tst_qdeclarativetextedit::sendRequestSoftwareInputPanelEvent() edit.setFocus(true); QCOMPARE(ic.openInputPanelReceived, false); QCOMPARE(ic.closeInputPanelReceived, false); - - edit.setShowInputPanelOnFocus(true); - QCOMPARE(inputPanelonFocusSpy.count(),2); } void tst_qdeclarativetextedit::geometrySignals() diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index c943c89..3cb4da0 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -45,6 +45,7 @@ #include <QFile> #include <QtDeclarative/qdeclarativeview.h> #include <private/qdeclarativetextinput_p.h> +#include <private/qdeclarativetextinput_p_p.h> #include <QDebug> #include <QStyle> #include <QInputContext> @@ -74,7 +75,8 @@ private slots: void navigation(); void readOnly(); - void sendRequestSoftwareInputPanelEvent(); + void openInputPanelOnClick(); + void openInputPanelOnFocus(); void setHAlignClearCache(); void focusOutClearSelection(); @@ -763,14 +765,14 @@ public: bool closeInputPanelReceived; }; -void tst_qdeclarativetextinput::sendRequestSoftwareInputPanelEvent() +void tst_qdeclarativetextinput::openInputPanelOnClick() { QGraphicsScene scene; QGraphicsView view(&scene); MyInputContext ic; view.setInputContext(&ic); QDeclarativeTextInput input; - QSignalSpy inputPanelonFocusSpy(&input, SIGNAL(showInputPanelOnFocusChanged(bool))); + QSignalSpy focusOnPressSpy(&input, SIGNAL(focusOnPressChanged(bool))); input.setText("Hello world"); input.setPos(0, 0); scene.addItem(&input); @@ -780,7 +782,58 @@ void tst_qdeclarativetextinput::sendRequestSoftwareInputPanelEvent() QTest::qWaitForWindowShown(&view); QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); - QVERIFY(input.showInputPanelOnFocus()); + QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(&input); + QDeclarativeTextInputPrivate *inputPrivate = static_cast<QDeclarativeTextInputPrivate*>(pri); + + // input panel on click + inputPrivate->showInputPanelOnFocus = false; + + QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel( + view.style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(input.scenePos())); + QApplication::processEvents(); + if (behavior == QStyle::RSIP_OnMouseClickAndAlreadyFocused) { + QCOMPARE(ic.openInputPanelReceived, false); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(input.scenePos())); + QApplication::processEvents(); + QCOMPARE(ic.openInputPanelReceived, true); + } else if (behavior == QStyle::RSIP_OnMouseClick) { + QCOMPARE(ic.openInputPanelReceived, true); + } + ic.openInputPanelReceived = false; + + // focus should not cause input panels to open or close + input.setFocus(false); + input.setFocus(true); + input.setFocus(false); + input.setFocus(true); + input.setFocus(false); + QCOMPARE(ic.openInputPanelReceived, false); + QCOMPARE(ic.closeInputPanelReceived, false); +} + +void tst_qdeclarativetextinput::openInputPanelOnFocus() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + MyInputContext ic; + view.setInputContext(&ic); + QDeclarativeTextInput input; + QSignalSpy focusOnPressSpy(&input, SIGNAL(focusOnPressChanged(bool))); + input.setText("Hello world"); + input.setPos(0, 0); + scene.addItem(&input); + view.show(); + qApp->setAutoSipEnabled(true); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); + + QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(&input); + QDeclarativeTextInputPrivate *inputPrivate = static_cast<QDeclarativeTextInputPrivate*>(pri); + inputPrivate->showInputPanelOnFocus = true; + + QVERIFY(input.focusOnPress()); QCOMPARE(ic.openInputPanelReceived, false); QCOMPARE(ic.closeInputPanelReceived, false); @@ -813,9 +866,9 @@ void tst_qdeclarativetextinput::sendRequestSoftwareInputPanelEvent() QCOMPARE(ic.closeInputPanelReceived, true); ic.closeInputPanelReceived = false; - // no input panel events if showInputPanelOnFocus is false - input.setShowInputPanelOnFocus(false); - QCOMPARE(inputPanelonFocusSpy.count(),1); + // no automatic input panel events if focusOnPress is false + input.setFocusOnPress(false); + QCOMPARE(focusOnPressSpy.count(),1); QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(input.scenePos())); QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(input.scenePos())); input.setFocus(false); @@ -823,8 +876,8 @@ void tst_qdeclarativetextinput::sendRequestSoftwareInputPanelEvent() QCOMPARE(ic.openInputPanelReceived, false); QCOMPARE(ic.closeInputPanelReceived, false); - input.setShowInputPanelOnFocus(false); - QCOMPARE(inputPanelonFocusSpy.count(),1); + input.setFocusOnPress(false); + QCOMPARE(focusOnPressSpy.count(),1); // one show input panel event when openSoftwareInputPanel is called input.openSoftwareInputPanel(); @@ -838,14 +891,17 @@ void tst_qdeclarativetextinput::sendRequestSoftwareInputPanelEvent() QCOMPARE(ic.closeInputPanelReceived, true); ic.openInputPanelReceived = false; - // set showInputPanelOnFocus back to true - input.setShowInputPanelOnFocus(true); - QCOMPARE(inputPanelonFocusSpy.count(),2); + // set focusOnPress back to true + input.setFocusOnPress(true); + QCOMPARE(focusOnPressSpy.count(),2); input.setFocus(false); QCOMPARE(ic.openInputPanelReceived, false); QCOMPARE(ic.closeInputPanelReceived, true); ic.closeInputPanelReceived = false; + input.setFocusOnPress(true); + QCOMPARE(focusOnPressSpy.count(),2); + // active window focus reason should not cause input panel to open QGraphicsObject * inputObject = qobject_cast<QGraphicsObject*>(&input); inputObject->setFocus(Qt::ActiveWindowFocusReason); @@ -856,9 +912,6 @@ void tst_qdeclarativetextinput::sendRequestSoftwareInputPanelEvent() input.setFocus(true); QCOMPARE(ic.openInputPanelReceived, false); QCOMPARE(ic.closeInputPanelReceived, false); - - input.setShowInputPanelOnFocus(true); - QCOMPARE(inputPanelonFocusSpy.count(),2); } class MyTextInput : public QDeclarativeTextInput diff --git a/tests/auto/declarative/qdeclarativeviewer/data/orientation.qml b/tests/auto/declarative/qdeclarativeviewer/data/orientation.qml index 687fac6..be911a3 100644 --- a/tests/auto/declarative/qdeclarativeviewer/data/orientation.qml +++ b/tests/auto/declarative/qdeclarativeviewer/data/orientation.qml @@ -1,10 +1,19 @@ import Qt 4.7 Rectangle { color: "black" - width: (runtime.orientation == Orientation.Landscape) ? 300 : 200 - height: (runtime.orientation == Orientation.Landscape) ? 200 : 300 + width: (runtime.orientation == Orientation.RightUp || runtime.orientation == Orientation.LeftUp) ? 300 : 200 + height: (runtime.orientation == Orientation.RightUp || runtime.orientation == Orientation.LeftUp) ? 200 : 300 Text { - text: runtime.orientation == Orientation.Landscape ? "Landscape" : "Portrait" + text: { + if (runtime.orientation == Orientation.TopUp) + return "TopUp" + if (runtime.orientation == Orientation.TopDown) + return "TopDown" + if (runtime.orientation == Orientation.LeftUp) + return "LeftUp" + if (runtime.orientation == Orientation.RightUp) + return "RightUp" + } color: "white" } -}
\ No newline at end of file +} diff --git a/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp b/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp index 9429dc9..f296d9e 100644 --- a/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp +++ b/tests/auto/declarative/qdeclarativeviewer/tst_qdeclarativeviewer.cpp @@ -82,7 +82,7 @@ void tst_QDeclarativeViewer::orientation() QCOMPARE(viewer->size(), QSize(200, 300+viewer->menuBar()->height())); QCOMPARE(viewer->size(), viewer->sizeHint()); - viewer->toggleOrientation(); + viewer->rotateOrientation(); qApp->processEvents(); QCOMPARE(rootItem->width(), 300.0); @@ -92,7 +92,7 @@ void tst_QDeclarativeViewer::orientation() QCOMPARE(viewer->size(), QSize(300, 200+viewer->menuBar()->height())); QCOMPARE(viewer->size(), viewer->sizeHint()); - viewer->toggleOrientation(); + viewer->rotateOrientation(); qApp->processEvents(); QCOMPARE(rootItem->width(), 200.0); diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 4a9f1d1..7c1170c 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -49,6 +49,7 @@ #include <qgesture.h> #include <qgesturerecognizer.h> #include <qgraphicsitem.h> +#include <qgraphicswidget.h> #include <qgraphicsview.h> #include <qmainwindow.h> @@ -358,6 +359,7 @@ private slots: void viewportCoordinates(); void partialGesturePropagation(); void testQGestureRecognizerCleanup(); + void testReuseCanceledGestures(); }; tst_Gestures::tst_Gestures() @@ -2069,5 +2071,169 @@ void tst_Gestures::testQGestureRecognizerCleanup() delete w; } +class ReuseCanceledGesturesRecognizer : public QGestureRecognizer +{ +public: + enum Type { + RmbAndCancelAllType, + LmbType + }; + + ReuseCanceledGesturesRecognizer(Type type) : m_type(type) {} + + QGesture *create(QObject *) { + QGesture *g = new QGesture; + return g; + } + + Result recognize(QGesture *gesture, QObject *, QEvent *event) { + QMouseEvent *me = static_cast<QMouseEvent *>(event); + Qt::MouseButton mouseButton(m_type == LmbType ? Qt::LeftButton : Qt::RightButton); + + switch(event->type()) { + case QEvent::MouseButtonPress: + if (me->button() == mouseButton && gesture->state() == Qt::NoGesture) { + gesture->setHotSpot(QPointF(me->globalPos())); + if (m_type == RmbAndCancelAllType) + gesture->setGestureCancelPolicy(QGesture::CancelAllInContext); + return QGestureRecognizer::TriggerGesture; + } + break; + case QEvent::MouseButtonRelease: + if (me->button() == mouseButton && gesture->state() > Qt::NoGesture) + return QGestureRecognizer::FinishGesture; + default: + break; + } + return QGestureRecognizer::Ignore; + } +private: + Type m_type; +}; + +class ReuseCanceledGesturesWidget : public QGraphicsWidget +{ + public: + ReuseCanceledGesturesWidget(Qt::GestureType gestureType = Qt::TapGesture, QGraphicsItem *parent = 0) + : QGraphicsWidget(parent), + m_gestureType(gestureType), + m_started(0), m_updated(0), m_canceled(0), m_finished(0) + { + } + + bool event(QEvent *event) { + if (event->type() == QEvent::Gesture) { + QGesture *gesture = static_cast<QGestureEvent*>(event)->gesture(m_gestureType); + if (gesture) { + switch(gesture->state()) { + case Qt::GestureStarted: m_started++; break; + case Qt::GestureUpdated: m_updated++; break; + case Qt::GestureFinished: m_finished++; break; + case Qt::GestureCanceled: m_canceled++; break; + default: break; + } + } + return true; + } + if (event->type() == QEvent::GraphicsSceneMousePress) { + return true; + } + return QGraphicsWidget::event(event); + } + + int started() { return m_started; } + int updated() { return m_updated; } + int finished() { return m_finished; } + int canceled() { return m_canceled; } + + private: + Qt::GestureType m_gestureType; + int m_started; + int m_updated; + int m_canceled; + int m_finished; +}; + +void tst_Gestures::testReuseCanceledGestures() +{ + Qt::GestureType cancellingGestureTypeId = QGestureRecognizer::registerRecognizer( + new ReuseCanceledGesturesRecognizer(ReuseCanceledGesturesRecognizer::RmbAndCancelAllType)); + Qt::GestureType tapGestureTypeId = QGestureRecognizer::registerRecognizer( + new ReuseCanceledGesturesRecognizer(ReuseCanceledGesturesRecognizer::LmbType)); + + QMainWindow mw; + mw.setWindowFlags(Qt::X11BypassWindowManagerHint); + QGraphicsView *gv = new QGraphicsView(&mw); + QGraphicsScene *scene = new QGraphicsScene; + + gv->setScene(scene); + scene->setSceneRect(0,0,100,100); + + // Create container and add to the scene + ReuseCanceledGesturesWidget *container = new ReuseCanceledGesturesWidget; + container->grabGesture(cancellingGestureTypeId); // << container grabs canceling gesture + + // Create widget and add to the scene + ReuseCanceledGesturesWidget *target = new ReuseCanceledGesturesWidget(tapGestureTypeId, container); + target->grabGesture(tapGestureTypeId); + + container->setGeometry(scene->sceneRect()); + + scene->addItem(container); + + mw.setCentralWidget(gv); + + // Viewport needs to grab all gestures that widgets in scene grab + gv->viewport()->grabGesture(cancellingGestureTypeId); + gv->viewport()->grabGesture(tapGestureTypeId); + + mw.show(); + QTest::qWaitForWindowShown(&mw); + + QPoint targetPos(gv->mapFromScene(target->mapToScene(target->rect().center()))); + targetPos = gv->viewport()->mapFromParent(targetPos); + + // "Tap" starts on child widget + QTest::mousePress(gv->viewport(), Qt::LeftButton, 0, targetPos); + QCOMPARE(target->started(), 1); + QCOMPARE(target->updated(), 0); + QCOMPARE(target->finished(), 0); + QCOMPARE(target->canceled(), 0); + + // Canceling gesture starts on parent + QTest::mousePress(gv->viewport(), Qt::RightButton, 0, targetPos); + QCOMPARE(target->started(), 1); + QCOMPARE(target->updated(), 0); + QCOMPARE(target->finished(), 0); + QCOMPARE(target->canceled(), 1); // <- child canceled + + // Canceling gesture ends + QTest::mouseRelease(gv->viewport(), Qt::RightButton, 0, targetPos); + QCOMPARE(target->started(), 1); + QCOMPARE(target->updated(), 0); + QCOMPARE(target->finished(), 0); + QCOMPARE(target->canceled(), 1); + + // Tap would end if not canceled + QTest::mouseRelease(gv->viewport(), Qt::LeftButton, 0, targetPos); + QCOMPARE(target->started(), 1); + QCOMPARE(target->updated(), 0); + QCOMPARE(target->finished(), 0); + QCOMPARE(target->canceled(), 1); + + // New "Tap" starts + QTest::mousePress(gv->viewport(), Qt::LeftButton, 0, targetPos); + QCOMPARE(target->started(), 2); + QCOMPARE(target->updated(), 0); + QCOMPARE(target->finished(), 0); + QCOMPARE(target->canceled(), 1); + + QTest::mouseRelease(gv->viewport(), Qt::LeftButton, 0, targetPos); + QCOMPARE(target->started(), 2); + QCOMPARE(target->updated(), 0); + QCOMPARE(target->finished(), 1); + QCOMPARE(target->canceled(), 1); +} + QTEST_MAIN(tst_Gestures) #include "tst_gestures.moc" diff --git a/tests/auto/linguist/lconvert/data/test20.ts b/tests/auto/linguist/lconvert/data/test20.ts index 542cdee..f042edf 100644 --- a/tests/auto/linguist/lconvert/data/test20.ts +++ b/tests/auto/linguist/lconvert/data/test20.ts @@ -147,4 +147,16 @@ <translation type="unfinished"></translation> </message> </context> +<context> + <name>Bizarre ~ and | context~</name> + <message> + <source>just something</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>something else</source> + <comment>comment with | and ~ and so~</comment> + <translation type="unfinished"></translation> + </message> +</context> </TS> diff --git a/tests/auto/linguist/lupdate/testdata/good/cmdline_order/a.h b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/a.h new file mode 100644 index 0000000..7059132 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/a.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#define XX QT_TRANSLATE_NOOP("aaa", "some text") diff --git a/tests/auto/linguist/lupdate/testdata/good/cmdline_order/b.h b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/b.h new file mode 100644 index 0000000..ce3e1a2 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/b.h @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "a.h" + +#define YY QT_TRANSLATE_NOOP("bbb", "some text") diff --git a/tests/auto/linguist/lupdate/testdata/good/cmdline_order/lupdatecmd b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/lupdatecmd new file mode 100644 index 0000000..edd91f7 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/lupdatecmd @@ -0,0 +1 @@ +lupdate b.h a.h -ts project.ts diff --git a/tests/auto/linguist/lupdate/testdata/good/cmdline_order/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/project.ts.result new file mode 100644 index 0000000..6028cbb --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/cmdline_order/project.ts.result @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0"> +<context> + <name>aaa</name> + <message> + <location filename="a.h" line="42"/> + <source>some text</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>bbb</name> + <message> + <location filename="b.h" line="44"/> + <source>some text</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> diff --git a/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt index 72ec3c5..f6fc400 100644 --- a/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt +++ b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt @@ -1,8 +1,4 @@ .*/lupdate/testdata/good/lacksqobject/main.cpp:58: Class 'B' lacks Q_OBJECT macro - .*/lupdate/testdata/good/lacksqobject/main.cpp:65: Class 'C' lacks Q_OBJECT macro - .*/lupdate/testdata/good/lacksqobject/main.cpp:78: Class 'nsB::B' lacks Q_OBJECT macro - .*/lupdate/testdata/good/lacksqobject/main.cpp:84: Class 'nsB::C' lacks Q_OBJECT macro - diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt index e3543c9..195c0e6 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt @@ -1,8 +1,4 @@ .*/lupdate/testdata/good/parsecpp2/main.cpp:51: Excess closing brace .* - .*/lupdate/testdata/good/parsecpp2/main.cpp:55: Excess closing brace .* - .*/lupdate/testdata/good/parsecpp2/main.cpp:61: Excess closing brace .* - .*/lupdate/testdata/good/parsecpp2/main.cpp:65: Excess closing brace .* - diff --git a/tests/auto/maketestselftest/checktest/checktest.pro b/tests/auto/maketestselftest/checktest/checktest.pro new file mode 100644 index 0000000..79c5ca5 --- /dev/null +++ b/tests/auto/maketestselftest/checktest/checktest.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = checktest +CONFIG += console +CONFIG -= app_bundle +DESTDIR = ./ +QT = core +SOURCES += main.cpp diff --git a/tests/auto/maketestselftest/checktest/main.cpp b/tests/auto/maketestselftest/checktest/main.cpp new file mode 100644 index 0000000..af98953 --- /dev/null +++ b/tests/auto/maketestselftest/checktest/main.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QCoreApplication> +#include <QDir> +#include <QFile> +#include <QFileInfo> +#include <QStringList> + +#include <stdio.h> +#include <stdlib.h> + +void fail(QString const& message) +{ + printf("CHECKTEST FAIL: %s\n", qPrintable(message)); + exit(0); +} + +void pass(QString const& message) +{ + printf("CHECKTEST PASS: %s\n", qPrintable(message)); + exit(0); +} + +int main(int argc, char** argv) +{ + QCoreApplication app(argc, argv); + + QStringList args = app.arguments(); + args.removeFirst(); // ourself + + QString args_quoted = QString("'%1'").arg(args.join("','")); + +#ifdef Q_WS_QWS + { + // for QWS we expect tests to be run as the QWS server + QString qws = args.takeLast(); + if (qws != "-qws") { + fail(QString("Expected test to be run with `-qws', but it wasn't; args: %1").arg(args_quoted)); + } + } +#endif + + if (args.count() != 1) { + fail(QString("These arguments are not what I expected: %1").arg(args_quoted)); + } + + QString test = args.at(0); + + QFileInfo testfile(test); + if (!testfile.exists()) { + fail(QString("File %1 does not exist (my working directory is: %2, my args are: %3)") + .arg(test) + .arg(QDir::currentPath()) + .arg(args_quoted) + ); + } + + pass(args_quoted); +} + diff --git a/tests/auto/maketestselftest/maketestselftest.pro b/tests/auto/maketestselftest/maketestselftest.pro index 6cc1744..a27d5d7 100644 --- a/tests/auto/maketestselftest/maketestselftest.pro +++ b/tests/auto/maketestselftest/maketestselftest.pro @@ -1,9 +1,6 @@ -load(qttest_p4) - -SOURCES += tst_maketestselftest.cpp -QT = core - -DEFINES += SRCDIR=\\\"$$PWD/\\\" +TEMPLATE = subdirs +SUBDIRS = checktest test +test.depends = checktest requires(!cross_compile) diff --git a/tests/auto/maketestselftest/test/test.pro b/tests/auto/maketestselftest/test/test.pro new file mode 100644 index 0000000..d9de51e --- /dev/null +++ b/tests/auto/maketestselftest/test/test.pro @@ -0,0 +1,18 @@ +load(qttest_p4) + +TARGET = ../tst_maketestselftest +SOURCES += ../tst_maketestselftest.cpp +QT = core + +DEFINES += SRCDIR=\\\"$$PWD/..\\\" + +requires(!cross_compile) + +win32 { + CONFIG(debug, debug|release) { + TARGET = ../../debug/tst_maketestselftest +} else { + TARGET = ../../release/tst_maketestselftest + } +} + diff --git a/tests/auto/maketestselftest/tst_maketestselftest.cpp b/tests/auto/maketestselftest/tst_maketestselftest.cpp index 437e143..a9077e3 100644 --- a/tests/auto/maketestselftest/tst_maketestselftest.cpp +++ b/tests/auto/maketestselftest/tst_maketestselftest.cpp @@ -66,6 +66,8 @@ private slots: void naming_convention(); void naming_convention_data(); + void make_check(); + private: QStringList find_subdirs(QString const&, FindSubdirsMode, QString const& = QString()); @@ -446,6 +448,83 @@ QStringList tst_MakeTestSelfTest::find_subdirs(QString const& pro_file, FindSubd return out; } +void tst_MakeTestSelfTest::make_check() +{ + /* + Run `make check' over the whole tests tree with a custom TESTRUNNER, + to verify that the TESTRUNNER mechanism works right. + */ + QString testsDir(SRCDIR "/.."); + QString checktest(SRCDIR "/checktest/checktest"); + +#if defined(Q_OS_WIN32) || defined(Q_OS_MAC) + if (qgetenv("RUN_SLOW_TESTS").isEmpty()) { + QSKIP("This test is too slow to run by default on this OS. Set RUN_SLOW_TESTS=1 to run it.", SkipAll); + } +#endif + +#ifdef Q_OS_WIN32 + checktest.replace("/", "\\"); + checktest += ".exe"; +#endif + + QProcess make; + make.setWorkingDirectory(testsDir); + + QStringList arguments; + arguments << "-k"; + arguments << "check"; + arguments << QString("TESTRUNNER=%1").arg(checktest); + + // find the right make; from externaltests.cpp + static const char makes[] = + "nmake.exe\0" + "mingw32-make.exe\0" + "gmake\0" + "make\0" + ; + + bool ok = false; + for (const char *p = makes; *p; p += strlen(p) + 1) { + make.start(p, arguments); + if (make.waitForStarted()) { + ok = true; + break; + } + } + + if (!ok) { + QFAIL("Could not find the right make tool in PATH"); + } + + QVERIFY(make.waitForFinished(1000 * 60 * 10)); + QCOMPARE(make.exitStatus(), QProcess::NormalExit); + + int pass = 0; + QList<QByteArray> out = make.readAllStandardOutput().split('\n'); + QStringList fails; + foreach (QByteArray line, out) { + while (line.endsWith("\r")) { + line.chop(1); + } + if (line.startsWith("CHECKTEST FAIL")) { + fails << QString::fromLocal8Bit(line); + } + if (line.startsWith("CHECKTEST PASS")) { + ++pass; + } + } + + // We can't check that the exit code of make is 0, because some tests + // may have failed to compile, but that doesn't mean `make check' is broken. + // We do assume there are at least this many unbroken tests, though. + QVERIFY2(fails.count() == 0, + qPrintable(QString("`make check' doesn't work for %1 tests:\n%2") + .arg(fails.count()).arg(fails.join("\n"))) + ); + QVERIFY(pass > 50); +} + QStringList find_test_class(QString const& filename) { QStringList out; diff --git a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp index 5d73764..a22d624 100644 --- a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp @@ -71,9 +71,9 @@ private slots: void elidedText(); void veryNarrowElidedText(); void averageCharWidth(); + void bypassShaping(); void elidedMultiLength(); void elidedMultiLengthF(); - void bearingIncludedInBoundingRect(); }; tst_QFontMetrics::tst_QFontMetrics() @@ -219,6 +219,21 @@ void tst_QFontMetrics::averageCharWidth() QVERIFY(fmf.averageCharWidth() != 0); } +void tst_QFontMetrics::bypassShaping() +{ + QFont f; + f.setStyleStrategy(QFont::ForceIntegerMetrics); + QFontMetrics fm(f); + QString text = " A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z"; + int textWidth = fm.width(text, -1, Qt::TextBypassShaping); + QVERIFY(textWidth != 0); + int charsWidth = 0; + for (int i = 0; i < text.size(); ++i) + charsWidth += fm.width(text[i]); + // This assertion is needed in QtWebKit's WebCore::Font::offsetForPositionForSimpleText + QCOMPARE(textWidth, charsWidth); +} + template<class FontMetrics> void elidedMultiLength_helper() { QString text1 = "Long Text 1\x9cShorter\x9csmall"; @@ -251,16 +266,5 @@ void tst_QFontMetrics::elidedMultiLengthF() elidedMultiLength_helper<QFontMetricsF>(); } -void tst_QFontMetrics::bearingIncludedInBoundingRect() -{ - QFont font; - font.setItalic(true); - QRect brectItalic = QFontMetrics(font).boundingRect("ITALIC"); - font.setItalic(false); - QRect brectNormal = QFontMetrics(font).boundingRect("ITALIC"); - - QVERIFY(brectItalic.width() >= brectNormal.width()); -} - QTEST_MAIN(tst_QFontMetrics) #include "tst_qfontmetrics.moc" diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 5547b02..fe68c8e 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -7584,6 +7584,7 @@ void tst_QGraphicsItem::itemUsesExtendedStyleOption() scene.addItem(rect); rect->setPos(200, 200); QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); rect->startTrack = false; view.show(); QTest::qWaitForWindowShown(&view); diff --git a/tests/auto/qhash/tst_qhash.cpp b/tests/auto/qhash/tst_qhash.cpp index 59576d9..3a7b54a 100644 --- a/tests/auto/qhash/tst_qhash.cpp +++ b/tests/auto/qhash/tst_qhash.cpp @@ -1154,6 +1154,26 @@ void tst_QHash::qmultihash_specific() QVERIFY(i.key() == 9); QVERIFY(i.value() == 98); } + + { + QMultiHash<int, int> map1; + map1.insert(42, 1); + map1.insert(10, 2); + map1.insert(48, 3); + QMultiHash<int, int> map2; + map2.insert(8, 4); + map2.insert(42, 5); + map2.insert(95, 12); + + map1+=map2; + map2.insert(42, 1); + map2.insert(10, 2); + map2.insert(48, 3); + QCOMPARE(map1.count(), map2.count()); + QVERIFY(map1.remove(42,5)); + QVERIFY(map2.remove(42,5)); + QVERIFY(map1 == map2); + } } template <typename T> diff --git a/tests/auto/qmap/tst_qmap.cpp b/tests/auto/qmap/tst_qmap.cpp index d3ed76d..a1b8de7 100644 --- a/tests/auto/qmap/tst_qmap.cpp +++ b/tests/auto/qmap/tst_qmap.cpp @@ -837,6 +837,26 @@ void tst_QMap::qmultimap_specific() QVERIFY(i.key() == 9); QVERIFY(i.value() == 98); } + + { + QMultiMap<int, int> map1; + map1.insert(42, 1); + map1.insert(10, 2); + map1.insert(48, 3); + QMultiMap<int, int> map2; + map2.insert(8, 4); + map2.insert(42, 5); + map2.insert(95, 12); + + map1+=map2; + map2.insert(42, 1); + map2.insert(10, 2); + map2.insert(48, 3); + QCOMPARE(map1.count(), map2.count()); + QVERIFY(map1.remove(42,5)); + QVERIFY(map2.remove(42,5)); + QVERIFY(map1 == map2); + } } QTEST_APPLESS_MAIN(tst_QMap) diff --git a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp index 5854ae1..72d8eda 100644 --- a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp +++ b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp @@ -693,6 +693,12 @@ void tst_QNetworkCookie::parseMultipleCookies_data() cookieA.setPath("/foo"); list = QList<QNetworkCookie>() << cookieA << cookieB; QTest::newRow("real-3") << "a=b; expires=Mar 10 07:00:00 2009 GMT, Tue; path=/foo\nc=d; expires=Fri Mar 20 07:00:00 2009 GMT" << list; + + // do not accept cookies with non-alphanumeric characters in domain field (QTBUG-11029) + cookie = QNetworkCookie("NonAlphNumDomName", "NonAlphNumDomValue"); + cookie.setDomain("!@#$%^&*();:."); // the ';' is actually problematic, because it is a separator + list = QList<QNetworkCookie>(); + QTest::newRow("domain-non-alpha-numeric") << "NonAlphNumDomName=NonAlphNumDomValue; domain=!@#$%^&*()" << list; } void tst_QNetworkCookie::parseMultipleCookies() diff --git a/tests/auto/qnetworkdiskcache/tst_qnetworkdiskcache.cpp b/tests/auto/qnetworkdiskcache/tst_qnetworkdiskcache.cpp index 8ce10fb..5bbe8f6 100644 --- a/tests/auto/qnetworkdiskcache/tst_qnetworkdiskcache.cpp +++ b/tests/auto/qnetworkdiskcache/tst_qnetworkdiskcache.cpp @@ -78,6 +78,56 @@ private slots: void oldCacheVersionFile(); void sync(); + + void crashWhenParentingCache(); +}; + +// FIXME same as in tst_qnetworkreply.cpp .. could be unified +// Does not work for POST/PUT! +class MiniHttpServer: public QTcpServer +{ + Q_OBJECT +public: + QTcpSocket *client; // always the last one that was received + QByteArray dataToTransmit; + QByteArray receivedData; + bool doClose; + bool multiple; + int totalConnections; + + MiniHttpServer(const QByteArray &data) : client(0), dataToTransmit(data), doClose(true), multiple(false), totalConnections(0) + { + listen(); + connect(this, SIGNAL(newConnection()), this, SLOT(doAccept())); + } + +public slots: + void doAccept() + { + client = nextPendingConnection(); + client->setParent(this); + ++totalConnections; + connect(client, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); + } + + void readyReadSlot() + { + receivedData += client->readAll(); + int doubleEndlPos = receivedData.indexOf("\r\n\r\n"); + + if (doubleEndlPos != -1) { + // multiple requests incoming. remove the bytes of the current one + if (multiple) + receivedData.remove(0, doubleEndlPos+4); + + client->write(dataToTransmit); + if (doClose) { + client->disconnectFromHost(); + disconnect(client, 0, this, 0); + client = 0; + } + } + } }; // Subclass that exposes the protected functions. @@ -581,6 +631,33 @@ public: Runner *other; }; +void tst_QNetworkDiskCache::crashWhenParentingCache() +{ + // the trick here is to not send the complete response + // but some data. So we get a readyRead() and it gets tried + // to be saved to the cache + QByteArray data("HTTP/1.0 200 OK\r\nCache-Control: max-age=300\r\nAge: 1\r\nContent-Length: 5\r\n\r\n123"); + MiniHttpServer server(data); + + QNetworkAccessManager *manager = new QNetworkAccessManager(); + QNetworkDiskCache *diskCache = new QNetworkDiskCache(manager); // parent to qnam! + // we expect the temp dir to be cleaned at some point anyway + diskCache->setCacheDirectory(QDir::tempPath() + "/cacheDir_" + QCoreApplication::applicationPid()); + manager->setCache(diskCache); + + QUrl url("http://127.0.0.1:" + QString::number(server.serverPort())); + QNetworkRequest request(url); + // request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); + QNetworkReply *reply = manager->get(request); // new reply is parented to qnam + + // wait for readyRead of reply! + connect(reply, SIGNAL(readyRead()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + + delete manager; // crashed before.. +} + void tst_QNetworkDiskCache::sync() { // This tests would be a nice to have, but is currently not supported. diff --git a/tests/auto/qsslcertificate/more-certificates/cert-large-serial-number.pem b/tests/auto/qsslcertificate/more-certificates/cert-large-serial-number.pem new file mode 100644 index 0000000..ecb6c35 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/cert-large-serial-number.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICGjCCAYMCFAECAwQFBgcICRCqu8zd7v8XGBkgMA0GCSqGSIb3DQEBBQUAMEwx +CzAJBgNVBAYTAkdCMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1 +cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMB4XDTEwMDYwMTE1MDI0MVoXDTEx +MDYwMTE1MDI0MVowTDELMAkGA1UEBhMCR0IxEjAQBgNVBAgTCUJlcmtzaGlyZTEQ +MA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkgQ29tcGFueSBMdGQwgZ8wDQYJ +KoZIhvcNAQEBBQADgY0AMIGJAoGBAM2q22/WNMmn8cC+5EEYGeICySLmp9W6Ay6e +KHr0Xxp3X3epETuPfvAuxp7rOtkS18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt93Cx +GBXMIChiMPAsFeYzGa/D6xzAkfcRaJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJrgsgB +fWrwHdxzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtlScqSn4IHFLRiQYQdfOgsPi +wdqD1MPZEniQE0Xp8McZ7kuYbGgdEqzeVgMHqitlzkNNtTz+2u37CbFNXDGCTy5D +2JCgZxaAWNkh1w+4VB91HfMwEU0MqvAO7SB31FwbKNaB3gVnua++NL1cAkujyRny +yR3PatYZCfESQ7oZgds= +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp index c76c11f..505b867 100644 --- a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp @@ -109,6 +109,7 @@ private slots: void task256066toPem(); void nulInCN(); void nulInSan(); + void largeSerialNumber(); // ### add tests for certificate bundles (multiple certificates concatenated into a single // structure); both PEM and DER formatted #endif @@ -786,6 +787,18 @@ void tst_QSslCertificate::nulInSan() QCOMPARE(dnssan, QString::fromLatin1(realSAN, sizeof realSAN - 1)); } +void tst_QSslCertificate::largeSerialNumber() +{ + QList<QSslCertificate> certList = + QSslCertificate::fromPath(SRCDIR "more-certificates/cert-large-serial-number.pem"); + + QCOMPARE(certList.size(), 1); + + const QSslCertificate &cert = certList.at(0); + QVERIFY(!cert.isNull()); + QCOMPARE(cert.serialNumber(), QByteArray("01:02:03:04:05:06:07:08:09:10:aa:bb:cc:dd:ee:ff:17:18:19:20")); +} + #endif // QT_NO_OPENSSL QTEST_MAIN(tst_QSslCertificate) diff --git a/tests/auto/qstatictext/tst_qstatictext.cpp b/tests/auto/qstatictext/tst_qstatictext.cpp index c7801ac..1d166f4 100644 --- a/tests/auto/qstatictext/tst_qstatictext.cpp +++ b/tests/auto/qstatictext/tst_qstatictext.cpp @@ -324,8 +324,7 @@ bool tst_QStaticText::supportsTransformations() const QPaintEngine::Type type = engine->type(); - if (type == QPaintEngine::OpenGL2 - || type == QPaintEngine::OpenGL + if (type == QPaintEngine::OpenGL #if !defined Q_WS_WIN || type == QPaintEngine::Raster #endif @@ -471,7 +470,7 @@ void tst_QStaticText::transformationChanged() p.drawText(QRectF(0, 0, 1000, 1000), 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); - p.scale(7.0, 5.0); + p.scale(2.0, 2.5); p.drawText(QRectF(0, 0, 1000, 1000), 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); } @@ -487,7 +486,7 @@ void tst_QStaticText::transformationChanged() p.drawStaticText(QPointF(0, 0), text); - p.scale(7.0, 5.0); + p.scale(2.0, 2.5); p.drawStaticText(QPointF(0, 0), text); } diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp index eb2d5f1..9d8c0b2 100644 --- a/tests/auto/qstring/tst_qstring.cpp +++ b/tests/auto/qstring/tst_qstring.cpp @@ -212,6 +212,7 @@ private slots: void repeated() const; void repeated_data() const; void task262677remove(); + void QTBUG10404_compareRef(); }; typedef QList<int> IntList; @@ -4900,6 +4901,38 @@ void tst_QString::task262677remove() QVERIFY(driveName == QLatin1String("V:")); } +void tst_QString::QTBUG10404_compareRef() +{ + QString a = "ABCDEFGH"; + + QCOMPARE(QStringRef(&a, 1, 2).compare(QLatin1String("BC")), 0); + QVERIFY(QStringRef(&a, 1, 2).compare(QLatin1String("BCD")) < 0); + QCOMPARE(QStringRef(&a, 1, 2).compare(QLatin1String("Bc"), Qt::CaseInsensitive), 0); + QVERIFY(QStringRef(&a, 1, 2).compare(QLatin1String("bCD"), Qt::CaseInsensitive) < 0); + + QCOMPARE(QStringRef(&a, 1, 2).compare(QString::fromLatin1("BC")), 0); + QVERIFY(QStringRef(&a, 1, 2).compare(QString::fromLatin1("BCD")) < 0); + QCOMPARE(QStringRef(&a, 1, 2).compare(QString::fromLatin1("Bc"), Qt::CaseInsensitive), 0); + QVERIFY(QStringRef(&a, 1, 2).compare(QString::fromLatin1("bCD"), Qt::CaseInsensitive) < 0); + + QCOMPARE(QString::fromLatin1("BC").compare(QStringRef(&a, 1, 2)), 0); + QVERIFY(QString::fromLatin1("BCD").compare(QStringRef(&a, 1, 2)) > 0); + QCOMPARE(QString::fromLatin1("Bc").compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive), 0); + QVERIFY(QString::fromLatin1("bCD").compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive) > 0); + + QCOMPARE(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 2)), 0); + QVERIFY(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 3)) < 0); + QCOMPARE(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive), 0); + QVERIFY(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 3), Qt::CaseInsensitive) < 0); + + QString a2 = "ABCDEFGh"; + QCOMPARE(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 2)), 0); + QVERIFY(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 3)) < 0); + QCOMPARE(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive), 0); + QVERIFY(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 3), Qt::CaseInsensitive) < 0); +} + + QTEST_APPLESS_MAIN(tst_QString) diff --git a/tests/auto/qtextcursor/tst_qtextcursor.cpp b/tests/auto/qtextcursor/tst_qtextcursor.cpp index d44ce72..99babac 100644 --- a/tests/auto/qtextcursor/tst_qtextcursor.cpp +++ b/tests/auto/qtextcursor/tst_qtextcursor.cpp @@ -226,9 +226,9 @@ void tst_QTextCursor::navigation1() cursor.movePosition(QTextCursor::End); cursor.insertBlock(); { - int oldPos = cursor.position(); - cursor.movePosition(QTextCursor::End); - QVERIFY(cursor.position() == oldPos); + int oldPos = cursor.position(); + cursor.movePosition(QTextCursor::End); + QVERIFY(cursor.position() == oldPos); } QVERIFY(cursor.atBlockStart()); QVERIFY(cursor.position() == 9); @@ -1699,8 +1699,10 @@ void tst_QTextCursor::adjustCursorsOnInsert() QCOMPARE(selection.position(), posAfter+1); doc->undo(); + selection.setKeepPositionOnInsert(true); cursor.setPosition(posAfter); cursor.insertText(QLatin1String("x")); + selection.setKeepPositionOnInsert(false); QCOMPARE(selection.anchor(), posBefore); QCOMPARE(selection.position(), posAfter); doc->undo(); diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 5d47aed..a1fc607 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -385,6 +385,7 @@ private slots: void setGraphicsEffect(); void destroyBackingStore(); + void destroyBackingStoreWhenHidden(); void activateWindow(); @@ -9499,9 +9500,7 @@ void tst_QWidget::destroyBackingStore() QTRY_VERIFY(w.numPaintEvents > 0); w.reset(); w.update(); - delete qt_widget_private(&w)->topData()->backingStore; - qt_widget_private(&w)->topData()->backingStore = 0; - qt_widget_private(&w)->topData()->backingStore = new QWidgetBackingStore(&w); + qt_widget_private(&w)->topData()->backingStore.create(&w); w.update(); QApplication::processEvents(); @@ -9519,6 +9518,252 @@ void tst_QWidget::destroyBackingStore() #endif } +// Helper function +QWidgetBackingStore* backingStore(QWidget &widget) +{ + QWidgetBackingStore *backingStore = 0; +#ifdef QT_BUILD_INTERNAL + if (QTLWExtra *topExtra = qt_widget_private(&widget)->maybeTopData()) + backingStore = topExtra->backingStore.data(); +#endif + return backingStore; +} + +// Wait for a condition to be true, timing out after 1 second +// This is used following calls to QWidget::show() and QWidget::hide(), which are +// expected to asynchronously trigger native window visibility events. +#define WAIT_AND_VERIFY(condition) \ + do { \ + QTime start = QTime::currentTime(); \ + while (!(condition) && (start.elapsed() < 1000)) { \ + qApp->processEvents(); \ + QTest::qWait(50); \ + } \ + if (!QTest::qVerify((condition), #condition, "", __FILE__, __LINE__)) \ + return; \ + } while (0) + +void tst_QWidget::destroyBackingStoreWhenHidden() +{ +#ifndef QT_BUILD_INTERNAL + QSKIP("Test step requires access to Q_AUTOTEST_EXPORT", SkipAll); +#endif + +#ifndef Q_OS_SYMBIAN + QSKIP("Only Symbian destroys backing store when native window becomes invisible", SkipAll); +#endif + + testWidget->hide(); + QTest::qWait(1000); + + // 1. Single top-level QWidget + { + QWidget w; + w.setAutoFillBackground(true); + w.setPalette(Qt::yellow); + w.setGeometry(0, 0, 100, 100); + w.show(); + QTest::qWaitForWindowShown(&w); + QVERIFY(0 != backingStore(w)); + + w.hide(); + WAIT_AND_VERIFY(0 == backingStore(w)); + + w.show(); + QTest::qWaitForWindowShown(&w); + QVERIFY(0 != backingStore(w)); + } + + // 2. Two top-level widgets + { + QWidget w1; + w1.setGeometry(0, 0, 100, 100); + w1.setAutoFillBackground(true); + w1.setPalette(Qt::red); + w1.show(); + QTest::qWaitForWindowShown(&w1); + QVERIFY(0 != backingStore(w1)); + + QWidget w2; + w2.setGeometry(w1.geometry()); + w1.setAutoFillBackground(true); + w1.setPalette(Qt::blue); + w2.show(); + QTest::qWaitForWindowShown(&w2); + QVERIFY(0 != backingStore(w2)); + + // Check that w1 deleted its backing store when obscured by w2 + QVERIFY(0 == backingStore(w1)); + + w2.move(w2.pos() + QPoint(10, 10)); + + // Check that w1 recreates its backing store when partially revealed + WAIT_AND_VERIFY(0 != backingStore(w1)); + } + + // 3. Native child widget + { + QWidget parent; + parent.setGeometry(0, 0, 100, 100); + parent.setAutoFillBackground(true); + parent.setPalette(Qt::yellow); + + QWidget child(&parent); + child.setAutoFillBackground(true); + child.setPalette(Qt::green); + + QVBoxLayout layout(&parent); + layout.setContentsMargins(10, 10, 10, 10); + layout.addWidget(&child); + parent.setLayout(&layout); + + child.winId(); + + parent.show(); + QTest::qWaitForWindowShown(&parent); + + // Check that child window does not obscure parent window + QVERIFY(!parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Native child widget should share parent's backing store + QWidgetBackingStore *const parentBs = backingStore(parent); + QVERIFY(0 != parentBs); + QVERIFY(0 == backingStore(child)); + + // Set margins to zero so that child widget totally obscures parent + layout.setContentsMargins(0, 0, 0, 0); + + WAIT_AND_VERIFY(parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Backing store should remain unchanged despite child window obscuring + // parent window + QVERIFY(parentBs == backingStore(parent)); + QVERIFY(0 == backingStore(child)); + } + + // 4. Alien child widget which is made full-screen + { + QWidget parent; + parent.setGeometry(0, 0, 100, 100); + parent.setAutoFillBackground(true); + parent.setPalette(Qt::red); + + QWidget child(&parent); + child.setAutoFillBackground(true); + child.setPalette(Qt::blue); + + QVBoxLayout layout(&parent); + layout.setContentsMargins(10, 10, 10, 10); + layout.addWidget(&child); + parent.setLayout(&layout); + + parent.show(); + QTest::qWaitForWindowShown(&parent); + + // Check that child window does not obscure parent window + QVERIFY(!parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Native child widget should share parent's backing store + QVERIFY(0 != backingStore(parent)); + QVERIFY(0 == backingStore(child)); + + // Make child widget full screen + child.setWindowFlags((child.windowFlags() | Qt::Window) ^ Qt::SubWindow); + child.setWindowState(child.windowState() | Qt::WindowFullScreen); + child.show(); + QTest::qWaitForWindowShown(&child); + + // Check that child window obscures parent window + QVERIFY(parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Now that extent of child widget goes beyond parent's extent, + // a new backing store should be created for the child widget. + QVERIFY(0 != backingStore(child)); + + // Parent is obscured, therefore its backing store should be destroyed + QVERIFY(0 == backingStore(parent)); + + // Disable full screen + child.setWindowFlags(child.windowFlags() ^ (Qt::Window | Qt::SubWindow)); + child.setWindowState(child.windowState() ^ Qt::WindowFullScreen); + child.show(); + QTest::qWaitForWindowShown(&child); + + // Check that parent is now visible again + QVERIFY(!parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Native child widget should once again share parent's backing store + QVERIFY(0 != backingStore(parent)); + QEXPECT_FAIL("", "QTBUG-10643", Continue); + QVERIFY(0 == backingStore(child)); + } + + // 5. Native child widget which is made full-screen + { + QWidget parent; + parent.setGeometry(0, 0, 100, 100); + parent.setAutoFillBackground(true); + parent.setPalette(Qt::red); + + QWidget child(&parent); + child.setAutoFillBackground(true); + child.setPalette(Qt::blue); + + QVBoxLayout layout(&parent); + layout.setContentsMargins(10, 10, 10, 10); + layout.addWidget(&child); + parent.setLayout(&layout); + + child.winId(); + + parent.show(); + QTest::qWaitForWindowShown(&parent); + + // Check that child window does not obscure parent window + QVERIFY(!parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Native child widget should share parent's backing store + QVERIFY(0 != backingStore(parent)); + QVERIFY(0 == backingStore(child)); + + // Make child widget full screen + child.setWindowFlags((child.windowFlags() | Qt::Window) ^ Qt::SubWindow); + child.setWindowState(child.windowState() | Qt::WindowFullScreen); + child.show(); + QTest::qWaitForWindowShown(&child); + + // Ensure that 'window hidden' event is received by parent + qApp->processEvents(); + + // Check that child window obscures parent window + QVERIFY(parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Now that extent of child widget goes beyond parent's extent, + // a new backing store should be created for the child widget. + QVERIFY(0 != backingStore(child)); + + // Parent is obscured, therefore its backing store should be destroyed + QEXPECT_FAIL("", "QTBUG-10643", Continue); + QVERIFY(0 == backingStore(parent)); + + // Disable full screen + child.setWindowFlags(child.windowFlags() ^ (Qt::Window | Qt::SubWindow)); + child.setWindowState(child.windowState() ^ Qt::WindowFullScreen); + child.show(); + QTest::qWaitForWindowShown(&child); + + // Check that parent is now visible again + QVERIFY(!parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Native child widget should once again share parent's backing store + QVERIFY(0 != backingStore(parent)); + QEXPECT_FAIL("", "QTBUG-10643", Continue); + QVERIFY(0 == backingStore(child)); + } +} + +#undef WAIT_AND_VERIFY + void tst_QWidget::rectOutsideCoordinatesLimit_task144779() { #ifdef Q_OS_WINCE_WM @@ -10000,15 +10245,12 @@ class scrollWidgetWBS : public QWidget public: void deleteBackingStore() { - if (static_cast<QWidgetPrivate*>(d_ptr.data())->maybeBackingStore()) { - delete static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStore; - static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStore = 0; - } + static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStore.destroy(); } void enableBackingStore() { if (!static_cast<QWidgetPrivate*>(d_ptr.data())->maybeBackingStore()) { - static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStore = new QWidgetBackingStore(this); + static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStore.create(this); static_cast<QWidgetPrivate*>(d_ptr.data())->invalidateBuffer(this->rect()); repaint(); } |