diff options
Diffstat (limited to 'tests/auto')
71 files changed, 2880 insertions, 293 deletions
diff --git a/tests/auto/collections/tst_collections.cpp b/tests/auto/collections/tst_collections.cpp index 670cff0..f97805e 100644 --- a/tests/auto/collections/tst_collections.cpp +++ b/tests/auto/collections/tst_collections.cpp @@ -164,6 +164,7 @@ private slots: void qtimerList(); void containerTypedefs(); void forwardDeclared(); + void alignment(); }; struct LargeStatic { @@ -3481,5 +3482,113 @@ void tst_Collections::forwardDeclared() { typedef QSet<T1> C; C *x = 0; /* C::iterator i; */ C::const_iterator j; Q_UNUSED(x) } } +#if defined(Q_ALIGNOF) && defined(Q_DECL_ALIGN) + +class Q_DECL_ALIGN(4) Aligned4 +{ + char i; +public: + Aligned4(int i = 0) : i(i) {} + bool checkAligned() const + { + return (quintptr(this) & 3) == 0; + } + + inline bool operator==(const Aligned4 &other) const { return i == other.i; } + inline bool operator<(const Aligned4 &other) const { return i < other.i; } + friend inline int qHash(const Aligned4 &a) { return qHash(a.i); } +}; + +class Q_DECL_ALIGN(128) Aligned128 +{ + char i; +public: + Aligned128(int i = 0) : i(i) {} + bool checkAligned() const + { + return (quintptr(this) & 127) == 0; + } + + inline bool operator==(const Aligned128 &other) const { return i == other.i; } + inline bool operator<(const Aligned128 &other) const { return i < other.i; } + friend inline int qHash(const Aligned128 &a) { return qHash(a.i); } +}; + +template<typename C> +void testVectorAlignment() +{ + typedef typename C::value_type Aligned; + C container; + container.append(Aligned()); + QVERIFY(container[0].checkAligned()); + + for (int i = 0; i < 200; ++i) + container.append(Aligned()); + + for (int i = 0; i < container.size(); ++i) + QVERIFY(container.at(i).checkAligned()); +} + +template<typename C> +void testContiguousCacheAlignment() +{ + typedef typename C::value_type Aligned; + C container(150); + container.append(Aligned()); + QVERIFY(container[container.firstIndex()].checkAligned()); + + for (int i = 0; i < 200; ++i) + container.append(Aligned()); + + for (int i = container.firstIndex(); i < container.lastIndex(); ++i) + QVERIFY(container.at(i).checkAligned()); +} + +template<typename C> +void testAssociativeContainerAlignment() +{ + typedef typename C::key_type Key; + typedef typename C::mapped_type Value; + C container; + container.insert(Key(), Value()); + + typename C::const_iterator it = container.constBegin(); + QVERIFY(it.key().checkAligned()); + QVERIFY(it.value().checkAligned()); + + // add some more elements + for (int i = 0; i < 200; ++i) + container.insert(Key(i), Value(i)); + + it = container.constBegin(); + for ( ; it != container.constEnd(); ++it) { + QVERIFY(it.key().checkAligned()); + QVERIFY(it.value().checkAligned()); + } +} + +void tst_Collections::alignment() +{ + testVectorAlignment<QVector<Aligned4> >(); + testVectorAlignment<QVector<Aligned128> >(); + testContiguousCacheAlignment<QContiguousCache<Aligned4> >(); + testContiguousCacheAlignment<QContiguousCache<Aligned128> >(); + testAssociativeContainerAlignment<QMap<Aligned4, Aligned4> >(); + testAssociativeContainerAlignment<QMap<Aligned4, Aligned128> >(); + testAssociativeContainerAlignment<QMap<Aligned128, Aligned4> >(); + testAssociativeContainerAlignment<QMap<Aligned128, Aligned128> >(); + testAssociativeContainerAlignment<QHash<Aligned4, Aligned4> >(); + testAssociativeContainerAlignment<QHash<Aligned4, Aligned128> >(); + testAssociativeContainerAlignment<QHash<Aligned128, Aligned4> >(); + testAssociativeContainerAlignment<QHash<Aligned128, Aligned128> >(); +} + +#else +void tst_Collections::alignment() +{ + QSKIP("Compiler doesn't support necessary extension keywords", SkipAll) +} +#endif + QTEST_APPLESS_MAIN(tst_Collections) #include "tst_collections.moc" diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 92f979f..02c8232 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -103,6 +103,8 @@ int CustomEvent::EventType = 0; class CustomGestureRecognizer : public QGestureRecognizer { public: + static bool ConsumeEvents; + CustomGestureRecognizer() { if (!CustomEvent::EventType) @@ -117,7 +119,9 @@ public: QGestureRecognizer::Result filterEvent(QGesture *state, QObject*, QEvent *event) { if (event->type() == CustomEvent::EventType) { - QGestureRecognizer::Result result = QGestureRecognizer::ConsumeEventHint; + QGestureRecognizer::Result result = 0; + if (CustomGestureRecognizer::ConsumeEvents) + result |= QGestureRecognizer::ConsumeEventHint; CustomGesture *g = static_cast<CustomGesture*>(state); CustomEvent *e = static_cast<CustomEvent*>(event); g->serial = e->serial; @@ -143,6 +147,7 @@ public: QGestureRecognizer::reset(state); } }; +bool CustomGestureRecognizer::ConsumeEvents = false; // same as CustomGestureRecognizer but triggers early without the maybe state class CustomContinuousGestureRecognizer : public QGestureRecognizer @@ -280,6 +285,7 @@ protected: } }; +// TODO rename to sendGestureSequence static void sendCustomGesture(CustomEvent *event, QObject *object, QGraphicsScene *scene = 0) { for (int i = CustomGesture::SerialMaybeThreshold; @@ -322,6 +328,10 @@ private slots: void multipleGesturesInTree(); void multipleGesturesInComplexTree(); void testMapToScene(); + void ungrabGesture(); + void consumeEventHint(); + void unregisterRecognizer(); + void autoCancelGestures(); }; tst_Gestures::tst_Gestures() @@ -334,13 +344,14 @@ tst_Gestures::~tst_Gestures() void tst_Gestures::initTestCase() { - CustomGesture::GestureType = qApp->registerGestureRecognizer(new CustomGestureRecognizer); + CustomGesture::GestureType = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); QVERIFY(CustomGesture::GestureType != Qt::GestureType(0)); QVERIFY(CustomGesture::GestureType != Qt::CustomGesture); } void tst_Gestures::cleanupTestCase() { + QApplication::unregisterGestureRecognizer(CustomGesture::GestureType); } void tst_Gestures::init() @@ -372,6 +383,19 @@ void tst_Gestures::customGesture() QCOMPARE(widget.events.canceled.size(), 0); } +void tst_Gestures::consumeEventHint() +{ + GestureWidget widget; + widget.grabGesture(CustomGesture::GestureType, Qt::WidgetGesture); + + CustomGestureRecognizer::ConsumeEvents = true; + CustomEvent event; + sendCustomGesture(&event, &widget); + CustomGestureRecognizer::ConsumeEvents = false; + + QCOMPARE(widget.customEventsReceived, 0); +} + void tst_Gestures::autoCancelingGestures() { GestureWidget widget; @@ -534,7 +558,7 @@ void tst_Gestures::conflictingGestures() parent.reset(); child->reset(); - Qt::GestureType ContinuousGesture = qApp->registerGestureRecognizer(new CustomContinuousGestureRecognizer); + Qt::GestureType ContinuousGesture = QApplication::registerGestureRecognizer(new CustomContinuousGestureRecognizer); static const int ContinuousGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1; child->grabGesture(ContinuousGesture); // child accepts override. And it also receives another custom gesture. @@ -547,6 +571,8 @@ void tst_Gestures::conflictingGestures() QCOMPARE(child->events.all.count(), TotalGestureEventsCount + ContinuousGestureEventsCount); QCOMPARE(parent.gestureOverrideEventsReceived, 0); QCOMPARE(parent.gestureEventsReceived, 0); + + QApplication::unregisterGestureRecognizer(ContinuousGesture); } void tst_Gestures::finishedWithoutStarted() @@ -710,6 +736,7 @@ void tst_Gestures::graphicsItemGesture() { QGraphicsScene scene; QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); GestureItem *item = new GestureItem("item"); scene.addItem(item); @@ -772,6 +799,7 @@ void tst_Gestures::graphicsItemTreeGesture() { QGraphicsScene scene; QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); GestureItem *item1 = new GestureItem("item1"); item1->setPos(100, 100); @@ -829,6 +857,7 @@ void tst_Gestures::explicitGraphicsObjectTarget() { QGraphicsScene scene; QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); GestureItem *item1 = new GestureItem("item1"); scene.addItem(item1); @@ -882,6 +911,7 @@ void tst_Gestures::gestureOverChildGraphicsItem() { QGraphicsScene scene; QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); GestureItem *item0 = new GestureItem("item0"); scene.addItem(item0); @@ -951,7 +981,7 @@ void tst_Gestures::twoGesturesOnDifferentLevel() GestureWidget *child = new GestureWidget("child"); l->addWidget(child); - Qt::GestureType SecondGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType SecondGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); parent.grabGesture(CustomGesture::GestureType, Qt::WidgetWithChildrenGesture); child->grabGesture(SecondGesture, Qt::WidgetWithChildrenGesture); @@ -978,6 +1008,8 @@ void tst_Gestures::twoGesturesOnDifferentLevel() QCOMPARE(parent.events.all.size(), TotalGestureEventsCount); for(int i = 0; i < child->events.all.size(); ++i) QCOMPARE(parent.events.all.at(i), CustomGesture::GestureType); + + QApplication::unregisterGestureRecognizer(SecondGesture); } void tst_Gestures::multipleGesturesInTree() @@ -989,8 +1021,8 @@ void tst_Gestures::multipleGesturesInTree() GestureWidget *D = new GestureWidget("D", C); Qt::GestureType FirstGesture = CustomGesture::GestureType; - Qt::GestureType SecondGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); - Qt::GestureType ThirdGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType SecondGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType ThirdGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); A->grabGesture(FirstGesture, Qt::WidgetWithChildrenGesture); // A [1 3] A->grabGesture(ThirdGesture, Qt::WidgetWithChildrenGesture); // | @@ -1046,6 +1078,9 @@ void tst_Gestures::multipleGesturesInTree() QCOMPARE(A->events.all.count(FirstGesture), TotalGestureEventsCount); QCOMPARE(A->events.all.count(SecondGesture), 0); QCOMPARE(A->events.all.count(ThirdGesture), TotalGestureEventsCount); + + QApplication::unregisterGestureRecognizer(SecondGesture); + QApplication::unregisterGestureRecognizer(ThirdGesture); } void tst_Gestures::multipleGesturesInComplexTree() @@ -1057,12 +1092,12 @@ void tst_Gestures::multipleGesturesInComplexTree() GestureWidget *D = new GestureWidget("D", C); Qt::GestureType FirstGesture = CustomGesture::GestureType; - Qt::GestureType SecondGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); - Qt::GestureType ThirdGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); - Qt::GestureType FourthGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); - Qt::GestureType FifthGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); - Qt::GestureType SixthGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); - Qt::GestureType SeventhGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType SecondGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType ThirdGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType FourthGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType FifthGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType SixthGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + Qt::GestureType SeventhGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); A->grabGesture(FirstGesture, Qt::WidgetWithChildrenGesture); // A [1,3,4] A->grabGesture(ThirdGesture, Qt::WidgetWithChildrenGesture); // | @@ -1139,6 +1174,13 @@ void tst_Gestures::multipleGesturesInComplexTree() QCOMPARE(A->events.all.count(FifthGesture), 0); QCOMPARE(A->events.all.count(SixthGesture), 0); QCOMPARE(A->events.all.count(SeventhGesture), 0); + + QApplication::unregisterGestureRecognizer(SecondGesture); + QApplication::unregisterGestureRecognizer(ThirdGesture); + QApplication::unregisterGestureRecognizer(FourthGesture); + QApplication::unregisterGestureRecognizer(FifthGesture); + QApplication::unregisterGestureRecognizer(SixthGesture); + QApplication::unregisterGestureRecognizer(SeventhGesture); } void tst_Gestures::testMapToScene() @@ -1151,6 +1193,7 @@ void tst_Gestures::testMapToScene() QGraphicsScene scene; QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); GestureItem *item0 = new GestureItem; scene.addItem(item0); @@ -1166,5 +1209,150 @@ void tst_Gestures::testMapToScene() QCOMPARE(event.mapToScene(origin + QPoint(100, 200)), view.mapToScene(QPoint(100, 200))); } +void tst_Gestures::ungrabGesture() // a method on QWidget +{ + class MockGestureWidget : public GestureWidget { + public: + MockGestureWidget(const char *name = 0, QWidget *parent = 0) + : GestureWidget(name, parent) { } + + + QSet<QGesture*> gestures; + protected: + bool event(QEvent *event) + { + if (event->type() == QEvent::Gesture) { + QGestureEvent *gestureEvent = static_cast<QGestureEvent*>(event); + if (gestureEvent) + foreach (QGesture *g, gestureEvent->allGestures()) + gestures.insert(g); + } + return GestureWidget::event(event); + } + }; + + MockGestureWidget parent("A"); + MockGestureWidget *a = &parent; + MockGestureWidget *b = new MockGestureWidget("B", a); + + a->grabGesture(CustomGesture::GestureType, Qt::WidgetGesture); + b->grabGesture(CustomGesture::GestureType, Qt::WidgetWithChildrenGesture); + b->ignoredGestures << CustomGesture::GestureType; + + CustomEvent event; + // sending an event will cause the QGesture objects to be instantiated for the widgets + sendCustomGesture(&event, b); + + QCOMPARE(a->gestures.count(), 1); + QPointer<QGesture> customGestureA; + customGestureA = *(a->gestures.begin()); + QVERIFY(!customGestureA.isNull()); + QCOMPARE(customGestureA->gestureType(), CustomGesture::GestureType); + + QCOMPARE(b->gestures.count(), 1); + QPointer<QGesture> customGestureB; + customGestureB = *(b->gestures.begin()); + QVERIFY(!customGestureB.isNull()); + QVERIFY(customGestureA.data() == customGestureB.data()); + QCOMPARE(customGestureB->gestureType(), CustomGesture::GestureType); + + a->gestures.clear(); + // sending an event will cause the QGesture objects to be instantiated for the widget + sendCustomGesture(&event, a); + + QCOMPARE(a->gestures.count(), 1); + customGestureA = *(a->gestures.begin()); + QVERIFY(!customGestureA.isNull()); + QCOMPARE(customGestureA->gestureType(), CustomGesture::GestureType); + QVERIFY(customGestureA.data() != customGestureB.data()); + + a->ungrabGesture(CustomGesture::GestureType); + QVERIFY(customGestureA.isNull()); + QVERIFY(!customGestureB.isNull()); + + a->gestures.clear(); + a->reset(); + // send again to 'b' and make sure a never gets it. + sendCustomGesture(&event, b); + QCOMPARE(a->gestureEventsReceived, 0); + QCOMPARE(a->gestureOverrideEventsReceived, 0); +} + +void tst_Gestures::unregisterRecognizer() // a method on QApplication +{ + /* + The hardest usecase to get right is when we remove a recognizer while several + of the gestures it created are in active state and we immediately add a new recognizer + for the same type (thus replacing the old one). + The expected result is that all old gestures continue till they are finished/cancelled + and the new recognizer starts creating gestures immediately at registration. + + This implies that deleting of the recognizer happens only when there are no more gestures + that it created. (since gestures might have a pointer to the recognizer) + */ + +} + +void tst_Gestures::autoCancelGestures() +{ + class MockRecognizer : public QGestureRecognizer { + public: + QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event) + { + Q_UNUSED(gesture); + Q_UNUSED(watched); + if (event->type() == QEvent::MouseButtonPress) + return QGestureRecognizer::GestureTriggered; + if (event->type() == QEvent::MouseButtonRelease) + return QGestureRecognizer::GestureFinished; + return QGestureRecognizer::Ignore; + } + }; + + class MockWidget : public GestureWidget { + public: + MockWidget(const char *name) : GestureWidget(name) { } + + bool event(QEvent *event) + { + if (event->type() == QEvent::Gesture) { + QGestureEvent *ge = static_cast<QGestureEvent*>(event); + Q_ASSERT(ge->allGestures().count() == 1); // can't use QCOMPARE here... + ge->allGestures().first()->setGestureCancelPolicy(QGesture::CancelAllInContext); + } + return GestureWidget::event(event); + } + }; + + MockWidget parent("parent"); // this one sets the cancel policy to CancelAllInContext + parent.resize(300, 100); + GestureWidget *child = new GestureWidget("child", &parent); + child->setGeometry(10, 10, 100, 80); + + Qt::GestureType type = QApplication::registerGestureRecognizer(new MockRecognizer()); + parent.grabGesture(type, Qt::WidgetWithChildrenGesture); + child->grabGesture(type, Qt::WidgetWithChildrenGesture); + + /* + An event is send to both the child and the parent, when the child gets it a gesture is triggered + and send to the child. + When the parent gets the event a new gesture is triggered and delivered to the parent. When the + parent gets it he accepts it and that causes the cancel policy to activate. + The cause of that is the gesture for the child is cancelled and send to the child as such. + */ + QMouseEvent event(QEvent::MouseButtonPress, QPoint(20,20), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QApplication::sendEvent(child, &event); + QCOMPARE(child->events.started.count(), 1); + QCOMPARE(child->events.all.count(), 1); + QCOMPARE(parent.events.all.count(), 0); + child->reset(); + QApplication::sendEvent(&parent, &event); + QCOMPARE(parent.events.all.count(), 1); + QCOMPARE(parent.events.started.count(), 1); + QCOMPARE(child->events.started.count(), 0); + QCOMPARE(child->events.all.count(), 1); + QCOMPARE(child->events.canceled.count(), 1); +} + QTEST_MAIN(tst_Gestures) #include "tst_gestures.moc" diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp index 8201add..e243e66 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp @@ -228,3 +228,22 @@ QT_TRID_NOOP("this_a_id") //~ some thing //% "This needs to be here. Really." QString test = qtTrId("this_another_id", n); + + + +class YetAnotherTest : QObject { + Q_OBJECT + + int function(void) + { + // + //: + //= + //~ + //# + //============= + //~~~~~~~~~~~~~ + //::::::::::::: + tr("nothing"); + } +}; diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result index d63c7c3..26e5a65 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result @@ -278,6 +278,14 @@ backslashed \ stuff.</source> </message> </context> <context> + <name>YetAnotherTest</name> + <message> + <location filename="main.cpp" line="247"/> + <source>nothing</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>scope</name> <message numerus="yes"> <location filename="main.cpp" line="187"/> diff --git a/tests/auto/qactiongroup/tst_qactiongroup.cpp b/tests/auto/qactiongroup/tst_qactiongroup.cpp index 2d215a0..7259479 100644 --- a/tests/auto/qactiongroup/tst_qactiongroup.cpp +++ b/tests/auto/qactiongroup/tst_qactiongroup.cpp @@ -70,6 +70,7 @@ private slots: void separators(); void testActionInTwoQActionGroup(); + void unCheckCurrentAction(); }; tst_QActionGroup::tst_QActionGroup() @@ -278,5 +279,25 @@ void tst_QActionGroup::testActionInTwoQActionGroup() QCOMPARE(group1.actions().isEmpty(), true); } +void tst_QActionGroup::unCheckCurrentAction() +{ + QActionGroup group(0); + QAction action1(&group) ,action2(&group); + action1.setCheckable(true); + action2.setCheckable(true); + QVERIFY(!action1.isChecked()); + QVERIFY(!action2.isChecked()); + action1.setChecked(true); + QVERIFY(action1.isChecked()); + QVERIFY(!action2.isChecked()); + QAction *current = group.checkedAction(); + QCOMPARE(current, &action1); + current->setChecked(false); + QVERIFY(!action1.isChecked()); + QVERIFY(!action2.isChecked()); + QVERIFY(group.checkedAction() == 0); +} + + QTEST_MAIN(tst_QActionGroup) #include "tst_qactiongroup.moc" diff --git a/tests/auto/qalgorithms/tst_qalgorithms.cpp b/tests/auto/qalgorithms/tst_qalgorithms.cpp index 1f1de82..176a451 100644 --- a/tests/auto/qalgorithms/tst_qalgorithms.cpp +++ b/tests/auto/qalgorithms/tst_qalgorithms.cpp @@ -602,9 +602,15 @@ void tst_QAlgorithms::test_qUpperBound() void tst_QAlgorithms::test_qBinaryFind_data() { QTest::addColumn<QList<int> >("data"); - QTest::addColumn<int>("resultValue"); + QTest::addColumn<int>("resultValue"); // -42 means not found QTest::newRow("sorted-duplicate") << (QList<int>() << 1 << 2 << 2 << 3) << 2; + QTest::newRow("sorted-end") << (QList<int>() << -5 << -2 << 0 << 8) << 8; + QTest::newRow("sorted-beginning") << (QList<int>() << -5 << -2 << 0 << 8) << -5; + QTest::newRow("sorted-duplicate-beginning") << (QList<int>() << -5 << -5 << -2 << 0 << 8) << -5; + QTest::newRow("empty") << (QList<int>()) << -42; + QTest::newRow("not found 1 ") << (QList<int>() << 1 << 5 << 8 << 65) << -42; + QTest::newRow("not found 2 ") << (QList<int>() << -456 << -5 << 8 << 65) << -42; } void tst_QAlgorithms::test_qBinaryFind() @@ -612,6 +618,15 @@ void tst_QAlgorithms::test_qBinaryFind() QFETCH(QList<int>, data); QFETCH(int, resultValue); + //-42 means not found + if (resultValue == -42) { + QVERIFY(qBinaryFind(data.constBegin(), data.constEnd(), resultValue) == data.end()); + QVERIFY(qBinaryFind(data, resultValue) == data.end()); + QVERIFY(qBinaryFind(data.begin(), data.end(), resultValue) == data.end()); + QVERIFY(qBinaryFind(data.begin(), data.end(), resultValue, qLess<int>()) == data.end()); + return; + } + QCOMPARE(*qBinaryFind(data.constBegin(), data.constEnd(), resultValue), resultValue); QCOMPARE(*qBinaryFind(data.begin(), data.end(), resultValue), resultValue); QCOMPARE(*qBinaryFind(data, resultValue), resultValue); diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp index 675e559..5888866 100644 --- a/tests/auto/qapplication/tst_qapplication.cpp +++ b/tests/auto/qapplication/tst_qapplication.cpp @@ -129,6 +129,7 @@ private slots: void style(); void allWidgets(); + void topLevelWidgets(); void setAttribute(); @@ -1795,6 +1796,27 @@ void tst_QApplication::allWidgets() QVERIFY(!app.allWidgets().contains(w)); // removal test } +void tst_QApplication::topLevelWidgets() +{ + int argc = 1; + QApplication app(argc, &argv0, QApplication::GuiServer); + QWidget *w = new QWidget; + w->show(); +#ifndef QT_NO_CLIPBOARD + QClipboard *clipboard = QApplication::clipboard(); + QString originalText = clipboard->text(); + clipboard->setText(QString("newText")); +#endif + app.processEvents(); + QVERIFY(QApplication::topLevelWidgets().contains(w)); + QCOMPARE(QApplication::topLevelWidgets().count(), 1); + delete w; + w = 0; + app.processEvents(); + QCOMPARE(QApplication::topLevelWidgets().count(), 0); +} + + void tst_QApplication::setAttribute() { diff --git a/tests/auto/qboxlayout/tst_qboxlayout.cpp b/tests/auto/qboxlayout/tst_qboxlayout.cpp index 7ff444b..8887288 100644 --- a/tests/auto/qboxlayout/tst_qboxlayout.cpp +++ b/tests/auto/qboxlayout/tst_qboxlayout.cpp @@ -211,7 +211,6 @@ void tst_QBoxLayout::setGeometry() QRect newGeom(0, 0, 70, 70); lay2->setGeometry(newGeom); - QApplication::processEvents(); QVERIFY2(newGeom.contains(dial->geometry()), "dial->geometry() should be smaller and within newGeom"); } diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index 0d3469d..51a7ff8 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -152,6 +152,8 @@ private slots: void subControlRectsWithOffset(); void task260974_menuItemRectangleForComboBoxPopup(); void removeItem(); + void resetModel(); + void keyBoardNavigationWithMouse(); protected slots: void onEditTextChanged( const QString &newString ); @@ -2416,5 +2418,88 @@ void tst_QComboBox::removeItem() QCOMPARE(cb.count(), 0); } +void tst_QComboBox::resetModel() +{ + class StringListModel : public QStringListModel + { + public: + StringListModel(const QStringList &list) : QStringListModel(list) + { + } + + void reset() + { + QStringListModel::reset(); + } + }; + QComboBox cb; + StringListModel model( QStringList() << "1" << "2"); + QSignalSpy spy(&cb, SIGNAL(currentIndexChanged(int))); + QCOMPARE(spy.count(), 0); + QCOMPARE(cb.currentIndex(), -1); //no selection + + cb.setModel(&model); + + QCOMPARE(spy.count(), 1); + QCOMPARE(cb.currentIndex(), 0); //first item selected + + model.reset(); + QCOMPARE(spy.count(), 2); + QCOMPARE(cb.currentIndex(), -1); //no selection + +} + +void tst_QComboBox::keyBoardNavigationWithMouse() +{ + QComboBox combo; + combo.setEditable(false); + for (int i = 0; i < 80; i++) + combo.addItem( QString::number(i)); + combo.show(); + QApplication::setActiveWindow(&combo); + QTest::qWaitForWindowShown(&combo); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&combo)); + + QCOMPARE(combo.currentText(), QLatin1String("0")); + + combo.setFocus(); + QTRY_VERIFY(combo.hasFocus()); + + QTest::keyClick(testWidget->lineEdit(), Qt::Key_Space); + QTest::qWait(30); + QTRY_VERIFY(combo.view()); + QTRY_VERIFY(combo.view()->isVisible()); + QTest::qWait(130); + + QCOMPARE(combo.currentText(), QLatin1String("0")); + + QCursor::setPos(combo.view()->mapToGlobal(combo.view()->rect().center())); + QTest::qWait(200); + +#define GET_SELECTION(SEL) \ + QCOMPARE(combo.view()->selectionModel()->selection().count(), 1); \ + QCOMPARE(combo.view()->selectionModel()->selection().indexes().count(), 1); \ + SEL = combo.view()->selectionModel()->selection().indexes().first().row() + + int selection; + GET_SELECTION(selection); + + //since we moved the mouse is in the middle it should even be around 5; + QVERIFY(selection > 3); + + static const int final = 40; + for (int i = selection + 1; i <= final; i++) + { + QTest::keyClick(combo.view(), Qt::Key_Down); + QTest::qWait(20); + GET_SELECTION(selection); + QCOMPARE(selection, i); + } + + QTest::keyClick(combo.view(), Qt::Key_Enter); + QTRY_COMPARE(combo.currentText(), QString::number(final)); +} + + QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc" diff --git a/tests/auto/qdatawidgetmapper/tst_qdatawidgetmapper.cpp b/tests/auto/qdatawidgetmapper/tst_qdatawidgetmapper.cpp index 002aeb7..dedc0cb 100644 --- a/tests/auto/qdatawidgetmapper/tst_qdatawidgetmapper.cpp +++ b/tests/auto/qdatawidgetmapper/tst_qdatawidgetmapper.cpp @@ -379,7 +379,7 @@ void tst_QDataWidgetMapper::comboBox() model->setData(model->index(0, 1), QString("read write item z"), Qt::EditRole); QCOMPARE(readOnlyBox.currentIndex(), 2); - QEXPECT_FAIL("", "See tasks 125493 and 147153", Abort); + QEXPECT_FAIL("", "See task 125493 and QTBUG-428", Abort); QCOMPARE(readWriteBox.currentText(), QString("read write item z")); } diff --git a/tests/auto/qdatetime/tst_qdatetime.cpp b/tests/auto/qdatetime/tst_qdatetime.cpp index 8fb0c91..c53780e 100644 --- a/tests/auto/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/qdatetime/tst_qdatetime.cpp @@ -447,7 +447,14 @@ void tst_QDateTime::toString_enumformat() QCOMPARE(str2, QString("1995-05-20T12:34:56")); QString str3 = dt1.toString(Qt::LocalDate); + qDebug() << str3; QVERIFY(!str3.isEmpty()); + //check for date/time components in any order + QVERIFY(str3.contains("1995")); + //day and month may be in numeric or word form + QVERIFY(str3.contains("12")); + QVERIFY(str3.contains("34")); + QVERIFY(str3.contains("56")); } void tst_QDateTime::addDays() diff --git a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp index baf769f..91050f5 100644 --- a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp +++ b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -103,6 +103,8 @@ private slots: void getComplexSignal_data(); void getComplexSignal(); + void followSignal(); + void createErrors_data(); void createErrors(); @@ -130,6 +132,9 @@ tst_QDBusAbstractInterface::tst_QDBusAbstractInterface() void tst_QDBusAbstractInterface::initTestCase() { + // enable debugging temporarily: + putenv("QDBUS_DEBUG=1"); + // register the object QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); @@ -432,6 +437,60 @@ void tst_QDBusAbstractInterface::getComplexSignal() QCOMPARE(s[0][0].value<RegisteredType>(), expectedValue); } +void tst_QDBusAbstractInterface::followSignal() +{ + const QString serviceToFollow = "com.trolltech.tst_qdbusabstractinterface.FollowMe"; + Pinger p = getPinger(serviceToFollow); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusConnection con = p->connection(); + QVERIFY(!con.interface()->isServiceRegistered(serviceToFollow)); + Pinger control = getPinger(""); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(voidSignal()), SLOT(exitLoop())); + QTestEventLoop::instance().connect(control.data(), SIGNAL(voidSignal()), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(voidSignal())); + + emit targetObj.voidSignal(); + QTestEventLoop::instance().enterLoop(200); + QVERIFY(!QTestEventLoop::instance().timeout()); + + // signal must not have been received because the service isn't registered + QVERIFY(s.isEmpty()); + + // now register the service + QDBusReply<QDBusConnectionInterface::RegisterServiceReply> r = + con.interface()->registerService(serviceToFollow, QDBusConnectionInterface::DontQueueService, + QDBusConnectionInterface::DontAllowReplacement); + QVERIFY(r.isValid() && r.value() == QDBusConnectionInterface::ServiceRegistered); + QVERIFY(con.interface()->isServiceRegistered(serviceToFollow)); + + // emit the signal again: + emit targetObj.voidSignal(); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + // now the signal must have been received: + QCOMPARE(s.size(), 1); + QVERIFY(s.at(0).size() == 0); + s.clear(); + + // disconnect the signal + disconnect(p.data(), SIGNAL(voidSignal()), &QTestEventLoop::instance(), 0); + + // emit the signal again: + emit targetObj.voidSignal(); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + // and now it mustn't have been received + QVERIFY(s.isEmpty()); + + // cleanup: + con.interface()->unregisterService(serviceToFollow); +} + void tst_QDBusAbstractInterface::createErrors_data() { QTest::addColumn<QString>("service"); diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp index e31a3a0..62d6342 100644 --- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp @@ -171,6 +171,13 @@ class tst_QDBusInterface: public QObject { Q_OBJECT MyObject obj; +public slots: + void testServiceOwnerChanged(const QString &service) + { + if (service == "com.example.Test") + QTestEventLoop::instance().exitLoop(); + } + private slots: void initTestCase(); @@ -235,32 +242,13 @@ void tst_QDBusInterface::invalidAfterServiceOwnerChanged() QDBusInterface invalidInterface("com.example.Test", "/"); QVERIFY(!invalidInterface.isValid()); + QTestEventLoop::instance().connect(connIface, SIGNAL(serviceOwnerChanged(QString, QString, QString)), + SLOT(exitLoop())); QVERIFY(connIface->registerService("com.example.Test") == QDBusConnectionInterface::ServiceRegistered); - QSignalSpy serviceOwnerChangedSpy(connIface, SIGNAL(serviceOwnerChanged(QString, QString, QString))); - - QEventLoop loop; - QObject::connect(connIface, SIGNAL(serviceOwnerChanged(QString, QString, QString)), - &loop, SLOT(quit())); - loop.exec(); - - // at least once, but other services might have changed while running the test, too. - QVERIFY(serviceOwnerChangedSpy.count() >= 1); - bool foundOurService = false; - for (int i = 0; i < serviceOwnerChangedSpy.count(); ++i) { - QList<QVariant> args = serviceOwnerChangedSpy.at(i); - QString name = args[0].toString(); - QString oldOwner = args[1].toString(); - QString newOwner = args[2].toString(); - if (name == QLatin1String("com.example.Test")) { - if (newOwner == conn.baseService()) { - foundOurService = true; - break; - } - } - } - QVERIFY(foundOurService); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(!invalidInterface.isValid()); } diff --git a/tests/auto/qdbusservicewatcher/qdbusservicewatcher.pro b/tests/auto/qdbusservicewatcher/qdbusservicewatcher.pro new file mode 100644 index 0000000..4970f16 --- /dev/null +++ b/tests/auto/qdbusservicewatcher/qdbusservicewatcher.pro @@ -0,0 +1,8 @@ +load(qttest_p4) +QT = core +contains(QT_CONFIG,dbus): { + SOURCES += tst_qdbusservicewatcher.cpp + QT += dbus +} else { + SOURCES += ../qdbusmarshall/dummy.cpp +} diff --git a/tests/auto/qdbusservicewatcher/tst_qdbusservicewatcher.cpp b/tests/auto/qdbusservicewatcher/tst_qdbusservicewatcher.cpp new file mode 100644 index 0000000..10b43b1 --- /dev/null +++ b/tests/auto/qdbusservicewatcher/tst_qdbusservicewatcher.cpp @@ -0,0 +1,273 @@ +/**************************************************************************** +** +** Copyright (C) 2009 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 <QtDBus/QDBusServiceWatcher> +#include <QtDBus> +#include <QtTest> + +class tst_QDBusServiceWatcher: public QObject +{ + Q_OBJECT + QString serviceName; +public: + tst_QDBusServiceWatcher(); + +private slots: + void initTestCase(); + void cleanup(); + + void watchForCreation(); + void watchForDisappearance(); + void watchForOwnerChange(); + void modeChange(); +}; + +tst_QDBusServiceWatcher::tst_QDBusServiceWatcher() + : serviceName("com.example.TestName") +{ +} + +void tst_QDBusServiceWatcher::initTestCase() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); +} + +void tst_QDBusServiceWatcher::cleanup() +{ + // ensure that the name isn't registered + QDBusConnection::sessionBus().unregisterService(serviceName); +} + +void tst_QDBusServiceWatcher::watchForCreation() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForRegistration); + + QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString))); + QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString))); + QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString))); + QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop())); + + // register a name + QVERIFY(con.registerService(serviceName)); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 1); + QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyU.count(), 0); + + QCOMPARE(spyO.count(), 1); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QVERIFY(spyO.at(0).at(1).toString().isEmpty()); + QCOMPARE(spyO.at(0).at(2).toString(), con.baseService()); + + spyR.clear(); + spyU.clear(); + spyO.clear(); + + // unregister it: + con.unregisterService(serviceName); + + // and register again + QVERIFY(con.registerService(serviceName)); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 1); + QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyU.count(), 0); + + QCOMPARE(spyO.count(), 1); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QVERIFY(spyO.at(0).at(1).toString().isEmpty()); + QCOMPARE(spyO.at(0).at(2).toString(), con.baseService()); +} + +void tst_QDBusServiceWatcher::watchForDisappearance() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForUnregistration); + + QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString))); + QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString))); + QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString))); + QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceUnregistered(QString)), SLOT(exitLoop())); + + // register a name + QVERIFY(con.registerService(serviceName)); + + // unregister it: + con.unregisterService(serviceName); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 0); + + QCOMPARE(spyU.count(), 1); + QCOMPARE(spyU.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyO.count(), 1); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(1).toString(), con.baseService()); + QVERIFY(spyO.at(0).at(2).toString().isEmpty()); +} + +void tst_QDBusServiceWatcher::watchForOwnerChange() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForOwnerChange); + + QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString))); + QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString))); + QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString))); + QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop())); + + // register a name + QVERIFY(con.registerService(serviceName)); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 1); + QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyU.count(), 0); + + QCOMPARE(spyO.count(), 1); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QVERIFY(spyO.at(0).at(1).toString().isEmpty()); + QCOMPARE(spyO.at(0).at(2).toString(), con.baseService()); + + spyR.clear(); + spyU.clear(); + spyO.clear(); + + // unregister it: + con.unregisterService(serviceName); + + // and register again + QVERIFY(con.registerService(serviceName)); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 1); + QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyU.count(), 1); + QCOMPARE(spyU.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyO.count(), 2); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(1).toString(), con.baseService()); + QVERIFY(spyO.at(0).at(2).toString().isEmpty()); + QCOMPARE(spyO.at(1).at(0).toString(), serviceName); + QVERIFY(spyO.at(1).at(1).toString().isEmpty()); + QCOMPARE(spyO.at(1).at(2).toString(), con.baseService()); +} + +void tst_QDBusServiceWatcher::modeChange() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForRegistration); + + QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString))); + QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString))); + QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString))); + QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop())); + + // register a name + QVERIFY(con.registerService(serviceName)); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 1); + QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyU.count(), 0); + + QCOMPARE(spyO.count(), 1); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QVERIFY(spyO.at(0).at(1).toString().isEmpty()); + QCOMPARE(spyO.at(0).at(2).toString(), con.baseService()); + + spyR.clear(); + spyU.clear(); + spyO.clear(); + + watcher.setWatchMode(QDBusServiceWatcher::WatchForUnregistration); + + // unregister it: + con.unregisterService(serviceName); + + QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceUnregistered(QString)), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(spyR.count(), 0); + + QCOMPARE(spyU.count(), 1); + QCOMPARE(spyU.at(0).at(0).toString(), serviceName); + + QCOMPARE(spyO.count(), 1); + QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(1).toString(), con.baseService()); + QVERIFY(spyO.at(0).at(2).toString().isEmpty()); +} + +QTEST_MAIN(tst_QDBusServiceWatcher) +#include "tst_qdbusservicewatcher.moc" diff --git a/tests/auto/qdockwidget/tst_qdockwidget.cpp b/tests/auto/qdockwidget/tst_qdockwidget.cpp index dc67f36..e62ba8c 100644 --- a/tests/auto/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/qdockwidget/tst_qdockwidget.cpp @@ -86,6 +86,7 @@ private slots: void visibilityChanged(); void dockLocationChanged(); void setTitleBarWidget(); + void titleBarDoubleClick(); // task specific tests: void task165177_deleteFocusWidget(); void task169808_setFloating(); @@ -694,6 +695,24 @@ void tst_QDockWidget::setTitleBarWidget() QCOMPARE(w2.isVisible(), false); } +void tst_QDockWidget::titleBarDoubleClick() +{ + QMainWindow win; + QDockWidget dock(&win); + win.show(); + dock.setFloating(true); + + QEvent e(QEvent::NonClientAreaMouseButtonDblClick); + QApplication::sendEvent(&dock, &e); + QVERIFY(dock.isFloating()); + QCOMPARE(win.dockWidgetArea(&dock), Qt::NoDockWidgetArea); + + win.addDockWidget(Qt::TopDockWidgetArea, &dock); + dock.setFloating(true); + QApplication::sendEvent(&dock, &e); + QVERIFY(!dock.isFloating()); + QCOMPARE(win.dockWidgetArea(&dock), Qt::TopDockWidgetArea); +} void tst_QDockWidget::task165177_deleteFocusWidget() { diff --git a/tests/auto/qdom/tst_qdom.cpp b/tests/auto/qdom/tst_qdom.cpp index 0d58554e..6637202 100644 --- a/tests/auto/qdom/tst_qdom.cpp +++ b/tests/auto/qdom/tst_qdom.cpp @@ -322,7 +322,6 @@ void tst_QDom::toString_01_data() */ void tst_QDom::toString_01() { - QFAIL("make test fail instead of timing out, will be fixed later (QT-2357)"); QFETCH(QString, fileName); QFile f(fileName); diff --git a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp index 6b2f0fe..e80f8e0 100644 --- a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp @@ -100,6 +100,20 @@ void tst_QFontMetrics::same() QFontMetrics fm(font); const QString text = QLatin1String("Some stupid STRING"); QCOMPARE(fm.size(0, text), fm.size(0, text)) ; + + { + QImage image; + QFontMetrics fm2(font, &image); + QString text2 = QLatin1String("Foo Foo"); + QCOMPARE(fm2.size(0, text2), fm2.size(0, text2)); //used to crash + } + + { + QImage image; + QFontMetricsF fm3(font, &image); + QString text2 = QLatin1String("Foo Foo"); + QCOMPARE(fm3.size(0, text2), fm3.size(0, text2)); //used to crash + } } diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 7b87969..c8a9fac 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -45,6 +45,7 @@ #include <QtGui/qgraphicswidget.h> #include <QtGui/qgraphicsproxywidget.h> #include <QtGui/qgraphicsview.h> +#include <QtGui/qwindowsstyle.h> class tst_QGraphicsAnchorLayout : public QObject { Q_OBJECT; @@ -72,6 +73,7 @@ private slots: void proportionalPreferred(); void example(); void setSpacing(); + void styleDefaults(); void hardComplexS60(); void stability(); void delete_anchor(); @@ -82,6 +84,8 @@ private slots: void expandingParallel(); void floatConflict(); void infiniteMaxSizes(); + void simplifiableUnfeasible(); + void simplificationVsOrder(); }; class RectWidget : public QGraphicsWidget @@ -1102,6 +1106,166 @@ void tst_QGraphicsAnchorLayout::setSpacing() delete view; } +class CustomLayoutStyle : public QWindowsStyle +{ + Q_OBJECT +public: + CustomLayoutStyle() : QWindowsStyle() + { + hspacing = 5; + vspacing = 10; + } + + virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0, + const QWidget * widget = 0 ) const; + + int hspacing; + int vspacing; + +protected slots: + int layoutSpacingImplementation(QSizePolicy::ControlType control1, + QSizePolicy::ControlType control2, + Qt::Orientation orientation, + const QStyleOption *option = 0, + const QWidget *widget = 0) const; + +}; + +#define CT1(c) CT2(c, c) +#define CT2(c1, c2) ((uint)c1 << 16) | (uint)c2 + +int CustomLayoutStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1, + QSizePolicy::ControlType control2, + Qt::Orientation orientation, + const QStyleOption * /*option = 0*/, + const QWidget * /*widget = 0*/) const +{ + if (orientation == Qt::Horizontal) { + switch (CT2(control1, control2)) { + case CT1(QSizePolicy::PushButton): + return 2; + break; + } + return 5; + } else { + switch (CT2(control1, control2)) { + case CT1(QSizePolicy::RadioButton): + return 2; + break; + + } + return 10; + } +} + +int CustomLayoutStyle::pixelMetric(PixelMetric metric, const QStyleOption * option /*= 0*/, + const QWidget * widget /*= 0*/ ) const +{ + switch (metric) { + case PM_LayoutLeftMargin: + return 0; + break; + case PM_LayoutTopMargin: + return 3; + break; + case PM_LayoutRightMargin: + return 6; + break; + case PM_LayoutBottomMargin: + return 9; + break; + case PM_LayoutHorizontalSpacing: + return hspacing; + case PM_LayoutVerticalSpacing: + return vspacing; + break; + default: + break; + } + return QWindowsStyle::pixelMetric(metric, option, widget); +} + +void tst_QGraphicsAnchorLayout::styleDefaults() +{ + QSizeF min (10, 10); + QSizeF pref(20, 20); + QSizeF max (50, 50); + + /* + create this layout, where a,b have controlType QSizePolicy::RadioButton + c,d have controlType QSizePolicy::PushButton: + +-------+ + |a | + | b | + | c | + | d| + +-------+ + */ + QGraphicsScene scene; + QGraphicsWidget *a = createItem(min, pref, max); + QSizePolicy spRadioButton = a->sizePolicy(); + spRadioButton.setControlType(QSizePolicy::RadioButton); + a->setSizePolicy(spRadioButton); + + QGraphicsWidget *b = createItem(min, pref, max); + b->setSizePolicy(spRadioButton); + + QGraphicsWidget *c = createItem(min, pref, max); + QSizePolicy spPushButton = c->sizePolicy(); + spPushButton.setControlType(QSizePolicy::PushButton); + c->setSizePolicy(spPushButton); + + QGraphicsWidget *d = createItem(min, pref, max); + d->setSizePolicy(spPushButton); + + QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window); + + // Test layoutSpacingImplementation + CustomLayoutStyle *style = new CustomLayoutStyle; + style->hspacing = -1; + style->vspacing = -1; + window->setStyle(style); + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + + l->addCornerAnchors(l, Qt::TopLeftCorner, a, Qt::TopLeftCorner); + l->addCornerAnchors(a, Qt::BottomRightCorner, b, Qt::TopLeftCorner); + l->addCornerAnchors(b, Qt::BottomRightCorner, c, Qt::TopLeftCorner); + l->addCornerAnchors(c, Qt::BottomRightCorner, d, Qt::TopLeftCorner); + l->addCornerAnchors(d, Qt::BottomRightCorner, l, Qt::BottomRightCorner); + + window->setLayout(l); + + scene.addItem(window); + + window->show(); + QGraphicsView *view = new QGraphicsView(&scene); + view->resize(200, 200); + view->show(); + + window->adjustSize(); + QCOMPARE(a->geometry(), QRectF(0, 3, 20, 20)); //radio + QCOMPARE(b->geometry(), QRectF(25, 25, 20, 20)); //radio + QCOMPARE(c->geometry(), QRectF(50, 55, 20, 20)); //push + QCOMPARE(d->geometry(), QRectF(72, 85, 20, 20)); //push + QCOMPARE(l->geometry(), QRectF(0, 0, 98, 114)); + + + // Test pixelMetric(PM_Layout{Horizontal|Vertical}Spacing + window->setStyle(0); + + style->hspacing = 1; + style->vspacing = 2; + + window->setStyle(style); + window->adjustSize(); + QCOMPARE(a->geometry(), QRectF(0, 3, 20, 20)); + QCOMPARE(b->geometry(), QRectF(21, 25, 20, 20)); + QCOMPARE(c->geometry(), QRectF(42, 47, 20, 20)); + QCOMPARE(d->geometry(), QRectF(63, 69, 20, 20)); + QCOMPARE(l->geometry(), QRectF(0, 0, 89, 98)); +} + + /*! Taken from "hard" complex case, found at https://cwiki.nokia.com/S60QTUI/AnchorLayoutComplexCases @@ -1755,5 +1919,100 @@ void tst_QGraphicsAnchorLayout::infiniteMaxSizes() QCOMPARE(d->geometry(), QRectF(QWIDGETSIZE_MAX - 50, 0, 50, 10)); } +void tst_QGraphicsAnchorLayout::simplifiableUnfeasible() +{ + QGraphicsWidget *a = createItem(QSizeF(70.0, 100.0), + QSizeF(100.0, 100.0), + QSizeF(100.0, 100.0), "A"); + + QGraphicsWidget *b = createItem(QSizeF(110.0, 100.0), + QSizeF(150.0, 100.0), + QSizeF(190.0, 100.0), "B"); + + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); + + l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop); + l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop); + l->addAnchor(b, Qt::AnchorBottom, l, Qt::AnchorBottom); + + l->addAnchors(l, a, Qt::Horizontal); + l->addAnchor(l, Qt::AnchorLeft, b, Qt::AnchorLeft); + l->addAnchor(b, Qt::AnchorRight, a, Qt::AnchorRight); + + QCOMPARE(l->count(), 2); + + QGraphicsWidget p; + p.setLayout(l); + + l->invalidate(); + QVERIFY(layoutHasConflict(l)); + if (hasSimplification) + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + + // Now we make it valid again + b->setMinimumWidth(100); + + l->invalidate(); + QVERIFY(!layoutHasConflict(l)); + if (hasSimplification) + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + + // And make it invalid again + a->setPreferredWidth(70); + a->setMaximumWidth(70); + + l->invalidate(); + QVERIFY(layoutHasConflict(l)); + if (hasSimplification) + QVERIFY(!usedSimplex(l, Qt::Horizontal)); +} + +/* + Test whether the anchor direction can prevent it from + being simplificated +*/ +void tst_QGraphicsAnchorLayout::simplificationVsOrder() +{ + QSizeF min(10, 10); + QSizeF pref(20, 10); + QSizeF max(50, 10); + + QGraphicsWidget *a = createItem(min, pref, max); + QGraphicsWidget *b = createItem(min, pref, max); + QGraphicsWidget *c = createItem(min, pref, max); + + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + + // Bulk anchors + l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); + l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft); + l->addAnchor(b, Qt::AnchorLeft, c, Qt::AnchorLeft); + l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight); + + // Problematic anchor, direction b->c + QGraphicsAnchor *anchor = l->addAnchor(b, Qt::AnchorRight, c, Qt::AnchorRight); + anchor->setSpacing(5); + + l->effectiveSizeHint(Qt::MinimumSize); + if (hasSimplification) { + QCOMPARE(usedSimplex(l, Qt::Horizontal), false); + QCOMPARE(usedSimplex(l, Qt::Vertical), false); + } + + // Problematic anchor, direction c->b + delete anchor; + anchor = l->addAnchor(c, Qt::AnchorRight, b, Qt::AnchorRight); + anchor->setSpacing(5); + + l->effectiveSizeHint(Qt::MinimumSize); + if (hasSimplification) { + QEXPECT_FAIL("", "Sequential anchors cannot handle children of opposite directions", Continue); + QCOMPARE(usedSimplex(l, Qt::Horizontal), false); + QCOMPARE(usedSimplex(l, Qt::Vertical), false); + } +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" diff --git a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp index 0201bc4..b40cf43 100644 --- a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp @@ -379,7 +379,8 @@ void tst_QGraphicsEffect::grayscale() item->setPen(Qt::NoPen); item->setBrush(QColor(122, 193, 66)); // Qt light green - QGraphicsGrayscaleEffect *effect = new QGraphicsGrayscaleEffect; + QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect; + effect->setColor(Qt::black); item->setGraphicsEffect(effect); QPainter painter; diff --git a/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp b/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp index 855950b..fbeb425 100644 --- a/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp +++ b/tests/auto/qgraphicseffectsource/tst_qgraphicseffectsource.cpp @@ -166,6 +166,9 @@ private slots: void deviceRect(); void pixmap(); + void pixmapPadding_data(); + void pixmapPadding(); + private: QGraphicsView *view; QGraphicsScene *scene; @@ -318,6 +321,102 @@ void tst_QGraphicsEffectSource::pixmap() QCOMPARE(pixmap1, pixmap2); } +class PaddingEffect : public QGraphicsEffect +{ +public: + PaddingEffect(QObject *parent) : QGraphicsEffect(parent) + { + } + + QRectF boundingRectFor(const QRectF &src) const { + return src.adjusted(-10, -10, 10, 10); + } + + void draw(QPainter *, QGraphicsEffectSource *source) { + pix = source->pixmap(coordinateMode, &offset, padMode); + } + + QPixmap pix; + QPoint offset; + QGraphicsEffectSource::PixmapPadMode padMode; + Qt::CoordinateSystem coordinateMode; +}; + +void tst_QGraphicsEffectSource::pixmapPadding_data() +{ + QTest::addColumn<int>("coordinateMode"); + QTest::addColumn<int>("padMode"); + QTest::addColumn<QSize>("size"); + QTest::addColumn<QPoint>("offset"); + QTest::addColumn<uint>("ulPixel"); + + QTest::newRow("log,nopad") << int(Qt::LogicalCoordinates) + << int(QGraphicsEffectSource::NoExpandPadMode) + << QSize(10, 10) << QPoint(0, 0) + << 0xffff0000u; + + QTest::newRow("log,transparent") << int(Qt::LogicalCoordinates) + << int(QGraphicsEffectSource::ExpandToTransparentBorderPadMode) + << QSize(12, 12) << QPoint(-1, -1) + << 0x00000000u; + + QTest::newRow("log,effectrect") << int(Qt::LogicalCoordinates) + << int(QGraphicsEffectSource::ExpandToEffectRectPadMode) + << QSize(30, 30) << QPoint(-10, -10) + << 0x00000000u; + + QTest::newRow("dev,nopad") << int(Qt::DeviceCoordinates) + << int(QGraphicsEffectSource::NoExpandPadMode) + << QSize(20, 20) << QPoint(40, 40) + << 0xffff0000u; + + QTest::newRow("dev,transparent") << int(Qt::DeviceCoordinates) + << int(QGraphicsEffectSource::ExpandToTransparentBorderPadMode) + << QSize(22, 22) << QPoint(39, 39) + << 0x00000000u; + + QTest::newRow("dev,effectrect") << int(Qt::DeviceCoordinates) + << int(QGraphicsEffectSource::ExpandToEffectRectPadMode) + << QSize(40, 40) << QPoint(30, 30) + << 0x00000000u; + +} + +void tst_QGraphicsEffectSource::pixmapPadding() +{ + QPixmap dummyTarget(100, 100); + QPainter dummyPainter(&dummyTarget); + dummyPainter.translate(40, 40); + dummyPainter.scale(2, 2); + + QPixmap pm(10, 10); + pm.fill(Qt::red); + + QGraphicsScene *scene = new QGraphicsScene(); + PaddingEffect *effect = new PaddingEffect(scene); + QGraphicsPixmapItem *pmItem = new QGraphicsPixmapItem(pm); + scene->addItem(pmItem); + pmItem->setGraphicsEffect(effect); + + QFETCH(int, coordinateMode); + QFETCH(int, padMode); + QFETCH(QPoint, offset); + QFETCH(QSize, size); + QFETCH(uint, ulPixel); + + effect->padMode = (QGraphicsEffectSource::PixmapPadMode) padMode; + effect->coordinateMode = (Qt::CoordinateSystem) coordinateMode; + + scene->render(&dummyPainter, scene->itemsBoundingRect(), scene->itemsBoundingRect()); + + QCOMPARE(effect->pix.size(), size); + QCOMPARE(effect->offset, offset); + QCOMPARE(effect->pix.toImage().pixel(0, 0), ulPixel); + + // ### Fix corruption in scene destruction, then enable... + // delete scene; +} + QTEST_MAIN(tst_QGraphicsEffectSource) #include "tst_qgraphicseffectsource.moc" diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index dcad8e1..684ad4f 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -372,6 +372,7 @@ private slots: void itemUsesExtendedStyleOption(); void itemSendsGeometryChanges(); void moveItem(); + void moveLineItem(); void sorting_data(); void sorting(); void itemHasNoContents(); @@ -390,6 +391,7 @@ private slots: void moveWhileDeleting(); void ensureDirtySceneTransform(); void focusScope(); + void focusScope2(); void stackBefore(); void sceneModality(); void panelModality(); @@ -3109,7 +3111,7 @@ void tst_QGraphicsItem::boundingRects() void tst_QGraphicsItem::boundingRects2() { QGraphicsPixmapItem pixmap(QPixmap::fromImage(QImage(100, 100, QImage::Format_ARGB32_Premultiplied))); - QCOMPARE(pixmap.boundingRect(), QRectF(-0.5, -0.5, 101, 101)); + QCOMPARE(pixmap.boundingRect(), QRectF(0, 0, 100, 100)); QGraphicsLineItem line(0, 0, 100, 0); line.setPen(QPen(Qt::black, 1)); @@ -4039,7 +4041,7 @@ void tst_QGraphicsItem::defaultItemTest_QGraphicsPixmapItem() item.setOffset(QPointF(-10, -10)); QCOMPARE(item.offset(), QPointF(-10, -10)); - QCOMPARE(item.boundingRect(), QRectF(-10.5, -10.5, 301, 201)); + QCOMPARE(item.boundingRect(), QRectF(-10, -10, 300, 200)); } void tst_QGraphicsItem::defaultItemTest_QGraphicsTextItem() @@ -7438,6 +7440,39 @@ void tst_QGraphicsItem::moveItem() COMPARE_REGIONS(view.paintedRegion, expectedParentRegion); } +void tst_QGraphicsItem::moveLineItem() +{ + QGraphicsScene scene; + scene.setSceneRect(0, 0, 200, 200); + QGraphicsLineItem *item = new QGraphicsLineItem(0, 0, 100, 0); + item->setPos(50, 50); + scene.addItem(item); + + MyGraphicsView view(&scene); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(200); + view.reset(); + + const QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform()) + .mapRect(item->boundingRect()).toRect(); + QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); // antialiasing + + // Make sure the calculated region is correct. + item->update(); + QTest::qWait(10); + QTRY_COMPARE(view.paintedRegion, expectedRegion); + view.reset(); + + // Old position: (50, 50) + item->setPos(50, 100); + expectedRegion += expectedRegion.translated(0, 50); + QTest::qWait(10); + QCOMPARE(view.paintedRegion, expectedRegion); +} + void tst_QGraphicsItem::sorting_data() { QTest::addColumn<int>("index"); @@ -8431,7 +8466,7 @@ void tst_QGraphicsItem::focusScope() QVERIFY(!scope2->focusScopeItem()); scope3->setParentItem(scope2); QCOMPARE(scope2->focusScopeItem(), (QGraphicsItem *)scope3); - QCOMPARE(scope2->focusItem(), (QGraphicsItem *)scope2); + QCOMPARE(scope2->focusItem(), (QGraphicsItem *)scope3); QGraphicsRectItem *scope1 = new QGraphicsRectItem; scope1->setData(0, "scope1"); @@ -8440,9 +8475,9 @@ void tst_QGraphicsItem::focusScope() QVERIFY(!scope1->focusScopeItem()); scope2->setParentItem(scope1); - QCOMPARE(scope1->focusItem(), (QGraphicsItem *)scope1); - QCOMPARE(scope2->focusItem(), (QGraphicsItem *)0); - QCOMPARE(scope3->focusItem(), (QGraphicsItem *)0); + QCOMPARE(scope1->focusItem(), (QGraphicsItem *)scope3); + QCOMPARE(scope2->focusItem(), (QGraphicsItem *)scope3); + QCOMPARE(scope3->focusItem(), (QGraphicsItem *)scope3); QCOMPARE(scope1->focusScopeItem(), (QGraphicsItem *)scope2); QCOMPARE(scope2->focusScopeItem(), (QGraphicsItem *)scope3); QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)0); @@ -8493,11 +8528,13 @@ void tst_QGraphicsItem::focusScope() rect5->setFocus(); rect5->setParentItem(rect4); QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)rect5); - QVERIFY(!rect5->hasFocus()); + QVERIFY(rect5->hasFocus()); rect4->setParentItem(0); + QVERIFY(rect5->hasFocus()); QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)0); - QVERIFY(scope3->hasFocus()); + QCOMPARE(scope3->focusItem(), (QGraphicsItem *)0); + QVERIFY(!scope3->hasFocus()); QGraphicsRectItem *rectA = new QGraphicsRectItem; QGraphicsRectItem *scopeA = new QGraphicsRectItem(rectA); @@ -8508,7 +8545,7 @@ void tst_QGraphicsItem::focusScope() scopeB->setFocus(); scene.addItem(rectA); - QVERIFY(!rect5->hasFocus()); + QVERIFY(rect5->hasFocus()); QVERIFY(!scopeB->hasFocus()); scopeA->setFocus(); @@ -8516,6 +8553,76 @@ void tst_QGraphicsItem::focusScope() QCOMPARE(scopeB->focusItem(), (QGraphicsItem *)scopeB); } +void tst_QGraphicsItem::focusScope2() +{ + QGraphicsRectItem *child1 = new QGraphicsRectItem; + child1->setFlags(QGraphicsItem::ItemIsFocusable); + child1->setFocus(); + QCOMPARE(child1->focusItem(), (QGraphicsItem *)child1); + + QGraphicsRectItem *child2 = new QGraphicsRectItem; + child2->setFlags(QGraphicsItem::ItemIsFocusable); + + QGraphicsRectItem *rootFocusScope = new QGraphicsRectItem; + rootFocusScope->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusScope); + rootFocusScope->setFocus(); + QCOMPARE(rootFocusScope->focusItem(), (QGraphicsItem *)rootFocusScope); + + child1->setParentItem(rootFocusScope); + child2->setParentItem(rootFocusScope); + + QCOMPARE(rootFocusScope->focusScopeItem(), (QGraphicsItem *)child1); + QCOMPARE(rootFocusScope->focusItem(), (QGraphicsItem *)child1); + + QGraphicsRectItem *siblingChild1 = new QGraphicsRectItem; + siblingChild1->setFlags(QGraphicsItem::ItemIsFocusable); + siblingChild1->setFocus(); + + QGraphicsRectItem *siblingChild2 = new QGraphicsRectItem; + siblingChild2->setFlags(QGraphicsItem::ItemIsFocusable); + + QGraphicsRectItem *siblingFocusScope = new QGraphicsRectItem; + siblingFocusScope->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusScope); + + siblingChild1->setParentItem(siblingFocusScope); + siblingChild2->setParentItem(siblingFocusScope); + + QCOMPARE(siblingFocusScope->focusScopeItem(), (QGraphicsItem *)siblingChild1); + QCOMPARE(siblingFocusScope->focusItem(), (QGraphicsItem *)0); + + QGraphicsItem *root = new QGraphicsRectItem; + rootFocusScope->setParentItem(root); + siblingFocusScope->setParentItem(root); + + QCOMPARE(root->focusItem(), (QGraphicsItem *)child1); + + QGraphicsScene scene; + scene.addItem(root); + + QEvent activate(QEvent::WindowActivate); + qApp->sendEvent(&scene, &activate); + scene.setFocus(); + + QCOMPARE(scene.focusItem(), (QGraphicsItem *)child1); + + // You cannot set focus on a descendant of a focus scope directly; + // this will only change the scope's focus scope item pointer. If + // you want to give true input focus, you must set it directly on + // the scope itself + siblingChild2->setFocus(); + QVERIFY(!siblingChild2->hasFocus()); + QVERIFY(!siblingChild2->focusItem()); + QCOMPARE(siblingFocusScope->focusScopeItem(), (QGraphicsItem *)siblingChild2); + QCOMPARE(siblingFocusScope->focusItem(), (QGraphicsItem *)0); + + // Set focus on the scope; focus is forwarded to the focus scope item. + siblingFocusScope->setFocus(); + QVERIFY(siblingChild2->hasFocus()); + QVERIFY(siblingChild2->focusItem()); + QCOMPARE(siblingFocusScope->focusScopeItem(), (QGraphicsItem *)siblingChild2); + QCOMPARE(siblingFocusScope->focusItem(), (QGraphicsItem *)siblingChild2); +} + void tst_QGraphicsItem::stackBefore() { QGraphicsRectItem parent; @@ -8535,24 +8642,24 @@ void tst_QGraphicsItem::stackBefore() QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child1 << child3 << child4 << child2)); // Move child2 before child1 - child2->stackBefore(child1); + child2->stackBefore(child1); // 2134 QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child2->stackBefore(child2); + child2->stackBefore(child2); // 2134 QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child1->setZValue(1); + child1->setZValue(1); // 2341 QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child3 << child4 << child1)); - child1->stackBefore(child2); // no effect + child1->stackBefore(child2); // 2341 QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child3 << child4 << child1)); - child1->setZValue(0); - QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child4->stackBefore(child1); - QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child4 << child1 << child3)); - child4->setZValue(1); - QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child3->stackBefore(child1); - QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child3 << child1 << child4)); - child4->setZValue(0); - QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child4 << child3 << child1)); + child1->setZValue(0); // 1234 + QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child1 << child2 << child3 << child4)); + child4->stackBefore(child1); // 4123 + QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child4 << child1 << child2 << child3)); + child4->setZValue(1); // 1234 (4123) + QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child1 << child2 << child3 << child4)); + child3->stackBefore(child1); // 3124 (4312) + QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child3 << child1 << child2 << child4)); + child4->setZValue(0); // 4312 + QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child4 << child3 << child1 << child2)); // Make them all toplevels child1->setParentItem(0); @@ -8574,24 +8681,24 @@ void tst_QGraphicsItem::stackBefore() QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child1 << child3 << child4 << child2)); // Move child2 before child1 - child2->stackBefore(child1); + child2->stackBefore(child1); // 2134 QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child2->stackBefore(child2); + child2->stackBefore(child2); // 2134 QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child1->setZValue(1); + child1->setZValue(1); // 2341 QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child3 << child4 << child1)); - child1->stackBefore(child2); // no effect + child1->stackBefore(child2); // 2341 QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child3 << child4 << child1)); - child1->setZValue(0); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child4->stackBefore(child1); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child4 << child1 << child3)); - child4->setZValue(1); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child3->stackBefore(child1); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child3 << child1 << child4)); - child4->setZValue(0); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child4 << child3 << child1)); + child1->setZValue(0); // 1234 + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child1 << child2 << child3 << child4)); + child4->stackBefore(child1); // 4123 + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child4 << child1 << child2 << child3)); + child4->setZValue(1); // 1234 (4123) + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child1 << child2 << child3 << child4)); + child3->stackBefore(child1); // 3124 (4312) + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child3 << child1 << child2 << child4)); + child4->setZValue(0); // 4312 + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child4 << child3 << child1 << child2)); } void tst_QGraphicsItem::QTBUG_4233_updateCachedWithSceneRect() diff --git a/tests/auto/qgraphicsobject/tst_qgraphicsobject.cpp b/tests/auto/qgraphicsobject/tst_qgraphicsobject.cpp index a9fd55a..194665d 100644 --- a/tests/auto/qgraphicsobject/tst_qgraphicsobject.cpp +++ b/tests/auto/qgraphicsobject/tst_qgraphicsobject.cpp @@ -46,6 +46,7 @@ #include <qgraphicssceneevent.h> #include <qgraphicsview.h> #include <qstyleoption.h> +#include <private/qobject_p.h> #include "../../shared/util.h" class tst_QGraphicsObject : public QObject { @@ -65,6 +66,7 @@ private slots: void opacity(); void enabled(); void visible(); + void deleted(); }; @@ -249,6 +251,46 @@ void tst_QGraphicsObject::visible() QVERIFY(object.property("visible") == true); } +class DeleteTester : public QGraphicsObject +{ +public: + DeleteTester(bool *w, bool *pw, QGraphicsItem *parent = 0) + : QGraphicsObject(parent), wasDeleted(w), parentWasDeleted(pw) + { } + + ~DeleteTester() + { + *wasDeleted = QObjectPrivate::get(this)->wasDeleted; + if (QGraphicsItem *p = parentItem()) { + if (QGraphicsObject *o = p->toGraphicsObject()) + *parentWasDeleted = QObjectPrivate::get(o)->wasDeleted; + } + } + + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0) + { } + QRectF boundingRect() const + { return QRectF(); } + + bool *wasDeleted; + bool *parentWasDeleted; +}; + +void tst_QGraphicsObject::deleted() +{ + bool item1_parentWasDeleted = false; + bool item1_wasDeleted = false; + bool item2_parentWasDeleted = false; + bool item2_wasDeleted = false; + DeleteTester *item1 = new DeleteTester(&item1_wasDeleted, &item1_parentWasDeleted); + DeleteTester *item2 = new DeleteTester(&item2_wasDeleted, &item2_parentWasDeleted, item1); + delete item1; + + QVERIFY(!item1_wasDeleted); // destructor not called yet + QVERIFY(!item1_parentWasDeleted); // no parent + QVERIFY(!item2_wasDeleted); // destructor not called yet + QVERIFY(item2_parentWasDeleted); +} QTEST_MAIN(tst_QGraphicsObject) #include "tst_qgraphicsobject.moc" diff --git a/tests/auto/qgraphicspixmapitem/tst_qgraphicspixmapitem.cpp b/tests/auto/qgraphicspixmapitem/tst_qgraphicspixmapitem.cpp index e25aef0..5a62dc0 100644 --- a/tests/auto/qgraphicspixmapitem/tst_qgraphicspixmapitem.cpp +++ b/tests/auto/qgraphicspixmapitem/tst_qgraphicspixmapitem.cpp @@ -165,7 +165,7 @@ void tst_QGraphicsPixmapItem::boundingRect_data() QTest::addColumn<QPixmap>("pixmap"); QTest::addColumn<QRectF>("boundingRect"); QTest::newRow("null") << QPixmap() << QRectF(); - QTest::newRow("10x10") << QPixmap(10, 10) << QRectF(-0.5, -0.5, 11, 11); + QTest::newRow("10x10") << QPixmap(10, 10) << QRectF(0, 0, 10, 10); } // public QRectF boundingRect() const diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 1109e5e..7d98748 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -45,6 +45,8 @@ #include <private/qgraphicsscenebsptreeindex_p.h> #include <private/qgraphicssceneindex_p.h> #include <private/qgraphicsscenelinearindex_p.h> +#include "../../shared/util.h" + //TESTED_CLASS= //TESTED_FILES= @@ -66,6 +68,7 @@ private slots: void movingItems(); void connectedToSceneRectChanged(); void items(); + void removeItems(); void clear(); private: @@ -268,6 +271,63 @@ void tst_QGraphicsSceneIndex::items() QCOMPARE(scene.items().size(), 3); } +class RectWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent) + { + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + painter->setBrush(brush); + painter->drawRect(boundingRect()); + } +public: + QBrush brush; +}; + +void tst_QGraphicsSceneIndex::removeItems() +{ + QGraphicsScene scene; + + RectWidget *parent = new RectWidget; + parent->brush = QBrush(QColor(Qt::magenta)); + parent->setGeometry(250, 250, 400, 400); + + RectWidget *widget = new RectWidget(parent); + widget->brush = QBrush(QColor(Qt::blue)); + widget->setGeometry(10, 10, 200, 200); + + RectWidget *widgetChild1 = new RectWidget(widget); + widgetChild1->brush = QBrush(QColor(Qt::green)); + widgetChild1->setGeometry(20, 20, 100, 100); + + RectWidget *widgetChild2 = new RectWidget(widgetChild1); + widgetChild2->brush = QBrush(QColor(Qt::yellow)); + widgetChild2->setGeometry(25, 25, 50, 50); + + scene.addItem(parent); + + QGraphicsView view(&scene); + view.resize(600, 600); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + + QApplication::processEvents(); + + scene.removeItem(widgetChild1); + + delete widgetChild1; + + //We move the parent + scene.items(295, 295, 50, 50); + + //This should not crash +} + void tst_QGraphicsSceneIndex::clear() { class MyItem : public QGraphicsItem @@ -298,7 +358,7 @@ void tst_QGraphicsSceneIndex::clear() MyItem *item = new MyItem; scene.addItem(item); qApp->processEvents(); - QCOMPARE(item->numPaints, 1); + QTRY_COMPARE(item->numPaints, 1); } QTEST_MAIN(tst_QGraphicsSceneIndex) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index dc08d0e..f07453c 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -194,6 +194,8 @@ private slots: void acceptDrops(); void optimizationFlags(); void optimizationFlags_dontSavePainterState(); + void optimizationFlags_dontSavePainterState2_data(); + void optimizationFlags_dontSavePainterState2(); void levelOfDetail_data(); void levelOfDetail(); void scrollBarRanges_data(); @@ -2455,6 +2457,57 @@ void tst_QGraphicsView::optimizationFlags_dontSavePainterState() QTest::qWaitForWindowShown(&painter2); } +void tst_QGraphicsView::optimizationFlags_dontSavePainterState2_data() +{ + QTest::addColumn<bool>("savePainter"); + QTest::newRow("With painter state protection") << true; + QTest::newRow("Without painter state protection") << false; +} + +void tst_QGraphicsView::optimizationFlags_dontSavePainterState2() +{ + QFETCH(bool, savePainter); + + class MyScene : public QGraphicsScene + { + public: + void drawBackground(QPainter *p, const QRectF &) + { transformInDrawBackground = p->worldTransform(); } + + void drawForeground(QPainter *p, const QRectF &) + { transformInDrawForeground = p->worldTransform(); } + + QTransform transformInDrawBackground; + QTransform transformInDrawForeground; + }; + + MyScene scene; + // Add transformed dummy items to make sure the painter's worldTransform() is changed in drawItems. + scene.addRect(0, 0, 20, 20)->setTransform(QTransform::fromScale(2, 2)); + scene.addRect(50, 50, 20, 20)->setTransform(QTransform::fromTranslate(200, 200)); + + CustomView view(&scene); + if (!savePainter) + view.setOptimizationFlag(QGraphicsView::DontSavePainterState); + view.rotate(45); + view.scale(1.5, 1.5); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + + // Make sure the view is repainted; otherwise the tests below will fail. + view.viewport()->repaint(); + QTest::qWait(200); + QVERIFY(view.painted); + + // Make sure the painter's world transform is preserved after drawItems. + const QTransform expectedTransform = view.viewportTransform(); + QVERIFY(!expectedTransform.isIdentity()); + QCOMPARE(scene.transformInDrawForeground, expectedTransform); + QCOMPARE(scene.transformInDrawBackground, expectedTransform); +} + class LodItem : public QGraphicsRectItem { public: @@ -3735,7 +3788,7 @@ void tst_QGraphicsView::task259503_scrollingArtifacts() { // qDebug() << event->region(); // qDebug() << updateRegion; - QEXPECT_FAIL("", "The event region doesn't include the original item position region. See task #259503.", Continue); + QEXPECT_FAIL("", "The event region doesn't include the original item position region. See QTBUG-4416", Continue); QCOMPARE(event->region(), updateRegion); } } diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 6e211ae..a5ff153 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -119,6 +119,8 @@ private slots: void task262152_setModelColumnNavigate(); void taskQTBUG_2233_scrollHiddenItems_data(); void taskQTBUG_2233_scrollHiddenItems(); + void taskQTBUG_633_changeModelData(); + void taskQTBUG_435_deselectOnViewportClick(); }; // Testing get/set functions @@ -1132,6 +1134,7 @@ void tst_QListView::selection() #endif v.show(); + QTest::qWaitForWindowShown(&v); QApplication::processEvents(); v.setSelection(selectionRect, QItemSelectionModel::ClearAndSelect); @@ -1184,6 +1187,7 @@ void tst_QListView::scrollTo() lv.setModel(&model); lv.setFixedSize(100, 200); lv.show(); + QTest::qWaitForWindowShown(&lv); //by default, the list view scrolls per item and has no wrapping QModelIndex index = model.index(6,0); @@ -1782,6 +1786,7 @@ void tst_QListView::task262152_setModelColumnNavigate() view.setModelColumn(1); view.show(); + QTest::qWaitForWindowShown(&view); QTest::qWait(100); QTest::keyClick(&view, Qt::Key_Down); QTest::qWait(100); @@ -1829,5 +1834,47 @@ void tst_QListView::taskQTBUG_2233_scrollHiddenItems() } } +void tst_QListView::taskQTBUG_633_changeModelData() +{ + QListView view; + view.setFlow(QListView::LeftToRight); + QStandardItemModel model(5,1); + for (int i = 0; i < model.rowCount(); ++i) { + model.setData( model.index(i, 0), QString::number(i)); + } + + view.setModel(&model); + view.show(); + QTest::qWaitForWindowShown(&view); + model.setData( model.index(1, 0), QLatin1String("long long text")); + QTest::qWait(100); //leave time for relayouting the items + QRect rectLongText = view.visualRect(model.index(1,0)); + QRect rect2 = view.visualRect(model.index(2,0)); + QVERIFY( ! rectLongText.intersects(rect2) ); +} + +void tst_QListView::taskQTBUG_435_deselectOnViewportClick() +{ + QListView view; + QStringListModel model( QStringList() << "1" << "2" << "3" << "4"); + view.setModel(&model); + view.setSelectionMode(QAbstractItemView::ExtendedSelection); + view.selectAll(); + QCOMPARE(view.selectionModel()->selectedIndexes().count(), model.rowCount()); + + + QPoint p = view.visualRect(model.index(model.rowCount() - 1)).center() + QPoint(0, 20); + //first the left button + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, p); + QVERIFY(!view.selectionModel()->hasSelection()); + + view.selectAll(); + QCOMPARE(view.selectionModel()->selectedIndexes().count(), model.rowCount()); + + //and now the right button + QTest::mouseClick(view.viewport(), Qt::RightButton, 0, p); + QVERIFY(!view.selectionModel()->hasSelection()); +} + QTEST_MAIN(tst_QListView) #include "tst_qlistview.moc" diff --git a/tests/auto/qlistwidget/tst_qlistwidget.cpp b/tests/auto/qlistwidget/tst_qlistwidget.cpp index e825c8f..5c6ed54 100644 --- a/tests/auto/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/qlistwidget/tst_qlistwidget.cpp @@ -46,6 +46,7 @@ #include <qlist.h> #include <qlistwidget.h> +#include <private/qlistwidget_p.h> //TESTED_CLASS= //TESTED_FILES= @@ -95,6 +96,8 @@ private slots: void insertItem(); void insertItems_data(); void insertItems(); + void moveItemsPriv_data(); + void moveItemsPriv(); void itemAssignment(); void item_data(); @@ -849,6 +852,62 @@ void tst_QListWidget::removeItems() } +void tst_QListWidget::moveItemsPriv_data() +{ + QTest::addColumn<int>("rowCount"); + QTest::addColumn<int>("srcRow"); + QTest::addColumn<int>("dstRow"); + QTest::addColumn<bool>("shouldHaveSignaled"); + + QTest::newRow("Empty") << 0 << 0 << 0 << false; + QTest::newRow("Overflow src") << 5 << 5 << 2 << false; + QTest::newRow("Underflow src") << 5 << -1 << 2 << false; + QTest::newRow("Overflow dst") << 5 << 2 << 5 << false; + QTest::newRow("Underflow dst") << 5 << 2 << -1 << false; + QTest::newRow("Same place") << 5 << 2 << 2 << false; + QTest::newRow("Up") << 5 << 4 << 2 << true; + QTest::newRow("Down") << 5 << 2 << 4 << true; +} + +void tst_QListWidget::moveItemsPriv() +{ + QFETCH(int, rowCount); + QFETCH(int, srcRow); + QFETCH(int, dstRow); + QFETCH(bool, shouldHaveSignaled); + + for (int r = 0; r < rowCount; ++r) + new QListWidgetItem(QString::number(r), testWidget); + + QListModel *model = dynamic_cast<QListModel *>(testWidget->model()); + QVERIFY(model); + QSignalSpy beginMoveSpy(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy movedSpy(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + model->move(srcRow, dstRow); + + if (shouldHaveSignaled) { + if (srcRow < dstRow) + QCOMPARE(testWidget->item(dstRow - 1)->text(), QString::number(srcRow)); + else + QCOMPARE(testWidget->item(dstRow)->text(), QString::number(srcRow)); + + QCOMPARE(beginMoveSpy.count(), 1); + const QList<QVariant> &beginMoveArgs = beginMoveSpy.takeFirst(); + QCOMPARE(beginMoveArgs.at(1).toInt(), srcRow); + QCOMPARE(beginMoveArgs.at(2).toInt(), srcRow); + QCOMPARE(beginMoveArgs.at(4).toInt(), dstRow); + + QCOMPARE(movedSpy.count(), 1); + const QList<QVariant> &movedArgs = movedSpy.takeFirst(); + QCOMPARE(movedArgs.at(1).toInt(), srcRow); + QCOMPARE(movedArgs.at(2).toInt(), srcRow); + QCOMPARE(movedArgs.at(4).toInt(), dstRow); + } else { + QCOMPARE(beginMoveSpy.count(), 0); + QCOMPARE(movedSpy.count(), 0); + } +} + void tst_QListWidget::itemStreaming_data() { QTest::addColumn<QString>("text"); diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index be39d00..ab7b0ac 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -976,7 +976,7 @@ void tst_QLocalSocket::writeOnlySocket() #if defined(Q_OS_SYMBIAN) QTest::qWait(250); #endif - QVERIFY(server.waitForNewConnection()); + QVERIFY(server.waitForNewConnection(200)); QLocalSocket* serverSocket = server.nextPendingConnection(); QVERIFY(serverSocket); diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp index 07aa9f4..4291c3e 100644 --- a/tests/auto/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/qmenubar/tst_qmenubar.cpp @@ -86,6 +86,18 @@ private: uint sel_count; }; +class Menu : public QMenu +{ + Q_OBJECT + public slots: + void addActions() + { + //this will change the geometry of the menu + addAction("action1"); + addAction("action2"); + } +}; + class tst_QMenuBar : public QObject { Q_OBJECT @@ -1442,7 +1454,7 @@ void tst_QMenuBar::check_menuPosition() #ifdef Q_OS_WINCE_WM QSKIP("Qt/CE uses native menubar", SkipAll); #endif - QMenu menu; + Menu menu; #ifdef QT3_SUPPORT initComplexMenubar(); #else @@ -1496,6 +1508,21 @@ void tst_QMenuBar::check_menuPosition() menu.close(); } + //in RTL, the menu should be stuck at the right of the action geometry + { + Qt::LayoutDirection dir = qApp->layoutDirection(); + qApp->setLayoutDirection(Qt::RightToLeft); + menu.clear(); + QObject::connect(&menu, SIGNAL(aboutToShow()), &menu, SLOT(addActions())); + QRect mbItemRect = mw->menuBar()->actionGeometry(menu_action); + mbItemRect.moveTo(mw->menuBar()->mapToGlobal(mbItemRect.topLeft())); + QTest::keyClick(mw, Qt::Key_M, Qt::AltModifier ); + QVERIFY(menu.isActiveWindow()); + QCOMPARE(menu.geometry().right(), mbItemRect.right()); + menu.close(); + qApp->setLayoutDirection(dir); + } + } void tst_QMenuBar::task223138_triggered() diff --git a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp index 8578d36..8d937e9 100644 --- a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp +++ b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp @@ -56,8 +56,7 @@ public: virtual ~tst_QParallelAnimationGroup(); public Q_SLOTS: - void init(); - void cleanup(); + void initTestCase(); private slots: void construction(); @@ -86,13 +85,13 @@ tst_QParallelAnimationGroup::~tst_QParallelAnimationGroup() { } -void tst_QParallelAnimationGroup::init() +void tst_QParallelAnimationGroup::initTestCase() { qRegisterMetaType<QAbstractAnimation::State>("QAbstractAnimation::State"); -} - -void tst_QParallelAnimationGroup::cleanup() -{ +#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAC) || defined(Q_WS_WINCE) + // give the Symbian and mac app start event queue time to clear + QTest::qWait(1000); +#endif } void tst_QParallelAnimationGroup::construction() @@ -486,10 +485,6 @@ void tst_QParallelAnimationGroup::updateChildrenWithRunningGroup() void tst_QParallelAnimationGroup::deleteChildrenWithRunningGroup() { -#if defined(Q_OS_SYMBIAN) - // give the Symbian app start event queue time to clear - QTest::qWait(1000); -#endif // test if children can be activated when their group is stopped QParallelAnimationGroup group; diff --git a/tests/auto/qpauseanimation/tst_qpauseanimation.cpp b/tests/auto/qpauseanimation/tst_qpauseanimation.cpp index b11efa0..4d0a7a7 100644 --- a/tests/auto/qpauseanimation/tst_qpauseanimation.cpp +++ b/tests/auto/qpauseanimation/tst_qpauseanimation.cpp @@ -93,8 +93,7 @@ public: virtual ~tst_QPauseAnimation(); public Q_SLOTS: - void init(); - void cleanup(); + void initTestCase(); private slots: void changeDirectionWhileRunning(); @@ -117,20 +116,15 @@ tst_QPauseAnimation::~tst_QPauseAnimation() { } -void tst_QPauseAnimation::init() +void tst_QPauseAnimation::initTestCase() { qRegisterMetaType<QAbstractAnimation::State>("QAbstractAnimation::State"); qRegisterMetaType<QAbstractAnimation::DeletionPolicy>("QAbstractAnimation::DeletionPolicy"); } -void tst_QPauseAnimation::cleanup() -{ -} - void tst_QPauseAnimation::changeDirectionWhileRunning() { - QUnifiedTimer *timer = QUnifiedTimer::instance(); - timer->setConsistentTiming(true); + EnableConsistentTiming enabled; TestablePauseAnimation animation; animation.setDuration(400); @@ -140,8 +134,6 @@ void tst_QPauseAnimation::changeDirectionWhileRunning() animation.setDirection(QAbstractAnimation::Backward); QTest::qWait(animation.totalDuration() + 50); QVERIFY(animation.state() == QAbstractAnimation::Stopped); - - timer->setConsistentTiming(false); } void tst_QPauseAnimation::noTimerUpdates_data() @@ -157,8 +149,7 @@ void tst_QPauseAnimation::noTimerUpdates_data() void tst_QPauseAnimation::noTimerUpdates() { - QUnifiedTimer *timer = QUnifiedTimer::instance(); - timer->setConsistentTiming(true); + EnableConsistentTiming enabled; QFETCH(int, duration); QFETCH(int, loopCount); @@ -168,16 +159,19 @@ void tst_QPauseAnimation::noTimerUpdates() animation.setLoopCount(loopCount); animation.start(); QTest::qWait(animation.totalDuration() + 100); + +#ifdef Q_OS_WIN + if (animation.state() != QAbstractAnimation::Stopped) + QEXPECT_FAIL("", "On windows, consistent timing is not working properly due to bad timer resolution", Abort); +#endif + QVERIFY(animation.state() == QAbstractAnimation::Stopped); QCOMPARE(animation.m_updateCurrentTimeCount, 1 + loopCount); - - timer->setConsistentTiming(false); } void tst_QPauseAnimation::mulitplePauseAnimations() { - QUnifiedTimer *timer = QUnifiedTimer::instance(); - timer->setConsistentTiming(true); + EnableConsistentTiming enabled; TestablePauseAnimation animation; animation.setDuration(200); @@ -188,16 +182,26 @@ void tst_QPauseAnimation::mulitplePauseAnimations() animation.start(); animation2.start(); QTest::qWait(animation.totalDuration() + 100); + +#ifdef Q_OS_WIN + if (animation.state() != QAbstractAnimation::Stopped) + QEXPECT_FAIL("", "On windows, consistent timing is not working properly due to bad timer resolution", Abort); +#endif + QVERIFY(animation.state() == QAbstractAnimation::Stopped); QVERIFY(animation2.state() == QAbstractAnimation::Running); QCOMPARE(animation.m_updateCurrentTimeCount, 2); QCOMPARE(animation2.m_updateCurrentTimeCount, 2); QTest::qWait(550); + +#ifdef Q_OS_WIN + if (animation2.state() != QAbstractAnimation::Stopped) + QEXPECT_FAIL("", "On windows, consistent timing is not working properly due to bad timer resolution", Abort); +#endif + QVERIFY(animation2.state() == QAbstractAnimation::Stopped); QCOMPARE(animation2.m_updateCurrentTimeCount, 3); - - timer->setConsistentTiming(false); } void tst_QPauseAnimation::pauseAndPropertyAnimations() @@ -243,7 +247,7 @@ void tst_QPauseAnimation::pauseResume() animation.pause(); QVERIFY(animation.state() == QAbstractAnimation::Paused); animation.start(); - QTest::qWait(250); + QTest::qWait(300); QVERIFY(animation.state() == QAbstractAnimation::Stopped); QCOMPARE(animation.m_updateCurrentTimeCount, 3); } @@ -260,6 +264,9 @@ void tst_QPauseAnimation::sequentialPauseGroup() animation3.setDuration(200); group.start(); + QCOMPARE(animation1.m_updateCurrentTimeCount, 1); + QCOMPARE(animation2.m_updateCurrentTimeCount, 0); + QCOMPARE(animation3.m_updateCurrentTimeCount, 0); QVERIFY(group.state() == QAbstractAnimation::Running); QVERIFY(animation1.state() == QAbstractAnimation::Running); @@ -267,6 +274,9 @@ void tst_QPauseAnimation::sequentialPauseGroup() QVERIFY(animation3.state() == QAbstractAnimation::Stopped); group.setCurrentTime(250); + QCOMPARE(animation1.m_updateCurrentTimeCount, 2); + QCOMPARE(animation2.m_updateCurrentTimeCount, 1); + QCOMPARE(animation3.m_updateCurrentTimeCount, 0); QVERIFY(group.state() == QAbstractAnimation::Running); QVERIFY(animation1.state() == QAbstractAnimation::Stopped); @@ -275,6 +285,9 @@ void tst_QPauseAnimation::sequentialPauseGroup() QVERIFY(animation3.state() == QAbstractAnimation::Stopped); group.setCurrentTime(500); + QCOMPARE(animation1.m_updateCurrentTimeCount, 2); + QCOMPARE(animation2.m_updateCurrentTimeCount, 2); + QCOMPARE(animation3.m_updateCurrentTimeCount, 1); QVERIFY(group.state() == QAbstractAnimation::Running); QVERIFY(animation1.state() == QAbstractAnimation::Stopped); diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 53b6230..8e02c74 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -1134,6 +1134,8 @@ void tst_QPixmap::fromSymbianCFbsBitmap_data() QTest::newRow("EColor4K big") << EColor4K << largeWidth << largeHeight << QColor(Qt::red); QTest::newRow("EColor64K small") << EColor64K << smallWidth << smallHeight << QColor(Qt::green); QTest::newRow("EColor64K big") << EColor64K << largeWidth << largeHeight << QColor(Qt::green); + QTest::newRow("EColor16M small") << EColor16M << smallWidth << smallHeight << QColor(Qt::yellow); + QTest::newRow("EColor16M big") << EColor16M << largeWidth << largeHeight << QColor(Qt::yellow); QTest::newRow("EColor16MU small") << EColor16MU << smallWidth << smallHeight << QColor(Qt::red); QTest::newRow("EColor16MU big") << EColor16MU << largeWidth << largeHeight << QColor(Qt::red); QTest::newRow("EColor16MA small opaque") << EColor16MA << smallWidth << smallHeight << QColor(255, 255, 0); diff --git a/tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp b/tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp index 5a9bad7..a80c787 100644 --- a/tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp +++ b/tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp @@ -383,7 +383,7 @@ void tst_QPixmapFilter::dropShadowBoundingRectFor() QPixmapDropShadowFilter filter; filter.setBlurRadius(0); - QCOMPARE(filter.blurRadius(), 0); + QCOMPARE(filter.blurRadius(), 0.); const QRectF rect1(0, 0, 50, 50); const QRectF rect2(30, 20, 10, 40); diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp index 7dd17e5..56c1ced 100644 --- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp @@ -495,7 +495,7 @@ void tst_QPropertyAnimation::startWhenAnotherIsRunning() anim->setEndValue(100); QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); anim->start(QVariantAnimation::DeleteWhenStopped); - QTest::qWait(anim->duration() + 50); + QTest::qWait(anim->duration() + 100); QCOMPARE(runningSpy.count(), 2); //started and then stopped QVERIFY(!anim); } @@ -659,7 +659,7 @@ void tst_QPropertyAnimation::playForwardBackward() anim.setStartValue(0); anim.setEndValue(100); anim.start(); - QTest::qWait(anim.duration() + 50); + QTest::qWait(anim.duration() + 100); QCOMPARE(anim.state(), QAbstractAnimation::Stopped); QCOMPARE(anim.currentTime(), anim.duration()); @@ -667,7 +667,7 @@ void tst_QPropertyAnimation::playForwardBackward() anim.setDirection(QVariantAnimation::Backward); anim.start(); QCOMPARE(anim.state(), QAbstractAnimation::Running); - QTest::qWait(anim.duration() + 50); + QTest::qWait(anim.duration() + 100); QCOMPARE(anim.state(), QAbstractAnimation::Stopped); QCOMPARE(anim.currentTime(), 0); @@ -676,7 +676,7 @@ void tst_QPropertyAnimation::playForwardBackward() anim.start(); QCOMPARE(anim.state(), QAbstractAnimation::Running); QCOMPARE(anim.currentTime(), anim.duration()); - QTest::qWait(anim.duration() + 50); + QTest::qWait(anim.duration() + 100); QCOMPARE(anim.state(), QAbstractAnimation::Stopped); QCOMPARE(anim.currentTime(), 0); } @@ -1093,7 +1093,7 @@ void tst_QPropertyAnimation::valueChanged() QSignalSpy spy(&anim, SIGNAL(valueChanged(QVariant))); anim.start(); - QTest::qWait(anim.duration() + 50); + QTest::qWait(anim.duration() + 100); QCOMPARE(anim.state(), QAbstractAnimation::Stopped); QCOMPARE(anim.currentTime(), anim.duration()); @@ -1144,7 +1144,7 @@ void tst_QPropertyAnimation::twoAnimations() o1.anim.start(); o2.anim.start(); - QTest::qWait(o1.anim.duration() + 50); + QTest::qWait(o1.anim.duration() + 100); QCOMPARE(o1.anim.state(), QAbstractAnimation::Stopped); QCOMPARE(o2.anim.state(), QAbstractAnimation::Stopped); @@ -1194,7 +1194,7 @@ void tst_QPropertyAnimation::deletedInUpdateCurrentTime() MyComposedAnimation composedAnimation(&o, "value", "realValue"); composedAnimation.start(); QCOMPARE(composedAnimation.state(), QAbstractAnimation::Running); - QTest::qWait(composedAnimation.duration() + 50); + QTest::qWait(composedAnimation.duration() + 100); QCOMPARE(composedAnimation.state(), QAbstractAnimation::Stopped); QCOMPARE(o.value(), 1000); diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index 25ee00f..804534f 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -44,6 +44,7 @@ #include <qscriptengine.h> #include <qscriptengineagent.h> +#include <qscriptprogram.h> #include <qscriptvalueiterator.h> #include <qgraphicsitem.h> #include <qstandarditemmodel.h> @@ -52,6 +53,7 @@ Q_DECLARE_METATYPE(QList<int>) Q_DECLARE_METATYPE(QObjectList) +Q_DECLARE_METATYPE(QScriptProgram) //TESTED_CLASS= //TESTED_FILES= @@ -151,6 +153,7 @@ private slots: void installTranslatorFunctions(); void functionScopes(); void nativeFunctionScopes(); + void evaluateProgram(); void qRegExpInport_data(); void qRegExpInport(); @@ -4289,6 +4292,152 @@ void tst_QScriptEngine::nativeFunctionScopes() } } +static QScriptValue createProgram(QScriptContext *ctx, QScriptEngine *eng) +{ + QString code = ctx->argument(0).toString(); + QScriptProgram result(code); + return qScriptValueFromValue(eng, result); +} + +void tst_QScriptEngine::evaluateProgram() +{ + QScriptEngine eng; + + { + QString code("1 + 2"); + QString fileName("hello.js"); + int lineNumber(123); + QScriptProgram program(code, fileName, lineNumber); + QVERIFY(!program.isNull()); + QCOMPARE(program.sourceCode(), code); + QCOMPARE(program.fileName(), fileName); + QCOMPARE(program.firstLineNumber(), lineNumber); + + QScriptValue expected = eng.evaluate(code); + for (int x = 0; x < 10; ++x) { + QScriptValue ret = eng.evaluate(program); + QVERIFY(ret.equals(expected)); + } + + // operator= + QScriptProgram sameProgram = program; + QVERIFY(sameProgram == program); + QVERIFY(eng.evaluate(sameProgram).equals(expected)); + + // copy constructor + QScriptProgram sameProgram2(program); + QVERIFY(sameProgram2 == program); + QVERIFY(eng.evaluate(sameProgram2).equals(expected)); + + QScriptProgram differentProgram("2 + 3"); + QVERIFY(differentProgram != program); + QVERIFY(!eng.evaluate(differentProgram).equals(expected)); + } + + // Program that accesses variable in the scope + { + QScriptProgram program("a"); + QVERIFY(!program.isNull()); + { + QScriptValue ret = eng.evaluate(program); + QVERIFY(ret.isError()); + QCOMPARE(ret.toString(), QString::fromLatin1("ReferenceError: Can't find variable: a")); + } + + QScriptValue obj = eng.newObject(); + obj.setProperty("a", 123); + QScriptContext *ctx = eng.currentContext(); + ctx->pushScope(obj); + { + QScriptValue ret = eng.evaluate(program); + QVERIFY(!ret.isError()); + QVERIFY(ret.equals(obj.property("a"))); + } + + obj.setProperty("a", QScriptValue()); + { + QScriptValue ret = eng.evaluate(program); + QVERIFY(ret.isError()); + } + + QScriptValue obj2 = eng.newObject(); + obj2.setProperty("a", 456); + ctx->pushScope(obj2); + { + QScriptValue ret = eng.evaluate(program); + QVERIFY(!ret.isError()); + QVERIFY(ret.equals(obj2.property("a"))); + } + + ctx->popScope(); + } + + // Program that creates closure + { + QScriptProgram program("(function() { var count = 0; return function() { return count++; }; })"); + QVERIFY(!program.isNull()); + QScriptValue createCounter = eng.evaluate(program); + QVERIFY(createCounter.isFunction()); + QScriptValue counter = createCounter.call(); + QVERIFY(counter.isFunction()); + { + QScriptValue ret = counter.call(); + QVERIFY(ret.isNumber()); + } + QScriptValue counter2 = createCounter.call(); + QVERIFY(counter2.isFunction()); + QVERIFY(!counter2.equals(counter)); + { + QScriptValue ret = counter2.call(); + QVERIFY(ret.isNumber()); + } + } + + // Program created in a function call, then executed later + { + QScriptValue fun = eng.newFunction(createProgram); + QScriptProgram program = qscriptvalue_cast<QScriptProgram>( + fun.call(QScriptValue(), QScriptValueList() << "a + 1")); + QVERIFY(!program.isNull()); + eng.globalObject().setProperty("a", QScriptValue()); + { + QScriptValue ret = eng.evaluate(program); + QVERIFY(ret.isError()); + QCOMPARE(ret.toString(), QString::fromLatin1("ReferenceError: Can't find variable: a")); + } + eng.globalObject().setProperty("a", 122); + { + QScriptValue ret = eng.evaluate(program); + QVERIFY(!ret.isError()); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + } + } + + // Same program run in different engines + { + QString code("1 + 2"); + QScriptProgram program(code); + QVERIFY(!program.isNull()); + double expected = eng.evaluate(program).toNumber(); + for (int x = 0; x < 2; ++x) { + QScriptEngine eng2; + for (int y = 0; y < 2; ++y) { + double ret = eng2.evaluate(program).toNumber(); + QCOMPARE(ret, expected); + } + } + } + + // No program + { + QScriptProgram program; + QVERIFY(program.isNull()); + QScriptValue ret = eng.evaluate(program); + QVERIFY(!ret.isValid()); + } +} + static QRegExp minimal(QRegExp r) { r.setMinimal(true); return r; } void tst_QScriptEngine::qRegExpInport_data() diff --git a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp index 82c8ccd..032c34b 100644 --- a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp +++ b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp @@ -44,6 +44,7 @@ #include <QtScript/qscriptengineagent.h> #include <QtScript/qscriptengine.h> +#include <QtScript/qscriptprogram.h> #include <qscriptvalueiterator.h> //TESTED_CLASS= @@ -110,6 +111,9 @@ private slots: void extension(); void isEvaluatingInExtension(); void hasUncaughtException(); + void evaluateProgram(); + void evaluateProgram_SyntaxError(); + void evaluateNullProgram(); private: double m_testProperty; @@ -2219,6 +2223,88 @@ void tst_QScriptEngineAgent::hasUncaughtException() QVERIFY2(spy->isPass(), "At least one of a functionExit event should set hasUncaughtException flag."); } +void tst_QScriptEngineAgent::evaluateProgram() +{ + QScriptEngine eng; + QScriptProgram program("1 + 2", "foo.js", 123); + ScriptEngineSpy *spy = new ScriptEngineSpy(&eng); + qint64 scriptId = -1; + for (int x = 0; x < 10; ++x) { + spy->clear(); + (void)eng.evaluate(program); + QCOMPARE(spy->count(), (x == 0) ? 4 : 3); + + if (x == 0) { + // script is only loaded on first execution + QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); + scriptId = spy->at(0).scriptId; + QVERIFY(scriptId != -1); + QCOMPARE(spy->at(0).script, program.sourceCode()); + QCOMPARE(spy->at(0).fileName, program.fileName()); + QCOMPARE(spy->at(0).lineNumber, program.firstLineNumber()); + spy->removeFirst(); + } + + QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); // evaluate() + QCOMPARE(spy->at(0).scriptId, scriptId); + + QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); + QCOMPARE(spy->at(1).scriptId, scriptId); + QCOMPARE(spy->at(1).lineNumber, program.firstLineNumber()); + + QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionExit); // evaluate() + QCOMPARE(spy->at(2).scriptId, scriptId); + QVERIFY(spy->at(2).value.isNumber()); + QCOMPARE(spy->at(2).value.toNumber(), qsreal(3)); + } +} + +void tst_QScriptEngineAgent::evaluateProgram_SyntaxError() +{ + QScriptEngine eng; + QScriptProgram program("this is not valid syntax", "foo.js", 123); + ScriptEngineSpy *spy = new ScriptEngineSpy(&eng); + qint64 scriptId = -1; + for (int x = 0; x < 10; ++x) { + spy->clear(); + (void)eng.evaluate(program); + QCOMPARE(spy->count(), (x == 0) ? 8 : 7); + + if (x == 0) { + // script is only loaded on first execution + QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); + scriptId = spy->at(0).scriptId; + QVERIFY(scriptId != -1); + QCOMPARE(spy->at(0).script, program.sourceCode()); + QCOMPARE(spy->at(0).fileName, program.fileName()); + QCOMPARE(spy->at(0).lineNumber, program.firstLineNumber()); + spy->removeFirst(); + } + + QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); // evaluate() + QCOMPARE(spy->at(0).scriptId, scriptId); + + QCOMPARE(spy->at(1).type, ScriptEngineEvent::ContextPush); // SyntaxError constructor + QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionEntry); // SyntaxError constructor + QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); // SyntaxError constructor + QCOMPARE(spy->at(4).type, ScriptEngineEvent::ContextPop); // SyntaxError constructor + + QCOMPARE(spy->at(5).type, ScriptEngineEvent::ExceptionThrow); + QVERIFY(spy->at(5).value.isError()); + QCOMPARE(spy->at(5).value.toString(), QString::fromLatin1("SyntaxError: Parse error")); + + QCOMPARE(spy->at(6).type, ScriptEngineEvent::FunctionExit); // evaluate() + QCOMPARE(spy->at(6).scriptId, scriptId); + } +} + +void tst_QScriptEngineAgent::evaluateNullProgram() +{ + QScriptEngine eng; + ScriptEngineSpy *spy = new ScriptEngineSpy(&eng); + (void)eng.evaluate(QScriptProgram()); + QCOMPARE(spy->count(), 0); +} QTEST_MAIN(tst_QScriptEngineAgent) #include "tst_qscriptengineagent.moc" diff --git a/tests/auto/qscriptstring/tst_qscriptstring.cpp b/tests/auto/qscriptstring/tst_qscriptstring.cpp index e1a4bc1..1229f4a 100644 --- a/tests/auto/qscriptstring/tst_qscriptstring.cpp +++ b/tests/auto/qscriptstring/tst_qscriptstring.cpp @@ -59,6 +59,8 @@ public: private slots: void test(); void hash(); + void toArrayIndex_data(); + void toArrayIndex(); }; tst_QScriptString::tst_QScriptString() @@ -155,5 +157,40 @@ void tst_QScriptString::hash() QCOMPARE(stringToInt.value(foo), 123); } +void tst_QScriptString::toArrayIndex_data() +{ + QTest::addColumn<QString>("input"); + QTest::addColumn<bool>("expectSuccess"); + QTest::addColumn<quint32>("expectedIndex"); + QTest::newRow("foo") << QString::fromLatin1("foo") << false << quint32(0xffffffff); + QTest::newRow("empty") << QString::fromLatin1("") << false << quint32(0xffffffff); + QTest::newRow("0") << QString::fromLatin1("0") << true << quint32(0); + QTest::newRow("00") << QString::fromLatin1("00") << false << quint32(0xffffffff); + QTest::newRow("1") << QString::fromLatin1("1") << true << quint32(1); + QTest::newRow("123") << QString::fromLatin1("123") << true << quint32(123); + QTest::newRow("-1") << QString::fromLatin1("-1") << false << quint32(0xffffffff); + QTest::newRow("0a") << QString::fromLatin1("0a") << false << quint32(0xffffffff); + QTest::newRow("0x1") << QString::fromLatin1("0x1") << false << quint32(0xffffffff); + QTest::newRow("01") << QString::fromLatin1("01") << false << quint32(0xffffffff); + QTest::newRow("4294967294") << QString::fromLatin1("4294967294") << true << quint32(0xfffffffe); + QTest::newRow("4294967295") << QString::fromLatin1("4294967295") << false << quint32(0xffffffff); +} + +void tst_QScriptString::toArrayIndex() +{ + QFETCH(QString, input); + QFETCH(bool, expectSuccess); + QFETCH(quint32, expectedIndex); + QScriptEngine engine; + for (int x = 0; x < 2; ++x) { + bool isArrayIndex; + bool *ptr = (x == 0) ? &isArrayIndex : (bool*)0; + quint32 result = engine.toStringHandle(input).toArrayIndex(ptr); + if (x == 0) + QCOMPARE(isArrayIndex, expectSuccess); + QCOMPARE(result, expectedIndex); + } +} + QTEST_MAIN(tst_QScriptString) #include "tst_qscriptstring.moc" diff --git a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp index aa6801a..f6afc5b 100644 --- a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp +++ b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp @@ -929,16 +929,13 @@ void tst_QSequentialAnimationGroup::startDelay() group.addPause(125); QCOMPARE(group.totalDuration(), 375); - QEventLoop loop; - QObject::connect(&group, SIGNAL(finished()), &loop, SLOT(quit())); - - QTime time; - time.start(); group.start(); - loop.exec(); + QCOMPARE(group.state(), QAnimationGroup::Running); - QVERIFY(time.elapsed() >= 375); - QVERIFY(time.elapsed() < 1000); + QTest::qWait(500); + + QVERIFY(group.currentTime() == 375); + QCOMPARE(group.state(), QAnimationGroup::Stopped); } void tst_QSequentialAnimationGroup::clearGroup() diff --git a/tests/auto/qsound/tst_qsound.cpp b/tests/auto/qsound/tst_qsound.cpp index fdbf6a2..56a330b 100644 --- a/tests/auto/qsound/tst_qsound.cpp +++ b/tests/auto/qsound/tst_qsound.cpp @@ -66,7 +66,7 @@ void tst_QSound::checkFinished() QTest::qWait(5000); #if defined(Q_WS_QWS) - QEXPECT_FAIL("", "QSound buggy on embedded (task 122221)", Abort); + QEXPECT_FAIL("", "QSound buggy on embedded (task QTBUG-157)", Abort); #endif QVERIFY(sound.isFinished() ); } diff --git a/tests/auto/qsplitter/tst_qsplitter.cpp b/tests/auto/qsplitter/tst_qsplitter.cpp index cf16421..b832f3a 100644 --- a/tests/auto/qsplitter/tst_qsplitter.cpp +++ b/tests/auto/qsplitter/tst_qsplitter.cpp @@ -102,6 +102,8 @@ private slots: void task187373_addAbstractScrollAreas(); void task187373_addAbstractScrollAreas_data(); void task169702_sizes(); + void taskQTBUG_4101_ensureOneNonCollapsedWidget_data(); + void taskQTBUG_4101_ensureOneNonCollapsedWidget(); private: void removeThirdWidget(); @@ -1281,6 +1283,8 @@ class MyFriendlySplitter : public QSplitter public: MyFriendlySplitter(QWidget *parent = 0) : QSplitter(parent) {} void setRubberBand(int pos) { QSplitter::setRubberBand(pos); } + + friend class tst_QSplitter; }; void tst_QSplitter::rubberBandNotInSplitter() @@ -1403,5 +1407,35 @@ void tst_QSplitter::task169702_sizes() QCOMPARE(testW->size().height(), testW->minimumSizeHint().height()); } +void tst_QSplitter::taskQTBUG_4101_ensureOneNonCollapsedWidget_data() +{ + QTest::addColumn<bool>("testingHide"); + + QTest::newRow("last non collapsed hidden") << true; + QTest::newRow("last non collapsed deleted") << false; +} + +void tst_QSplitter::taskQTBUG_4101_ensureOneNonCollapsedWidget() +{ + QFETCH(bool, testingHide); + + MyFriendlySplitter s; + QLabel *l; + for (int i = 0; i < 5; ++i) { + l = new QLabel(QString("Label ") + QChar('A' + i)); + l->setAlignment(Qt::AlignCenter); + s.addWidget(l); + s.moveSplitter(0, i); // Collapse all the labels except the last one. + } + + s.show(); + if (testingHide) + l->hide(); + else + delete l; + QTest::qWait(100); + QVERIFY(s.sizes().at(0) > 0); +} + QTEST_MAIN(tst_QSplitter) #include "tst_qsplitter.moc" diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 82b6066..fe7c3ea 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -1234,6 +1234,7 @@ void tst_QSqlDatabase::recordSQLite() FieldDef("integer", QVariant::Int, QVariant(13)), FieldDef("int", QVariant::Int, QVariant(12)), + FieldDef("real", QVariant::String, QVariant(1.234567890123456)), FieldDef() }; diff --git a/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp b/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp index 3131f35..02b48fa 100644 --- a/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp +++ b/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp @@ -96,6 +96,7 @@ private slots: void task_180617(); void task_180617_data() { generic_data(); } + void task_QTBUG_4963_setHeaderDataWithProxyModel(); private: void generic_data(const QString &engine=QString()); @@ -428,6 +429,8 @@ void tst_QSqlQueryModel::setHeaderData() QVERIFY(!model.setHeaderData(5, Qt::Vertical, "foo")); QVERIFY(model.headerData(5, Qt::Vertical).isValid()); + model.setQuery(QSqlQuery("select * from " + qTableName("test"), db)); + qRegisterMetaType<Qt::Orientation>("Qt::Orientation"); QSignalSpy spy(&model, SIGNAL(headerDataChanged(Qt::Orientation, int, int))); QVERIFY(model.setHeaderData(2, Qt::Horizontal, "bar")); @@ -437,10 +440,8 @@ void tst_QSqlQueryModel::setHeaderData() QCOMPARE(spy.value(0).value(1).toInt(), 2); QCOMPARE(spy.value(0).value(2).toInt(), 2); - QVERIFY(model.setHeaderData(7, Qt::Horizontal, "foo", Qt::ToolTipRole)); - QVERIFY(model.headerData(7, Qt::Horizontal, Qt::ToolTipRole).isValid()); - - model.setQuery(QSqlQuery("select * from " + qTableName("test"), db)); + QVERIFY(!model.setHeaderData(7, Qt::Horizontal, "foo", Qt::ToolTipRole)); + QVERIFY(!model.headerData(7, Qt::Horizontal, Qt::ToolTipRole).isValid()); bool isToUpper = db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2"); QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), isToUpper ? QString("ID") : QString("id")); @@ -603,5 +604,14 @@ void tst_QSqlQueryModel::task_180617() QCOMPARE(view.rowAt(0), -1); } +void tst_QSqlQueryModel::task_QTBUG_4963_setHeaderDataWithProxyModel() +{ + QSqlQueryModel plainModel; + QSortFilterProxyModel proxyModel; + proxyModel.setSourceModel(&plainModel); + QVERIFY(!plainModel.setHeaderData(0, Qt::Horizontal, QObject::tr("ID"))); + // And it should not crash. +} + QTEST_MAIN(tst_QSqlQueryModel) #include "tst_qsqlquerymodel.moc" diff --git a/tests/auto/qsslsocket/tst_qsslsocket.cpp b/tests/auto/qsslsocket/tst_qsslsocket.cpp index 2bd1684..db46b66 100644 --- a/tests/auto/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/qsslsocket/tst_qsslsocket.cpp @@ -1755,9 +1755,7 @@ void tst_QSslSocket::readFromClosedSocket() socket->close(); QVERIFY(!socket->bytesAvailable()); QVERIFY(!socket->bytesToWrite()); - socket->waitForDisconnected(); - QVERIFY(!socket->bytesAvailable()); - QVERIFY(!socket->bytesToWrite()); + QVERIFY(socket->state() == QAbstractSocket::UnconnectedState); } void tst_QSslSocket::writeBigChunk() diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 1516346..975b301 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -117,6 +117,7 @@ private slots: void cleanup(); void rootState(); + void machineWithParent(); void addAndRemoveState(); void stateEntryAndExit(); void assignProperty(); @@ -124,6 +125,7 @@ private slots: void postEvent(); void cancelDelayedEvent(); void postDelayedEventAndStop(); + void stopAndPostEvent(); void stateFinished(); void parallelStates(); void parallelRootState(); @@ -205,6 +207,7 @@ private slots: void goToState(); void task260403_clonedSignals(); + void postEventFromOtherThread(); }; tst_QStateMachine::tst_QStateMachine() @@ -1043,6 +1046,14 @@ void tst_QStateMachine::rootState() QCOMPARE(s2->parentState(), static_cast<QState*>(&machine)); } +void tst_QStateMachine::machineWithParent() +{ + QObject object; + QStateMachine *machine = new QStateMachine(&object); + QCOMPARE(machine->parent(), &object); + QCOMPARE(machine->parentState(), (QObject*)0); +} + void tst_QStateMachine::addAndRemoveState() { #ifdef QT_BUILD_INTERNAL @@ -1681,6 +1692,22 @@ void tst_QStateMachine::postDelayedEventAndStop() QVERIFY(machine.configuration().contains(s1)); } +void tst_QStateMachine::stopAndPostEvent() +{ + QStateMachine machine; + QState *s1 = new QState(&machine); + machine.setInitialState(s1); + QSignalSpy startedSpy(&machine, SIGNAL(started())); + machine.start(); + QTRY_COMPARE(startedSpy.count(), 1); + QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); + machine.stop(); + QCOMPARE(stoppedSpy.count(), 0); + machine.postEvent(new QEvent(QEvent::User)); + QTRY_COMPARE(stoppedSpy.count(), 1); + QCoreApplication::processEvents(); +} + void tst_QStateMachine::stateFinished() { QStateMachine machine; @@ -4188,5 +4215,52 @@ void tst_QStateMachine::task260403_clonedSignals() QCOMPARE(t1->eventSignalIndex, emitter.metaObject()->indexOfSignal("signalWithDefaultArg()")); } +class EventPosterThread : public QThread +{ + Q_OBJECT +public: + EventPosterThread(QStateMachine *machine, QObject *parent = 0) + : QThread(parent), m_machine(machine), m_count(0) + { + moveToThread(this); + QObject::connect(m_machine, SIGNAL(started()), + this, SLOT(postEvent())); + } +protected: + virtual void run() + { + exec(); + } +private Q_SLOTS: + void postEvent() + { + m_machine->postEvent(new QEvent(QEvent::User)); + if (++m_count < 10000) + QTimer::singleShot(0, this, SLOT(postEvent())); + else + quit(); + } +private: + QStateMachine *m_machine; + int m_count; +}; + +void tst_QStateMachine::postEventFromOtherThread() +{ + QStateMachine machine; + EventPosterThread poster(&machine); + StringEventPoster *s1 = new StringEventPoster("foo", &machine); + s1->addTransition(new EventTransition(QEvent::User, s1)); + QFinalState *f = new QFinalState(&machine); + s1->addTransition(&poster, SIGNAL(finished()), f); + machine.setInitialState(s1); + + poster.start(); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" diff --git a/tests/auto/qstringbuilder1/qstringbuilder1.pro b/tests/auto/qstringbuilder1/qstringbuilder1.pro index 1ca9d45..5bb14d4 100644 --- a/tests/auto/qstringbuilder1/qstringbuilder1.pro +++ b/tests/auto/qstringbuilder1/qstringbuilder1.pro @@ -3,7 +3,4 @@ load(qttest_p4) QT = core SOURCES += tst_qstringbuilder1.cpp -HEADERS += ../qstringbuilder1/stringbuilder.h - -DEFINES += SCENARIO=1 diff --git a/tests/auto/qstringbuilder1/stringbuilder.cpp b/tests/auto/qstringbuilder1/stringbuilder.cpp index 9fea137..f35d4d2 100644 --- a/tests/auto/qstringbuilder1/stringbuilder.cpp +++ b/tests/auto/qstringbuilder1/stringbuilder.cpp @@ -39,61 +39,9 @@ ** ****************************************************************************/ -// This is included in various .cpp files as a compile test for various scenarios -// depending on NO_CAST_* and QT_USE_FAST_OPERATOR_PLUS and QT_USE_FAST_CONCATENATION - -#if SCENARIO == 1 -// this is the "no harm done" version. Only operator% is active, -// with NO_CAST * defined -#define P % -#undef QT_USE_FAST_OPERATOR_PLUS -#undef QT_USE_FAST_CONCATENATION -#define QT_NO_CAST_FROM_ASCII -#define QT_NO_CAST_TO_ASCII -#endif - - -#if SCENARIO == 2 -// this is the "full" version. Operator+ is replaced by a QStringBuilder -// based version -// with NO_CAST * defined -#define P + -#define QT_USE_FAST_OPERATOR_PLUS -#define QT_USE_FAST_CONCATENATION -#define QT_NO_CAST_FROM_ASCII -#define QT_NO_CAST_TO_ASCII -#endif - -#if SCENARIO == 3 -// this is the "no harm done" version. Only operator% is active, -// with NO_CAST * _not_ defined -#define P % -#undef QT_USE_FAST_OPERATOR_PLUS -#undef QT_USE_FAST_CONCATENATION -#undef QT_NO_CAST_FROM_ASCII -#undef QT_NO_CAST_TO_ASCII -#endif - -#if SCENARIO == 4 -// this is the "full" version. Operator+ is replaced by a QStringBuilder -// based version -// with NO_CAST * _not_ defined -#define P + -#define QT_USE_FAST_OPERATOR_PLUS -#define QT_USE_FAST_CONCATENATION -#undef QT_NO_CAST_FROM_ASCII -#undef QT_NO_CAST_TO_ASCII -#endif - -#include <QtTest/QtTest> -#include "stringbuilder.h" - -//TESTED_CLASS=QStringBuilder -//TESTED_FILES=qstringbuilder.cpp - #define LITERAL "some literal" -void tst_QStringBuilder::scenario() +void runScenario() { QLatin1Literal l1literal(LITERAL); QLatin1String l1string(LITERAL); @@ -129,5 +77,3 @@ void tst_QStringBuilder::scenario() QCOMPARE(r, r2); #endif } - -QTEST_APPLESS_MAIN(tst_QStringBuilder) diff --git a/tests/auto/qstringbuilder1/stringbuilder.h b/tests/auto/qstringbuilder1/stringbuilder.h deleted file mode 100644 index 5ac9dbe..0000000 --- a/tests/auto/qstringbuilder1/stringbuilder.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 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$ -** -****************************************************************************/ - -#ifndef TST_QSTRINGBUILDER_H -#define TST_QSTRINGBUILDER_H - -#include <qobject.h> - -class tst_QStringBuilder : public QObject -{ - Q_OBJECT - -private slots: - void scenario(); -}; - -#endif diff --git a/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp b/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp index bd2e4b0..d0a613c 100644 --- a/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp +++ b/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp @@ -39,4 +39,35 @@ ** ****************************************************************************/ -#include "../qstringbuilder1/stringbuilder.cpp" + +// SCENARIO 1 +// this is the "no harm done" version. Only operator% is active, +// with NO_CAST * defined +#define P % +#undef QT_USE_FAST_OPERATOR_PLUS +#undef QT_USE_FAST_CONCATENATION +#define QT_NO_CAST_FROM_ASCII +#define QT_NO_CAST_TO_ASCII + + +#include <QtTest/QtTest> + +//TESTED_CLASS=QStringBuilder +//TESTED_FILES=qstringbuilder.cpp + +#define LITERAL "some literal" + +void runScenario(); // Defined in stringbuilder.cpp #included below. + +class tst_QStringBuilder1 : public QObject +{ + Q_OBJECT + +private slots: + void scenario() { runScenario(); } +}; + +#include "stringbuilder.cpp" +#include "tst_qstringbuilder1.moc" + +QTEST_APPLESS_MAIN(tst_QStringBuilder1) diff --git a/tests/auto/qstringbuilder2/qstringbuilder2.pro b/tests/auto/qstringbuilder2/qstringbuilder2.pro index c0b3ebc..4152dc3 100644 --- a/tests/auto/qstringbuilder2/qstringbuilder2.pro +++ b/tests/auto/qstringbuilder2/qstringbuilder2.pro @@ -3,6 +3,3 @@ load(qttest_p4) QT = core SOURCES += tst_qstringbuilder2.cpp -HEADERS += ../qstringbuilder1/stringbuilder.h - -DEFINES += SCENARIO=2 diff --git a/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp b/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp index bd2e4b0..4470928 100644 --- a/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp +++ b/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp @@ -39,4 +39,36 @@ ** ****************************************************************************/ + +// SCENARIO 2 +// this is the "full" version. Operator+ is replaced by a QStringBuilder +// based version +// with NO_CAST * defined +#define P + +#define QT_USE_FAST_OPERATOR_PLUS +#define QT_USE_FAST_CONCATENATION +#define QT_NO_CAST_FROM_ASCII +#define QT_NO_CAST_TO_ASCII + + +#include <QtTest/QtTest> + +//TESTED_CLASS=QStringBuilder +//TESTED_FILES=qstringbuilder.cpp + +#define LITERAL "some literal" + +void runScenario(); // Defined in stringbuilder.cpp #included below. + +class tst_QStringBuilder2 : public QObject +{ + Q_OBJECT + +private slots: + void scenario() { runScenario(); } +}; + #include "../qstringbuilder1/stringbuilder.cpp" +#include "tst_qstringbuilder2.moc" + +QTEST_APPLESS_MAIN(tst_QStringBuilder2) diff --git a/tests/auto/qstringbuilder3/qstringbuilder3.pro b/tests/auto/qstringbuilder3/qstringbuilder3.pro index 93d1a39..b4d2225 100644 --- a/tests/auto/qstringbuilder3/qstringbuilder3.pro +++ b/tests/auto/qstringbuilder3/qstringbuilder3.pro @@ -3,6 +3,3 @@ load(qttest_p4) QT = core SOURCES += tst_qstringbuilder3.cpp -HEADERS += ../qstringbuilder1/stringbuilder.h - -DEFINES += SCENARIO=3 diff --git a/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp b/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp index bd2e4b0..30f0181 100644 --- a/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp +++ b/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp @@ -39,4 +39,35 @@ ** ****************************************************************************/ + +// SCENARIO 3 +// this is the "no harm done" version. Only operator% is active, +// with NO_CAST * _not_ defined +#define P % +#undef QT_USE_FAST_OPERATOR_PLUS +#undef QT_USE_FAST_CONCATENATION +#undef QT_NO_CAST_FROM_ASCII +#undef QT_NO_CAST_TO_ASCII + + +#include <QtTest/QtTest> + +//TESTED_CLASS=QStringBuilder +//TESTED_FILES=qstringbuilder.cpp + +#define LITERAL "some literal" + +void runScenario(); // Defined in stringbuilder.cpp #included below. + +class tst_QStringBuilder3 : public QObject +{ + Q_OBJECT + +private slots: + void scenario() { runScenario(); } +}; + #include "../qstringbuilder1/stringbuilder.cpp" +#include "tst_qstringbuilder3.moc" + +QTEST_APPLESS_MAIN(tst_QStringBuilder3) diff --git a/tests/auto/qstringbuilder4/qstringbuilder4.pro b/tests/auto/qstringbuilder4/qstringbuilder4.pro index eeec447..6ec5228 100644 --- a/tests/auto/qstringbuilder4/qstringbuilder4.pro +++ b/tests/auto/qstringbuilder4/qstringbuilder4.pro @@ -3,6 +3,3 @@ load(qttest_p4) QT = core SOURCES += tst_qstringbuilder4.cpp -HEADERS += ../qstringbuilder1/stringbuilder.h - -DEFINES += SCENARIO=4 diff --git a/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp b/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp index 2159283..95b4ec3 100644 --- a/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp +++ b/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** This file is part of the test suite module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -39,4 +39,36 @@ ** ****************************************************************************/ + +// SCENARIO 4 +// this is the "full" version. Operator+ is replaced by a QStringBuilder +// based version +// with NO_CAST * _not_ defined +#define P + +#define QT_USE_FAST_OPERATOR_PLUS +#define QT_USE_FAST_CONCATENATION +#undef QT_NO_CAST_FROM_ASCII +#undef QT_NO_CAST_TO_ASCII + + +#include <QtTest/QtTest> + +//TESTED_CLASS=QStringBuilder +//TESTED_FILES=qstringbuilder.cpp + +#define LITERAL "some literal" + +void runScenario(); // Defined in stringbuilder.cpp #included below. + +class tst_QStringBuilder4 : public QObject +{ + Q_OBJECT + +private slots: + void scenario() { runScenario(); } +}; + #include "../qstringbuilder1/stringbuilder.cpp" +#include "tst_qstringbuilder4.moc" + +QTEST_APPLESS_MAIN(tst_QStringBuilder4) diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index d8110e1..227ca6f 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -41,6 +41,7 @@ #include <QtGui/QtGui> +#include <private/qtablewidget_p.h> #include <QtTest/QtTest> #include "../../shared/util.h" #include "private/qapplication_p.h" @@ -58,6 +59,13 @@ } \ } while(0) +#ifdef QT_BUILD_INTERNAL +#define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) \ + QVERIFY(static_cast<QTableViewPrivate*>(QObjectPrivate::get(TEST_VIEW_))->spans.checkConsistency()) +#else +#define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) (void)false +#endif + typedef QList<int> IntList; Q_DECLARE_METATYPE(IntList) @@ -188,12 +196,15 @@ private slots: void task248688_autoScrollNavigation(); void task259308_scrollVerticalHeaderSwappedSections(); void task191545_dragSelectRows(); + void taskQTBUG_5062_spansInconsistency(); void mouseWheel_data(); void mouseWheel(); void addColumnWhileEditing(); void task234926_setHeaderSorting(); + + void changeHeaderData(); }; // Testing get/set functions @@ -2017,8 +2028,9 @@ void tst_QTableView::resizeRowsToContents() view.resizeRowsToContents(); QCOMPARE(resizedSpy.count(), model.rowCount()); - for (int r = 0; r < model.rowCount(); ++r) + for (int r = 0; r < model.rowCount(); ++r) { QCOMPARE(view.rowHeight(r), rowHeight); + } } void tst_QTableView::resizeColumnsToContents_data() @@ -2898,6 +2910,8 @@ void tst_QTableView::span() view.clearSpans(); QCOMPARE(view.rowSpan(row, column), 1); QCOMPARE(view.columnSpan(row, column), 1); + + VERIFY_SPANS_CONSISTENCY(&view); } typedef QVector<QRect> SpanList; @@ -3033,6 +3047,8 @@ void tst_QTableView::spans() QCOMPARE(view.columnSpan(pos.x(), pos.y()), expectedColumnSpan); QCOMPARE(view.rowSpan(pos.x(), pos.y()), expectedRowSpan); + + VERIFY_SPANS_CONSISTENCY(&view); } void tst_QTableView::spansAfterRowInsertion() @@ -3067,6 +3083,8 @@ void tst_QTableView::spansAfterRowInsertion() view.model()->insertRows(12, 2); QCOMPARE(view.rowSpan(7, 3), 5); QCOMPARE(view.columnSpan(7, 3), 3); + + VERIFY_SPANS_CONSISTENCY(&view); } void tst_QTableView::spansAfterColumnInsertion() @@ -3101,6 +3119,8 @@ void tst_QTableView::spansAfterColumnInsertion() view.model()->insertColumns(12, 2); QCOMPARE(view.rowSpan(3, 7), 3); QCOMPARE(view.columnSpan(3, 7), 5); + + VERIFY_SPANS_CONSISTENCY(&view); } void tst_QTableView::spansAfterRowRemoval() @@ -3138,6 +3158,8 @@ void tst_QTableView::spansAfterRowRemoval() QCOMPARE(view.columnSpan(span.top(), span.left()), span.width()); QCOMPARE(view.rowSpan(span.top(), span.left()), span.height()); } + + VERIFY_SPANS_CONSISTENCY(&view); } void tst_QTableView::spansAfterColumnRemoval() @@ -3176,6 +3198,8 @@ void tst_QTableView::spansAfterColumnRemoval() QCOMPARE(view.columnSpan(span.left(), span.top()), span.height()); QCOMPARE(view.rowSpan(span.left(), span.top()), span.width()); } + + VERIFY_SPANS_CONSISTENCY(&view); } class Model : public QAbstractTableModel { @@ -3267,12 +3291,12 @@ void tst_QTableView::resizeToContents() //now let's check the row/col sizes for(int i = 0;i<table.columnCount();i++) { - QVERIFY( table.columnWidth(i) == table2.columnWidth(i)); - QVERIFY( table2.columnWidth(i) == table3.columnWidth(i)); + QCOMPARE( table.columnWidth(i), table2.columnWidth(i)); + QCOMPARE( table2.columnWidth(i), table3.columnWidth(i)); } for(int i = 0;i<table.rowCount();i++) { - QVERIFY( table.rowHeight(i) == table2.rowHeight(i)); - QVERIFY( table2.rowHeight(i) == table3.rowHeight(i)); + QCOMPARE( table.rowHeight(i), table2.rowHeight(i)); + QCOMPARE( table2.rowHeight(i), table3.rowHeight(i)); } } @@ -3844,5 +3868,41 @@ void tst_QTableView::task234926_setHeaderSorting() QCOMPARE(model.stringList() , sortedDataD); } +void tst_QTableView::taskQTBUG_5062_spansInconsistency() +{ + const int nRows = 5; + const int nColumns = 5; + + QtTestTableModel model(nRows, nColumns); + QtTestTableView view; + view.setModel(&model); + + for (int i = 0; i < nRows; ++i) + view.setSpan(i, 0, 1, nColumns); + view.setSpan(2, 0, 1, 1); + view.setSpan(3, 0, 1, 1); + + VERIFY_SPANS_CONSISTENCY(&view); +} + +void tst_QTableView::changeHeaderData() +{ + QTableView view; + QStandardItemModel model(5,5); + view.setModel(&model); + view.show(); + QTest::qWaitForWindowShown(&view); + + QString text = "long long long text"; + const int textWidth = view.fontMetrics().width(text); + QVERIFY(view.verticalHeader()->width() < textWidth); + + model.setHeaderData(2, Qt::Vertical, text); + QTest::qWait(100); //leave time for layout + + QVERIFY(view.verticalHeader()->width() > textWidth); +} + + QTEST_MAIN(tst_QTableView) #include "tst_qtableview.moc" diff --git a/tests/auto/qtextdocument/qtextdocument.pro b/tests/auto/qtextdocument/qtextdocument.pro index d3ec45d..1e44a9c 100644 --- a/tests/auto/qtextdocument/qtextdocument.pro +++ b/tests/auto/qtextdocument/qtextdocument.pro @@ -1,4 +1,5 @@ load(qttest_p4) +QT += xml HEADERS += common.h SOURCES += tst_qtextdocument.cpp diff --git a/tests/auto/qtextdocument/tst_qtextdocument.cpp b/tests/auto/qtextdocument/tst_qtextdocument.cpp index f393393..5237438 100644 --- a/tests/auto/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/qtextdocument/tst_qtextdocument.cpp @@ -59,6 +59,7 @@ #include <qfontmetrics.h> #include <qimage.h> #include <qtextlayout.h> +#include <QDomDocument> #include "common.h" @@ -175,6 +176,8 @@ private slots: void testUndoBlocks(); void receiveCursorPositionChangedAfterContentsChange(); + void escape_data(); + void escape(); private: void backgroundImage_checkExpectedHtml(const QTextDocument &doc); @@ -576,7 +579,7 @@ void tst_QTextDocument::task240325() } void tst_QTextDocument::stylesheetFont_data() -{ +{ QTest::addColumn<QString>("stylesheet"); QTest::addColumn<QFont>("font"); @@ -732,7 +735,7 @@ void tst_QTextDocument::toHtml_data() cursor.insertText("Blah", fmt); QTest::newRow("font-family-with-quotes1") << QTextDocumentFragment(&doc) - << QString("<p DEFAULTBLOCKSTYLE><span style=\" font-family:\"Foo's Family\";\">Blah</span></p>"); + << QString("<p DEFAULTBLOCKSTYLE><span style=\" font-family:"Foo's Family";\">Blah</span></p>"); } { @@ -743,7 +746,7 @@ void tst_QTextDocument::toHtml_data() cursor.insertText("Blah", fmt); QTest::newRow("font-family-with-quotes2") << QTextDocumentFragment(&doc) - << QString("<p DEFAULTBLOCKSTYLE><span style=\" font-family:'Foo\"s Family';\">Blah</span></p>"); + << QString("<p DEFAULTBLOCKSTYLE><span style=\" font-family:'Foo"s Family';\">Blah</span></p>"); } { @@ -974,6 +977,30 @@ void tst_QTextDocument::toHtml_data() { CREATE_DOC_AND_CURSOR(); + QTextCharFormat fmt; + fmt.setAnchor(true); + fmt.setAnchorHref("http://www.kde.org/?a=1&b=2"); + cursor.insertText("Blah", fmt); + + QTest::newRow("href anchor with &") << QTextDocumentFragment(&doc) + << QString("<p DEFAULTBLOCKSTYLE><a href=\"http://www.kde.org/?a=1&b=2\">Blah</a></p>"); + } + + { + CREATE_DOC_AND_CURSOR(); + + QTextCharFormat fmt; + fmt.setAnchor(true); + fmt.setAnchorHref("http://www.kde.org/?a='&b=\""); + cursor.insertText("Blah", fmt); + + QTest::newRow("href anchor with ' and \"") << QTextDocumentFragment(&doc) + << QString("<p DEFAULTBLOCKSTYLE><a href=\"http://www.kde.org/?a='&b="\">Blah</a></p>"); + } + + { + CREATE_DOC_AND_CURSOR(); + cursor.insertTable(2, 2); QTest::newRow("simpletable") << QTextDocumentFragment(&doc) @@ -1541,6 +1568,9 @@ void tst_QTextDocument::toHtml() QString output = doc->toHtml(); QCOMPARE(output, expectedOutput); + + QDomDocument document; + QVERIFY2(document.setContent(output), "Output was not valid XML"); } void tst_QTextDocument::toHtml2() @@ -2652,5 +2682,25 @@ void tst_QTextDocument::receiveCursorPositionChangedAfterContentsChange() QCOMPARE(rec.first, QString("contentsChanged")); } +void tst_QTextDocument::escape_data() +{ + QTest::addColumn<QString>("original"); + QTest::addColumn<QString>("expected"); + + QTest::newRow("1") << "Hello World\n" << "Hello World\n"; + QTest::newRow("2") << "#include <QtCore>" << "#include <QtCore>"; + QTest::newRow("3") << "<p class=\"cool\"><a href=\"http://example.com/?foo=bar&bar=foo\">plop --> </a></p>" + << "<p class="cool"><a href="http://example.com/?foo=bar&amp;bar=foo">plop --&gt; </a></p>"; + QTest::newRow("4") << QString::fromUtf8("<\320\222\321\201>") << QString::fromUtf8("<\320\222\321\201>"); +} + +void tst_QTextDocument::escape() +{ + QFETCH(QString, original); + QFETCH(QString, expected); + + QCOMPARE(Qt::escape(original), expected); +} + QTEST_MAIN(tst_QTextDocument) #include "tst_qtextdocument.moc" diff --git a/tests/auto/qtextedit/fullWidthSelection/centered-fully-selected.png b/tests/auto/qtextedit/fullWidthSelection/centered-fully-selected.png Binary files differindex 7467478..ced6eb6 100644 --- a/tests/auto/qtextedit/fullWidthSelection/centered-fully-selected.png +++ b/tests/auto/qtextedit/fullWidthSelection/centered-fully-selected.png diff --git a/tests/auto/qtextedit/fullWidthSelection/centered-partly-selected.png b/tests/auto/qtextedit/fullWidthSelection/centered-partly-selected.png Binary files differindex 7a10e63..481b99c 100644 --- a/tests/auto/qtextedit/fullWidthSelection/centered-partly-selected.png +++ b/tests/auto/qtextedit/fullWidthSelection/centered-partly-selected.png diff --git a/tests/auto/qtextedit/fullWidthSelection/last-char-on-line.png b/tests/auto/qtextedit/fullWidthSelection/last-char-on-line.png Binary files differindex df5b92e..292d3f9 100644 --- a/tests/auto/qtextedit/fullWidthSelection/last-char-on-line.png +++ b/tests/auto/qtextedit/fullWidthSelection/last-char-on-line.png diff --git a/tests/auto/qtextedit/fullWidthSelection/last-char-on-parag.png b/tests/auto/qtextedit/fullWidthSelection/last-char-on-parag.png Binary files differindex d58d4cc..69b72ed 100644 --- a/tests/auto/qtextedit/fullWidthSelection/last-char-on-parag.png +++ b/tests/auto/qtextedit/fullWidthSelection/last-char-on-parag.png diff --git a/tests/auto/qtextedit/fullWidthSelection/multiple-full-width-lines.png b/tests/auto/qtextedit/fullWidthSelection/multiple-full-width-lines.png Binary files differindex c5c3c22..467b91e 100644 --- a/tests/auto/qtextedit/fullWidthSelection/multiple-full-width-lines.png +++ b/tests/auto/qtextedit/fullWidthSelection/multiple-full-width-lines.png diff --git a/tests/auto/qtextedit/fullWidthSelection/nowrap_long.png b/tests/auto/qtextedit/fullWidthSelection/nowrap_long.png Binary files differindex 7ded254..cce921b 100644 --- a/tests/auto/qtextedit/fullWidthSelection/nowrap_long.png +++ b/tests/auto/qtextedit/fullWidthSelection/nowrap_long.png diff --git a/tests/auto/qtextedit/fullWidthSelection/single-full-width-line.png b/tests/auto/qtextedit/fullWidthSelection/single-full-width-line.png Binary files differindex d2fd629..937494a 100644 --- a/tests/auto/qtextedit/fullWidthSelection/single-full-width-line.png +++ b/tests/auto/qtextedit/fullWidthSelection/single-full-width-line.png diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp index 59abbd5..fee030c 100644 --- a/tests/auto/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/qtextedit/tst_qtextedit.cpp @@ -1967,7 +1967,7 @@ void tst_QTextEdit::fullWidthSelection() qt_setQtEnableTestFont(true); QFont testFont; testFont.setFamily("__Qt__Box__Engine__"); - testFont.setPixelSize(12); + testFont.setPixelSize(11); testFont.setWeight(QFont::Normal); QTextCharFormat cf; cf.setFont(testFont); @@ -2015,7 +2015,7 @@ void tst_QTextEdit::fullWidthSelection2() qt_setQtEnableTestFont(true); QFont testFont; testFont.setFamily("__Qt__Box__Engine__"); - testFont.setPixelSize(12); + testFont.setPixelSize(11); testFont.setWeight(QFont::Normal); QTextCharFormat cf; cf.setFont(testFont); diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index da58725..90e6c5c 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -235,6 +235,7 @@ private slots: void task254234_proxySort(); void task248022_changeSelection(); void task245654_changeModelAndExpandAll(); + void doubleClickedWithSpans(); }; class QtTestModel: public QAbstractItemModel @@ -2891,7 +2892,10 @@ void tst_QTreeView::styleOptionViewItem() QVERIFY(!opt.text.isEmpty()); QCOMPARE(opt.index, index); - QCOMPARE(!(opt.features & QStyleOptionViewItemV2::Alternate), !(index.row() % 2)); + //qDebug() << index << opt.text; + + if (allCollapsed) + QCOMPARE(!(opt.features & QStyleOptionViewItemV2::Alternate), !(index.row() % 2)); QCOMPARE(!(opt.features & QStyleOptionViewItemV2::HasCheckIndicator), !opt.text.contains("Checkable")); if (opt.text.contains("Beginning")) @@ -2911,12 +2915,16 @@ void tst_QTreeView::styleOptionViewItem() else QCOMPARE(opt.checkState, Qt::Unchecked); + QCOMPARE(!(opt.state & QStyle::State_Children) , !opt.text.contains("HasChildren")); + QCOMPARE(!!(opt.state & QStyle::State_Sibling) , !opt.text.contains("Last")); + QVERIFY(!opt.text.contains("Assert")); QStyledItemDelegate::paint(painter, option, index); count++; } mutable int count; + bool allCollapsed; }; QTreeView view; @@ -2926,8 +2934,9 @@ void tst_QTreeView::styleOptionViewItem() view.setItemDelegate(&delegate); model.appendRow(QList<QStandardItem*>() << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + QStandardItem *par1 = new QStandardItem("Beginning HasChildren"); model.appendRow(QList<QStandardItem*>() - << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + << par1 << new QStandardItem("Middle HasChildren") << new QStandardItem("Middle HasChildren") << new QStandardItem("End HasChildren") ); model.appendRow(QList<QStandardItem*>() << new QStandardItem("OnlyOne") << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Assert") ); QStandardItem *checkable = new QStandardItem("Checkable"); @@ -2937,13 +2946,143 @@ void tst_QTreeView::styleOptionViewItem() checked->setCheckState(Qt::Checked); model.appendRow(QList<QStandardItem*>() << new QStandardItem("Beginning") << checkable << checked << new QStandardItem("End") ); + model.appendRow(QList<QStandardItem*>() + << new QStandardItem("Beginning Last") << new QStandardItem("Middle Last") << new QStandardItem("Middle Last") << new QStandardItem("End Last") ); + + par1->appendRow(QList<QStandardItem*>() + << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + QStandardItem *par2 = new QStandardItem("Beginning HasChildren"); + par1->appendRow(QList<QStandardItem*>() + << par2 << new QStandardItem("Middle HasChildren") << new QStandardItem("Middle HasChildren") << new QStandardItem("End HasChildren") ); + par2->appendRow(QList<QStandardItem*>() + << new QStandardItem("Beginning Last") << new QStandardItem("Middle Last") << new QStandardItem("Middle Last") << new QStandardItem("End Last") ); + + QStandardItem *par3 = new QStandardItem("Beginning Last"); + par1->appendRow(QList<QStandardItem*>() + << par3 << new QStandardItem("Middle Last") << new QStandardItem("Middle Last") << new QStandardItem("End Last") ); + par3->appendRow(QList<QStandardItem*>() + << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Asser") ); + view.setRowHidden(0, par3->index(), true); + par1->appendRow(QList<QStandardItem*>() + << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Asser") ); + view.setRowHidden(3, par1->index(), true); + view.setFirstColumnSpanned(2, QModelIndex(), true); view.setAlternatingRowColors(true); delegate.count = 0; + delegate.allCollapsed = true; view.showMaximized(); + QApplication::processEvents(); QTRY_VERIFY(delegate.count >= 13); + delegate.count = 0; + delegate.allCollapsed = false; + view.expandAll(); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 13); + delegate.count = 0; + view.collapse(par2->index()); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 4); + + + //test dynamic models + { + delegate.count = 0; + QStandardItemModel model2; + QStandardItem *item0 = new QStandardItem("OnlyOne Last"); + model2.appendRow(QList<QStandardItem*>() << item0); + view.setModel(&model2); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 1); + QApplication::processEvents(); + + QStandardItem *item00 = new QStandardItem("OnlyOne Last"); + item0->appendRow(QList<QStandardItem*>() << item00); + item0->setText("OnlyOne Last HasChildren"); + QApplication::processEvents(); + delegate.count = 0; + view.expandAll(); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 2); + QApplication::processEvents(); + + QStandardItem *item1 = new QStandardItem("OnlyOne Last"); + delegate.count = 0; + item0->setText("OnlyOne HasChildren"); + model2.appendRow(QList<QStandardItem*>() << item1); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 3); + QApplication::processEvents(); + + QStandardItem *item01 = new QStandardItem("OnlyOne Last"); + delegate.count = 0; + item00->setText("OnlyOne"); + item0->appendRow(QList<QStandardItem*>() << item01); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 4); + QApplication::processEvents(); + + QStandardItem *item000 = new QStandardItem("OnlyOne Last"); + delegate.count = 0; + item00->setText("OnlyOne HasChildren"); + item00->appendRow(QList<QStandardItem*>() << item000); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 5); + QApplication::processEvents(); + + delegate.count = 0; + item0->removeRow(0); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 3); + QApplication::processEvents(); + + item00 = new QStandardItem("OnlyOne"); + item0->insertRow(0, QList<QStandardItem*>() << item00); + QApplication::processEvents(); + delegate.count = 0; + view.expandAll(); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 4); + QApplication::processEvents(); + + delegate.count = 0; + item0->removeRow(1); + item00->setText("OnlyOne Last"); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 3); + QApplication::processEvents(); + + delegate.count = 0; + item0->removeRow(0); + item0->setText("OnlyOne"); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 2); + QApplication::processEvents(); + + //with hidden items + item0->setText("OnlyOne HasChildren"); + item00 = new QStandardItem("OnlyOne"); + item0->appendRow(QList<QStandardItem*>() << item00); + item01 = new QStandardItem("Assert"); + item0->appendRow(QList<QStandardItem*>() << item01); + view.setRowHidden(1, item0->index(), true); + view.expandAll(); + QStandardItem *item02 = new QStandardItem("OnlyOne Last"); + item0->appendRow(QList<QStandardItem*>() << item02); + delegate.count = 0; + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 4); + QApplication::processEvents(); + + item0->removeRow(2); + item00->setText("OnlyOne Last"); + delegate.count = 0; + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 3); + QApplication::processEvents(); + } } class task174627_TreeView : public QTreeView @@ -3507,7 +3646,35 @@ void tst_QTreeView::task245654_changeModelAndExpandAll() } +void tst_QTreeView::doubleClickedWithSpans() +{ + QTreeView view; + QStandardItemModel model(1, 2); + view.setModel(&model); + view.setFirstColumnSpanned(0, QModelIndex(), true); + view.show(); + QTest::qWaitForWindowShown(&view); + + QPoint p(10, 10); + QCOMPARE(view.indexAt(p), model.index(0, 0)); + QSignalSpy spy(&view, SIGNAL(doubleClicked(QModelIndex))); + QTest::mousePress(view.viewport(), Qt::LeftButton, 0, p); + QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, p); + QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, p); + QCOMPARE(spy.count(), 1); + //let's click on the 2nd column + p.setX(p.x() + view.header()->sectionSize(0)); + QCOMPARE(view.indexAt(p), model.index(0, 0)); + + //end the previous edition + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, p); + QTest::qWait(100); + QTest::mousePress(view.viewport(), Qt::LeftButton, 0, p); + QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, p); + QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, p); + QCOMPARE(spy.count(), 2); +} QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" diff --git a/tests/auto/qudpsocket/tst_qudpsocket.cpp b/tests/auto/qudpsocket/tst_qudpsocket.cpp index 7ea2163..9418be0 100644 --- a/tests/auto/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/qudpsocket/tst_qudpsocket.cpp @@ -719,6 +719,8 @@ void tst_QUdpSocket::outOfProcessConnectedClientServerTest() QProcess serverProcess; serverProcess.start(QLatin1String("clientserver/clientserver server 1 1"), QIODevice::ReadWrite | QIODevice::Text); + QVERIFY2(serverProcess.waitForStarted(3000), + qPrintable("Failed to start subprocess: " + serverProcess.errorString())); // Wait until the server has started and reports success. while (!serverProcess.canReadLine()) @@ -732,6 +734,9 @@ void tst_QUdpSocket::outOfProcessConnectedClientServerTest() clientProcess.start(QString::fromLatin1("clientserver/clientserver connectedclient %1 %2") .arg(QLatin1String("127.0.0.1")).arg(serverPort), QIODevice::ReadWrite | QIODevice::Text); + QVERIFY2(clientProcess.waitForStarted(3000), + qPrintable("Failed to start subprocess: " + clientProcess.errorString())); + // Wait until the server has started and reports success. while (!clientProcess.canReadLine()) QVERIFY(clientProcess.waitForReadyRead(3000)); @@ -779,6 +784,8 @@ void tst_QUdpSocket::outOfProcessUnconnectedClientServerTest() QProcess serverProcess; serverProcess.start(QLatin1String("clientserver/clientserver server 1 1"), QIODevice::ReadWrite | QIODevice::Text); + QVERIFY2(serverProcess.waitForStarted(3000), + qPrintable("Failed to start subprocess: " + serverProcess.errorString())); // Wait until the server has started and reports success. while (!serverProcess.canReadLine()) @@ -792,6 +799,9 @@ void tst_QUdpSocket::outOfProcessUnconnectedClientServerTest() clientProcess.start(QString::fromLatin1("clientserver/clientserver unconnectedclient %1 %2") .arg(QLatin1String("127.0.0.1")).arg(serverPort), QIODevice::ReadWrite | QIODevice::Text); + QVERIFY2(clientProcess.waitForStarted(3000), + qPrintable("Failed to start subprocess: " + clientProcess.errorString())); + // Wait until the server has started and reports success. while (!clientProcess.canReadLine()) QVERIFY(clientProcess.waitForReadyRead(3000)); diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index 72c13bf..c8fe4e5 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -3679,15 +3679,21 @@ void tst_QUrl::binaryData() void tst_QUrl::fromUserInput_data() { + // + // most of this test is: + // Copyright (C) Research In Motion Limited 2009. All rights reserved. + // Distributed under the BSD license. + // See qurl.cpp + // + QTest::addColumn<QString>("string"); - QTest::addColumn<QUrl>("url"); + QTest::addColumn<QUrl>("guessUrlFromString"); // Null QTest::newRow("null") << QString() << QUrl(); // File QDirIterator it(QDir::homePath()); - QString fileString; int c = 0; while (it.hasNext()) { it.next(); @@ -3695,49 +3701,52 @@ void tst_QUrl::fromUserInput_data() } // basic latin1 - QTest::newRow("unicode-0") << QString::fromUtf8("\xC3\xA5.com/") << QUrl::fromEncoded(QString::fromUtf8("http://\xC3\xA5.com/").toUtf8(), QUrl::TolerantMode); + QTest::newRow("unicode-0") << QString::fromUtf8("\xc3\xa5.com/") << QUrl::fromEncoded(QString::fromUtf8("http://\xc3\xa5.com/").toUtf8(), QUrl::TolerantMode); + QTest::newRow("unicode-0b") << QString::fromUtf8("\xc3\xa5.com/") << QUrl::fromEncoded("http://%C3%A5.com/", QUrl::TolerantMode); + QTest::newRow("unicode-0c") << QString::fromUtf8("\xc3\xa5.com/") << QUrl::fromEncoded("http://xn--5ca.com/", QUrl::TolerantMode); // unicode - QTest::newRow("unicode-1") << QString::fromUtf8("\xCE\xBB.com/") << QUrl::fromEncoded(QString::fromUtf8("http://\xCE\xBB.com/").toUtf8(), QUrl::TolerantMode); + QTest::newRow("unicode-1") << QString::fromUtf8("\xce\xbb.com/") << QUrl::fromEncoded(QString::fromUtf8("http://\xce\xbb.com/").toUtf8(), QUrl::TolerantMode); + QTest::newRow("unicode-1b") << QString::fromUtf8("\xce\xbb.com/") << QUrl::fromEncoded("http://%CE%BB.com/", QUrl::TolerantMode); + QTest::newRow("unicode-1c") << QString::fromUtf8("\xce\xbb.com/") << QUrl::fromEncoded("http://xn--wxa.com/", QUrl::TolerantMode); // no scheme - QTest::newRow("add scheme-0") << "webkit.org" << QUrl("http://webkit.org"); - QTest::newRow("add scheme-1") << "www.webkit.org" << QUrl("http://www.webkit.org"); - QTest::newRow("add scheme-2") << "ftp.webkit.org" << QUrl("ftp://ftp.webkit.org"); + QTest::newRow("add scheme-0") << "example.org" << QUrl("http://example.org"); + QTest::newRow("add scheme-1") << "www.example.org" << QUrl("http://www.example.org"); + QTest::newRow("add scheme-2") << "ftp.example.org" << QUrl("ftp://ftp.example.org"); QTest::newRow("add scheme-3") << "webkit" << QUrl("webkit"); // QUrl's tolerant parser should already handle this - QTest::newRow("not-encoded-0") << "http://webkit.org/test page.html" << QUrl("http://webkit.org/test%20page.html"); + QTest::newRow("not-encoded-0") << "http://example.org/test page.html" << QUrl::fromEncoded("http://example.org/test%20page.html"); // Make sure the :80, i.e. port doesn't screw anything up - QUrl portUrl("http://webkit.org"); + QUrl portUrl("http://example.org"); portUrl.setPort(80); - QTest::newRow("port-0") << "webkit.org:80" << portUrl; - QTest::newRow("port-1") << "http://webkit.org:80" << portUrl; + QTest::newRow("port-0") << "example.org:80" << portUrl; + QTest::newRow("port-1") << "http://example.org:80" << portUrl; // mailto doesn't have a ://, but is valid - QUrl mailto("somebody@somewhere.net"); + QUrl mailto("ben@example.net"); mailto.setScheme("mailto"); - QTest::newRow("mailto") << "mailto:somebody@somewhere.net" << mailto; + QTest::newRow("mailto") << "mailto:ben@example.net" << mailto; // misc QTest::newRow("localhost-0") << "localhost" << QUrl("http://localhost"); QTest::newRow("localhost-1") << "localhost:80" << QUrl("http://localhost:80"); - QTest::newRow("spaces-0") << " http://webkit.org/test page.html " << QUrl("http://webkit.org/test%20page.html"); - QTest::newRow("trash-0") << "webkit.org/test?someData=42%&someOtherData=abcde#anchor" << QUrl::fromEncoded("http://webkit.org/test?someData=42%25&someOtherData=abcde#anchor"); + QTest::newRow("spaces-0") << " http://example.org/test page.html " << QUrl("http://example.org/test%20page.html"); + QTest::newRow("trash-0") << "example.org/test?someData=42%&someOtherData=abcde#anchor" << QUrl::fromEncoded("http://example.org/test?someData=42%25&someOtherData=abcde#anchor"); // FYI: The scheme in the resulting url user QUrl authUrl("user:pass@domain.com"); QTest::newRow("misc-1") << "user:pass@domain.com" << authUrl; } -// public static QUrl guessUrlFromString(QString const& string) void tst_QUrl::fromUserInput() { QFETCH(QString, string); - QFETCH(QUrl, url); + QFETCH(QUrl, guessUrlFromString); - QUrl guessedUrl = QUrl::fromUserInput(string); - QCOMPARE(guessedUrl, url); + QUrl url = QUrl::fromUserInput(string); + QCOMPARE(url, guessUrlFromString); } void tst_QUrl::task_199967() diff --git a/tests/auto/qvariant/tst_qvariant.cpp b/tests/auto/qvariant/tst_qvariant.cpp index 9295897..e2a606f 100644 --- a/tests/auto/qvariant/tst_qvariant.cpp +++ b/tests/auto/qvariant/tst_qvariant.cpp @@ -270,6 +270,8 @@ private slots: void task256984_setValue(); void numericalConvert(); + void moreCustomTypes(); + void variantInVariant(); }; Q_DECLARE_METATYPE(QDate) @@ -318,6 +320,14 @@ void tst_QVariant::constructor() QVariant var6(qlonglong(0)); QCOMPARE(var6.type(), QVariant::LongLong); QCOMPARE(var6.typeName(), "qlonglong"); + + QVariant var7 = 5; + QVERIFY(var7.isValid()); + QVERIFY(!var7.isNull()); + QVariant var8; + var8.setValue<int>(5); + QVERIFY(var8.isValid()); + QVERIFY(!var8.isNull()); } void tst_QVariant::copy_constructor() @@ -3127,7 +3137,254 @@ void tst_QVariant::numericalConvert() } +template<class T> void playWithVariant(const T &orig, bool isNull, const QString &toString, double toDouble, bool toBool) +{ + QVariant v = QVariant::fromValue(orig); + QVERIFY(v.isValid()); + QCOMPARE(v.isNull(), isNull); + QCOMPARE(v.toString(), toString); + QCOMPARE(v.toDouble(), toDouble); + QCOMPARE(v.toBool(), toBool); + QCOMPARE(qvariant_cast<T>(v), orig); + + { + QVariant v2 = v; + QCOMPARE(v2, v); + QVERIFY(v2.isValid()); + QCOMPARE(v2.isNull(), isNull); + QCOMPARE(v2.toString(), toString); + QCOMPARE(v2.toDouble(), toDouble); + QCOMPARE(v2.toBool(), toBool); + QCOMPARE(qvariant_cast<T>(v2), orig); + + QVariant v3; + v = QVariant(); + QCOMPARE(v3, v); + v = v2; + QCOMPARE(v, v2); + QCOMPARE(qvariant_cast<T>(v2), qvariant_cast<T>(v)); + QCOMPARE(v2.toString(), toString); + v3 = qVariantFromValue(orig); + + QVERIFY(v3.isValid()); + QCOMPARE(v3.isNull(), isNull); + QCOMPARE(v3.toString(), toString); + QCOMPARE(v3.toDouble(), toDouble); + QCOMPARE(v3.toBool(), toBool); + QCOMPARE(qvariant_cast<T>(v3), qvariant_cast<T>(v)); + } + + QVERIFY(v.isValid()); + QCOMPARE(v.isNull(), isNull); + QCOMPARE(v.toString(), toString); + QCOMPARE(v.toDouble(), toDouble); + QCOMPARE(v.toBool(), toBool); + QCOMPARE(qvariant_cast<T>(v), orig); + + if (qMetaTypeId<T>() != qMetaTypeId<QVariant>()) { + QCOMPARE(v.userType(), qMetaTypeId<T>()); + QCOMPARE(QVariant::typeToName(QVariant::Type(v.userType())), QMetaType::typeName(qMetaTypeId<T>())); + } +} + + +struct MyPrimitive +{ + char x, y; + bool operator==(const MyPrimitive &o) const + { + return x == o.x && y == o.y; + } +}; +Q_DECLARE_TYPEINFO(MyPrimitive, Q_PRIMITIVE_TYPE); + +struct MyData +{ + void *ptr; + MyData() : ptr(this) {} + ~MyData() { Q_ASSERT(ptr == this); } + MyData(const MyData& o) : ptr(this) { Q_ASSERT(o.ptr == &o); } + MyData &operator=(const MyData &o) + { + Q_ASSERT(ptr == this); + Q_ASSERT(o.ptr == &o); + return *this; + } + bool operator==(const MyData &o) const + { + Q_ASSERT(ptr == this); + Q_ASSERT(o.ptr == &o); + return true; + } +}; + +struct MyMovable +{ + static int count; + int v; + MyMovable() { v = count++; } + ~MyMovable() { count--; } + MyMovable(const MyMovable &o) : v(o.v) { count++; } + + bool operator==(const MyMovable &o) const + { + return v == o.v; + } +}; + +int MyMovable::count = 0; + + +Q_DECLARE_TYPEINFO(MyMovable, Q_MOVABLE_TYPE); + +Q_DECLARE_METATYPE(QList<QSize>) +Q_DECLARE_METATYPE(MyPrimitive) +Q_DECLARE_METATYPE(MyData) +Q_DECLARE_METATYPE(MyMovable) +Q_DECLARE_METATYPE(QList<MyPrimitive>) +Q_DECLARE_METATYPE(QList<MyData>) +Q_DECLARE_METATYPE(QList<MyMovable>) +Q_DECLARE_METATYPE(MyPrimitive *) +Q_DECLARE_METATYPE(MyData *) +Q_DECLARE_METATYPE(MyMovable *) +void tst_QVariant::moreCustomTypes() +{ + { + QList<QSize> listSize; + playWithVariant(listSize, false, QString(), 0, false); + listSize << QSize(4,5) << QSize(89,23) << QSize(5,6); + playWithVariant(listSize, false, QString(), 0, false); + } + + { + QString str; + playWithVariant(str, true, QString(), 0, false); + str = QString::fromLatin1("123456789.123"); + playWithVariant(str, false, str, 123456789.123, true); + } + + { + QSize size; + playWithVariant(size, false, QString(), 0, false); + playWithVariant(QSize(45,78), false, QString(), 0, false); + } + + { + MyData d; + playWithVariant(d, false, QString(), 0, false); + playWithVariant(&d, false, QString(), 0, false); + QList<MyData> l; + playWithVariant(l, false, QString(), 0, false); + l << MyData() << MyData(); + playWithVariant(l, false, QString(), 0, false); + } + + { + MyPrimitive d = { 4, 5 }; + playWithVariant(d, false, QString(), 0, false); + playWithVariant(&d, false, QString(), 0, false); + QList<MyPrimitive> l; + playWithVariant(l, false, QString(), 0, false); + l << d; + playWithVariant(l, false, QString(), 0, false); + } + + { + MyMovable d; + playWithVariant(d, false, QString(), 0, false); + playWithVariant(&d, false, QString(), 0, false); + QList<MyMovable> l; + playWithVariant(l, false, QString(), 0, false); + l << MyMovable() << d; + playWithVariant(l, false, QString(), 0, false); + } + QCOMPARE(MyMovable::count, 0); + + { + playWithVariant(12.12, false, "12.12", 12.12, true); + playWithVariant(12.12f, false, "12.12", 12.12f, true); + playWithVariant('a', false, "a", 'a', true); + playWithVariant((unsigned char)('a'), false, "a", 'a', true); + playWithVariant( quint8(12), false, "\xc", 12, true); + playWithVariant( qint8(13), false, "\xd", 13, true); + playWithVariant(quint16(14), false, "14", 14, true); + playWithVariant( qint16(15), false, "15", 15, true); + playWithVariant(quint32(16), false, "16", 16, true); + playWithVariant( qint32(17), false, "17", 17, true); + playWithVariant(quint64(18), false, "18", 18, true); + playWithVariant( qint64(19), false, "19", 19, true); + playWithVariant( qint8(-12), false, "\xf4", -12, true); + playWithVariant( qint16(-13), false, "-13", -13, true); + playWithVariant( qint32(-14), false, "-14", -14, true); + playWithVariant( qint64(-15), false, "-15", -15, true); + playWithVariant(quint64(0), false, "0", 0, false); + playWithVariant( true, false, "true", 1, true); + playWithVariant( false, false, "false", 0, false); + + playWithVariant(QString("hello\n"), false, "hello\n", 0, true); + } + + { + int i = 5; + playWithVariant((void *)(&i), false, QString(), 0, false); + playWithVariant((void *)(0), false, QString(), 0, false); + } + + { + QVariant v1 = QVariant::fromValue(5); + QVariant v2 = QVariant::fromValue(5.0); + QVariant v3 = QVariant::fromValue(quint16(5)); + QVariant v4 = 5; + QVariant v5 = QVariant::fromValue(MyPrimitive()); + QVariant v6 = QVariant::fromValue(MyMovable()); + QVariant v7 = QVariant::fromValue(MyData()); + playWithVariant(v1, false, "5", 5, true); + playWithVariant(v2, false, "5", 5, true); + playWithVariant(v3, false, "5", 5, true); + playWithVariant(v4, false, "5", 5, true); + + playWithVariant(v5, false, QString(), 0, false); + } +} + + +void tst_QVariant::variantInVariant() +{ + QVariant var1 = 5; + QCOMPARE(var1.type(), QVariant::Int); + QVariant var2 = var1; + QCOMPARE(var2, var1); + QCOMPARE(var2.type(), QVariant::Int); + QVariant var3 = QVariant::fromValue(var1); + QCOMPARE(var3, var1); + QCOMPARE(var3.type(), QVariant::Int); + QVariant var4 = qvariant_cast<QVariant>(var1); + QCOMPARE(var4, var1); + QCOMPARE(var4.type(), QVariant::Int); + QVariant var5; + var5 = var1; + QCOMPARE(var5, var1); + QCOMPARE(var5.type(), QVariant::Int); + QVariant var6; + var6.setValue(var1); + QCOMPARE(var6, var1); + QCOMPARE(var6.type(), QVariant::Int); + + QCOMPARE(QVariant::fromValue(var1), QVariant::fromValue(var2)); + QCOMPARE(qvariant_cast<QVariant>(var3), QVariant::fromValue(var4)); + QCOMPARE(qvariant_cast<QVariant>(var5), qvariant_cast<QVariant>(var6)); + + QString str("hello"); + QVariant var8 = qvariant_cast<QVariant>(QVariant::fromValue(QVariant::fromValue(str))); + QCOMPARE((int)var8.type(), (int)QVariant::String); + QCOMPARE(qvariant_cast<QString>(QVariant(qvariant_cast<QVariant>(var8))), str); + + QVariant var9(qMetaTypeId<QVariant>(), &var1); + QCOMPARE(var9.userType(), qMetaTypeId<QVariant>()); + QCOMPARE(qvariant_cast<QVariant>(var9), var1); +} + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 050d1c5..3d801cc 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -332,6 +332,7 @@ private slots: void doubleRepaint(); #ifndef Q_WS_MAC void resizeInPaintEvent(); + void opaqueChildren(); #endif void setMaskInResizeEvent(); @@ -2982,7 +2983,7 @@ void tst_QWidget::stackUnder() qApp->processEvents(); #endif #ifndef Q_WS_MAC - QEXPECT_FAIL(0, "Task 153869", Continue); + QEXPECT_FAIL(0, "See QTBUG-493", Continue); #endif QCOMPARE(child->numPaintEvents, 0); } else { @@ -6319,6 +6320,7 @@ void tst_QWidget::compatibilityChildInsertedEvents() widget.show(); expected = EventRecorder::EventList() + << qMakePair(&widget, QEvent::WinIdChange) << qMakePair(&widget, QEvent::Polish) << qMakePair(&widget, QEvent::Move) << qMakePair(&widget, QEvent::Resize) @@ -6404,6 +6406,7 @@ void tst_QWidget::compatibilityChildInsertedEvents() widget.show(); expected = EventRecorder::EventList() + << qMakePair(&widget, QEvent::WinIdChange) << qMakePair(&widget, QEvent::Polish) #ifdef QT_HAS_QT3SUPPORT << qMakePair(&widget, QEvent::ChildInserted) @@ -6501,6 +6504,7 @@ void tst_QWidget::compatibilityChildInsertedEvents() widget.show(); expected = EventRecorder::EventList() + << qMakePair(&widget, QEvent::WinIdChange) << qMakePair(&widget, QEvent::Polish) #ifdef QT_HAS_QT3SUPPORT << qMakePair(&widget, QEvent::ChildInserted) @@ -8272,6 +8276,47 @@ void tst_QWidget::resizeInPaintEvent() // Make sure the resize triggers another update. QTRY_COMPARE(widget.numPaintEvents, 1); } + +void tst_QWidget::opaqueChildren() +{ + QWidget widget; + widget.resize(200, 200); + + QWidget child(&widget); + child.setGeometry(-700, -700, 200, 200); + + QWidget grandChild(&child); + grandChild.resize(200, 200); + + QWidget greatGrandChild(&grandChild); + greatGrandChild.setGeometry(50, 50, 200, 200); + greatGrandChild.setPalette(Qt::red); + greatGrandChild.setAutoFillBackground(true); // Opaque child widget. + + widget.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&widget); +#endif + QTest::qWait(100); + + // Child, grandChild and greatGrandChild are outside the ancestor clip. + QRegion expectedOpaqueRegion(50, 50, 150, 150); + QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), expectedOpaqueRegion); + + // Now they are all inside the ancestor clip. + child.setGeometry(50, 50, 150, 150); + QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), expectedOpaqueRegion); + + // Set mask on greatGrandChild. + const QRegion mask(10, 10, 50, 50); + greatGrandChild.setMask(mask); + expectedOpaqueRegion &= mask.translated(50, 50); + QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), expectedOpaqueRegion); + + // Make greatGrandChild "transparent". + greatGrandChild.setAutoFillBackground(false); + QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), QRegion()); +} #endif |