diff options
Diffstat (limited to 'tests/auto/corelib')
65 files changed, 6030 insertions, 570 deletions
diff --git a/tests/auto/corelib/animation/qanimationgroup/tst_qanimationgroup.cpp b/tests/auto/corelib/animation/qanimationgroup/tst_qanimationgroup.cpp index f6d9d2c14f..c0a3ae6114 100644 --- a/tests/auto/corelib/animation/qanimationgroup/tst_qanimationgroup.cpp +++ b/tests/auto/corelib/animation/qanimationgroup/tst_qanimationgroup.cpp @@ -137,7 +137,7 @@ private: void tst_QAnimationGroup::emptyGroup() { QSequentialAnimationGroup group; - QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy groupStateChangedSpy(&group, &QSequentialAnimationGroup::stateChanged); QVERIFY(groupStateChangedSpy.isValid()); QCOMPARE(group.state(), QAnimationGroup::Stopped); diff --git a/tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp index 2021eefd8f..bbe9e1a816 100644 --- a/tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp +++ b/tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp @@ -256,10 +256,10 @@ void tst_QParallelAnimationGroup::stateChanged() group.addAnimation(anim3); group.addAnimation(anim4); - QSignalSpy spy1(anim1, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy spy2(anim2, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy spy3(anim3, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy spy4(anim4, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy spy1(anim1, &TestAnimation::stateChanged); + QSignalSpy spy2(anim2, &TestAnimation::stateChanged); + QSignalSpy spy3(anim3, &TestAnimation::stateChanged); + QSignalSpy spy4(anim4, &TestAnimation::stateChanged); QVERIFY(spy1.isValid()); QVERIFY(spy2.isValid()); @@ -434,8 +434,8 @@ void tst_QParallelAnimationGroup::updateChildrenWithRunningGroup() anim.setEndValue(100); anim.setDuration(200); - QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy childStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy groupStateChangedSpy(&group, &QParallelAnimationGroup::stateChanged); + QSignalSpy childStateChangedSpy(&anim, &TestAnimation::stateChanged); QVERIFY(groupStateChangedSpy.isValid()); QVERIFY(childStateChangedSpy.isValid()); @@ -601,8 +601,8 @@ void tst_QParallelAnimationGroup::startGroupWithRunningChild() anim2.setEndValue(100); anim2.setDuration(200); - QSignalSpy stateChangedSpy1(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy stateChangedSpy2(&anim2, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy stateChangedSpy1(&anim1, &TestAnimation::stateChanged); + QSignalSpy stateChangedSpy2(&anim2, &TestAnimation::stateChanged); QVERIFY(stateChangedSpy1.isValid()); QVERIFY(stateChangedSpy2.isValid()); @@ -669,20 +669,20 @@ void tst_QParallelAnimationGroup::zeroDurationAnimation() anim3.setEndValue(100); anim3.setDuration(10); - QSignalSpy stateChangedSpy1(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy finishedSpy1(&anim1, SIGNAL(finished())); + QSignalSpy stateChangedSpy1(&anim1, &TestAnimation::stateChanged); + QSignalSpy finishedSpy1(&anim1, &TestAnimation::finished); QVERIFY(stateChangedSpy1.isValid()); QVERIFY(finishedSpy1.isValid()); - QSignalSpy stateChangedSpy2(&anim2, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy finishedSpy2(&anim2, SIGNAL(finished())); + QSignalSpy stateChangedSpy2(&anim2, &TestAnimation::stateChanged); + QSignalSpy finishedSpy2(&anim2, &TestAnimation::finished); QVERIFY(stateChangedSpy2.isValid()); QVERIFY(finishedSpy2.isValid()); - QSignalSpy stateChangedSpy3(&anim3, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy finishedSpy3(&anim3, SIGNAL(finished())); + QSignalSpy stateChangedSpy3(&anim3, &TestAnimation::stateChanged); + QSignalSpy finishedSpy3(&anim3, &TestAnimation::finished); QVERIFY(stateChangedSpy3.isValid()); QVERIFY(finishedSpy3.isValid()); @@ -760,7 +760,7 @@ void tst_QParallelAnimationGroup::stopUncontrolledAnimations() loopsForever.setDuration(100); loopsForever.setLoopCount(-1); - QSignalSpy stateChangedSpy(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy stateChangedSpy(&anim1, &TestAnimation::stateChanged); QVERIFY(stateChangedSpy.isValid()); group.addAnimation(&anim1); @@ -968,7 +968,7 @@ void tst_QParallelAnimationGroup::pauseResume() { QParallelAnimationGroup group; TestAnimation2 *anim = new TestAnimation2(250, &group); // 0, duration = 250; - QSignalSpy spy(anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy spy(anim, &TestAnimation::stateChanged); QVERIFY(spy.isValid()); QCOMPARE(group.duration(), 250); group.start(); diff --git a/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp index dc731ee765..0dab56a9cc 100644 --- a/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp @@ -230,9 +230,9 @@ void tst_QPropertyAnimation::statesAndSignals() anim = new DummyPropertyAnimation; anim->setDuration(100); - QSignalSpy finishedSpy(anim, SIGNAL(finished())); - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy currentLoopSpy(anim, SIGNAL(currentLoopChanged(int))); + QSignalSpy finishedSpy(anim, &QPropertyAnimation::finished); + QSignalSpy runningSpy(anim, &QPropertyAnimation::stateChanged); + QSignalSpy currentLoopSpy(anim, &QPropertyAnimation::currentLoopChanged); QVERIFY(finishedSpy.isValid()); QVERIFY(runningSpy.isValid()); @@ -311,8 +311,8 @@ void tst_QPropertyAnimation::deletion1() QPointer<QPropertyAnimation> anim = new QPropertyAnimation(object, "minimumWidth"); //test that the animation is deleted correctly depending of the deletion flag passed in start() - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy finishedSpy(anim, SIGNAL(finished())); + QSignalSpy runningSpy(anim.data(), &QPropertyAnimation::stateChanged); + QSignalSpy finishedSpy(anim.data(), &QPropertyAnimation::finished); QVERIFY(runningSpy.isValid()); QVERIFY(finishedSpy.isValid()); anim->setStartValue(10); @@ -355,8 +355,8 @@ void tst_QPropertyAnimation::deletion2() anim->setEndValue(20); anim->setDuration(200); - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy finishedSpy(anim, SIGNAL(finished())); + QSignalSpy runningSpy(anim.data(), &QPropertyAnimation::stateChanged); + QSignalSpy finishedSpy(anim.data(), &QPropertyAnimation::finished); QVERIFY(runningSpy.isValid()); QVERIFY(finishedSpy.isValid()); @@ -389,8 +389,8 @@ void tst_QPropertyAnimation::deletion3() anim->setEndValue(20); anim->setDuration(200); - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy finishedSpy(anim, SIGNAL(finished())); + QSignalSpy runningSpy(anim, &QPropertyAnimation::stateChanged); + QSignalSpy finishedSpy(anim, &QPropertyAnimation::finished); QVERIFY(runningSpy.isValid()); QVERIFY(finishedSpy.isValid()); @@ -490,7 +490,7 @@ void tst_QPropertyAnimation::startWhenAnotherIsRunning() //normal case: the animation finishes and is deleted QPointer<QVariantAnimation> anim = new QPropertyAnimation(&o, "ole"); anim->setEndValue(100); - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy runningSpy(anim.data(), &QVariantAnimation::stateChanged); QVERIFY(runningSpy.isValid()); anim->start(QVariantAnimation::DeleteWhenStopped); QTest::qWait(anim->duration() + 100); @@ -501,7 +501,7 @@ void tst_QPropertyAnimation::startWhenAnotherIsRunning() { QPointer<QVariantAnimation> anim = new QPropertyAnimation(&o, "ole"); anim->setEndValue(100); - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy runningSpy(anim.data(), &QVariantAnimation::stateChanged); QVERIFY(runningSpy.isValid()); anim->start(QVariantAnimation::DeleteWhenStopped); QTest::qWait(anim->duration()/2); @@ -850,7 +850,7 @@ void tst_QPropertyAnimation::setStartEndValues() void tst_QPropertyAnimation::zeroDurationStart() { DummyPropertyAnimation anim; - QSignalSpy spy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy spy(&anim, &DummyPropertyAnimation::stateChanged); QVERIFY(spy.isValid()); anim.setDuration(0); QCOMPARE(anim.state(), QAbstractAnimation::Stopped); @@ -972,7 +972,7 @@ void tst_QPropertyAnimation::operationsInStates() o.setProperty("ole", 42); QPropertyAnimation anim(&o, "ole"); anim.setEndValue(100); - QSignalSpy spy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy spy(&anim, &QPropertyAnimation::stateChanged); QVERIFY(spy.isValid()); anim.stop(); @@ -1132,7 +1132,7 @@ void tst_QPropertyAnimation::valueChanged() QPropertyAnimation anim(&o, "ole"); anim.setEndValue(5); anim.setDuration(1000); - QSignalSpy spy(&anim, SIGNAL(valueChanged(QVariant))); + QSignalSpy spy(&anim, &QPropertyAnimation::valueChanged); QVERIFY(spy.isValid()); anim.start(); @@ -1263,8 +1263,8 @@ void tst_QPropertyAnimation::zeroLoopCount() anim->setDuration(20); anim->setLoopCount(0); - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy finishedSpy(anim, SIGNAL(finished())); + QSignalSpy runningSpy(anim, &QPropertyAnimation::stateChanged); + QSignalSpy finishedSpy(anim, &QPropertyAnimation::finished); QVERIFY(runningSpy.isValid()); QVERIFY(finishedSpy.isValid()); diff --git a/tests/auto/corelib/animation/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp b/tests/auto/corelib/animation/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp index 51f07993cd..cbd484c016 100644 --- a/tests/auto/corelib/animation/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp +++ b/tests/auto/corelib/animation/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp @@ -637,8 +637,8 @@ void tst_QSequentialAnimationGroup::pauseAndResume() sequence->addAnimation(a3_s_o1); sequence->setLoopCount(2); - QSignalSpy a1StateChangedSpy(a1_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy seqStateChangedSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy a1StateChangedSpy(a1_s_o1, &QVariantAnimation::stateChanged); + QSignalSpy seqStateChangedSpy(sequence, &QAnimationGroup::stateChanged); QVERIFY(a1StateChangedSpy.isValid()); QVERIFY(seqStateChangedSpy.isValid()); @@ -744,8 +744,8 @@ void tst_QSequentialAnimationGroup::restart() { // sequence operating on same object/property QAnimationGroup *sequence = new QSequentialAnimationGroup(); - QSignalSpy seqCurrentAnimChangedSpy(sequence, SIGNAL(currentAnimationChanged(QAbstractAnimation*))); - QSignalSpy seqStateChangedSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy seqCurrentAnimChangedSpy(static_cast<QSequentialAnimationGroup*>(sequence), &QSequentialAnimationGroup::currentAnimationChanged); + QSignalSpy seqStateChangedSpy(sequence, &QAnimationGroup::stateChanged); QVERIFY(seqCurrentAnimChangedSpy.isValid()); QVERIFY(seqStateChangedSpy.isValid()); @@ -756,7 +756,7 @@ void tst_QSequentialAnimationGroup::restart() for (int i = 0; i < 3; i++) { anims[i] = new DummyPropertyAnimation; anims[i]->setDuration(100); - animsStateChanged[i] = new QSignalSpy(anims[i], SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + animsStateChanged[i] = new QSignalSpy(anims[i], &QVariantAnimation::stateChanged); QVERIFY(animsStateChanged[i]->isValid()); } @@ -816,10 +816,10 @@ void tst_QSequentialAnimationGroup::looping() QAbstractAnimation *a2_s_o1 = new DummyPropertyAnimation; QAbstractAnimation *a3_s_o1 = new DummyPropertyAnimation; - QSignalSpy a1Spy(a1_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy a2Spy(a2_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy a3Spy(a3_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy seqSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy a1Spy(a1_s_o1, &QAbstractAnimation::stateChanged); + QSignalSpy a2Spy(a2_s_o1, &QAbstractAnimation::stateChanged); + QSignalSpy a3Spy(a3_s_o1, &QAbstractAnimation::stateChanged); + QSignalSpy seqSpy(sequence, &QSequentialAnimationGroup::stateChanged); QVERIFY(a1Spy.isValid()); QVERIFY(a2Spy.isValid()); @@ -833,7 +833,7 @@ void tst_QSequentialAnimationGroup::looping() sequence->setLoopCount(2); QSequentialAnimationGroup group; - QSignalSpy groupSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy groupSpy(&group, &QSequentialAnimationGroup::stateChanged); QVERIFY(groupSpy.isValid()); group.addAnimation(sequence); @@ -1101,8 +1101,8 @@ void tst_QSequentialAnimationGroup::updateChildrenWithRunningGroup() anim.setEndValue(100); anim.setDuration(200); - QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy childStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy groupStateChangedSpy(&group, &QSequentialAnimationGroup::stateChanged); + QSignalSpy childStateChangedSpy(&anim, &TestAnimation::stateChanged); QVERIFY(groupStateChangedSpy.isValid()); QVERIFY(childStateChangedSpy.isValid()); @@ -1268,8 +1268,8 @@ void tst_QSequentialAnimationGroup::startGroupWithRunningChild() anim2->setEndValue(100); anim2->setDuration(200); - QSignalSpy stateChangedSpy1(anim1, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); - QSignalSpy stateChangedSpy2(anim2, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy stateChangedSpy1(anim1, &TestAnimation::stateChanged); + QSignalSpy stateChangedSpy2(anim2, &TestAnimation::stateChanged); QVERIFY(stateChangedSpy1.isValid()); QVERIFY(stateChangedSpy2.isValid()); @@ -1345,7 +1345,7 @@ void tst_QSequentialAnimationGroup::zeroDurationAnimation() anim3->setEndValue(100); anim3->setDuration(0); - QSignalSpy stateChangedSpy(anim1, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy stateChangedSpy(anim1, &TestAnimation::stateChanged); QVERIFY(stateChangedSpy.isValid()); group.addAnimation(anim1); @@ -1417,7 +1417,7 @@ void tst_QSequentialAnimationGroup::finishWithUncontrolledAnimation() //first we test a group with one uncontrolled animation QSequentialAnimationGroup group; UncontrolledAnimation notTimeDriven(&o1, &group); - QSignalSpy spy(&group, SIGNAL(finished())); + QSignalSpy spy(&group, &QSequentialAnimationGroup::finished); QVERIFY(spy.isValid()); group.start(); @@ -1437,7 +1437,7 @@ void tst_QSequentialAnimationGroup::finishWithUncontrolledAnimation() // lets make sure the seeking will work again spy.clear(); DummyPropertyAnimation anim(&group); - QSignalSpy animStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy animStateChangedSpy(&anim, &DummyPropertyAnimation::stateChanged); QVERIFY(animStateChangedSpy.isValid()); group.setCurrentTime(300); @@ -1639,7 +1639,7 @@ void tst_QSequentialAnimationGroup::pauseResume() QPropertyAnimation *anim = new QPropertyAnimation(&dummy, "foo", &group); anim->setDuration(250); anim->setEndValue(250); - QSignalSpy spy(anim, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + QSignalSpy spy(anim, &QPropertyAnimation::stateChanged); QVERIFY(spy.isValid()); QCOMPARE(group.duration(), 250); group.start(); diff --git a/tests/auto/corelib/global/global.pro b/tests/auto/corelib/global/global.pro index c05905bd15..219e9de818 100644 --- a/tests/auto/corelib/global/global.pro +++ b/tests/auto/corelib/global/global.pro @@ -9,4 +9,4 @@ SUBDIRS=\ qlogging \ qtendian \ qglobalstatic \ - + qhooks diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp index 73a69a1309..42add6150a 100644 --- a/tests/auto/corelib/global/qflags/tst_qflags.cpp +++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp @@ -50,6 +50,7 @@ private slots: void constExpr(); void signedness(); void classEnum(); + void initializerLists(); }; void tst_QFlags::testFlag() const @@ -143,6 +144,9 @@ enum class MyStrictEnum { StrictZero, StrictOne, StrictTwo, StrictFour=4 }; Q_DECLARE_FLAGS( MyStrictFlags, MyStrictEnum ) Q_DECLARE_OPERATORS_FOR_FLAGS( MyStrictFlags ) +enum class MyStrictNoOpEnum { StrictZero, StrictOne, StrictTwo, StrictFour=4 }; +Q_DECLARE_FLAGS( MyStrictNoOpFlags, MyStrictNoOpEnum ) + Q_STATIC_ASSERT( !QTypeInfo<MyStrictFlags>::isComplex ); Q_STATIC_ASSERT( !QTypeInfo<MyStrictFlags>::isStatic ); Q_STATIC_ASSERT( !QTypeInfo<MyStrictFlags>::isLarge ); @@ -253,6 +257,26 @@ void tst_QFlags::classEnum() #endif } +void tst_QFlags::initializerLists() +{ +#if defined(Q_COMPILER_INITIALIZER_LISTS) + Qt::MouseButtons bts = { Qt::LeftButton, Qt::RightButton }; + QVERIFY(bts.testFlag(Qt::LeftButton)); + QVERIFY(bts.testFlag(Qt::RightButton)); + QVERIFY(!bts.testFlag(Qt::MiddleButton)); + +#if defined(Q_COMPILER_CLASS_ENUM) + MyStrictNoOpFlags flags = { MyStrictNoOpEnum::StrictOne, MyStrictNoOpEnum::StrictFour }; + QVERIFY(flags.testFlag(MyStrictNoOpEnum::StrictOne)); + QVERIFY(flags.testFlag(MyStrictNoOpEnum::StrictFour)); + QVERIFY(!flags.testFlag(MyStrictNoOpEnum::StrictTwo)); +#endif // Q_COMPILER_CLASS_ENUM + +#else + QSKIP("This test requires C++11 initializer_list support."); +#endif // Q_COMPILER_INITIALIZER_LISTS +} + // (statically) check QTypeInfo for QFlags instantiations: enum MyEnum { Zero, One, Two, Four=4 }; Q_DECLARE_FLAGS( MyFlags, MyEnum ) diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp index 4eb3e4fc98..0389ae7976 100644 --- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp +++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp @@ -43,6 +43,9 @@ #include <QtTest/QtTest> #include <QtCore/qtypetraits.h> +#include <QPair> +#include <QTextCodec> + class tst_QGlobal: public QObject { Q_OBJECT @@ -60,6 +63,8 @@ private slots: void isEnum(); void qAlignOf(); void integerForSize(); + void qprintable(); + void qprintable_data(); }; void tst_QGlobal::qIsNull() @@ -588,5 +593,64 @@ void tst_QGlobal::integerForSize() Q_STATIC_ASSERT(sizeof(QIntegerForSize<8>::Unsigned) == 8); } +typedef QPair<const char *, const char *> stringpair; +Q_DECLARE_METATYPE(stringpair) + +void tst_QGlobal::qprintable() +{ + QFETCH(QList<stringpair>, localestrings); + QFETCH(int, utf8index); + + QVERIFY(utf8index >= 0 && utf8index < localestrings.count()); + if (utf8index < 0 || utf8index >= localestrings.count()) + return; + + const char *const utf8string = localestrings.at(utf8index).second; + + QString string = QString::fromUtf8(utf8string); + + foreach (const stringpair &pair, localestrings) { + QTextCodec *codec = QTextCodec::codecForName(pair.first); + if (!codec) + continue; + QTextCodec::setCodecForLocale(codec); + // test qPrintable() + QVERIFY(qstrcmp(qPrintable(string), pair.second) == 0); + foreach (const stringpair &pair2, localestrings) { + if (pair2.second == pair.second) + continue; + QVERIFY(qstrcmp(qPrintable(string), pair2.second) != 0); + } + // test qUtf8Printable() + QVERIFY(qstrcmp(qUtf8Printable(string), utf8string) == 0); + foreach (const stringpair &pair2, localestrings) { + if (qstrcmp(pair2.second, utf8string) == 0) + continue; + QVERIFY(qstrcmp(qUtf8Printable(string), pair2.second) != 0); + } + } + + QTextCodec::setCodecForLocale(0); +} + +void tst_QGlobal::qprintable_data() +{ + QTest::addColumn<QList<stringpair> >("localestrings"); + QTest::addColumn<int>("utf8index"); // index of utf8 string + + // Unicode: HIRAGANA LETTER A, I, U, E, O (U+3442, U+3444, U+3446, U+3448, U+344a) + static const char *const utf8string = "\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a"; + static const char *const eucjpstring = "\xa4\xa2\xa4\xa4\xa4\xa6\xa4\xa8\xa4\xaa"; + static const char *const sjisstring = "\x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8"; + + QList<stringpair> japanesestrings; + japanesestrings << stringpair("UTF-8", utf8string) + << stringpair("EUC-JP", eucjpstring) + << stringpair("Shift_JIS", sjisstring); + + QTest::newRow("Japanese") << japanesestrings << 0; + +} + QTEST_APPLESS_MAIN(tst_QGlobal) #include "tst_qglobal.moc" diff --git a/tests/auto/corelib/global/qhooks/qhooks.pro b/tests/auto/corelib/global/qhooks/qhooks.pro new file mode 100644 index 0000000000..f886e7d49a --- /dev/null +++ b/tests/auto/corelib/global/qhooks/qhooks.pro @@ -0,0 +1,4 @@ +CONFIG += testcase parallel_test +TARGET = tst_qhooks +QT = core-private testlib +SOURCES = tst_qhooks.cpp diff --git a/tests/auto/corelib/global/qhooks/tst_qhooks.cpp b/tests/auto/corelib/global/qhooks/tst_qhooks.cpp new file mode 100644 index 0000000000..817c0b8173 --- /dev/null +++ b/tests/auto/corelib/global/qhooks/tst_qhooks.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Volker Krause <volker.krause@kdab.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <QtCore/private/qhooks_p.h> + +class tst_QHooks: public QObject +{ + Q_OBJECT + +private slots: + void testVersion(); + void testAddRemoveObject(); +}; + +void tst_QHooks::testVersion() +{ + QVERIFY(qtHookData[QHooks::HookDataVersion] >= 1); + QCOMPARE(qtHookData[QHooks::HookDataSize], (quintptr)QHooks::LastHookIndex); + QCOMPARE(qtHookData[QHooks::QtVersion], (quintptr)QT_VERSION); +} + +static int objectCount = 0; + +static void objectAddHook(QObject*) +{ + ++objectCount; +} + +static void objectRemoveHook(QObject*) +{ + --objectCount; +} + +void tst_QHooks::testAddRemoveObject() +{ + QCOMPARE(qtHookData[QHooks::AddQObject], (quintptr)0); + QCOMPARE(qtHookData[QHooks::RemoveQObject], (quintptr)0); + + qtHookData[QHooks::AddQObject] = (quintptr)&objectAddHook; + qtHookData[QHooks::RemoveQObject] = (quintptr)&objectRemoveHook; + + QCOMPARE(objectCount, 0); + QObject *obj = new QObject; + QVERIFY(objectCount > 0); + delete obj; + QCOMPARE(objectCount, 0); +} + +QTEST_APPLESS_MAIN(tst_QHooks) +#include "tst_qhooks.moc" diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp index 21e07630e2..3c1a26c629 100644 --- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp +++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp @@ -63,8 +63,9 @@ private slots: void cleanupFuncinfo(); #endif + void qMessagePattern_data(); void qMessagePattern(); - void qMessagePatternIf(); + void setMessagePattern(); private: QString m_appDir; @@ -641,11 +642,77 @@ void tst_qmessagehandler::cleanupFuncinfo() } #endif +void tst_qmessagehandler::qMessagePattern_data() +{ + QTest::addColumn<QString>("pattern"); + QTest::addColumn<bool>("valid"); + QTest::addColumn<QList<QByteArray> >("expected"); + + // %{file} is tricky because of shadow builds + QTest::newRow("basic") << "%{type} %{appname} %{line} %{function} %{message}" << true << (QList<QByteArray>() + << "debug 46 T::T static constructor" + // we can't be sure whether the QT_MESSAGE_PATTERN is already destructed + << "static destructor" + << "debug tst_qlogging 57 main qDebug" + << "warning tst_qlogging 58 main qWarning" + << "critical tst_qlogging 59 main qCritical" + << "warning tst_qlogging 62 main qDebug with category" + << "debug tst_qlogging 66 main qDebug2"); + + + QTest::newRow("invalid") << "PREFIX: %{unknown} %{message}" << false << (QList<QByteArray>() + << "QT_MESSAGE_PATTERN: Unknown placeholder %{unknown}" + << "PREFIX: qDebug"); + + // test the if condition + QTest::newRow("ifs") << "[%{if-debug}D%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{if-category}%{category}: %{endif}%{message}" + << true << (QList<QByteArray>() + << "[D] static constructor" + // we can't be sure whether the QT_MESSAGE_PATTERN is already destructed + << "static destructor" + << "[D] qDebug" + << "[W] qWarning" + << "[C] qCritical" + << "[W] category: qDebug with category" + << "[D] qDebug2"); + + // test few errors cases + QTest::newRow("ifs-invalid1") << "PREFIX: %{unknown} %{endif} %{if-warning}" + << false << (QList<QByteArray>() + << "QT_MESSAGE_PATTERN: Unknown placeholder %{unknown}" + << "QT_MESSAGE_PATTERN: %{endif} without an %{if-*}" + << "QT_MESSAGE_PATTERN: missing %{endif}"); + + QTest::newRow("ifs-invalid2") << "A %{if-debug}DEBUG%{if-warning}WARNING%{endif} %{message} " + << false << (QList<QByteArray>() + << "QT_MESSAGE_PATTERN: %{if-*} cannot be nested" + << "A DEBUG qDebug " + << "A qWarning "); + + // This test won't work when midnight is too close... wait a bit + while (QTime::currentTime() > QTime(23, 59, 30)) + QTest::qWait(10000); + QTest::newRow("time") << "/%{time yyyy - MM - d}/%{message}" + << true << (QList<QByteArray>() + << ('/' + QDateTime::currentDateTime().toString("yyyy - MM - d").toUtf8() + "/qDebug")); + + // %{time} should have a padding of 6 so if it takes less than 10 seconds to show + // the first message, there should be 5 spaces + QTest::newRow("time") << "<%{time}>%{message}" << true << (QList<QByteArray>() + << "< "); + +} + + void tst_qmessagehandler::qMessagePattern() { #ifdef QT_NO_PROCESS QSKIP("This test requires QProcess support"); #else + QFETCH(QString, pattern); + QFETCH(bool, valid); + QFETCH(QList<QByteArray>, expected); + QProcess process; const QString appExe = m_appDir + "/app"; @@ -653,8 +720,7 @@ void tst_qmessagehandler::qMessagePattern() // test QT_MESSAGE_PATTERN // QStringList environment = m_baseEnvironment; - // %{file} is tricky because of shadow builds - environment.prepend("QT_MESSAGE_PATTERN=\"%{type} %{appname} %{line} %{function} %{message}\""); + environment.prepend("QT_MESSAGE_PATTERN=\"" + pattern + "\""); process.setEnvironment(environment); process.start(appExe); @@ -665,35 +731,29 @@ void tst_qmessagehandler::qMessagePattern() QByteArray output = process.readAllStandardError(); // qDebug() << output; QVERIFY(!output.isEmpty()); + QCOMPARE(!output.contains("QT_MESSAGE_PATTERN"), valid); - QVERIFY(output.contains("debug 46 T::T static constructor")); - // we can't be sure whether the QT_MESSAGE_PATTERN is already destructed - QVERIFY(output.contains("static destructor")); - QVERIFY(output.contains("debug tst_qlogging 57 main qDebug")); - QVERIFY(output.contains("warning tst_qlogging 58 main qWarning")); - QVERIFY(output.contains("critical tst_qlogging 59 main qCritical")); - QVERIFY(output.contains("warning tst_qlogging 62 main qDebug with category")); - QVERIFY(output.contains("debug tst_qlogging 66 main qDebug2")); - - environment = m_baseEnvironment; - environment.prepend("QT_MESSAGE_PATTERN=\"PREFIX: %{unknown} %{message}\""); - process.setEnvironment(environment); - - process.start(appExe); - QVERIFY2(process.waitForStarted(), qPrintable( - QString::fromLatin1("Could not start %1: %2").arg(appExe, process.errorString()))); - process.waitForFinished(); - - output = process.readAllStandardError(); -// qDebug() << output; - QVERIFY(!output.isEmpty()); + foreach (const QByteArray &e, expected) { + QVERIFY(output.contains(e)); + } +#endif +} - QVERIFY(output.contains("QT_MESSAGE_PATTERN: Unknown placeholder %{unknown}")); - QVERIFY(output.contains("PREFIX: qDebug")); +void tst_qmessagehandler::setMessagePattern() +{ +#ifdef QT_NO_PROCESS + QSKIP("This test requires QProcess support"); +#else // // test qSetMessagePattern // + + QProcess process; + const QString appExe = m_appDir + "/app"; + + // make sure there is no QT_MESSAGE_PATTERN in the environment + QStringList environment = m_baseEnvironment; QMutableListIterator<QString> iter(environment); while (iter.hasNext()) { if (iter.next().startsWith("QT_MESSAGE_PATTERN")) @@ -706,7 +766,7 @@ void tst_qmessagehandler::qMessagePattern() QString::fromLatin1("Could not start %1: %2").arg(appExe, process.errorString()))); process.waitForFinished(); - output = process.readAllStandardError(); + QByteArray output = process.readAllStandardError(); //qDebug() << output; QByteArray expected = "static constructor\n" "[debug] qDebug\n" @@ -720,73 +780,6 @@ void tst_qmessagehandler::qMessagePattern() #endif // !QT_NO_PROCESS } -void tst_qmessagehandler::qMessagePatternIf() -{ -#ifdef QT_NO_PROCESS - QSKIP("This test requires QProcess support"); -#else - QProcess process; - const QString appExe = m_appDir + "/app"; - - QStringList environment = m_baseEnvironment; - environment.prepend("QT_MESSAGE_PATTERN=\"[%{if-debug}D%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{if-category}%{category}: %{endif}%{message}\""); - process.setEnvironment(environment); - process.start(appExe); - QVERIFY2(process.waitForStarted(), qPrintable( - QString::fromLatin1("Could not start %1: %2").arg(appExe, process.errorString()))); - process.waitForFinished(); - - QByteArray output = process.readAllStandardError(); - // qDebug() << output; - QVERIFY(!output.isEmpty()); - QVERIFY(!output.contains("QT_MESSAGE_PATTERN")); - - QVERIFY(output.contains("[D] static constructor")); - // we can't be sure whether the QT_MESSAGE_PATTERN is already destructed - QVERIFY(output.contains("static destructor")); - QVERIFY(output.contains("[D] qDebug")); - QVERIFY(output.contains("[W] qWarning")); - QVERIFY(output.contains("[C] qCritical")); - QVERIFY(output.contains("[W] category: qDebug with category")); - QVERIFY(output.contains("[D] qDebug2")); - - // - // Tests some errors - // - environment = m_baseEnvironment; - environment.prepend("QT_MESSAGE_PATTERN=\"PREFIX: %{unknown} %{endif} %{if-warning}\""); - process.setEnvironment(environment); - - process.start(appExe); - QVERIFY2(process.waitForStarted(), qPrintable( - QString::fromLatin1("Could not start %1: %2").arg(appExe, process.errorString()))); - process.waitForFinished(); - - output = process.readAllStandardError(); - // qDebug() << output; - QVERIFY(!output.isEmpty()); - QVERIFY(output.contains("QT_MESSAGE_PATTERN: Unknown placeholder %{unknown}")); - QVERIFY(output.contains("QT_MESSAGE_PATTERN: %{endif} without an %{if-*}")); - QVERIFY(output.contains("QT_MESSAGE_PATTERN: missing %{endif}")); - - - environment = m_baseEnvironment; - environment.prepend("QT_MESSAGE_PATTERN=\"A %{if-debug}DEBUG%{if-warning}WARNING%{endif} %{message} \""); - process.setEnvironment(environment); - - process.start(appExe); - QVERIFY2(process.waitForStarted(), qPrintable( - QString::fromLatin1("Could not start %1: %2").arg(appExe, process.errorString()))); - process.waitForFinished(); - - output = process.readAllStandardError(); - // qDebug() << output; - QVERIFY(!output.isEmpty()); - QVERIFY(output.contains("QT_MESSAGE_PATTERN: %{if-*} cannot be nested")); - QVERIFY(output.contains("A DEBUG qDebug")); - QVERIFY(output.contains("A qWarning")); -#endif // !QT_NO_PROCESS -} QTEST_MAIN(tst_qmessagehandler) #include "tst_qlogging.moc" diff --git a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp index a6d76ea7b6..a477d6bc6c 100644 --- a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp @@ -270,7 +270,9 @@ static int NColorRoles[] = { QPalette::ToolTipText + 1, // Qt_5_0 QPalette::ToolTipText + 1, // Qt_5_1 QPalette::ToolTipText + 1, // Qt_5_2 - 0 // add the correct value for Qt_5_3 here later + QPalette::ToolTipText + 1, // Qt_5_3 + QPalette::ToolTipText + 1, // Qt_5_4 + 0 // add the correct value for Qt_5_5 here later }; // Testing get/set functions diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp index 99c4ee7edc..2143a8874c 100644 --- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp +++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -56,11 +56,15 @@ private slots: void criticalWithoutDebug() const; void debugWithBool() const; void debugSpaceHandling() const; + void debugNoQuotes() const; void stateSaver() const; void veryLongWarningMessage() const; + void qDebugQChar() const; void qDebugQStringRef() const; void qDebugQLatin1String() const; + void qDebugQByteArray() const; void textStreamModifiers() const; + void resetFormat() const; void defaultMessagehandler() const; void threadSafety() const; }; @@ -167,7 +171,8 @@ public: QDebug operator<< (QDebug s, const MyPoint& point) { const QDebugStateSaver saver(s); - return s.nospace() << "MyPoint(" << point.v1 << ", " << point.v2 << ")"; + s.nospace() << "MyPoint(" << point.v1 << ", " << point.v2 << ")"; + return s; } class MyLine @@ -203,10 +208,45 @@ void tst_QDebug::debugSpaceHandling() const d << 1 << 2; MyLine line(MyPoint(10, 11), MyPoint (12, 13)); d << line; + d << "bar"; // With the old implementation of MyPoint doing dbg.nospace() << ...; dbg.space() we ended up with // MyLine(MyPoint(10, 11) , MyPoint(12, 13) ) } - QCOMPARE(s_msg, QString::fromLatin1(" foo key=value 1 2 MyLine(MyPoint(10, 11), MyPoint(12, 13))")); + QCOMPARE(s_msg, QString::fromLatin1(" foo key=value 1 2 MyLine(MyPoint(10, 11), MyPoint(12, 13)) bar")); + + QVERIFY(qDebug().autoInsertSpaces()); + qDebug() << QPoint(21, 22) << QRect(23, 24, 25, 26) << QLine(27, 28, 29, 30); + QCOMPARE(s_msg, QString::fromLatin1("QPoint(21,22) QRect(23,24 25x26) QLine(QPoint(27,28),QPoint(29,30))")); + qDebug() << QPointF(21, 22) << QRectF(23, 24, 25, 26) << QLineF(27, 28, 29, 30); + QCOMPARE(s_msg, QString::fromLatin1("QPointF(21,22) QRectF(23,24 25x26) QLineF(QPointF(27,28),QPointF(29,30))")); + qDebug() << QMimeType() << QMimeDatabase().mimeTypeForName("application/pdf") << "foo"; + QCOMPARE(s_msg, QString::fromLatin1("QMimeType(invalid) QMimeType(\"application/pdf\") foo")); +} + +void tst_QDebug::debugNoQuotes() const +{ + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << QStringLiteral("Hello"); + d.noquote(); + d << QStringLiteral("Hello"); + d.quote(); + d << QStringLiteral("Hello"); + } + QCOMPARE(s_msg, QString::fromLatin1("\"Hello\" Hello \"Hello\"")); + + { + QDebug d = qDebug(); + d << QChar('H'); + d << QLatin1String("Hello"); + d << QByteArray("Hello"); + d.noquote(); + d << QChar('H'); + d << QLatin1String("Hello"); + d << QByteArray("Hello"); + } + QCOMPARE(s_msg, QString::fromLatin1("'H' \"Hello\" \"Hello\" H Hello Hello")); } void tst_QDebug::stateSaver() const @@ -218,9 +258,19 @@ void tst_QDebug::stateSaver() const QDebugStateSaver saver(d); d.nospace() << hex << right << qSetFieldWidth(3) << qSetPadChar('0') << 42; } - d.space() << 42; + d << 42; } QCOMPARE(s_msg, QString::fromLatin1("02a 42")); + + { + QDebug d = qDebug(); + { + QDebugStateSaver saver(d); + d.nospace().noquote() << QStringLiteral("Hello"); + } + d << QStringLiteral("World"); + } + QCOMPARE(s_msg, QString::fromLatin1("Hello \"World\"")); } void tst_QDebug::veryLongWarningMessage() const @@ -241,6 +291,23 @@ void tst_QDebug::veryLongWarningMessage() const QCOMPARE(QString::fromLatin1(s_function), function); } +void tst_QDebug::qDebugQChar() const +{ + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << QChar('f'); + d.nospace().noquote() << QChar('o') << QChar('o'); + } + QString file = __FILE__; int line = __LINE__ - 4; QString function = Q_FUNC_INFO; + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("'f' oo")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + +} + void tst_QDebug::qDebugQStringRef() const { /* Use a basic string. */ @@ -276,10 +343,30 @@ void tst_QDebug::qDebugQStringRef() const void tst_QDebug::qDebugQLatin1String() const { MessageHandlerSetter mhs(myMessageHandler); - { qDebug() << QLatin1String("foo") << QLatin1String("") << QLatin1String("barbaz", 3); } - QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO; + { + QDebug d = qDebug(); + d << QLatin1String("foo") << QLatin1String("") << QLatin1String("barbaz", 3); + d.nospace().noquote() << QLatin1String("baz"); + } + QString file = __FILE__; int line = __LINE__ - 4; QString function = Q_FUNC_INFO; + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); +} + +void tst_QDebug::qDebugQByteArray() const +{ + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << QByteArrayLiteral("foo") << QByteArrayLiteral("") << QByteArray("barbaz", 3); + d.nospace().noquote() << QByteArrayLiteral("baz"); + } + QString file = __FILE__; int line = __LINE__ - 4; QString function = Q_FUNC_INFO; QCOMPARE(s_msgType, QtDebugMsg); - QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\"")); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); QCOMPARE(QString::fromLatin1(s_file), file); QCOMPARE(s_line, line); QCOMPARE(QString::fromLatin1(s_function), function); @@ -297,6 +384,22 @@ void tst_QDebug::textStreamModifiers() const QCOMPARE(QString::fromLatin1(s_function), function); } +void tst_QDebug::resetFormat() const +{ + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d.nospace().noquote() << hex << int(0xf); + d.resetFormat() << int(0xf) << QStringLiteral("foo"); + } + QString file = __FILE__; int line = __LINE__ - 4; QString function = Q_FUNC_INFO; + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("f15 \"foo\"")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); +} + void tst_QDebug::defaultMessagehandler() const { MessageHandlerSetter mhs(0); // set 0, should set default handler diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index e06af5a799..7e04fa5957 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -140,7 +140,7 @@ void tst_QFileSystemWatcher::basicTest() watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend); QVERIFY(watcher.addPath(testFile.fileName())); - QSignalSpy changedSpy(&watcher, SIGNAL(fileChanged(QString))); + QSignalSpy changedSpy(&watcher, &QFileSystemWatcher::fileChanged); QVERIFY(changedSpy.isValid()); QEventLoop eventLoop; QTimer timer; @@ -278,7 +278,7 @@ void tst_QFileSystemWatcher::watchDirectory() watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend); QVERIFY(watcher.addPath(testDir.absolutePath())); - QSignalSpy changedSpy(&watcher, SIGNAL(directoryChanged(QString))); + QSignalSpy changedSpy(&watcher, &QFileSystemWatcher::directoryChanged); QVERIFY(changedSpy.isValid()); QEventLoop eventLoop; QTimer timer; @@ -441,8 +441,8 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory() QVERIFY(watcher.addPath(testDir.absolutePath())); QVERIFY(watcher.addPath(testFileName)); - QSignalSpy fileChangedSpy(&watcher, SIGNAL(fileChanged(QString))); - QSignalSpy dirChangedSpy(&watcher, SIGNAL(directoryChanged(QString))); + QSignalSpy fileChangedSpy(&watcher, &QFileSystemWatcher::fileChanged); + QSignalSpy dirChangedSpy(&watcher, &QFileSystemWatcher::directoryChanged); QVERIFY(fileChangedSpy.isValid()); QVERIFY(dirChangedSpy.isValid()); QEventLoop eventLoop; @@ -601,7 +601,7 @@ void tst_QFileSystemWatcher::QTBUG2331() QVERIFY(watcher.addPath(temporaryDirectory.path())); // watch signal - QSignalSpy changedSpy(&watcher, SIGNAL(directoryChanged(QString))); + QSignalSpy changedSpy(&watcher, &QFileSystemWatcher::directoryChanged); QVERIFY(changedSpy.isValid()); // remove directory, we should get one change signal, and we should no longer @@ -680,7 +680,7 @@ void tst_QFileSystemWatcher::signalsEmittedAfterFileMoved() connect(&watcher, SIGNAL(fileChanged(QString)), &signalReceiver, SLOT(fileChanged(QString))); // watch signals - QSignalSpy changedSpy(&watcher, SIGNAL(fileChanged(QString))); + QSignalSpy changedSpy(&watcher, &QFileSystemWatcher::fileChanged); QVERIFY(changedSpy.isValid()); // move files to second directory diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 82a0f3f832..1d6418cbc0 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -259,7 +259,7 @@ void tst_QProcess::simpleStart() qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState"); process = new QProcess; - QSignalSpy spy(process, SIGNAL(stateChanged(QProcess::ProcessState))); + QSignalSpy spy(process, &QProcess::stateChanged); QVERIFY(spy.isValid()); connect(process, SIGNAL(readyRead()), this, SLOT(readFromProcess())); @@ -351,7 +351,7 @@ void tst_QProcess::crashTest() { qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState"); process = new QProcess; - QSignalSpy stateSpy(process, SIGNAL(stateChanged(QProcess::ProcessState))); + QSignalSpy stateSpy(process, &QProcess::stateChanged); QVERIFY(stateSpy.isValid()); process->start("testProcessCrash/testProcessCrash"); QVERIFY(process->waitForStarted(5000)); @@ -359,8 +359,8 @@ void tst_QProcess::crashTest() qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); - QSignalSpy spy(process, SIGNAL(error(QProcess::ProcessError))); - QSignalSpy spy2(process, SIGNAL(finished(int,QProcess::ExitStatus))); + QSignalSpy spy(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy spy2(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(spy.isValid()); QVERIFY(spy2.isValid()); @@ -394,8 +394,8 @@ void tst_QProcess::crashTest2() qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); - QSignalSpy spy(process, SIGNAL(error(QProcess::ProcessError))); - QSignalSpy spy2(process, SIGNAL(finished(int,QProcess::ExitStatus))); + QSignalSpy spy(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy spy2(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(spy.isValid()); QVERIFY(spy2.isValid()); @@ -503,8 +503,8 @@ void tst_QProcess::echoTest2() QCOMPARE(process->error(), QProcess::Timedout); process->write("Hello"); - QSignalSpy spy1(process, SIGNAL(readyReadStandardOutput())); - QSignalSpy spy2(process, SIGNAL(readyReadStandardError())); + QSignalSpy spy1(process, &QProcess::readyReadStandardOutput); + QSignalSpy spy2(process, &QProcess::readyReadStandardError); QVERIFY(spy1.isValid()); QVERIFY(spy2.isValid()); @@ -685,7 +685,7 @@ void tst_QProcess::readTimeoutAndThenCrash() QCOMPARE(process->error(), QProcess::Timedout); qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); - QSignalSpy spy(process, SIGNAL(error(QProcess::ProcessError))); + QSignalSpy spy(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); QVERIFY(spy.isValid()); process->kill(); @@ -887,7 +887,7 @@ void tst_QProcess::emitReadyReadOnlyWhenNewDataArrives() QProcess proc; connect(&proc, SIGNAL(readyRead()), this, SLOT(exitLoopSlot())); - QSignalSpy spy(&proc, SIGNAL(readyRead())); + QSignalSpy spy(&proc, &QProcess::readyRead); QVERIFY(spy.isValid()); proc.start("testProcessEcho/testProcessEcho"); @@ -1283,7 +1283,7 @@ void tst_QProcess::waitForReadyReadInAReadyReadSlot() process->start("testProcessEcho/testProcessEcho"); QVERIFY(process->waitForStarted(5000)); - QSignalSpy spy(process, SIGNAL(readyRead())); + QSignalSpy spy(process, &QProcess::readyRead); QVERIFY(spy.isValid()); process->write("foo"); QTestEventLoop::instance().enterLoop(30); @@ -1323,7 +1323,7 @@ void tst_QProcess::waitForBytesWrittenInABytesWrittenSlot() process->start("testProcessEcho/testProcessEcho"); QVERIFY(process->waitForStarted(5000)); - QSignalSpy spy(process, SIGNAL(bytesWritten(qint64))); + QSignalSpy spy(process, &QProcess::bytesWritten); QVERIFY(spy.isValid()); process->write("f"); QTestEventLoop::instance().enterLoop(30); @@ -1538,10 +1538,10 @@ void tst_QProcess::failToStart() qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState"); QProcess process; - QSignalSpy stateSpy(&process, SIGNAL(stateChanged(QProcess::ProcessState))); - QSignalSpy errorSpy(&process, SIGNAL(error(QProcess::ProcessError))); - QSignalSpy finishedSpy(&process, SIGNAL(finished(int))); - QSignalSpy finishedSpy2(&process, SIGNAL(finished(int,QProcess::ExitStatus))); + QSignalSpy stateSpy(&process, &QProcess::stateChanged); + QSignalSpy errorSpy(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy finishedSpy(&process, static_cast<void (QProcess::*)(int)>(&QProcess::finished)); + QSignalSpy finishedSpy2(&process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(stateSpy.isValid()); QVERIFY(errorSpy.isValid()); @@ -1605,9 +1605,9 @@ void tst_QProcess::failToStartWithWait() QProcess process; QEventLoop loop; - QSignalSpy errorSpy(&process, SIGNAL(error(QProcess::ProcessError))); - QSignalSpy finishedSpy(&process, SIGNAL(finished(int))); - QSignalSpy finishedSpy2(&process, SIGNAL(finished(int,QProcess::ExitStatus))); + QSignalSpy errorSpy(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy finishedSpy(&process, static_cast<void (QProcess::*)(int)>(&QProcess::finished)); + QSignalSpy finishedSpy2(&process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(errorSpy.isValid()); QVERIFY(finishedSpy.isValid()); @@ -1632,9 +1632,9 @@ void tst_QProcess::failToStartWithEventLoop() QProcess process; QEventLoop loop; - QSignalSpy errorSpy(&process, SIGNAL(error(QProcess::ProcessError))); - QSignalSpy finishedSpy(&process, SIGNAL(finished(int))); - QSignalSpy finishedSpy2(&process, SIGNAL(finished(int,QProcess::ExitStatus))); + QSignalSpy errorSpy(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy finishedSpy(&process, static_cast<void (QProcess::*)(int)>(&QProcess::finished)); + QSignalSpy finishedSpy2(&process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(errorSpy.isValid()); QVERIFY(finishedSpy.isValid()); @@ -1864,9 +1864,9 @@ void tst_QProcess::waitForReadyReadForNonexistantProcess() qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); QProcess process; - QSignalSpy errorSpy(&process, SIGNAL(error(QProcess::ProcessError))); - QSignalSpy finishedSpy1(&process, SIGNAL(finished(int))); - QSignalSpy finishedSpy2(&process, SIGNAL(finished(int,QProcess::ExitStatus))); + QSignalSpy errorSpy(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); + QSignalSpy finishedSpy1(&process, static_cast<void (QProcess::*)(int)>(&QProcess::finished)); + QSignalSpy finishedSpy2(&process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(errorSpy.isValid()); QVERIFY(finishedSpy1.isValid()); @@ -2202,7 +2202,7 @@ void tst_QProcess::invalidProgramString() QProcess process; qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); - QSignalSpy spy(&process, SIGNAL(error(QProcess::ProcessError))); + QSignalSpy spy(&process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error)); QVERIFY(spy.isValid()); process.start(programString); @@ -2218,8 +2218,8 @@ void tst_QProcess::onlyOneStartedSignal() qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus"); QProcess process; - QSignalSpy spyStarted(&process, SIGNAL(started())); - QSignalSpy spyFinished(&process, SIGNAL(finished(int,QProcess::ExitStatus))); + QSignalSpy spyStarted(&process, &QProcess::started); + QSignalSpy spyFinished(&process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished)); QVERIFY(spyStarted.isValid()); QVERIFY(spyFinished.isValid()); diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp index 515a10426c..230030d5cd 100644 --- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp +++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -47,6 +47,9 @@ class tst_QResourceEngine: public QObject { Q_OBJECT +public: + tst_QResourceEngine() : m_runtimeResourceRcc(QFINDTESTDATA("runtime_resource.rcc")) {} + private slots: void initTestCase(); void cleanupTestCase(); @@ -59,20 +62,24 @@ private slots: void searchPath(); void doubleSlashInRoot(); void setLocale(); + +private: + const QString m_runtimeResourceRcc; }; void tst_QResourceEngine::initTestCase() { - QVERIFY(QResource::registerResource(QFINDTESTDATA("runtime_resource.rcc"))); - QVERIFY(QResource::registerResource(QFINDTESTDATA("runtime_resource.rcc"), "/secondary_root/")); + QVERIFY(!m_runtimeResourceRcc.isEmpty()); + QVERIFY(QResource::registerResource(m_runtimeResourceRcc)); + QVERIFY(QResource::registerResource(m_runtimeResourceRcc, "/secondary_root/")); } void tst_QResourceEngine::cleanupTestCase() { // make sure we don't leak memory - QVERIFY(QResource::unregisterResource(QFINDTESTDATA("runtime_resource.rcc"))); - QVERIFY(QResource::unregisterResource(QFINDTESTDATA("runtime_resource.rcc"), "/secondary_root/")); + QVERIFY(QResource::unregisterResource(m_runtimeResourceRcc)); + QVERIFY(QResource::unregisterResource(m_runtimeResourceRcc, "/secondary_root/")); } void tst_QResourceEngine::checkStructure_data() diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp index 87bcfe572d..08b943ba72 100644 --- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp +++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp @@ -93,6 +93,8 @@ private slots: void transactionalWriteNoPermissionsOnFile(); void transactionalWriteCanceled(); void transactionalWriteErrorRenaming(); + void symlink(); + void directory(); }; static inline QByteArray msgCannotOpen(const QFileDevice &f) @@ -340,5 +342,142 @@ void tst_QSaveFile::transactionalWriteErrorRenaming() QCOMPARE(file.error(), QFile::RenameError); } +void tst_QSaveFile::symlink() +{ +#ifdef Q_OS_UNIX + QByteArray someData = "some data"; + QTemporaryDir dir; + QVERIFY(dir.isValid()); + + const QString targetFile = dir.path() + QLatin1String("/outfile"); + const QString linkFile = dir.path() + QLatin1String("/linkfile"); + { + QFile file(targetFile); + QVERIFY2(file.open(QIODevice::WriteOnly), msgCannotOpen(file).constData()); + QCOMPARE(file.write("Hello"), Q_INT64_C(5)); + file.close(); + } + + QVERIFY(QFile::link(targetFile, linkFile)); + + QString canonical = QFileInfo(linkFile).canonicalFilePath(); + QCOMPARE(canonical, QFileInfo(targetFile).canonicalFilePath()); + + // Try saving into it + { + QSaveFile saveFile(linkFile); + QVERIFY(saveFile.open(QIODevice::WriteOnly)); + QCOMPARE(saveFile.write(someData), someData.size()); + saveFile.commit(); + + //Check that the linkFile is still a link and still has the same canonical path + QFileInfo info(linkFile); + QVERIFY(info.isSymLink()); + QCOMPARE(QFileInfo(linkFile).canonicalFilePath(), canonical); + + QFile file(targetFile); + QVERIFY2(file.open(QIODevice::ReadOnly), msgCannotOpen(file).constData()); + QCOMPARE(file.readAll(), someData); + file.remove(); + } + + // Save into a symbolic link that point to a removed file + someData = "more stuff"; + { + QSaveFile saveFile(linkFile); + QVERIFY(saveFile.open(QIODevice::WriteOnly)); + QCOMPARE(saveFile.write(someData), someData.size()); + saveFile.commit(); + + QFileInfo info(linkFile); + QVERIFY(info.isSymLink()); + QCOMPARE(QFileInfo(linkFile).canonicalFilePath(), canonical); + + QFile file(targetFile); + QVERIFY2(file.open(QIODevice::ReadOnly), msgCannotOpen(file).constData()); + QCOMPARE(file.readAll(), someData); + } + + // link to a link in another directory + QTemporaryDir dir2; + QVERIFY(dir2.isValid()); + + const QString linkFile2 = dir2.path() + QLatin1String("/linkfile"); + QVERIFY(QFile::link(linkFile, linkFile2)); + QCOMPARE(QFileInfo(linkFile2).canonicalFilePath(), canonical); + + + someData = "hello everyone"; + + { + QSaveFile saveFile(linkFile2); + QVERIFY(saveFile.open(QIODevice::WriteOnly)); + QCOMPARE(saveFile.write(someData), someData.size()); + saveFile.commit(); + + QFile file(targetFile); + QVERIFY2(file.open(QIODevice::ReadOnly), msgCannotOpen(file).constData()); + QCOMPARE(file.readAll(), someData); + } + + //cyclic link + const QString cyclicLink = dir.path() + QLatin1String("/cyclic"); + QVERIFY(QFile::link(cyclicLink, cyclicLink)); + { + QSaveFile saveFile(cyclicLink); + QVERIFY(saveFile.open(QIODevice::WriteOnly)); + QCOMPARE(saveFile.write(someData), someData.size()); + saveFile.commit(); + + QFile file(cyclicLink); + QVERIFY2(file.open(QIODevice::ReadOnly), msgCannotOpen(file).constData()); + QCOMPARE(file.readAll(), someData); + } + + //cyclic link2 + QVERIFY(QFile::link(cyclicLink + QLatin1Char('1'), cyclicLink + QLatin1Char('2'))); + QVERIFY(QFile::link(cyclicLink + QLatin1Char('2'), cyclicLink + QLatin1Char('1'))); + + { + QSaveFile saveFile(cyclicLink + QLatin1Char('1')); + QVERIFY(saveFile.open(QIODevice::WriteOnly)); + QCOMPARE(saveFile.write(someData), someData.size()); + saveFile.commit(); + + // the explicit file becomes a file instead of a link + QVERIFY(!QFileInfo(cyclicLink + QLatin1Char('1')).isSymLink()); + QVERIFY(QFileInfo(cyclicLink + QLatin1Char('2')).isSymLink()); + + QFile file(cyclicLink + QLatin1Char('1')); + QVERIFY2(file.open(QIODevice::ReadOnly), msgCannotOpen(file).constData()); + QCOMPARE(file.readAll(), someData); + } +#endif +} + +void tst_QSaveFile::directory() +{ + QTemporaryDir dir; + QVERIFY(dir.isValid()); + + const QString subdir = dir.path() + QLatin1String("/subdir"); + QVERIFY(QDir(dir.path()).mkdir(QStringLiteral("subdir"))); + { + QFile sf(subdir); + QVERIFY(!sf.open(QIODevice::WriteOnly)); + } + +#ifdef Q_OS_UNIX + //link to a directory + const QString linkToDir = dir.path() + QLatin1String("/linkToDir"); + QVERIFY(QFile::link(subdir, linkToDir)); + + { + QFile sf(linkToDir); + QVERIFY(!sf.open(QIODevice::WriteOnly)); + } +#endif +} + QTEST_MAIN(tst_QSaveFile) #include "tst_qsavefile.moc" diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index 7247b02498..c373e80408 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -56,7 +56,7 @@ #define Q_XDG_PLATFORM #endif -static const int MaxStandardLocation = QStandardPaths::GenericConfigLocation; +static const int MaxStandardLocation = QStandardPaths::AppDataLocation; class tst_qstandardpaths : public QObject { @@ -129,7 +129,8 @@ static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths "ConfigLocation", "DownloadLocation", "GenericCacheLocation", - "GenericConfigLocation" + "GenericConfigLocation", + "AppDataLocation" }; void tst_qstandardpaths::dump() @@ -238,7 +239,8 @@ void tst_qstandardpaths::enableTestMode() // Check this for locations where test programs typically write. Not desktop, download, music etc... typedef QHash<QStandardPaths::StandardLocation, QString> LocationHash; LocationHash testLocations; - testLocations.insert(QStandardPaths::DataLocation, QStandardPaths::writableLocation(QStandardPaths::DataLocation)); + testLocations.insert(QStandardPaths::AppDataLocation, QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + testLocations.insert(QStandardPaths::AppLocalDataLocation, QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); testLocations.insert(QStandardPaths::GenericDataLocation, QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)); testLocations.insert(QStandardPaths::ConfigLocation, QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); testLocations.insert(QStandardPaths::GenericConfigLocation, QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)); @@ -294,18 +296,18 @@ void tst_qstandardpaths::testDataLocation() // applications are sandboxed. #if !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_ANDROID) && !defined(Q_OS_WINRT) const QString base = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::DataLocation), base + "/tst_qstandardpaths"); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation), base + "/tst_qstandardpaths"); QCoreApplication::instance()->setOrganizationName("Qt"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::DataLocation), base + "/Qt/tst_qstandardpaths"); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation), base + "/Qt/tst_qstandardpaths"); QCoreApplication::instance()->setApplicationName("QtTest"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::DataLocation), base + "/Qt/QtTest"); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation), base + "/Qt/QtTest"); #endif #ifdef Q_XDG_PLATFORM setDefaultLocations(); const QString expectedAppDataDir = QDir::homePath() + QString::fromLatin1("/.local/share/Qt/QtTest"); - QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::DataLocation), expectedAppDataDir); - const QStringList appDataDirs = QStandardPaths::standardLocations(QStandardPaths::DataLocation); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation), expectedAppDataDir); + const QStringList appDataDirs = QStandardPaths::standardLocations(QStandardPaths::AppLocalDataLocation); QCOMPARE(appDataDirs.count(), 3); QCOMPARE(appDataDirs.at(0), expectedAppDataDir); QCOMPARE(appDataDirs.at(1), QString::fromLatin1("/usr/local/share/Qt/QtTest")); @@ -463,7 +465,7 @@ void tst_qstandardpaths::testAllWritableLocations_data() QTest::newRow("PicturesLocation") << QStandardPaths::PicturesLocation; QTest::newRow("TempLocation") << QStandardPaths::TempLocation; QTest::newRow("HomeLocation") << QStandardPaths::HomeLocation; - QTest::newRow("DataLocation") << QStandardPaths::DataLocation; + QTest::newRow("AppLocalDataLocation") << QStandardPaths::AppLocalDataLocation; QTest::newRow("DownloadLocation") << QStandardPaths::DownloadLocation; } diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index 5ad798ae1f..74220d7f97 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -251,6 +251,11 @@ void tst_QTemporaryFile::autoRemove() QTemporaryFile file("tempXXXXXX"); QVERIFY(file.open()); fileName = file.fileName(); + // QTBUG-39976, file mappings should be cleared as well. + QVERIFY(file.write("test")); + QVERIFY(file.flush()); + uchar *mapped = file.map(0, file.size()); + QVERIFY(mapped); file.close(); } QVERIFY(!QFile::exists(fileName)); @@ -441,13 +446,15 @@ void tst_QTemporaryFile::rename() void tst_QTemporaryFile::renameFdLeak() { #ifdef Q_OS_UNIX + const QByteArray sourceFile = QFile::encodeName(QFINDTESTDATA(__FILE__)); + QVERIFY(!sourceFile.isEmpty()); // Test this on Unix only // Open a bunch of files to force the fd count to go up static const int count = 10; int bunch_of_files[count]; for (int i = 0; i < count; ++i) { - bunch_of_files[i] = ::open(qPrintable(QFINDTESTDATA("tst_qtemporaryfile.cpp")), O_RDONLY); + bunch_of_files[i] = ::open(sourceFile.constData(), O_RDONLY); QVERIFY(bunch_of_files[i] != -1); } @@ -642,8 +649,10 @@ void tst_QTemporaryFile::createNativeFile_data() QTest::addColumn<bool>("valid"); QTest::addColumn<QByteArray>("content"); - QTest::newRow("nativeFile") << QFINDTESTDATA("resources/test.txt") << (qint64)-1 << false << QByteArray(); - QTest::newRow("nativeFileWithPos") << QFINDTESTDATA("resources/test.txt") << (qint64)5 << false << QByteArray(); + const QString nativeFilePath = QFINDTESTDATA("resources/test.txt"); + + QTest::newRow("nativeFile") << nativeFilePath << (qint64)-1 << false << QByteArray(); + QTest::newRow("nativeFileWithPos") << nativeFilePath << (qint64)5 << false << QByteArray(); QTest::newRow("resourceFile") << ":/resources/test.txt" << (qint64)-1 << true << QByteArray("This is a test"); QTest::newRow("resourceFileWithPos") << ":/resources/test.txt" << (qint64)5 << true << QByteArray("This is a test"); } diff --git a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp index 2ae085cb0b..15fd235048 100644 --- a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -245,6 +245,8 @@ private: QTemporaryDir tempDir; QString testFileName; + const QString m_rfc3261FilePath; + const QString m_shiftJisFilePath; }; void runOnExit() @@ -256,11 +258,16 @@ Q_DESTRUCTOR_FUNCTION(runOnExit) tst_QTextStream::tst_QTextStream() : tempDir(QDir::tempPath() + "/tst_qtextstream.XXXXXX") + , m_rfc3261FilePath(QFINDTESTDATA("rfc3261.txt")) + , m_shiftJisFilePath(QFINDTESTDATA("shift-jis.txt")) { } void tst_QTextStream::initTestCase() { + QVERIFY(!m_rfc3261FilePath.isEmpty()); + QVERIFY(!m_shiftJisFilePath.isEmpty()); + testFileName = tempDir.path() + "/testfile"; // chdir into the testdata dir and refer to our helper apps with relative paths @@ -768,7 +775,7 @@ void tst_QTextStream::generateAllData(bool for_QString) // ------------------------------------------------------------------------------ void tst_QTextStream::readLineUntilNull() { - QFile file(QFINDTESTDATA("rfc3261.txt")); + QFile file(m_rfc3261FilePath); QVERIFY(file.open(QFile::ReadOnly)); QTextStream stream(&file); @@ -887,7 +894,7 @@ void tst_QTextStream::lineCount_data() QTest::newRow("buffersize+1 line") << QByteArray(16384, '\n') << 16384; QTest::newRow("buffersize+2 line") << QByteArray(16385, '\n') << 16385; - QFile file(QFINDTESTDATA("rfc3261.txt")); file.open(QFile::ReadOnly); + QFile file(m_rfc3261FilePath); file.open(QFile::ReadOnly); QTest::newRow("rfc3261") << file.readAll() << 15067; } @@ -923,7 +930,7 @@ void tst_QTextStream::performance() stopWatch.restart(); int nlines1 = 0; - QFile file(QFINDTESTDATA("rfc3261.txt")); + QFile file(m_rfc3261FilePath); QVERIFY(file.open(QFile::ReadOnly)); while (!file.atEnd()) { @@ -935,7 +942,7 @@ void tst_QTextStream::performance() stopWatch.restart(); int nlines2 = 0; - QFile file2(QFINDTESTDATA("rfc3261.txt")); + QFile file2(m_rfc3261FilePath); QVERIFY(file2.open(QFile::ReadOnly)); QTextStream stream(&file2); @@ -1155,7 +1162,7 @@ void tst_QTextStream::readNewlines() // ------------------------------------------------------------------------------ void tst_QTextStream::seek() { - QFile file(QFINDTESTDATA("rfc3261.txt")); + QFile file(m_rfc3261FilePath); QVERIFY(file.open(QFile::ReadOnly)); QTextStream stream(&file); @@ -1248,7 +1255,7 @@ void tst_QTextStream::pos() } { // Latin1 device - QFile file(QFINDTESTDATA("rfc3261.txt")); + QFile file(m_rfc3261FilePath); QVERIFY(file.open(QIODevice::ReadOnly)); QTextStream stream(&file); @@ -1280,7 +1287,7 @@ void tst_QTextStream::pos() { // Shift-JIS device for (int i = 0; i < 2; ++i) { - QFile file(QFINDTESTDATA("shift-jis.txt")); + QFile file(m_shiftJisFilePath); if (i == 0) QVERIFY(file.open(QIODevice::ReadOnly)); else @@ -1788,8 +1795,6 @@ void tst_QTextStream::writeSeekWriteNoBOM() QCOMPARE(out16.buffer(), first); } - - // ------------------------------------------------------------------------------ void tst_QTextStream::generateOperatorCharData(bool for_QString) { @@ -2304,12 +2309,14 @@ void tst_QTextStream::generateRealNumbersDataWrite() { QTest::addColumn<double>("number"); QTest::addColumn<QByteArray>("data"); + QTest::addColumn<QByteArray>("dataWithSeparators"); - QTest::newRow("0") << 0.0 << QByteArray("0"); - QTest::newRow("3.14") << 3.14 << QByteArray("3.14"); - QTest::newRow("-3.14") << -3.14 << QByteArray("-3.14"); - QTest::newRow("1.2e+10") << 1.2e+10 << QByteArray("1.2e+10"); - QTest::newRow("-1.2e+10") << -1.2e+10 << QByteArray("-1.2e+10"); + QTest::newRow("0") << 0.0 << QByteArray("0") << QByteArray("0"); + QTest::newRow("3.14") << 3.14 << QByteArray("3.14") << QByteArray("3.14"); + QTest::newRow("-3.14") << -3.14 << QByteArray("-3.14") << QByteArray("-3.14"); + QTest::newRow("1.2e+10") << 1.2e+10 << QByteArray("1.2e+10") << QByteArray("1.2e+10"); + QTest::newRow("-1.2e+10") << -1.2e+10 << QByteArray("-1.2e+10") << QByteArray("-1.2e+10"); + QTest::newRow("12345") << 12345. << QByteArray("12345") << QByteArray("12,345"); } // ------------------------------------------------------------------------------ @@ -2320,14 +2327,22 @@ void tst_QTextStream::generateRealNumbersDataWrite() { \ QFETCH(double, number); \ QFETCH(QByteArray, data); \ + QFETCH(QByteArray, dataWithSeparators); \ \ QBuffer buffer; \ buffer.open(QBuffer::WriteOnly); \ QTextStream stream(&buffer); \ + stream.setLocale(QLocale::c()); \ float f = (float)number; \ stream << f; \ stream.flush(); \ QCOMPARE(buffer.data().constData(), data.constData()); \ + \ + buffer.reset(); \ + stream.setLocale(QLocale("en-US")); \ + stream << f; \ + stream.flush(); \ + QCOMPARE(buffer.data(), dataWithSeparators); \ } IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(float, float) IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(double, float) diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index d5eab54363..28b68dc750 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -165,6 +165,8 @@ private slots: void binaryData(); void fromUserInput_data(); void fromUserInput(); + void fromUserInputWithCwd_data(); + void fromUserInputWithCwd(); void fileName_data(); void fileName(); void isEmptyForEncodedUrl(); @@ -2920,6 +2922,52 @@ void tst_QUrl::fromUserInput() QCOMPARE(url, guessUrlFromString); } +void tst_QUrl::fromUserInputWithCwd_data() +{ + QTest::addColumn<QString>("string"); + QTest::addColumn<QString>("directory"); + QTest::addColumn<QUrl>("guessedUrlDefault"); + QTest::addColumn<QUrl>("guessedUrlAssumeLocalFile"); + + // Null + QTest::newRow("null") << QString() << QString() << QUrl() << QUrl(); + + // Existing file + QDirIterator it(QDir::currentPath(), QDir::NoDotDot | QDir::AllEntries); + int c = 0; + while (it.hasNext()) { + it.next(); + QUrl url = QUrl::fromLocalFile(it.filePath()); + QTest::newRow(QString("file-%1").arg(c++).toLatin1()) << it.fileName() << QDir::currentPath() << url << url; + } + QDir parent = QDir::current(); + QVERIFY(parent.cdUp()); + QUrl parentUrl = QUrl::fromLocalFile(parent.path()); + QTest::newRow("dotdot") << ".." << QDir::currentPath() << parentUrl << parentUrl; + + QTest::newRow("nonexisting") << "nonexisting" << QDir::currentPath() << QUrl("http://nonexisting") << QUrl::fromLocalFile(QDir::currentPath() + "/nonexisting"); + QTest::newRow("short-url") << "example.org" << QDir::currentPath() << QUrl("http://example.org") << QUrl::fromLocalFile(QDir::currentPath() + "/example.org"); + QTest::newRow("full-url") << "http://example.org" << QDir::currentPath() << QUrl("http://example.org") << QUrl("http://example.org"); + QTest::newRow("absolute") << "/doesnotexist.txt" << QDir::currentPath() << QUrl("file:///doesnotexist.txt") << QUrl("file:///doesnotexist.txt"); +#ifdef Q_OS_WIN + QTest::newRow("windows-absolute") << "c:/doesnotexist.txt" << QDir::currentPath() << QUrl("file:///c:/doesnotexist.txt") << QUrl("file:///c:/doesnotexist.txt"); +#endif +} + +void tst_QUrl::fromUserInputWithCwd() +{ + QFETCH(QString, string); + QFETCH(QString, directory); + QFETCH(QUrl, guessedUrlDefault); + QFETCH(QUrl, guessedUrlAssumeLocalFile); + + QUrl url = QUrl::fromUserInput(string, directory); + QCOMPARE(url, guessedUrlDefault); + + url = QUrl::fromUserInput(string, directory, QUrl::AssumeLocalFile); + QCOMPARE(url, guessedUrlAssumeLocalFile); +} + void tst_QUrl::fileName_data() { QTest::addColumn<QString>("urlStr"); diff --git a/tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp b/tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp index 8321f76bec..16f94e7c5d 100644 --- a/tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp +++ b/tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp @@ -58,6 +58,7 @@ private slots: void readFile(); void waitForNotified_data(); void waitForNotified(); + void waitForAnyNotified(); void brokenPipe(); void multipleOperations(); @@ -195,6 +196,45 @@ void tst_QWinOverlappedIoNotifier::waitForNotified() QCOMPARE(notifier.waitForNotified(100, &overlapped), false); } +void tst_QWinOverlappedIoNotifier::waitForAnyNotified() +{ + const QString fileName = QDir::toNativeSeparators(sourceFileInfo.absoluteFilePath()); + const int readBufferSize = sourceFileInfo.size(); + + QWinOverlappedIoNotifier notifier; + HANDLE hFile = CreateFile(reinterpret_cast<const wchar_t*>(fileName.utf16()), + GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + notifier.setHandle(hFile); + notifier.setEnabled(true); + QVERIFY(notifier.waitForAnyNotified(100) == 0); + + OVERLAPPED overlapped1; + ZeroMemory(&overlapped1, sizeof(OVERLAPPED)); + QByteArray buffer1(readBufferSize, 0); + BOOL readSuccess = ReadFile(hFile, buffer1.data(), buffer1.size(), NULL, &overlapped1); + QVERIFY(readSuccess || GetLastError() == ERROR_IO_PENDING); + + OVERLAPPED overlapped2; + ZeroMemory(&overlapped2, sizeof(OVERLAPPED)); + QByteArray buffer2(readBufferSize, 0); + readSuccess = ReadFile(hFile, buffer2.data(), buffer2.size(), NULL, &overlapped2); + QVERIFY(readSuccess || GetLastError() == ERROR_IO_PENDING); + + QSet<OVERLAPPED *> overlappedObjects; + overlappedObjects << &overlapped1 << &overlapped2; + + for (int i = 1; i <= 2; ++i) { + OVERLAPPED *notifiedOverlapped = notifier.waitForAnyNotified(3000); + QVERIFY(overlappedObjects.contains(notifiedOverlapped)); + overlappedObjects.remove(notifiedOverlapped); + } + + CloseHandle(hFile); + QVERIFY(overlappedObjects.isEmpty()); + QVERIFY(notifier.waitForAnyNotified(100) == 0); +} + void tst_QWinOverlappedIoNotifier::brokenPipe() { QWinOverlappedIoNotifier notifier; diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp index 2d2ae14fb8..0503371714 100644 --- a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp +++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp @@ -158,6 +158,8 @@ public: QVector<QVector<QString> > table; }; +Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint); + QtTestModel::QtTestModel(int rows, int columns, QObject *parent) : QAbstractItemModel(parent), cCount(columns), rCount(rows), wrongIndex(false) { @@ -353,6 +355,8 @@ void tst_QAbstractItemModel::init() insertCommand->setStartRow(0); insertCommand->setEndRow(9); insertCommand->doCommand(); + + qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>(); } void tst_QAbstractItemModel::cleanup() @@ -807,8 +811,8 @@ void tst_QAbstractItemModel::removeRows() { QtTestModel model(10, 10); - QSignalSpy rowsAboutToBeRemovedSpy(&model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int))); - QSignalSpy rowsRemovedSpy(&model, SIGNAL(rowsRemoved(QModelIndex,int,int))); + QSignalSpy rowsAboutToBeRemovedSpy(&model, &QtTestModel::rowsAboutToBeRemoved); + QSignalSpy rowsRemovedSpy(&model, &QtTestModel::rowsRemoved); QVERIFY(rowsAboutToBeRemovedSpy.isValid()); QVERIFY(rowsRemovedSpy.isValid()); @@ -822,8 +826,8 @@ void tst_QAbstractItemModel::removeColumns() { QtTestModel model(10, 10); - QSignalSpy columnsAboutToBeRemovedSpy(&model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int))); - QSignalSpy columnsRemovedSpy(&model, SIGNAL(columnsRemoved(QModelIndex,int,int))); + QSignalSpy columnsAboutToBeRemovedSpy(&model, &QtTestModel::columnsAboutToBeRemoved); + QSignalSpy columnsRemovedSpy(&model, &QtTestModel::columnsRemoved); QVERIFY(columnsAboutToBeRemovedSpy.isValid()); QVERIFY(columnsRemovedSpy.isValid()); @@ -837,8 +841,8 @@ void tst_QAbstractItemModel::insertRows() { QtTestModel model(10, 10); - QSignalSpy rowsAboutToBeInsertedSpy(&model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); - QSignalSpy rowsInsertedSpy(&model, SIGNAL(rowsInserted(QModelIndex,int,int))); + QSignalSpy rowsAboutToBeInsertedSpy(&model, &QtTestModel::rowsAboutToBeInserted); + QSignalSpy rowsInsertedSpy(&model, &QtTestModel::rowsInserted); QVERIFY(rowsAboutToBeInsertedSpy.isValid()); QVERIFY(rowsInsertedSpy.isValid()); @@ -852,8 +856,8 @@ void tst_QAbstractItemModel::insertColumns() { QtTestModel model(10, 10); - QSignalSpy columnsAboutToBeInsertedSpy(&model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int))); - QSignalSpy columnsInsertedSpy(&model, SIGNAL(columnsInserted(QModelIndex,int,int))); + QSignalSpy columnsAboutToBeInsertedSpy(&model, &QtTestModel::columnsAboutToBeInserted); + QSignalSpy columnsInsertedSpy(&model, &QtTestModel::columnsInserted); QVERIFY(columnsAboutToBeInsertedSpy.isValid()); QVERIFY(columnsInsertedSpy.isValid()); @@ -867,8 +871,8 @@ void tst_QAbstractItemModel::moveRows() { QtTestModel model(10, 10); - QSignalSpy rowsAboutToBeMovedSpy(&model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy rowsMovedSpy(&model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy rowsAboutToBeMovedSpy(&model, &QtTestModel::rowsAboutToBeMoved); + QSignalSpy rowsMovedSpy(&model, &QtTestModel::rowsMoved); QVERIFY(rowsAboutToBeMovedSpy.isValid()); QVERIFY(rowsMovedSpy.isValid()); @@ -882,8 +886,8 @@ void tst_QAbstractItemModel::moveColumns() { QtTestModel model(10, 10); - QSignalSpy columnsAboutToBeMovedSpy(&model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy columnsMovedSpy(&model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy columnsAboutToBeMovedSpy(&model, &QtTestModel::columnsAboutToBeMoved); + QSignalSpy columnsMovedSpy(&model, &QtTestModel::columnsMoved); QVERIFY(columnsAboutToBeMovedSpy.isValid()); QVERIFY(columnsMovedSpy.isValid()); @@ -901,7 +905,7 @@ void tst_QAbstractItemModel::reset() { QtTestModel model(10, 10); - QSignalSpy resetSpy(&model, SIGNAL(modelReset())); + QSignalSpy resetSpy(&model, &QtTestModel::modelReset); QVERIFY(resetSpy.isValid()); model.reset(); QCOMPARE(resetSpy.count(), 1); @@ -1023,8 +1027,8 @@ void tst_QAbstractItemModel::testMoveSameParentDown() } } - QSignalSpy beforeSpy(m_model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy afterSpy(m_model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy beforeSpy(m_model, &DynamicTreeModel::rowsAboutToBeMoved); + QSignalSpy afterSpy(m_model, &DynamicTreeModel::rowsMoved); QVERIFY(beforeSpy.isValid()); QVERIFY(afterSpy.isValid()); @@ -1138,8 +1142,8 @@ void tst_QAbstractItemModel::testMoveSameParentUp() } } - QSignalSpy beforeSpy(m_model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy afterSpy(m_model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy beforeSpy(m_model, &DynamicTreeModel::rowsAboutToBeMoved); + QSignalSpy afterSpy(m_model, &DynamicTreeModel::rowsMoved); QVERIFY(beforeSpy.isValid()); QVERIFY(afterSpy.isValid()); @@ -1287,8 +1291,8 @@ void tst_QAbstractItemModel::testMoveToGrandParent() } } - QSignalSpy beforeSpy(m_model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy afterSpy(m_model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy beforeSpy(m_model, &DynamicTreeModel::rowsAboutToBeMoved); + QSignalSpy afterSpy(m_model, &DynamicTreeModel::rowsMoved); QVERIFY(beforeSpy.isValid()); QVERIFY(afterSpy.isValid()); @@ -1427,8 +1431,8 @@ void tst_QAbstractItemModel::testMoveToSibling() persistentList << QPersistentModelIndex(idx); } - QSignalSpy beforeSpy(m_model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy afterSpy(m_model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy beforeSpy(m_model, &DynamicTreeModel::rowsAboutToBeMoved); + QSignalSpy afterSpy(m_model, &DynamicTreeModel::rowsMoved); QVERIFY(beforeSpy.isValid()); QVERIFY(afterSpy.isValid()); @@ -1577,8 +1581,8 @@ void tst_QAbstractItemModel::testMoveToUncle() persistentList << QPersistentModelIndex(idx); } - QSignalSpy beforeSpy(m_model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy afterSpy(m_model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy beforeSpy(m_model, &DynamicTreeModel::rowsAboutToBeMoved); + QSignalSpy afterSpy(m_model, &DynamicTreeModel::rowsMoved); QVERIFY(beforeSpy.isValid()); QVERIFY(afterSpy.isValid()); @@ -1684,8 +1688,8 @@ void tst_QAbstractItemModel::testMoveToDescendants() persistentList << QPersistentModelIndex(idx); } - QSignalSpy beforeSpy(m_model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy afterSpy(m_model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy beforeSpy(m_model, &DynamicTreeModel::rowsAboutToBeMoved); + QSignalSpy afterSpy(m_model, &DynamicTreeModel::rowsMoved); QVERIFY(beforeSpy.isValid()); QVERIFY(afterSpy.isValid()); @@ -1748,8 +1752,8 @@ void tst_QAbstractItemModel::testMoveWithinOwnRange() QFETCH(int, endRow); QFETCH(int, destRow); - QSignalSpy beforeSpy(m_model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy afterSpy(m_model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy beforeSpy(m_model, &DynamicTreeModel::rowsAboutToBeMoved); + QSignalSpy afterSpy(m_model, &DynamicTreeModel::rowsMoved); QVERIFY(beforeSpy.isValid()); QVERIFY(afterSpy.isValid()); @@ -1841,8 +1845,8 @@ void ListenerObject::slotReset() void tst_QAbstractItemModel::testReset() { - QSignalSpy beforeResetSpy(m_model, SIGNAL(modelAboutToBeReset())); - QSignalSpy afterResetSpy(m_model, SIGNAL(modelReset())); + QSignalSpy beforeResetSpy(m_model, &DynamicTreeModel::modelAboutToBeReset); + QSignalSpy afterResetSpy(m_model, &DynamicTreeModel::modelReset); QVERIFY(beforeResetSpy.isValid()); QVERIFY(afterResetSpy.isValid()); @@ -1874,8 +1878,8 @@ void tst_QAbstractItemModel::testReset() // Delete it because its slots test things which are not true after this point. delete listener; - QSignalSpy proxyBeforeResetSpy(nullProxy, SIGNAL(modelAboutToBeReset())); - QSignalSpy proxyAfterResetSpy(nullProxy, SIGNAL(modelReset())); + QSignalSpy proxyBeforeResetSpy(nullProxy, &QSortFilterProxyModel::modelAboutToBeReset); + QSignalSpy proxyAfterResetSpy(nullProxy, &QSortFilterProxyModel::modelReset); // Before setting it, it does not have custom roles. QCOMPARE(nullProxy->roleNames().value(Qt::UserRole + 1), QByteArray()); @@ -1925,8 +1929,8 @@ void tst_QAbstractItemModel::testDataChanged() { CustomRoleModel model; - QSignalSpy withRoles(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>))); - QSignalSpy withoutRoles(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex))); + QSignalSpy withRoles(&model, &CustomRoleModel::dataChanged); + QSignalSpy withoutRoles(&model, &CustomRoleModel::dataChanged); QVERIFY(withRoles.isValid()); QVERIFY(withoutRoles.isValid()); @@ -2027,8 +2031,8 @@ void tst_QAbstractItemModel::testChildrenLayoutsChanged() QCOMPARE(model.rowCount(p1), 10); QCOMPARE(model.rowCount(p2), 10); - QSignalSpy beforeSpy(&model, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>))); - QSignalSpy afterSpy(&model, SIGNAL(layoutChanged(QList<QPersistentModelIndex>))); + QSignalSpy beforeSpy(&model, &DynamicTreeModel::layoutAboutToBeChanged); + QSignalSpy afterSpy(&model, &DynamicTreeModel::layoutChanged); QVERIFY(beforeSpy.isValid()); QVERIFY(afterSpy.isValid()); @@ -2043,8 +2047,8 @@ void tst_QAbstractItemModel::testChildrenLayoutsChanged() const QVariantList beforeSignal = beforeSpy.first(); const QVariantList afterSignal = afterSpy.first(); - QCOMPARE(beforeSignal.size(), 1); - QCOMPARE(afterSignal.size(), 1); + QCOMPARE(beforeSignal.size(), 2); + QCOMPARE(afterSignal.size(), 2); const QList<QPersistentModelIndex> beforeParents = beforeSignal.first().value<QList<QPersistentModelIndex> >(); QCOMPARE(beforeParents.size(), 2); @@ -2093,8 +2097,8 @@ void tst_QAbstractItemModel::testChildrenLayoutsChanged() const QPersistentModelIndex p2FirstPersistent = model.index(0, 0, p2); const QPersistentModelIndex p2LastPersistent = model.index(9, 0, p2); - QSignalSpy beforeSpy(&model, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>))); - QSignalSpy afterSpy(&model, SIGNAL(layoutChanged(QList<QPersistentModelIndex>))); + QSignalSpy beforeSpy(&model, &DynamicTreeModel::layoutAboutToBeChanged); + QSignalSpy afterSpy(&model, &DynamicTreeModel::layoutChanged); QVERIFY(beforeSpy.isValid()); QVERIFY(afterSpy.isValid()); @@ -2116,8 +2120,8 @@ void tst_QAbstractItemModel::testChildrenLayoutsChanged() const QVariantList beforeSignal = beforeSpy.first(); const QVariantList afterSignal = afterSpy.first(); - QCOMPARE(beforeSignal.size(), 1); - QCOMPARE(afterSignal.size(), 1); + QCOMPARE(beforeSignal.size(), 2); + QCOMPARE(afterSignal.size(), 2); QVERIFY(p1FirstPersistent.row() == 1); QVERIFY(p1LastPersistent.row() == 0); diff --git a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp index ea0a14c18c..5d21509c86 100644 --- a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp @@ -163,10 +163,10 @@ void tst_QIdentityProxyModel::insertRows() verifyIdentity(m_model); - QSignalSpy modelBeforeSpy(m_model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); - QSignalSpy modelAfterSpy(m_model, SIGNAL(rowsInserted(QModelIndex,int,int))); - QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); - QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(rowsInserted(QModelIndex,int,int))); + QSignalSpy modelBeforeSpy(m_model, &QStandardItemModel::rowsAboutToBeInserted); + QSignalSpy modelAfterSpy(m_model, &QStandardItemModel::rowsInserted); + QSignalSpy proxyBeforeSpy(m_proxy, &QStandardItemModel::rowsAboutToBeInserted); + QSignalSpy proxyAfterSpy(m_proxy, &QStandardItemModel::rowsInserted); QVERIFY(modelBeforeSpy.isValid()); QVERIFY(modelAfterSpy.isValid()); @@ -203,10 +203,10 @@ void tst_QIdentityProxyModel::removeRows() verifyIdentity(m_model); - QSignalSpy modelBeforeSpy(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int))); - QSignalSpy modelAfterSpy(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int))); - QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int))); - QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(rowsRemoved(QModelIndex,int,int))); + QSignalSpy modelBeforeSpy(m_model, &QStandardItemModel::rowsAboutToBeRemoved); + QSignalSpy modelAfterSpy(m_model, &QStandardItemModel::rowsRemoved); + QSignalSpy proxyBeforeSpy(m_proxy, &QStandardItemModel::rowsAboutToBeRemoved); + QSignalSpy proxyAfterSpy(m_proxy, &QStandardItemModel::rowsRemoved); QVERIFY(modelBeforeSpy.isValid()); QVERIFY(modelAfterSpy.isValid()); @@ -257,10 +257,10 @@ void tst_QIdentityProxyModel::moveRows() verifyIdentity(&model); - QSignalSpy modelBeforeSpy(&model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy modelAfterSpy(&model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy modelBeforeSpy(&model, &DynamicTreeModel::rowsAboutToBeMoved); + QSignalSpy modelAfterSpy(&model, &DynamicTreeModel::rowsMoved); + QSignalSpy proxyBeforeSpy(m_proxy, &QIdentityProxyModel::rowsAboutToBeMoved); + QSignalSpy proxyAfterSpy(m_proxy, &QIdentityProxyModel::rowsMoved); QVERIFY(modelBeforeSpy.isValid()); QVERIFY(modelAfterSpy.isValid()); @@ -318,10 +318,10 @@ void tst_QIdentityProxyModel::reset() verifyIdentity(&model); - QSignalSpy modelBeforeSpy(&model, SIGNAL(modelAboutToBeReset())); - QSignalSpy modelAfterSpy(&model, SIGNAL(modelReset())); - QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(modelAboutToBeReset())); - QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(modelReset())); + QSignalSpy modelBeforeSpy(&model, &DynamicTreeModel::modelAboutToBeReset); + QSignalSpy modelAfterSpy(&model, &DynamicTreeModel::modelReset); + QSignalSpy proxyBeforeSpy(m_proxy, &QIdentityProxyModel::modelAboutToBeReset); + QSignalSpy proxyAfterSpy(m_proxy, &QIdentityProxyModel::modelReset); QVERIFY(modelBeforeSpy.isValid()); QVERIFY(modelAfterSpy.isValid()); @@ -351,8 +351,8 @@ void tst_QIdentityProxyModel::dataChanged() verifyIdentity(&model); - QSignalSpy modelSpy(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>))); - QSignalSpy proxySpy(m_proxy, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>))); + QSignalSpy modelSpy(&model, &DataChangedModel::dataChanged); + QSignalSpy proxySpy(m_proxy, &QIdentityProxyModel::dataChanged); QVERIFY(modelSpy.isValid()); QVERIFY(proxySpy.isValid()); diff --git a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp index 30434bfd56..df4d8d0916 100644 --- a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp +++ b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp @@ -608,7 +608,7 @@ void tst_QItemModel::setData() QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); QVERIFY(currentModel); - QSignalSpy spy(currentModel, SIGNAL(dataChanged(QModelIndex,QModelIndex))); + QSignalSpy spy(currentModel, &QAbstractItemModel::dataChanged); QVERIFY(spy.isValid()); QCOMPARE(currentModel->setData(QModelIndex(), QVariant()), false); QCOMPARE(spy.count(), 0); @@ -670,7 +670,7 @@ void tst_QItemModel::setHeaderData() QVERIFY(index.isValid()); qRegisterMetaType<Qt::Orientation>("Qt::Orientation"); - QSignalSpy spy(currentModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int))); + QSignalSpy spy(currentModel, &QAbstractItemModel::headerDataChanged); QVERIFY(spy.isValid()); QString text = "Index private pointers should always be the same"; @@ -711,7 +711,7 @@ void tst_QItemModel::sort() QVERIFY(currentModel->hasChildren(topIndex)); QModelIndex index = currentModel->index(0, 0, topIndex); QVERIFY(index.isValid()); - QSignalSpy spy(currentModel, SIGNAL(layoutChanged())); + QSignalSpy spy(currentModel, &QAbstractItemModel::layoutChanged); QVERIFY(spy.isValid()); for (int i=-1; i < 10; ++i){ currentModel->sort(i); @@ -849,12 +849,12 @@ void tst_QItemModel::remove() // When a row or column is removed there should be two signals. // Watch to make sure they are emitted and get the row/column count when they do get emitted by connecting them to a slot - QSignalSpy columnsAboutToBeRemovedSpy(currentModel, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int))); - QSignalSpy rowsAboutToBeRemovedSpy(currentModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int))); - QSignalSpy columnsRemovedSpy(currentModel, SIGNAL(columnsRemoved(QModelIndex,int,int))); - QSignalSpy rowsRemovedSpy(currentModel, SIGNAL(rowsRemoved(QModelIndex,int,int))); - QSignalSpy modelResetSpy(currentModel, SIGNAL(modelReset())); - QSignalSpy modelLayoutChangedSpy(currentModel, SIGNAL(layoutChanged())); + QSignalSpy columnsAboutToBeRemovedSpy(currentModel, &QAbstractItemModel::columnsAboutToBeRemoved); + QSignalSpy rowsAboutToBeRemovedSpy(currentModel, &QAbstractItemModel::rowsAboutToBeRemoved); + QSignalSpy columnsRemovedSpy(currentModel, &QAbstractItemModel::columnsRemoved); + QSignalSpy rowsRemovedSpy(currentModel, &QAbstractItemModel::rowsRemoved); + QSignalSpy modelResetSpy(currentModel, &QAbstractItemModel::modelReset); + QSignalSpy modelLayoutChangedSpy(currentModel, &QAbstractItemModel::layoutChanged); QVERIFY(columnsAboutToBeRemovedSpy.isValid()); QVERIFY(rowsAboutToBeRemovedSpy.isValid()); @@ -1191,12 +1191,12 @@ void tst_QItemModel::insert() // When a row or column is inserted there should be two signals. // Watch to make sure they are emitted and get the row/column count when they do get emitted by connecting them to a slot - QSignalSpy columnsAboutToBeInsertedSpy(currentModel, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int))); - QSignalSpy rowsAboutToBeInsertedSpy(currentModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); - QSignalSpy columnsInsertedSpy(currentModel, SIGNAL(columnsInserted(QModelIndex,int,int))); - QSignalSpy rowsInsertedSpy(currentModel, SIGNAL(rowsInserted(QModelIndex,int,int))); - QSignalSpy modelResetSpy(currentModel, SIGNAL(modelReset())); - QSignalSpy modelLayoutChangedSpy(currentModel, SIGNAL(layoutChanged())); + QSignalSpy columnsAboutToBeInsertedSpy(currentModel, &QAbstractItemModel::columnsAboutToBeInserted); + QSignalSpy rowsAboutToBeInsertedSpy(currentModel, &QAbstractItemModel::rowsAboutToBeInserted); + QSignalSpy columnsInsertedSpy(currentModel, &QAbstractItemModel::columnsInserted); + QSignalSpy rowsInsertedSpy(currentModel, &QAbstractItemModel::rowsInserted); + QSignalSpy modelResetSpy(currentModel, &QAbstractItemModel::modelReset); + QSignalSpy modelLayoutChangedSpy(currentModel, &QAbstractItemModel::layoutChanged); QVERIFY(columnsAboutToBeInsertedSpy.isValid()); QVERIFY(rowsAboutToBeInsertedSpy.isValid()); diff --git a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp index 9e3457a25a..a4e219a040 100644 --- a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -1529,7 +1529,7 @@ void tst_QItemSelectionModel::resetModel() MyStandardItemModel model(20, 20); QItemSelectionModel *selectionModel = new QItemSelectionModel(&model); - QSignalSpy spy(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection))); + QSignalSpy spy(selectionModel, &QItemSelectionModel::selectionChanged); QVERIFY(spy.isValid()); selectionModel->select(QItemSelection(model.index(0, 0), model.index(5, 5)), QItemSelectionModel::Select); @@ -1592,7 +1592,7 @@ void tst_QItemSelectionModel::removeRows() MyStandardItemModel model(rowCount, columnCount); QItemSelectionModel selections(&model); - QSignalSpy spy(&selections, SIGNAL(selectionChanged(QItemSelection,QItemSelection))); + QSignalSpy spy(&selections, &QItemSelectionModel::selectionChanged); QVERIFY(spy.isValid()); QModelIndex tl = model.index(selectTop, selectLeft); @@ -1655,7 +1655,7 @@ void tst_QItemSelectionModel::removeColumns() MyStandardItemModel model(rowCount, columnCount); QItemSelectionModel selections(&model); - QSignalSpy spy(&selections, SIGNAL(selectionChanged(QItemSelection,QItemSelection))); + QSignalSpy spy(&selections, &QItemSelectionModel::selectionChanged); QVERIFY(spy.isValid()); QModelIndex tl = model.index(selectTop, selectLeft); @@ -1914,12 +1914,9 @@ void tst_QItemSelectionModel::setCurrentIndex() treemodel->index(0, 0, treemodel->index(0, 0)), QItemSelectionModel::SelectCurrent); - QSignalSpy currentSpy(&selectionModel, - SIGNAL(currentChanged(QModelIndex,QModelIndex))); - QSignalSpy rowSpy(&selectionModel, - SIGNAL(currentRowChanged(QModelIndex,QModelIndex))); - QSignalSpy columnSpy(&selectionModel, - SIGNAL(currentColumnChanged(QModelIndex,QModelIndex))); + QSignalSpy currentSpy(&selectionModel, &QItemSelectionModel::currentChanged); + QSignalSpy rowSpy(&selectionModel, &QItemSelectionModel::currentRowChanged); + QSignalSpy columnSpy(&selectionModel, &QItemSelectionModel::currentColumnChanged); QVERIFY(currentSpy.isValid()); QVERIFY(rowSpy.isValid()); @@ -2223,7 +2220,7 @@ void tst_QItemSelectionModel::childrenDeselectionSignal() QItemSelectionModel selectionModel(&model); selectionModel.select(sel, QItemSelectionModel::SelectCurrent); - QSignalSpy deselectSpy(&selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection))); + QSignalSpy deselectSpy(&selectionModel, &QItemSelectionModel::selectionChanged); QVERIFY(deselectSpy.isValid()); model.removeRows(0, 1, root); QVERIFY(deselectSpy.count() == 1); @@ -2406,7 +2403,7 @@ void tst_QItemSelectionModel::deselectRemovedMiddleRange() RemovalObserver ro(&selModel); - QSignalSpy spy(&selModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection))); + QSignalSpy spy(&selModel, &QItemSelectionModel::selectionChanged); QVERIFY(spy.isValid()); bool ok = model.removeRows(4, 2); @@ -2738,7 +2735,7 @@ void tst_QItemSelectionModel::testClearCurrentIndex() QItemSelectionModel selectionModel(&model, 0); - QSignalSpy currentIndexSpy(&selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex))); + QSignalSpy currentIndexSpy(&selectionModel, &QItemSelectionModel::currentChanged); QVERIFY(currentIndexSpy.isValid()); QModelIndex firstIndex = model.index(0, 0); diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 0f72b419a0..471e5e6655 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -150,6 +150,8 @@ private slots: void chainedProxyModelRoleNames(); void noMapAfterSourceDelete(); + void forwardDropApi(); + protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); void checkHierarchy(const QStringList &data, const QAbstractItemModel *model); @@ -159,6 +161,8 @@ private: QSortFilterProxyModel *m_proxy; }; +Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint) + // Testing get/set functions void tst_QSortFilterProxyModel::getSetCheck() { @@ -177,6 +181,7 @@ void tst_QSortFilterProxyModel::getSetCheck() tst_QSortFilterProxyModel::tst_QSortFilterProxyModel() : m_model(0), m_proxy(0) { + qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>(); } void tst_QSortFilterProxyModel::initTestCase() @@ -1472,7 +1477,7 @@ void tst_QSortFilterProxyModel::filterCurrent() view.show(); view.setModel(&proxy); - QSignalSpy spy(view.selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex))); + QSignalSpy spy(view.selectionModel(), &QItemSelectionModel::currentChanged); QVERIFY(spy.isValid()); view.setCurrentIndex(proxy.index(0, 0)); @@ -1620,10 +1625,10 @@ void tst_QSortFilterProxyModel::removeSourceRows() proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder)); (void)proxy.rowCount(QModelIndex()); // force mapping - QSignalSpy removeSpy(&proxy, SIGNAL(rowsRemoved(QModelIndex,int,int))); - QSignalSpy insertSpy(&proxy, SIGNAL(rowsInserted(QModelIndex,int,int))); - QSignalSpy aboutToRemoveSpy(&proxy, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int))); - QSignalSpy aboutToInsertSpy(&proxy, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); + QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved); + QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted); + QSignalSpy aboutToRemoveSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeRemoved); + QSignalSpy aboutToInsertSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeInserted); QVERIFY(removeSpy.isValid()); QVERIFY(insertSpy.isValid()); @@ -1801,8 +1806,8 @@ void tst_QSortFilterProxyModel::changeFilter() proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder)); (void)proxy.rowCount(QModelIndex()); // force mapping - QSignalSpy initialRemoveSpy(&proxy, SIGNAL(rowsRemoved(QModelIndex,int,int))); - QSignalSpy initialInsertSpy(&proxy, SIGNAL(rowsInserted(QModelIndex,int,int))); + QSignalSpy initialRemoveSpy(&proxy, &QSortFilterProxyModel::rowsRemoved); + QSignalSpy initialInsertSpy(&proxy, &QSortFilterProxyModel::rowsInserted); QVERIFY(initialRemoveSpy.isValid()); QVERIFY(initialInsertSpy.isValid()); @@ -1825,8 +1830,8 @@ void tst_QSortFilterProxyModel::changeFilter() QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), initialProxyItems.at(i)); } - QSignalSpy finalRemoveSpy(&proxy, SIGNAL(rowsRemoved(QModelIndex,int,int))); - QSignalSpy finalInsertSpy(&proxy, SIGNAL(rowsInserted(QModelIndex,int,int))); + QSignalSpy finalRemoveSpy(&proxy, &QSortFilterProxyModel::rowsRemoved); + QSignalSpy finalInsertSpy(&proxy, &QSortFilterProxyModel::rowsInserted); QVERIFY(finalRemoveSpy.isValid()); QVERIFY(finalInsertSpy.isValid()); @@ -1976,8 +1981,8 @@ void tst_QSortFilterProxyModel::changeSourceData() proxy.setFilterRegExp(filter); - QSignalSpy removeSpy(&proxy, SIGNAL(rowsRemoved(QModelIndex,int,int))); - QSignalSpy insertSpy(&proxy, SIGNAL(rowsInserted(QModelIndex,int,int))); + QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved); + QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted); QVERIFY(removeSpy.isValid()); QVERIFY(insertSpy.isValid()); @@ -2075,7 +2080,7 @@ void tst_QSortFilterProxyModel::selectionFilteredOut() view.show(); view.setModel(&proxy); - QSignalSpy spy(view.selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex))); + QSignalSpy spy(view.selectionModel(), &QItemSelectionModel::currentChanged); QVERIFY(spy.isValid()); view.setCurrentIndex(proxy.index(0, 0)); @@ -2190,8 +2195,8 @@ void tst_QSortFilterProxyModel::insertIntoChildrenlessItem() QSortFilterProxyModel proxy; proxy.setSourceModel(&model); - QSignalSpy colsInsertedSpy(&proxy, SIGNAL(columnsInserted(QModelIndex,int,int))); - QSignalSpy rowsInsertedSpy(&proxy, SIGNAL(rowsInserted(QModelIndex,int,int))); + QSignalSpy colsInsertedSpy(&proxy, &QSortFilterProxyModel::columnsInserted); + QSignalSpy rowsInsertedSpy(&proxy, &QSortFilterProxyModel::rowsInserted); QVERIFY(colsInsertedSpy.isValid()); QVERIFY(rowsInsertedSpy.isValid()); @@ -2270,7 +2275,7 @@ void tst_QSortFilterProxyModel::insertRowIntoFilteredParent() EvenOddFilterModel proxy; proxy.setSourceModel(&model); - QSignalSpy spy(&proxy, SIGNAL(rowsInserted(QModelIndex,int,int))); + QSignalSpy spy(&proxy, &EvenOddFilterModel::rowsInserted); QVERIFY(spy.isValid()); QStandardItem *itemA = new QStandardItem(); @@ -2299,8 +2304,8 @@ void tst_QSortFilterProxyModel::filterOutParentAndFilterInChild() QStandardItem *itemC = new QStandardItem("C"); itemA->appendRow(itemC); // filtered - QSignalSpy removedSpy(&proxy, SIGNAL(rowsRemoved(QModelIndex,int,int))); - QSignalSpy insertedSpy(&proxy, SIGNAL(rowsInserted(QModelIndex,int,int))); + QSignalSpy removedSpy(&proxy, &QSortFilterProxyModel::rowsRemoved); + QSignalSpy insertedSpy(&proxy, &QSortFilterProxyModel::rowsInserted); QVERIFY(removedSpy.isValid()); QVERIFY(insertedSpy.isValid()); @@ -2903,8 +2908,8 @@ void tst_QSortFilterProxyModel::appearsAndSort() QCOMPARE(sourceModel.rowCount(), 3); QCOMPARE(proxyModel.rowCount(), 0); //all rows are hidden at first; - QSignalSpy spyAbout1(&proxyModel, SIGNAL(layoutAboutToBeChanged())); - QSignalSpy spyChanged1(&proxyModel, SIGNAL(layoutChanged())); + QSignalSpy spyAbout1(&proxyModel, &PModel::layoutAboutToBeChanged); + QSignalSpy spyChanged1(&proxyModel, &PModel::layoutChanged); QVERIFY(spyAbout1.isValid()); QVERIFY(spyChanged1.isValid()); @@ -2915,8 +2920,8 @@ void tst_QSortFilterProxyModel::appearsAndSort() secondProxyModel.setDynamicSortFilter(true); secondProxyModel.sort(0, Qt::DescendingOrder); QCOMPARE(secondProxyModel.rowCount(), 0); //all rows are hidden at first; - QSignalSpy spyAbout2(&secondProxyModel, SIGNAL(layoutAboutToBeChanged())); - QSignalSpy spyChanged2(&secondProxyModel, SIGNAL(layoutChanged())); + QSignalSpy spyAbout2(&secondProxyModel, &QSortFilterProxyModel::layoutAboutToBeChanged); + QSignalSpy spyChanged2(&secondProxyModel, &QSortFilterProxyModel::layoutChanged); QVERIFY(spyAbout2.isValid()); QVERIFY(spyChanged2.isValid()); @@ -3443,25 +3448,25 @@ void tst_QSortFilterProxyModel::testParentLayoutChanged() proxy2.setSourceModel(&proxy); proxy2.setObjectName("proxy2"); - QSignalSpy dataChangedSpy(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex))); + QSignalSpy dataChangedSpy(&model, &QSortFilterProxyModel::dataChanged); QVERIFY(dataChangedSpy.isValid()); // Verify that the no-arg signal is still emitted. - QSignalSpy layoutAboutToBeChangedSpy(&proxy, SIGNAL(layoutAboutToBeChanged())); - QSignalSpy layoutChangedSpy(&proxy, SIGNAL(layoutChanged())); + QSignalSpy layoutAboutToBeChangedSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged); + QSignalSpy layoutChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged); QVERIFY(layoutAboutToBeChangedSpy.isValid()); QVERIFY(layoutChangedSpy.isValid()); - QSignalSpy parentsAboutToBeChangedSpy(&proxy, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>))); - QSignalSpy parentsChangedSpy(&proxy, SIGNAL(layoutChanged(QList<QPersistentModelIndex>))); + QSignalSpy parentsAboutToBeChangedSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged); + QSignalSpy parentsChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged); QVERIFY(parentsAboutToBeChangedSpy.isValid()); QVERIFY(parentsChangedSpy.isValid()); - QSignalSpy proxy2ParentsAboutToBeChangedSpy(&proxy2, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>))); - QSignalSpy proxy2ParentsChangedSpy(&proxy2, SIGNAL(layoutChanged(QList<QPersistentModelIndex>))); + QSignalSpy proxy2ParentsAboutToBeChangedSpy(&proxy2, &QSortFilterProxyModel::layoutAboutToBeChanged); + QSignalSpy proxy2ParentsChangedSpy(&proxy2, &QSortFilterProxyModel::layoutChanged); QVERIFY(proxy2ParentsAboutToBeChangedSpy.isValid()); QVERIFY(proxy2ParentsChangedSpy.isValid()); @@ -3484,8 +3489,8 @@ void tst_QSortFilterProxyModel::testParentLayoutChanged() QVariantList beforeSignal = parentsAboutToBeChangedSpy.first(); QVariantList afterSignal = parentsChangedSpy.first(); - QCOMPARE(beforeSignal.size(), 1); - QCOMPARE(afterSignal.size(), 1); + QCOMPARE(beforeSignal.size(), 2); + QCOMPARE(afterSignal.size(), 2); QList<QPersistentModelIndex> beforeParents = beforeSignal.first().value<QList<QPersistentModelIndex> >(); QList<QPersistentModelIndex> afterParents = afterSignal.first().value<QList<QPersistentModelIndex> >(); @@ -3620,16 +3625,16 @@ void tst_QSortFilterProxyModel::moveSourceRows() filterBothProxy.setSourceModel(&proxy); filterBothProxy.setFilterRegExp("5"); // The parents are 6 and 3. This filters both out. - QSignalSpy modelBeforeSpy(&model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy modelAfterSpy(&model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy proxyBeforeMoveSpy(m_proxy, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy proxyAfterMoveSpy(m_proxy, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); - QSignalSpy proxyBeforeParentLayoutSpy(&proxy, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>))); - QSignalSpy proxyAfterParentLayoutSpy(&proxy, SIGNAL(layoutChanged(QList<QPersistentModelIndex>))); - QSignalSpy filterBeforeParentLayoutSpy(&filterProxy, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>))); - QSignalSpy filterAfterParentLayoutSpy(&filterProxy, SIGNAL(layoutChanged(QList<QPersistentModelIndex>))); - QSignalSpy filterBothBeforeParentLayoutSpy(&filterBothProxy, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>))); - QSignalSpy filterBothAfterParentLayoutSpy(&filterBothProxy, SIGNAL(layoutChanged(QList<QPersistentModelIndex>))); + QSignalSpy modelBeforeSpy(&model, &DynamicTreeModel::rowsAboutToBeMoved); + QSignalSpy modelAfterSpy(&model, &DynamicTreeModel::rowsMoved); + QSignalSpy proxyBeforeMoveSpy(m_proxy, &QSortFilterProxyModel::rowsAboutToBeMoved); + QSignalSpy proxyAfterMoveSpy(m_proxy, &QSortFilterProxyModel::rowsMoved); + QSignalSpy proxyBeforeParentLayoutSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged); + QSignalSpy proxyAfterParentLayoutSpy(&proxy, &QSortFilterProxyModel::layoutChanged); + QSignalSpy filterBeforeParentLayoutSpy(&filterProxy, &QSortFilterProxyModel::layoutAboutToBeChanged); + QSignalSpy filterAfterParentLayoutSpy(&filterProxy, &QSortFilterProxyModel::layoutChanged); + QSignalSpy filterBothBeforeParentLayoutSpy(&filterBothProxy, &QSortFilterProxyModel::layoutAboutToBeChanged); + QSignalSpy filterBothAfterParentLayoutSpy(&filterBothProxy, &QSortFilterProxyModel::layoutChanged); QVERIFY(modelBeforeSpy.isValid()); QVERIFY(modelAfterSpy.isValid()); @@ -3872,5 +3877,35 @@ void tst_QSortFilterProxyModel::noMapAfterSourceDelete() QVERIFY(!persistent.isValid()); } +// QTBUG-39549, test whether canDropMimeData(), dropMimeData() are proxied as well +// by invoking them on a QSortFilterProxyModel proxying a QStandardItemModel that allows drops +// on row #1, filtering for that row. +class DropTestModel : public QStandardItemModel { +public: + explicit DropTestModel(QObject *parent = 0) : QStandardItemModel(0, 1, parent) + { + appendRow(new QStandardItem(QStringLiteral("Row0"))); + appendRow(new QStandardItem(QStringLiteral("Row1"))); + } + + bool canDropMimeData(const QMimeData *, Qt::DropAction, + int row, int /* column */, const QModelIndex & /* parent */) const Q_DECL_OVERRIDE + { return row == 1; } + + bool dropMimeData(const QMimeData *, Qt::DropAction, + int row, int /* column */, const QModelIndex & /* parent */) Q_DECL_OVERRIDE + { return row == 1; } +}; + +void tst_QSortFilterProxyModel::forwardDropApi() +{ + QSortFilterProxyModel model; + model.setSourceModel(new DropTestModel(&model)); + model.setFilterFixedString(QStringLiteral("Row1")); + QCOMPARE(model.rowCount(), 1); + QVERIFY(model.canDropMimeData(0, Qt::CopyAction, 0, 0, QModelIndex())); + QVERIFY(model.dropMimeData(0, Qt::CopyAction, 0, 0, QModelIndex())); +} + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index a17fe7561a..761da2b0a3 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -132,6 +132,7 @@ private Q_SLOTS: void testTrailingComma(); void testDetachBug(); + void testJsonValueRefDefault(); void valueEquals(); @@ -139,6 +140,8 @@ private Q_SLOTS: void nesting(); void longStrings(); + + void arrayInitializerList(); private: QString testDataDir; }; @@ -2425,5 +2428,72 @@ void tst_QtJson::longStrings() } } +void tst_QtJson::testJsonValueRefDefault() +{ + QJsonObject empty; + + QCOMPARE(empty["n/a"].toString(), QString()); + QCOMPARE(empty["n/a"].toString("default"), QStringLiteral("default")); + + QCOMPARE(empty["n/a"].toBool(), false); + QCOMPARE(empty["n/a"].toBool(true), true); + + QCOMPARE(empty["n/a"].toInt(), 0); + QCOMPARE(empty["n/a"].toInt(42), 42); + + QCOMPARE(empty["n/a"].toDouble(), 0.0); + QCOMPARE(empty["n/a"].toDouble(42.0), 42.0); +} + +void tst_QtJson::arrayInitializerList() +{ +#ifndef Q_COMPILER_INITIALIZER_LISTS + QSKIP("initializer_list is enabled only with c++11 support"); +#else + QVERIFY(QJsonArray{}.isEmpty()); + QCOMPARE(QJsonArray{"one"}.count(), 1); + QCOMPARE(QJsonArray{1}.count(), 1); + + { + QJsonArray a{1.3, "hello", 0}; + QCOMPARE(QJsonValue(a[0]), QJsonValue(1.3)); + QCOMPARE(QJsonValue(a[1]), QJsonValue("hello")); + QCOMPARE(QJsonValue(a[2]), QJsonValue(0)); + QCOMPARE(a.count(), 3); + } + { + QJsonObject o; + o["property"] = 1; + QJsonArray a1 {o}; + QCOMPARE(a1.count(), 1); + QCOMPARE(a1[0].toObject(), o); + + QJsonArray a2 {o, 23}; + QCOMPARE(a2.count(), 2); + QCOMPARE(a2[0].toObject(), o); + QCOMPARE(QJsonValue(a2[1]), QJsonValue(23)); + + QJsonArray a3 { a1, o, a2 }; + QCOMPARE(QJsonValue(a3[0]), QJsonValue(a1)); + QCOMPARE(QJsonValue(a3[1]), QJsonValue(o)); + QCOMPARE(QJsonValue(a3[2]), QJsonValue(a2)); + + QJsonArray a4 { 1, QJsonArray{1,2,3}, QJsonArray{"hello", 2} }; + QCOMPARE(a4.count(), 3); + QCOMPARE(QJsonValue(a4[0]), QJsonValue(1)); + + { + QJsonArray a41 = a4[1].toArray(); + QJsonArray a42 = a4[2].toArray(); + QCOMPARE(a41.count(), 3); + QCOMPARE(a42.count(), 2); + + QCOMPARE(QJsonValue(a41[2]), QJsonValue(3)); + QCOMPARE(QJsonValue(a42[1]), QJsonValue(2)); + } + } +#endif +} + QTEST_MAIN(tst_QtJson) #include "tst_qtjson.moc" diff --git a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp index a7833aa835..ce9577e0ed 100644 --- a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp +++ b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp @@ -195,8 +195,8 @@ protected: void tst_QEventLoop::processEvents() { - QSignalSpy aboutToBlockSpy(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock())); - QSignalSpy awakeSpy(QAbstractEventDispatcher::instance(), SIGNAL(awake())); + QSignalSpy aboutToBlockSpy(QAbstractEventDispatcher::instance(), &QAbstractEventDispatcher::aboutToBlock); + QSignalSpy awakeSpy(QAbstractEventDispatcher::instance(), &QAbstractEventDispatcher::awake); QVERIFY(aboutToBlockSpy.isValid()); QVERIFY(awakeSpy.isValid()); @@ -282,7 +282,7 @@ void tst_QEventLoop::exec() thread.cond.wait(&thread.mutex); // make sure the eventloop runs - QSignalSpy spy(QAbstractEventDispatcher::instance(&thread), SIGNAL(awake())); + QSignalSpy spy(QAbstractEventDispatcher::instance(&thread), &QAbstractEventDispatcher::awake); QVERIFY(spy.isValid()); thread.cond.wakeOne(); thread.cond.wait(&thread.mutex); @@ -345,7 +345,7 @@ void tst_QEventLoop::wakeUp() thread.start(); (void) eventLoop.exec(); - QSignalSpy spy(QAbstractEventDispatcher::instance(&thread), SIGNAL(awake())); + QSignalSpy spy(QAbstractEventDispatcher::instance(&thread), &QAbstractEventDispatcher::awake); QVERIFY(spy.isValid()); thread.eventLoop->wakeUp(); @@ -633,7 +633,7 @@ void tst_QEventLoop::testQuitLock() QTimer timer; timer.setInterval(100); - QSignalSpy timerSpy(&timer, SIGNAL(timeout())); + QSignalSpy timerSpy(&timer, &QTimer::timeout); timer.start(); QEventLoopPrivate* privateClass = static_cast<QEventLoopPrivate*>(QObjectPrivate::get(&eventLoop)); diff --git a/tests/auto/corelib/kernel/qmath/tst_qmath.cpp b/tests/auto/corelib/kernel/qmath/tst_qmath.cpp index 24934ac138..8d6964cbcd 100644 --- a/tests/auto/corelib/kernel/qmath/tst_qmath.cpp +++ b/tests/auto/corelib/kernel/qmath/tst_qmath.cpp @@ -54,6 +54,14 @@ private slots: void degreesToRadians(); void radiansToDegrees_data(); void radiansToDegrees(); + void qNextPowerOfTwo32S_data(); + void qNextPowerOfTwo32S(); + void qNextPowerOfTwo64S_data(); + void qNextPowerOfTwo64S(); + void qNextPowerOfTwo32U_data(); + void qNextPowerOfTwo32U(); + void qNextPowerOfTwo64U_data(); + void qNextPowerOfTwo64U(); }; void tst_QMath::fastSinCos() @@ -137,6 +145,117 @@ void tst_QMath::radiansToDegrees() QCOMPARE(qRadiansToDegrees(radiansDouble), degreesDouble); } + +void tst_QMath::qNextPowerOfTwo32S_data() +{ + QTest::addColumn<qint32>("input"); + QTest::addColumn<quint32>("output"); + + QTest::newRow("0") << 0 << 1U; + QTest::newRow("1") << 1 << 2U; + QTest::newRow("2") << 2 << 4U; + QTest::newRow("17") << 17 << 32U; + QTest::newRow("128") << 128 << 256U; + QTest::newRow("65535") << 65535 << 65536U; + QTest::newRow("65536") << 65536 << 131072U; + QTest::newRow("2^30") << (1 << 30) << (1U << 31); + QTest::newRow("2^30 + 1") << (1 << 30) + 1 << (1U << 31); + QTest::newRow("2^31 - 1") << 0x7FFFFFFF << (1U<<31); + QTest::newRow("-1") << -1 << 0U; + QTest::newRow("-128") << -128 << 0U; + QTest::newRow("-(2^31)") << int(0x80000000) << 0U; +} + +void tst_QMath::qNextPowerOfTwo32S() +{ + QFETCH(qint32, input); + QFETCH(quint32, output); + + QCOMPARE(qNextPowerOfTwo(input), output); +} + +void tst_QMath::qNextPowerOfTwo32U_data() +{ + QTest::addColumn<quint32>("input"); + QTest::addColumn<quint32>("output"); + + QTest::newRow("0") << 0U << 1U; + QTest::newRow("1") << 1U << 2U; + QTest::newRow("2") << 2U << 4U; + QTest::newRow("17") << 17U << 32U; + QTest::newRow("128") << 128U << 256U; + QTest::newRow("65535") << 65535U << 65536U; + QTest::newRow("65536") << 65536U << 131072U; + QTest::newRow("2^30") << (1U << 30) << (1U << 31); + QTest::newRow("2^30 + 1") << (1U << 30) + 1 << (1U << 31); + QTest::newRow("2^31 - 1") << 2147483647U << 2147483648U; + QTest::newRow("2^31") << 2147483648U << 0U; + QTest::newRow("2^31 + 1") << 2147483649U << 0U; +} + +void tst_QMath::qNextPowerOfTwo32U() +{ + QFETCH(quint32, input); + QFETCH(quint32, output); + + QCOMPARE(qNextPowerOfTwo(input), output); +} + +void tst_QMath::qNextPowerOfTwo64S_data() +{ + QTest::addColumn<qint64>("input"); + QTest::addColumn<quint64>("output"); + + QTest::newRow("0") << Q_INT64_C(0) << Q_UINT64_C(1); + QTest::newRow("1") << Q_INT64_C(1) << Q_UINT64_C(2); + QTest::newRow("2") << Q_INT64_C(2) << Q_UINT64_C(4); + QTest::newRow("17") << Q_INT64_C(17) << Q_UINT64_C(32); + QTest::newRow("128") << Q_INT64_C(128) << Q_UINT64_C(256); + QTest::newRow("65535") << Q_INT64_C(65535) << Q_UINT64_C(65536); + QTest::newRow("65536") << Q_INT64_C(65536) << Q_UINT64_C(131072); + QTest::newRow("2^31 - 1") << Q_INT64_C(2147483647) << Q_UINT64_C(0x80000000); + QTest::newRow("2^31") << Q_INT64_C(2147483648) << Q_UINT64_C(0x100000000); + QTest::newRow("2^31 + 1") << Q_INT64_C(2147483649) << Q_UINT64_C(0x100000000); + QTest::newRow("2^63 - 1") << Q_INT64_C(0x7FFFFFFFFFFFFFFF) << Q_UINT64_C(0x8000000000000000); + QTest::newRow("-1") << Q_INT64_C(-1) << Q_UINT64_C(0); + QTest::newRow("-128") << Q_INT64_C(-128) << Q_UINT64_C(0); + QTest::newRow("-(2^31)") << -Q_INT64_C(0x80000000) << Q_UINT64_C(0); + QTest::newRow("-(2^63)") << (qint64)Q_INT64_C(0x8000000000000000) << Q_UINT64_C(0); +} + +void tst_QMath::qNextPowerOfTwo64S() +{ + QFETCH(qint64, input); + QFETCH(quint64, output); + + QCOMPARE(qNextPowerOfTwo(input), output); +} + +void tst_QMath::qNextPowerOfTwo64U_data() +{ + QTest::addColumn<quint64>("input"); + QTest::addColumn<quint64>("output"); + + QTest::newRow("0") << Q_UINT64_C(0) << Q_UINT64_C(1); + QTest::newRow("1") << Q_UINT64_C(1) << Q_UINT64_C(2); + QTest::newRow("2") << Q_UINT64_C(2) << Q_UINT64_C(4); + QTest::newRow("17") << Q_UINT64_C(17) << Q_UINT64_C(32); + QTest::newRow("128") << Q_UINT64_C(128) << Q_UINT64_C(256); + QTest::newRow("65535") << Q_UINT64_C(65535) << Q_UINT64_C(65536); + QTest::newRow("65536") << Q_UINT64_C(65536) << Q_UINT64_C(131072); + QTest::newRow("2^63 - 1") << Q_UINT64_C(0x7FFFFFFFFFFFFFFF) << Q_UINT64_C(0x8000000000000000); + QTest::newRow("2^63") << Q_UINT64_C(0x8000000000000000) << Q_UINT64_C(0); + QTest::newRow("2^63 + 1") << Q_UINT64_C(0x8000000000000001) << Q_UINT64_C(0); +} + +void tst_QMath::qNextPowerOfTwo64U() +{ + QFETCH(quint64, input); + QFETCH(quint64, output); + + QCOMPARE(qNextPowerOfTwo(input), output); +} + QTEST_APPLESS_MAIN(tst_QMath) #include "tst_qmath.moc" diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index 3afc2bc574..a920ea7a01 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -561,9 +561,11 @@ void tst_QMetaObject::invokeMetaMember() QVERIFY(!QMetaObject::invokeMethod(&obj, "doesNotExist")); QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString)(QString)"); QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1(QString)", Q_ARG(QString, "arg"))); - QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl3(QString)"); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl3(QString)\n" + "Candidates are:\n sl3(QString,QString,QString)"); QVERIFY(!QMetaObject::invokeMethod(&obj, "sl3", Q_ARG(QString, "arg"))); - QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,QString)"); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,QString)\n" + "Candidates are:\n sl1(QString)"); QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1", Q_ARG(QString, "arg"), Q_ARG(QString, "arg"), Q_ARG(QString, "arg"))); //should not have changed since last test. @@ -747,9 +749,11 @@ void tst_QMetaObject::invokeBlockingQueuedMetaMember() QVERIFY(!QMetaObject::invokeMethod(&obj, "doesNotExist", Qt::BlockingQueuedConnection)); QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString)(QString)"); QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1(QString)", Qt::BlockingQueuedConnection, Q_ARG(QString, "arg"))); - QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl3(QString)"); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl3(QString)\n" + "Candidates are:\n sl3(QString,QString,QString)"); QVERIFY(!QMetaObject::invokeMethod(&obj, "sl3", Qt::BlockingQueuedConnection, Q_ARG(QString, "arg"))); - QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,QString)"); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,QString)\n" + "Candidates are:\n sl1(QString)"); QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1", Qt::BlockingQueuedConnection, Q_ARG(QString, "arg"), Q_ARG(QString, "arg"), Q_ARG(QString, "arg"))); //should not have changed since last test. @@ -857,7 +861,7 @@ void tst_QMetaObject::invokeTypedefTypes() { qRegisterMetaType<CustomString>("CustomString"); QtTestCustomObject obj; - QSignalSpy spy(&obj, SIGNAL(sig_custom(CustomString))); + QSignalSpy spy(&obj, &QtTestCustomObject::sig_custom); QVERIFY(spy.isValid()); QCOMPARE(spy.count(), 0); diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 0e7005799e..62e41a96c5 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -1593,7 +1593,7 @@ void tst_QMetaObjectBuilder::usage_signal() { QScopedPointer<TestObject> testObject(new TestObject); - QSignalSpy propChangedSpy(testObject.data(), SIGNAL(intPropChanged(int))); + QSignalSpy propChangedSpy(testObject.data(), &TestObject::intPropChanged); testObject->emitIntPropChanged(); QCOMPARE(propChangedSpy.count(), 1); QCOMPARE(propChangedSpy.at(0).count(), 1); @@ -1608,7 +1608,7 @@ void tst_QMetaObjectBuilder::usage_property() QCOMPARE(prop.type(), QVariant::Int); QCOMPARE(prop.toInt(), testObject->intProp()); - QSignalSpy propChangedSpy(testObject.data(), SIGNAL(intPropChanged(int))); + QSignalSpy propChangedSpy(testObject.data(), &TestObject::intPropChanged); QVERIFY(testObject->intProp() != 123); testObject->setProperty("intProp", 123); QCOMPARE(propChangedSpy.count(), 1); diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 959c79ed60..9a86dc03e5 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -1341,6 +1341,8 @@ static QByteArray createTypeName(const char *begin, const char *va) } #endif +Q_DECLARE_METATYPE(const void*) + void tst_QMetaType::automaticTemplateRegistration() { #define TEST_SEQUENTIAL_CONTAINER(CONTAINER, VALUE_TYPE) \ @@ -1358,6 +1360,17 @@ void tst_QMetaType::automaticTemplateRegistration() TEST_SEQUENTIAL_CONTAINER(std::list, int) { + std::vector<bool> vecbool; + vecbool.push_back(true); + vecbool.push_back(false); + vecbool.push_back(true); + QVERIFY(QVariant::fromValue(vecbool).value<std::vector<bool> >().front() == true); + QVector<std::vector<bool> > vectorList; + vectorList << vecbool; + QVERIFY(QVariant::fromValue(vectorList).value<QVector<std::vector<bool> > >().first().front() == true); + } + + { QList<QByteArray> bytearrayList; bytearrayList << QByteArray("foo"); QVERIFY(QVariant::fromValue(bytearrayList).value<QList<QByteArray> >().first() == QByteArray("foo")); @@ -1577,6 +1590,12 @@ void tst_QMetaType::automaticTemplateRegistration() ) CREATE_AND_VERIFY_CONTAINER(QList, QList<QMap<int, QHash<char, QVariantList> > >) + CREATE_AND_VERIFY_CONTAINER(QVector, void*) + CREATE_AND_VERIFY_CONTAINER(QVector, const void*) + CREATE_AND_VERIFY_CONTAINER(QList, void*) + CREATE_AND_VERIFY_CONTAINER(QPair, void*, void*) + CREATE_AND_VERIFY_CONTAINER(QHash, void*, void*) + CREATE_AND_VERIFY_CONTAINER(QHash, const void*, const void*) #endif // Q_COMPILER_VARIADIC_MACROS diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 1c0a495116..0308e870be 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -270,6 +270,21 @@ public slots: int ReceiverObject::sequence = 0; +static void playWithObjects() +{ + // Do operations that will lock the internal signalSlotLock mutex on many QObjects. + // The more QObjects, the higher the chance that the signalSlotLock mutex used + // is already in use. If the number of objects is higher than the number of mutexes in + // the pool (currently 131), the deadlock should always trigger. Use an even higher number + // to be on the safe side. + const int objectCount = 1024; + SenderObject lotsOfObjects[objectCount]; + for (int i = 0; i < objectCount; ++i) { + QObject::connect(&lotsOfObjects[i], &SenderObject::signal1, + &lotsOfObjects[i], &SenderObject::aPublicSlot); + } +} + void tst_QObject::initTestCase() { const QString testDataDir = QFileInfo(QFINDTESTDATA("signalbug")).absolutePath(); @@ -1368,10 +1383,10 @@ struct CheckInstanceCount struct CustomType { CustomType(int l1 = 0, int l2 = 0, int l3 = 0): i1(l1), i2(l2), i3(l3) - { ++instanceCount; } + { ++instanceCount; playWithObjects(); } CustomType(const CustomType &other): i1(other.i1), i2(other.i2), i3(other.i3) - { ++instanceCount; } - ~CustomType() { --instanceCount; } + { ++instanceCount; playWithObjects(); } + ~CustomType() { --instanceCount; playWithObjects(); } int i1, i2, i3; int value() { return i1 + i2 + i3; } @@ -5749,17 +5764,7 @@ public: {} ~MyFunctor() { - // Do operations that will lock the internal signalSlotLock mutex on many QObjects. - // The more QObjects, the higher the chance that the signalSlotLock mutex used - // is already in use. If the number of objects is higher than the number of mutexes in - // the pool (currently 131), the deadlock should always trigger. Use an even higher number - // to be on the safe side. - const int objectCount = 1024; - SenderObject lotsOfObjects[objectCount]; - for (int i = 0; i < objectCount; ++i) { - QObject::connect(&lotsOfObjects[i], &SenderObject::signal1, - &lotsOfObjects[i], &SenderObject::aPublicSlot); - } + playWithObjects(); } void operator()() { diff --git a/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp b/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp index ce5e83288f..82f0a846bc 100644 --- a/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp +++ b/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -114,7 +114,7 @@ private slots: void uniqueKey(); protected: - QString helperBinary(); + static QString helperBinary(); int remove(const QString &key); QString rememberKey(const QString &key) @@ -131,10 +131,14 @@ protected: QStringList keys; QList<QSharedMemory*> jail; QSharedMemory *existingSharedMemory; + +private: + const QString m_helperBinary; }; -tst_QSharedMemory::tst_QSharedMemory() : - existingSharedMemory(0) +tst_QSharedMemory::tst_QSharedMemory() + : existingSharedMemory(0) + , m_helperBinary(tst_QSharedMemory::helperBinary()) { } @@ -144,7 +148,7 @@ tst_QSharedMemory::~tst_QSharedMemory() void tst_QSharedMemory::initTestCase() { - QVERIFY2(!helperBinary().isEmpty(), "Could not find helper binary"); + QVERIFY2(!m_helperBinary.isEmpty(), "Could not find helper binary"); } void tst_QSharedMemory::init() @@ -455,7 +459,7 @@ void tst_QSharedMemory::readOnly() rememberKey("readonly_segfault"); // ### on windows disable the popup somehow QProcess p; - p.start(helperBinary(), QStringList("readonly_segfault")); + p.start(m_helperBinary, QStringList("readonly_segfault")); p.setProcessChannelMode(QProcess::ForwardedChannels); p.waitForFinished(); QCOMPARE(p.error(), QProcess::Crashed); @@ -753,7 +757,7 @@ void tst_QSharedMemory::simpleProcessProducerConsumer() rememberKey("market"); QProcess producer; - producer.start(helperBinary(), QStringList("producer")); + producer.start(m_helperBinary, QStringList("producer")); QVERIFY2(producer.waitForStarted(), "Could not start helper binary"); QVERIFY2(producer.waitForReadyRead(), "Helper process failed to create shared memory segment: " + producer.readAllStandardError()); @@ -764,7 +768,7 @@ void tst_QSharedMemory::simpleProcessProducerConsumer() for (int i = 0; i < processes; ++i) { QProcess *p = new QProcess; p->setProcessChannelMode(QProcess::ForwardedChannels); - p->start(helperBinary(), consumerArguments); + p->start(m_helperBinary, consumerArguments); if (p->waitForStarted(2000)) consumers.append(p); else diff --git a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp index 5632bcacc4..c650041e1e 100644 --- a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp +++ b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp @@ -267,12 +267,12 @@ void tst_QSocketNotifier::posixSockets() { QSocketNotifier rn(posixSocket, QSocketNotifier::Read); connect(&rn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); - QSignalSpy readSpy(&rn, SIGNAL(activated(int))); + QSignalSpy readSpy(&rn, &QSocketNotifier::activated); QVERIFY(readSpy.isValid()); // No write notifier, some systems trigger write notification on socket creation, but not all QSocketNotifier en(posixSocket, QSocketNotifier::Exception); connect(&en, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); - QSignalSpy errorSpy(&en, SIGNAL(activated(int))); + QSignalSpy errorSpy(&en, &QSocketNotifier::activated); QVERIFY(errorSpy.isValid()); passive->write("hello",6); @@ -289,7 +289,7 @@ void tst_QSocketNotifier::posixSockets() QSocketNotifier wn(posixSocket, QSocketNotifier::Write); connect(&wn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); - QSignalSpy writeSpy(&wn, SIGNAL(activated(int))); + QSignalSpy writeSpy(&wn, &QSocketNotifier::activated); QVERIFY(writeSpy.isValid()); qt_safe_write(posixSocket, "goodbye", 8); diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp b/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp index 9e33f56a34..42f2709384 100644 --- a/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp +++ b/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -80,17 +80,20 @@ private slots: #endif // QT_NO_PROCESS private: - QString helperBinary(); + static QString helperBinary(); QSystemSemaphore *existingLock; + + const QString m_helperBinary; }; tst_QSystemSemaphore::tst_QSystemSemaphore() + : m_helperBinary(helperBinary()) { } void tst_QSystemSemaphore::initTestCase() { - QVERIFY2(!helperBinary().isEmpty(), "Could not find helper binary"); + QVERIFY2(!m_helperBinary.isEmpty(), "Could not find helper binary"); } void tst_QSystemSemaphore::init() @@ -193,12 +196,12 @@ void tst_QSystemSemaphore::basicProcesses() QProcess release; release.setProcessChannelMode(QProcess::ForwardedChannels); - acquire.start(helperBinary(), QStringList("acquire")); + acquire.start(m_helperBinary, QStringList("acquire")); QVERIFY2(acquire.waitForStarted(), "Could not start helper binary"); acquire.waitForFinished(HELPERWAITTIME); QVERIFY(acquire.state() == QProcess::Running); acquire.kill(); - release.start(helperBinary(), QStringList("release")); + release.start(m_helperBinary, QStringList("release")); QVERIFY2(release.waitForStarted(), "Could not start helper binary"); acquire.waitForFinished(HELPERWAITTIME); release.waitForFinished(HELPERWAITTIME); @@ -227,7 +230,7 @@ void tst_QSystemSemaphore::processes() QProcess *p = new QProcess; p->setProcessChannelMode(QProcess::ForwardedChannels); consumers.append(p); - p->start(helperBinary(), QStringList(scripts.at(i))); + p->start(m_helperBinary, QStringList(scripts.at(i))); } while (!consumers.isEmpty()) { @@ -247,14 +250,14 @@ void tst_QSystemSemaphore::undo() QStringList acquireArguments = QStringList("acquire"); QProcess acquire; acquire.setProcessChannelMode(QProcess::ForwardedChannels); - acquire.start(helperBinary(), acquireArguments); + acquire.start(m_helperBinary, acquireArguments); QVERIFY2(acquire.waitForStarted(), "Could not start helper binary"); acquire.waitForFinished(HELPERWAITTIME); QVERIFY(acquire.state()== QProcess::NotRunning); // At process exit the kernel should auto undo - acquire.start(helperBinary(), acquireArguments); + acquire.start(m_helperBinary, acquireArguments); QVERIFY2(acquire.waitForStarted(), "Could not start helper binary"); acquire.waitForFinished(HELPERWAITTIME); QVERIFY(acquire.state()== QProcess::NotRunning); @@ -273,18 +276,18 @@ void tst_QSystemSemaphore::initialValue() QProcess release; release.setProcessChannelMode(QProcess::ForwardedChannels); - acquire.start(helperBinary(), acquireArguments); + acquire.start(m_helperBinary, acquireArguments); QVERIFY2(acquire.waitForStarted(), "Could not start helper binary"); acquire.waitForFinished(HELPERWAITTIME); QVERIFY(acquire.state()== QProcess::NotRunning); - acquire.start(helperBinary(), acquireArguments << QLatin1String("2")); + acquire.start(m_helperBinary, acquireArguments << QLatin1String("2")); QVERIFY2(acquire.waitForStarted(), "Could not start helper binary"); acquire.waitForFinished(HELPERWAITTIME); QVERIFY(acquire.state()== QProcess::Running); acquire.kill(); - release.start(helperBinary(), releaseArguments); + release.start(m_helperBinary, releaseArguments); QVERIFY2(release.waitForStarted(), "Could not start helper binary"); acquire.waitForFinished(HELPERWAITTIME); release.waitForFinished(HELPERWAITTIME); diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp index 27ea3faf81..31c627afcb 100644 --- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp +++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp @@ -77,6 +77,7 @@ private slots: void cancelLongTimer(); void singleShotStaticFunctionZeroTimeout(); void recurseOnTimeoutAndStopTimer(); + void singleShotToFunctors(); void dontBlockEvents(); void postedEventsShouldNotStarveTimers(); @@ -586,6 +587,14 @@ void tst_QTimer::singleShotStaticFunctionZeroTimeout() QCOMPARE(helper.count, 1); QTest::qWait(500); QCOMPARE(helper.count, 1); + + TimerHelper nhelper; + + QTimer::singleShot(0, &nhelper, &TimerHelper::timeout); + QCoreApplication::processEvents(); + QCOMPARE(nhelper.count, 1); + QCoreApplication::processEvents(); + QCOMPARE(nhelper.count, 1); } class RecursOnTimeoutAndStopTimerTimer : public QObject @@ -631,6 +640,96 @@ void tst_QTimer::recurseOnTimeoutAndStopTimer() QVERIFY(!t.two->isActive()); } +struct CountedStruct +{ + CountedStruct(int *count, QThread *t = Q_NULLPTR) : count(count), thread(t) { } + ~CountedStruct() { } + void operator()() const { ++(*count); if (thread) QCOMPARE(QThread::currentThread(), thread); } + + int *count; + QThread *thread; +}; + +static QEventLoop _e; +static QThread *_t = Q_NULLPTR; + +class StaticEventLoop +{ +public: + static void quitEventLoop() { _e.quit(); if (_t) QCOMPARE(QThread::currentThread(), _t); } +}; + +void tst_QTimer::singleShotToFunctors() +{ + int count = 0; + QEventLoop e; + + QTimer::singleShot(0, CountedStruct(&count)); + QCoreApplication::processEvents(); + QCOMPARE(count, 1); + + QTimer::singleShot(0, &StaticEventLoop::quitEventLoop); + QCOMPARE(_e.exec(), 0); + + QThread t1; + QObject c1; + c1.moveToThread(&t1); + + QObject::connect(&t1, SIGNAL(started()), &e, SLOT(quit())); + t1.start(); + QCOMPARE(e.exec(), 0); + + QTimer::singleShot(0, &c1, CountedStruct(&count, &t1)); + QTest::qWait(500); + QCOMPARE(count, 2); + + t1.quit(); + t1.wait(); + + _t = new QThread; + QObject c2; + c2.moveToThread(_t); + + QObject::connect(_t, SIGNAL(started()), &e, SLOT(quit())); + _t->start(); + QCOMPARE(e.exec(), 0); + + QTimer::singleShot(0, &c2, &StaticEventLoop::quitEventLoop); + QCOMPARE(_e.exec(), 0); + + _t->quit(); + _t->wait(); + _t->deleteLater(); + _t = Q_NULLPTR; + + { + QObject c3; + QTimer::singleShot(500, &c3, CountedStruct(&count)); + } + QTest::qWait(800); + QCOMPARE(count, 2); + +#if defined(Q_COMPILER_LAMBDA) + QTimer::singleShot(0, [&count] { ++count; }); + QCoreApplication::processEvents(); + QCOMPARE(count, 3); + + QObject context; + QThread thread; + + context.moveToThread(&thread); + QObject::connect(&thread, SIGNAL(started()), &e, SLOT(quit())); + thread.start(); + QCOMPARE(e.exec(), 0); + + QTimer::singleShot(0, &context, [&count, &thread] { ++count; QCOMPARE(QThread::currentThread(), &thread); }); + QTest::qWait(500); + QCOMPARE(count, 4); + + thread.quit(); + thread.wait(); +#endif +} class DontBlockEvents : public QObject diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index aef79e0c2f..660d0f804e 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -318,18 +318,16 @@ void tst_QVariant::constructor_invalid() QFETCH(uint, typeId); { - MessageHandlerInvalidType msg; + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type, type id:")); QVariant variant(static_cast<QVariant::Type>(typeId)); QVERIFY(!variant.isValid()); QVERIFY(variant.userType() == QMetaType::UnknownType); - QVERIFY(msg.ok); } { - MessageHandlerInvalidType msg; + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type, type id:")); QVariant variant(typeId, /* copy */ 0); QVERIFY(!variant.isValid()); QVERIFY(variant.userType() == QMetaType::UnknownType); - QVERIFY(msg.ok); } } diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp index 351e3a23e0..4447eb7a0b 100644 --- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp @@ -264,8 +264,8 @@ void tst_QPluginLoader::deleteinstanceOnUnload() PluginInterface *instance2 = qobject_cast<PluginInterface*>(loader2.instance()); QCOMPARE(instance2->pluginName(), QLatin1String("Plugin ok")); - QSignalSpy spy1(loader1.instance(), SIGNAL(destroyed())); - QSignalSpy spy2(loader2.instance(), SIGNAL(destroyed())); + QSignalSpy spy1(loader1.instance(), &QObject::destroyed); + QSignalSpy spy2(loader2.instance(), &QObject::destroyed); QVERIFY(spy1.isValid()); QVERIFY(spy2.isValid()); if (pass == 0) { @@ -423,7 +423,7 @@ void tst_QPluginLoader::reloadPlugin() QVERIFY(instance); QCOMPARE(instance->pluginName(), QLatin1String("Plugin ok")); - QSignalSpy spy(loader.instance(), SIGNAL(destroyed())); + QSignalSpy spy(loader.instance(), &QObject::destroyed); QVERIFY(spy.isValid()); QVERIFY(loader.unload()); // refcount reached 0, did really unload QCOMPARE(spy.count(), 1); diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp index 2d7beaa7c8..e8d4fe51a8 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp @@ -71,6 +71,27 @@ static int globalTick; QCoreApplication::exec(); \ } +#define TEST_RUNNING_CHANGED(RUNNING) \ +{ \ + QTRY_COMPARE(runningSpy.count(), 1); \ + QList<QVariant> runningArgs = runningSpy.takeFirst(); \ + QVERIFY(runningArgs.at(0).type() == QVariant::Bool); \ + QVERIFY(runningArgs.at(0).toBool() == RUNNING); \ + QCOMPARE(machine.isRunning(), runningArgs.at(0).toBool()); \ +} + +#define TEST_RUNNING_CHANGED_STARTED_STOPPED \ +{ \ + QTRY_COMPARE(runningSpy.count(), 2); \ + QList<QVariant> runningArgs = runningSpy.takeFirst(); \ + QVERIFY(runningArgs.at(0).type() == QVariant::Bool); \ + QVERIFY(runningArgs.at(0).toBool() == true); \ + runningArgs = runningSpy.takeFirst(); \ + QVERIFY(runningArgs.at(0).type() == QVariant::Bool); \ + QVERIFY(runningArgs.at(0).toBool() == false); \ + QCOMPARE(machine.isRunning(), runningArgs.at(0).toBool()); \ +} + class SignalEmitter : public QObject { Q_OBJECT @@ -120,6 +141,7 @@ private slots: #endif void historyStates(); void startAndStop(); + void setRunning(); void targetStateWithNoParent(); void targetStateDeleted(); void transitionToRootState(); @@ -916,10 +938,13 @@ void tst_QStateMachine::historyStateAfterRestart() s2->addTransition(new EventTransition(QEvent::User, s1)); for (int x = 0; x < 2; ++x) { - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s1)); @@ -952,10 +977,11 @@ void tst_QStateMachine::historyStateAfterRestart() QVERIFY(machine.configuration().contains(s2)); QVERIFY(machine.configuration().contains(s22)); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); QVERIFY(stoppedSpy.isValid()); machine.stop(); QTRY_COMPARE(stoppedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } } @@ -1232,13 +1258,15 @@ void tst_QStateMachine::stateEntryAndExit() QCOMPARE(trans->sourceState(), (QState*)s2); } - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(stoppedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.setInitialState(s1); QCOMPARE(machine.initialState(), (QAbstractState*)s1); @@ -1252,11 +1280,11 @@ void tst_QStateMachine::stateEntryAndExit() QVERIFY(machine.configuration().isEmpty()); globalTick = 0; QVERIFY(!machine.isRunning()); - QSignalSpy s1EnteredSpy(s1, SIGNAL(entered())); - QSignalSpy s1ExitedSpy(s1, SIGNAL(exited())); - QSignalSpy tTriggeredSpy(t, SIGNAL(triggered())); - QSignalSpy s2EnteredSpy(s2, SIGNAL(entered())); - QSignalSpy s2ExitedSpy(s2, SIGNAL(exited())); + QSignalSpy s1EnteredSpy(s1, &TestState::entered); + QSignalSpy s1ExitedSpy(s1, &TestState::exited); + QSignalSpy tTriggeredSpy(t, &TestTransition::triggered); + QSignalSpy s2EnteredSpy(s2, &TestState::entered); + QSignalSpy s2ExitedSpy(s2, &TestState::exited); QVERIFY(s1EnteredSpy.isValid()); QVERIFY(s1ExitedSpy.isValid()); @@ -1269,6 +1297,7 @@ void tst_QStateMachine::stateEntryAndExit() QTRY_COMPARE(startedSpy.count(), 1); QTRY_COMPARE(finishedSpy.count(), 1); QTRY_COMPARE(stoppedSpy.count(), 0); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s3)); @@ -1312,16 +1341,19 @@ void tst_QStateMachine::stateEntryAndExit() s12->addTransition(t2); s2->addTransition(s3); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.setInitialState(s1); globalTick = 0; machine.start(); QTRY_COMPARE(startedSpy.count(), 1); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s3)); @@ -1388,7 +1420,7 @@ void tst_QStateMachine::assignProperty() QCOMPARE(s1->objectName(), QString::fromLatin1("foo")); { - QSignalSpy propertiesAssignedSpy(s1, SIGNAL(propertiesAssigned())); + QSignalSpy propertiesAssignedSpy(s1, &QState::propertiesAssigned); QVERIFY(propertiesAssignedSpy.isValid()); machine.start(); QTRY_COMPARE(propertiesAssignedSpy.count(), 1); @@ -1444,10 +1476,13 @@ void tst_QStateMachine::assignPropertyWithAnimation() s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(obj.property("foo").toInt(), 456); QCOMPARE(obj.property("bar").toInt(), 789); } @@ -1473,10 +1508,13 @@ void tst_QStateMachine::assignPropertyWithAnimation() s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(obj.property("foo").toInt(), 456); QCOMPARE(obj.property("bar").toInt(), 789); } @@ -1502,10 +1540,13 @@ void tst_QStateMachine::assignPropertyWithAnimation() s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(obj.property("foo").toInt(), 456); QCOMPARE(obj.property("bar").toInt(), 654); QCOMPARE(obj.property("baz").toInt(), 789); @@ -1552,10 +1593,13 @@ void tst_QStateMachine::assignPropertyWithAnimation() s22->addTransition(s2, SIGNAL(propertiesAssigned()), s3); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(obj.property("foo").toInt(), 321); QCOMPARE(obj.property("bar").toInt(), 789); } @@ -1587,7 +1631,7 @@ void tst_QStateMachine::assignPropertyWithAnimation() machine.setInitialState(group); machine.start(); QTRY_COMPARE(machine.configuration().contains(s1), true); - QSignalSpy propertiesAssignedSpy(s2, SIGNAL(propertiesAssigned())); + QSignalSpy propertiesAssignedSpy(s2, &QState::propertiesAssigned); QVERIFY(propertiesAssignedSpy.isValid()); emitter.emitSignalWithNoArg(); QTRY_COMPARE(machine.configuration().contains(s2), true); @@ -1675,10 +1719,13 @@ void tst_QStateMachine::postEvent() machine.addState(s1); machine.addState(s2); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); @@ -1705,10 +1752,13 @@ void tst_QStateMachine::cancelDelayedEvent() s1->addTransition(new StringTransition("a", s2)); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); @@ -1725,9 +1775,10 @@ void tst_QStateMachine::cancelDelayedEvent() QVERIFY(machine.cancelDelayedEvent(id2)); QVERIFY(!machine.cancelDelayedEvent(id2)); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); } @@ -1740,24 +1791,29 @@ void tst_QStateMachine::postDelayedEventAndStop() s1->addTransition(new StringTransition("a", s2)); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); int id1 = machine.postDelayedEvent(new StringEvent("a"), 0); QVERIFY(id1 != -1); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); QVERIFY(stoppedSpy.isValid()); machine.stop(); QTRY_COMPARE(stoppedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); machine.start(); QTRY_COMPARE(startedSpy.count(), 2); + TEST_RUNNING_CHANGED(true); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); @@ -1765,8 +1821,10 @@ void tst_QStateMachine::postDelayedEventAndStop() QVERIFY(id2 != -1); machine.stop(); QTRY_COMPARE(stoppedSpy.count(), 2); + TEST_RUNNING_CHANGED(false); machine.start(); QTRY_COMPARE(startedSpy.count(), 3); + TEST_RUNNING_CHANGED(true); QTestEventLoop::instance().enterLoop(2); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); @@ -1813,11 +1871,13 @@ void tst_QStateMachine::postDelayedEventFromThread() DelayedEventPosterThread poster(&machine); poster.start(); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); - + TEST_RUNNING_CHANGED_STARTED_STOPPED; QVERIFY(poster.firstEventWasCancelled); } @@ -1826,16 +1886,20 @@ void tst_QStateMachine::stopAndPostEvent() QStateMachine machine; QState *s1 = new QState(&machine); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); + TEST_RUNNING_CHANGED(true); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); QVERIFY(stoppedSpy.isValid()); machine.stop(); QCOMPARE(stoppedSpy.count(), 0); machine.postEvent(new QEvent(QEvent::User)); QTRY_COMPARE(stoppedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); QCoreApplication::processEvents(); } @@ -1850,10 +1914,13 @@ void tst_QStateMachine::stateFinished() QFinalState *s2 = new QFinalState(&machine); s1->addTransition(s1, SIGNAL(finished()), s2); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); } @@ -1888,11 +1955,14 @@ void tst_QStateMachine::parallelStates() s1->addTransition(s1, SIGNAL(finished()), s2); machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); globalTick = 0; machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); @@ -1933,9 +2003,11 @@ void tst_QStateMachine::parallelRootState() QFinalState *s2_f = new QFinalState(s2); s2->setInitialState(s2_f); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); @@ -1945,6 +2017,7 @@ void tst_QStateMachine::parallelRootState() QVERIFY(machine.configuration().contains(s2)); QVERIFY(machine.configuration().contains(s2_f)); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } void tst_QStateMachine::allSourceToTargetConfigurations() @@ -1984,7 +2057,9 @@ void tst_QStateMachine::allSourceToTargetConfigurations() s2->addTransition(new StringTransition("f", s11)); s0->addTransition(new StringTransition("e", s211)); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2008,6 +2083,7 @@ void tst_QStateMachine::allSourceToTargetConfigurations() QCoreApplication::processEvents(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } class TestSignalTransition : public QSignalTransition @@ -2094,7 +2170,9 @@ void tst_QStateMachine::signalTransitions() QCOMPARE(trans->senderObject(), (QObject*)&emitter); QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg()))); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2103,6 +2181,7 @@ void tst_QStateMachine::signalTransitions() emitter.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; emitter.emitSignalWithNoArg(); @@ -2112,6 +2191,7 @@ void tst_QStateMachine::signalTransitions() QCoreApplication::processEvents(); emitter.emitSignalWithIntArg(123); QTRY_COMPARE(finishedSpy.count(), 2); + TEST_RUNNING_CHANGED_STARTED_STOPPED; machine.start(); QCoreApplication::processEvents(); @@ -2119,6 +2199,7 @@ void tst_QStateMachine::signalTransitions() QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg()))); emitter.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 3); + TEST_RUNNING_CHANGED_STARTED_STOPPED; SignalEmitter emitter2; machine.start(); @@ -2126,12 +2207,14 @@ void tst_QStateMachine::signalTransitions() trans->setSenderObject(&emitter2); emitter2.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 4); + TEST_RUNNING_CHANGED_STARTED_STOPPED; machine.start(); QCoreApplication::processEvents(); QTest::ignoreMessage(QtWarningMsg, "QSignalTransition: no such signal: SignalEmitter::noSuchSignal()"); trans->setSignal(SIGNAL(noSuchSignal())); QCOMPARE(trans->signal(), QByteArray(SIGNAL(noSuchSignal()))); + TEST_RUNNING_CHANGED(true); } { QStateMachine machine; @@ -2145,7 +2228,9 @@ void tst_QStateMachine::signalTransitions() QCOMPARE(trans->senderObject(), (QObject*)&emitter); QCOMPARE(trans->signal(), QByteArray("signalWithNoArg()")); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2154,6 +2239,7 @@ void tst_QStateMachine::signalTransitions() emitter.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; trans->setSignal("signalWithIntArg(int)"); QCOMPARE(trans->signal(), QByteArray("signalWithIntArg(int)")); @@ -2161,6 +2247,7 @@ void tst_QStateMachine::signalTransitions() QCoreApplication::processEvents(); emitter.emitSignalWithIntArg(123); QTRY_COMPARE(finishedSpy.count(), 2); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } { QStateMachine machine; @@ -2170,7 +2257,9 @@ void tst_QStateMachine::signalTransitions() TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithIntArg(int)), s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2179,6 +2268,7 @@ void tst_QStateMachine::signalTransitions() emitter.emitSignalWithIntArg(123); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(trans->eventTestSenderReceived(), (QObject*)&emitter); QCOMPARE(trans->eventTestSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithIntArg(int)")); QCOMPARE(trans->eventTestArgumentsReceived().size(), 1); @@ -2196,7 +2286,9 @@ void tst_QStateMachine::signalTransitions() TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2206,6 +2298,7 @@ void tst_QStateMachine::signalTransitions() emitter.emitSignalWithStringArg(testString); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(trans->eventTestSenderReceived(), (QObject*)&emitter); QCOMPARE(trans->eventTestSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithStringArg(QString)")); QCOMPARE(trans->eventTestArgumentsReceived().size(), 1); @@ -2232,7 +2325,9 @@ void tst_QStateMachine::signalTransitions() trans->setTargetState(s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2241,6 +2336,7 @@ void tst_QStateMachine::signalTransitions() emitter.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } // Multiple transitions for same (object,signal) { @@ -2251,7 +2347,7 @@ void tst_QStateMachine::signalTransitions() QSignalTransition *t0 = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); QSignalTransition *t1 = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s0); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2300,30 +2396,38 @@ void tst_QStateMachine::signalTransitions() QFinalState *s3 = new QFinalState(&machine); s0->addTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s3); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.setInitialState(s0); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); emitter.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); machine.start(); QTRY_COMPARE(startedSpy.count(), 2); + TEST_RUNNING_CHANGED(true); emitter.emitSignalWithIntArg(123); QTRY_COMPARE(finishedSpy.count(), 2); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); machine.start(); QTRY_COMPARE(startedSpy.count(), 3); + TEST_RUNNING_CHANGED(true); emitter.emitSignalWithStringArg("hello"); QTRY_COMPARE(finishedSpy.count(), 3); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s3)); } @@ -2341,18 +2445,22 @@ void tst_QStateMachine::signalTransitions() QVERIFY(t1 != 0); QCOMPARE(t1->signal(), QByteArray(SIGNAL(signalWithStringArg(QString)))); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.setInitialState(s0); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED(true); emitter.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } } @@ -2406,7 +2514,9 @@ void tst_QStateMachine::eventTransitions() QCOMPARE(trans->targetState(), (QAbstractState*)s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2414,6 +2524,7 @@ void tst_QStateMachine::eventTransitions() QTest::mousePress(&button, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QTest::mousePress(&button, Qt::LeftButton); @@ -2423,12 +2534,14 @@ void tst_QStateMachine::eventTransitions() QCoreApplication::processEvents(); QTest::mouseRelease(&button, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 2); + TEST_RUNNING_CHANGED_STARTED_STOPPED; machine.start(); QCoreApplication::processEvents(); trans->setEventType(QEvent::MouseButtonPress); QTest::mousePress(&button, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 3); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QPushButton button2; machine.start(); @@ -2436,6 +2549,7 @@ void tst_QStateMachine::eventTransitions() trans->setEventSource(&button2); QTest::mousePress(&button2, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 4); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } for (int x = 0; x < 2; ++x) { QStateMachine machine; @@ -2459,7 +2573,9 @@ void tst_QStateMachine::eventTransitions() QCOMPARE(trans->targetState(), (QAbstractState*)s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2469,6 +2585,7 @@ void tst_QStateMachine::eventTransitions() QCoreApplication::processEvents(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } { QStateMachine machine; @@ -2485,16 +2602,19 @@ void tst_QStateMachine::eventTransitions() trans->setTargetState(s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); - + TEST_RUNNING_CHANGED(true); QTest::mousePress(&button, Qt::LeftButton); QCoreApplication::processEvents(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } { @@ -2508,16 +2628,20 @@ void tst_QStateMachine::eventTransitions() trans->setTargetState(s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); + TEST_RUNNING_CHANGED(true); QTest::keyPress(&button, Qt::Key_A); QCoreApplication::processEvents(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } { QStateMachine machine; @@ -2534,16 +2658,20 @@ void tst_QStateMachine::eventTransitions() trans->setTargetState(s1); s0->addTransition(trans); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); + TEST_RUNNING_CHANGED(true); QTest::keyPress(&button, Qt::Key_A); QCoreApplication::processEvents(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } // Multiple transitions for same (object,event) { @@ -2557,7 +2685,7 @@ void tst_QStateMachine::eventTransitions() t1->setTargetState(s0); s1->addTransition(t1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); @@ -2607,23 +2735,29 @@ void tst_QStateMachine::eventTransitions() t1->setTargetState(s2); s0->addTransition(t1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.setInitialState(s0); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); QTest::mousePress(&button, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); machine.start(); QTRY_COMPARE(startedSpy.count(), 2); + TEST_RUNNING_CHANGED(true); QTest::mouseRelease(&button, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 2); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); } @@ -2637,12 +2771,15 @@ void tst_QStateMachine::eventTransitions() trans->setTargetState(s1); s0->addTransition(trans); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); machine.setInitialState(s0); machine.start(); QTest::ignoreMessage(QtWarningMsg, "QObject event transitions are not supported for custom types"); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); } // custom transition { @@ -2655,16 +2792,20 @@ void tst_QStateMachine::eventTransitions() QCOMPARE(trans->eventSourceReceived(), (QObject*)0); QCOMPARE(trans->eventTypeReceived(), QEvent::None); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.setInitialState(s0); machine.start(); QCoreApplication::processEvents(); + TEST_RUNNING_CHANGED(true); QTest::mousePress(&button, Qt::LeftButton); QCoreApplication::processEvents(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); QCOMPARE(trans->eventSourceReceived(), (QObject*)&button); QCOMPARE(trans->eventTypeReceived(), QEvent::MouseButtonPress); @@ -2684,16 +2825,20 @@ void tst_QStateMachine::graphicsSceneEventTransitions() s1->addTransition(t); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); QVERIFY(finishedSpy.count() == 0); + TEST_RUNNING_CHANGED(true); QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove); scene.sendEvent(textItem, &mouseEvent); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } #endif @@ -2734,7 +2879,9 @@ void tst_QStateMachine::historyStates() root->setInitialState(s0); s0->setInitialState(s00); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.start(); QCoreApplication::processEvents(); @@ -2765,19 +2912,22 @@ void tst_QStateMachine::historyStates() QVERIFY(machine.configuration().contains(s2)); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } } void tst_QStateMachine::startAndStop() { QStateMachine machine; - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(stoppedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); QVERIFY(!machine.isRunning()); QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start: No initial state set for machine. Refusing to start."); @@ -2785,11 +2935,13 @@ void tst_QStateMachine::startAndStop() QCOMPARE(startedSpy.count(), 0); QCOMPARE(stoppedSpy.count(), 0); QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(runningSpy.count(), 0); QVERIFY(!machine.isRunning()); machine.stop(); QCOMPARE(startedSpy.count(), 0); QCOMPARE(stoppedSpy.count(), 0); QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(runningSpy.count(), 0); QState *s1 = new QState(&machine); machine.setInitialState(s1); @@ -2798,17 +2950,20 @@ void tst_QStateMachine::startAndStop() QTRY_COMPARE(startedSpy.count(), 1); QCOMPARE(stoppedSpy.count(), 0); QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED(true); QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s1)); QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start(): already running"); machine.start(); + QCOMPARE(runningSpy.count(), 0); machine.stop(); QTRY_COMPARE(machine.isRunning(), false); QTRY_COMPARE(stoppedSpy.count(), 1); QCOMPARE(startedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s1)); @@ -2817,6 +2972,81 @@ void tst_QStateMachine::startAndStop() machine.stop(); QTRY_COMPARE(startedSpy.count(), 2); QCOMPARE(stoppedSpy.count(), 2); + TEST_RUNNING_CHANGED_STARTED_STOPPED; +} + +void tst_QStateMachine::setRunning() +{ + QStateMachine machine; + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + + QVERIFY(startedSpy.isValid()); + QVERIFY(stoppedSpy.isValid()); + QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); + + QVERIFY(!machine.isRunning()); + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start: No initial state set for machine. Refusing to start."); + machine.setRunning(true); + QCOMPARE(startedSpy.count(), 0); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(runningSpy.count(), 0); + QVERIFY(!machine.isRunning()); + machine.setRunning(false); + QCOMPARE(startedSpy.count(), 0); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(runningSpy.count(), 0); + + QState *s1 = new QState(&machine); + machine.setInitialState(s1); + machine.setRunning(true); + QTRY_COMPARE(machine.isRunning(), true); + QTRY_COMPARE(startedSpy.count(), 1); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED(true); + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(s1)); + + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start(): already running"); + machine.setRunning(true); + QCOMPARE(runningSpy.count(), 0); + + machine.setRunning(false); + QTRY_COMPARE(machine.isRunning(), false); + QTRY_COMPARE(stoppedSpy.count(), 1); + QCOMPARE(startedSpy.count(), 1); + QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED(false); + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(s1)); + + machine.setRunning(false); + QCOMPARE(runningSpy.count(), 0); + + machine.start(); + machine.setRunning(false); + QTRY_COMPARE(startedSpy.count(), 2); + QCOMPARE(stoppedSpy.count(), 2); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + QState *s1_1 = new QState(s1); + QFinalState *s1_2 = new QFinalState(s1); + s1_1->addTransition(s1_2); + s1->setInitialState(s1_1); + QFinalState *s2 = new QFinalState(&machine); + s1->addTransition(s1, SIGNAL(finished()), s2); + machine.setRunning(false); + QCOMPARE(runningSpy.count(), 0); + machine.setRunning(true); + TEST_RUNNING_CHANGED_STARTED_STOPPED; + QTRY_COMPARE(startedSpy.count(), 3); + QCOMPARE(stoppedSpy.count(), 2); + QCOMPARE(finishedSpy.count(), 1); } void tst_QStateMachine::targetStateWithNoParent() @@ -2827,13 +3057,15 @@ void tst_QStateMachine::targetStateWithNoParent() QState s2; s1->addTransition(&s2); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(stoppedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 's1'"); @@ -2841,6 +3073,7 @@ void tst_QStateMachine::targetStateWithNoParent() QCOMPARE(machine.isRunning(), false); QCOMPARE(stoppedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.error(), QStateMachine::NoCommonAncestorForTransitionError); } @@ -3263,17 +3496,20 @@ void tst_QStateMachine::propertiesAssignedSignalTransitionsReuseAnimationGroup() QParallelAnimationGroup animationGroup; animationGroup.addAnimation(new QPropertyAnimation(object, "foo")); - QSignalSpy animationFinishedSpy(&animationGroup, SIGNAL(finished())); + QSignalSpy animationFinishedSpy(&animationGroup, &QParallelAnimationGroup::finished); QVERIFY(animationFinishedSpy.isValid()); s1->addTransition(s1, SIGNAL(propertiesAssigned()), s2)->addAnimation(&animationGroup); s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3)->addAnimation(&animationGroup); s3->addTransition(s3, SIGNAL(propertiesAssigned()), s4); machine.setInitialState(s1); - QSignalSpy machineFinishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy machineFinishedSpy(&machine, &QStateMachine::finished); QVERIFY(machineFinishedSpy.isValid()); machine.start(); QTRY_COMPARE(machineFinishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s4)); QCOMPARE(object->property("foo").toInt(), 789); @@ -3770,12 +4006,15 @@ void tst_QStateMachine::nestedStateMachines() group->addTransition(group, SIGNAL(finished()), final); machine.setInitialState(group); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); QTRY_COMPARE(machine.configuration().count(), 1+2*3); QVERIFY(machine.configuration().contains(group)); for (int i = 0; i < 3; ++i) @@ -3787,6 +4026,7 @@ void tst_QStateMachine::nestedStateMachines() subMachines[i]->postEvent(new QEvent(QEvent::User)); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); } void tst_QStateMachine::goToState() @@ -3795,10 +4035,13 @@ void tst_QStateMachine::goToState() QState *s1 = new QState(&machine); QState *s2 = new QState(&machine); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); QStateMachinePrivate::get(&machine)->goToState(s2); QCoreApplication::processEvents(); @@ -3838,10 +4081,13 @@ void tst_QStateMachine::goToStateFromSourceWithTransition() s1->addTransition(new QSignalTransition); QState *s2 = new QState(&machine); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); QStateMachinePrivate::get(&machine)->goToState(s2); QCoreApplication::processEvents(); @@ -3928,10 +4174,13 @@ void tst_QStateMachine::postEventFromOtherThread() poster.start(); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(finishedSpy.isValid()); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } #ifndef QT_NO_WIDGETS @@ -3984,18 +4233,21 @@ void tst_QStateMachine::stopInTransitionToFinalState() machine.setInitialState(s1); QObject::connect(t1, SIGNAL(triggered()), &machine, SLOT(stop())); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - QSignalSpy s2EnteredSpy(s2, SIGNAL(entered())); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); + QSignalSpy s2EnteredSpy(s2, &QFinalState::entered); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); QVERIFY(stoppedSpy.isValid()); QVERIFY(finishedSpy.isValid()); QVERIFY(s2EnteredSpy.isValid()); + QVERIFY(runningSpy.isValid()); machine.start(); // Stopping should take precedence over finished. QTRY_COMPARE(stoppedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); QCOMPARE(s2EnteredSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); } @@ -4029,19 +4281,23 @@ void tst_QStateMachine::stopInEventTest() s1->addTransition(new StopInEventTestTransition()); machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); QVERIFY(startedSpy.isValid()); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); QVERIFY(stoppedSpy.isValid()); QVERIFY(finishedSpy.isValid()); machine.postEvent(new QEvent(QEvent::User), QStateMachine::EventPriority(eventPriority)); QTRY_COMPARE(stoppedSpy.count(), 1); QCOMPARE(finishedSpy.count(), 0); + TEST_RUNNING_CHANGED(false); QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); } @@ -4070,12 +4326,16 @@ void tst_QStateMachine::testIncrementReceivers() IncrementReceiversTest testObject; s1->addTransition(&testObject, SIGNAL(mySignal()), s2); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); machine.start(); + TEST_RUNNING_CHANGED(true); QMetaObject::invokeMethod(&testObject, "mySignal", Qt::QueuedConnection); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); QCOMPARE(testObject.signalList.size(), 1); QCOMPARE(testObject.signalList.at(0), QMetaMethod::fromSignal(&IncrementReceiversTest::mySignal)); } @@ -4091,9 +4351,12 @@ void tst_QStateMachine::initialStateIsEnteredBeforeStartedEmitted() // transition should trigger. s1->addTransition(&machine, SIGNAL(started()), s2); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); machine.start(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } void tst_QStateMachine::deletePropertyAssignmentObjectBeforeEntry() @@ -4226,9 +4489,9 @@ void tst_QStateMachine::transitionWithNoTarget() EventTransition *t1 = new EventTransition(QEvent::User, /*target=*/0); s1->addTransition(t1); - QSignalSpy s1EnteredSpy(s1, SIGNAL(entered())); - QSignalSpy s1ExitedSpy(s1, SIGNAL(exited())); - QSignalSpy t1TriggeredSpy(t1, SIGNAL(triggered())); + QSignalSpy s1EnteredSpy(s1, &QState::entered); + QSignalSpy s1ExitedSpy(s1, &QState::exited); + QSignalSpy t1TriggeredSpy(t1, &EventTransition::triggered); machine.start(); QTRY_VERIFY(machine.configuration().contains(s1)); @@ -4261,10 +4524,13 @@ void tst_QStateMachine::initialStateIsFinal() QStateMachine machine; QFinalState *f = new QFinalState(&machine); machine.setInitialState(f); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); machine.start(); QTRY_VERIFY(machine.configuration().contains(f)); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED_STARTED_STOPPED; } class PropertyObject : public QObject @@ -4921,15 +5187,19 @@ void tst_QStateMachine::signalTransitionSenderInDifferentThread2() thread.start(); QTRY_VERIFY(thread.isRunning()); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged); + QVERIFY(runningSpy.isValid()); + QSignalSpy startedSpy(&machine, &QStateMachine::started); + QSignalSpy finishedSpy(&machine, &QStateMachine::finished); machine.start(); QTRY_COMPARE(startedSpy.count(), 1); + TEST_RUNNING_CHANGED(true); emitter.emitSignalWithNoArg(); // The second emission should not get "lost". emitter.emitSignalWithDefaultArg(); QTRY_COMPARE(finishedSpy.count(), 1); + TEST_RUNNING_CHANGED(false); thread.quit(); QTRY_VERIFY(thread.wait()); diff --git a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp index b2b0eace34..5c9f26b70e 100644 --- a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp +++ b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp @@ -87,8 +87,8 @@ void tst_QFutureWatcher::startFinish() { QFutureWatcher<void> futureWatcher; - QSignalSpy startedSpy(&futureWatcher, SIGNAL(started())); - QSignalSpy finishedSpy(&futureWatcher, SIGNAL(finished())); + QSignalSpy startedSpy(&futureWatcher, &QFutureWatcher<void>::started); + QSignalSpy finishedSpy(&futureWatcher, &QFutureWatcher<void>::finished); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); @@ -322,7 +322,7 @@ void tst_QFutureWatcher::futureSignals() a.reportStarted(); f.setFuture(a.future()); - QSignalSpy progressSpy(&f, SIGNAL(progressValueChanged(int))); + QSignalSpy progressSpy(&f, &QFutureWatcher<void>::progressValueChanged); QVERIFY(progressSpy.isValid()); const int progress = 1; a.setProgressValue(progress); @@ -331,8 +331,8 @@ void tst_QFutureWatcher::futureSignals() QCOMPARE(progressSpy.takeFirst().at(0).toInt(), 0); QCOMPARE(progressSpy.takeFirst().at(0).toInt(), 1); - QSignalSpy finishedSpy(&f, SIGNAL(finished())); - QSignalSpy resultReadySpy(&f, SIGNAL(resultReadyAt(int))); + QSignalSpy finishedSpy(&f, &QFutureWatcher<void>::finished); + QSignalSpy resultReadySpy(&f, &QFutureWatcher<void>::resultReadyAt); QVERIFY(finishedSpy.isValid()); QVERIFY(resultReadySpy.isValid()); @@ -374,10 +374,10 @@ void tst_QFutureWatcher::watchFinishedFuture() #endif connect(&watcher, SIGNAL(resultReadyAt(int)), &object, SLOT(resultReadyAt(int))); - QSignalSpy startedSpy(&watcher, SIGNAL(started())); - QSignalSpy finishedSpy(&watcher, SIGNAL(finished())); - QSignalSpy resultReadySpy(&watcher, SIGNAL(resultReadyAt(int))); - QSignalSpy canceledSpy(&watcher, SIGNAL(canceled())); + QSignalSpy startedSpy(&watcher, &QFutureWatcher<int>::started); + QSignalSpy finishedSpy(&watcher, &QFutureWatcher<int>::finished); + QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt); + QSignalSpy canceledSpy(&watcher, &QFutureWatcher<int>::canceled); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); @@ -408,10 +408,10 @@ void tst_QFutureWatcher::watchCanceledFuture() #endif connect(&watcher, SIGNAL(resultReadyAt(int)), &object, SLOT(resultReadyAt(int))); - QSignalSpy startedSpy(&watcher, SIGNAL(started())); - QSignalSpy finishedSpy(&watcher, SIGNAL(finished())); - QSignalSpy resultReadySpy(&watcher, SIGNAL(resultReadyAt(int))); - QSignalSpy canceledSpy(&watcher, SIGNAL(canceled())); + QSignalSpy startedSpy(&watcher, &QFutureWatcher<int>::started); + QSignalSpy finishedSpy(&watcher, &QFutureWatcher<int>::finished); + QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt); + QSignalSpy canceledSpy(&watcher, &QFutureWatcher<int>::canceled); QVERIFY(startedSpy.isValid()); QVERIFY(finishedSpy.isValid()); @@ -439,8 +439,8 @@ void tst_QFutureWatcher::disconnectRunningFuture() SignalSlotObject object; connect(watcher, SIGNAL(resultReadyAt(int)), &object, SLOT(resultReadyAt(int))); - QSignalSpy finishedSpy(watcher, SIGNAL(finished())); - QSignalSpy resultReadySpy(watcher, SIGNAL(resultReadyAt(int))); + QSignalSpy finishedSpy(watcher, &QFutureWatcher<int>::finished); + QSignalSpy resultReadySpy(watcher, &QFutureWatcher<int>::resultReadyAt); QVERIFY(finishedSpy.isValid()); QVERIFY(resultReadySpy.isValid()); @@ -634,7 +634,7 @@ void tst_QFutureWatcher::changeFuture() SignalSlotObject object; connect(&watcher, SIGNAL(resultReadyAt(int)), &object, SLOT(resultReadyAt(int))); - QSignalSpy resultReadySpy(&watcher, SIGNAL(resultReadyAt(int))); + QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt); QVERIFY(resultReadySpy.isValid()); watcher.setFuture(a); // Watch 'a' which will genere a resultReady event. @@ -666,7 +666,7 @@ void tst_QFutureWatcher::cancelEvents() SignalSlotObject object; connect(&watcher, SIGNAL(resultReadyAt(int)), &object, SLOT(resultReadyAt(int))); - QSignalSpy resultReadySpy(&watcher, SIGNAL(resultReadyAt(int))); + QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt); QVERIFY(resultReadySpy.isValid()); watcher.setFuture(a); @@ -694,7 +694,7 @@ void tst_QFutureWatcher::pauseEvents() SignalSlotObject object; connect(&watcher, SIGNAL(resultReadyAt(int)), &object, SLOT(resultReadyAt(int))); - QSignalSpy resultReadySpy(&watcher, SIGNAL(resultReadyAt(int))); + QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt); QVERIFY(resultReadySpy.isValid()); watcher.setFuture(a); @@ -720,7 +720,7 @@ void tst_QFutureWatcher::pauseEvents() SignalSlotObject object; connect(&watcher, SIGNAL(resultReadyAt(int)), &object, SLOT(resultReadyAt(int))); - QSignalSpy resultReadySpy(&watcher, SIGNAL(resultReadyAt(int))); + QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt); QVERIFY(resultReadySpy.isValid()); watcher.setFuture(a); diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp index 0e53139414..a8c052119c 100644 --- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp +++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp @@ -53,13 +53,11 @@ #ifdef Q_OS_UNIX #include <pthread.h> #endif -#if defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) #include <windows.h> -#elif defined(Q_OS_WINRT) -#include <thread> -#elif defined(Q_OS_WIN) +#if defined(Q_OS_WIN32) #include <process.h> -#include <windows.h> +#endif #endif class tst_QThread : public QObject @@ -328,9 +326,6 @@ void tst_QThread::isRunning() void tst_QThread::setPriority() { -#if defined(Q_OS_WINRT) - QSKIP("Thread priority is not supported on WinRT"); -#endif Simple_Thread thread; // cannot change the priority, since the thread is not running @@ -465,10 +460,6 @@ void tst_QThread::start() QVERIFY(!thread.isFinished()); QVERIFY(!thread.isRunning()); QMutexLocker locker(&thread.mutex); -#ifdef Q_OS_WINRT - if (priorities[i] != QThread::NormalPriority && priorities[i] != QThread::InheritPriority) - QTest::ignoreMessage(QtWarningMsg, "QThread::start: Failed to set thread priority (not implemented)"); -#endif thread.start(priorities[i]); QVERIFY(thread.isRunning()); QVERIFY(!thread.isFinished()); @@ -482,7 +473,7 @@ void tst_QThread::start() void tst_QThread::terminate() { #if defined(Q_OS_WINRT) - QSKIP("Terminate is not supported on WinRT"); + QSKIP("Thread termination is not supported on WinRT."); #endif Terminate_Thread thread; { @@ -548,7 +539,7 @@ void tst_QThread::finished() void tst_QThread::terminated() { #if defined(Q_OS_WINRT) - QSKIP("Terminate is not supported on WinRT"); + QSKIP("Thread termination is not supported on WinRT."); #endif SignalRecorder recorder; Terminate_Thread thread; @@ -645,8 +636,6 @@ void noop(void*) { } #if defined Q_OS_UNIX typedef pthread_t ThreadHandle; -#elif defined Q_OS_WINRT - typedef std::thread ThreadHandle; #elif defined Q_OS_WIN typedef HANDLE ThreadHandle; #endif @@ -689,7 +678,7 @@ void NativeThreadWrapper::start(FunctionPointer functionPointer, void *data) const int state = pthread_create(&nativeThreadHandle, 0, NativeThreadWrapper::runUnix, this); Q_UNUSED(state); #elif defined(Q_OS_WINRT) - nativeThreadHandle = std::thread(NativeThreadWrapper::runWin, this); + // creating a new worker from within the GUI thread is not supported #elif defined(Q_OS_WINCE) nativeThreadHandle = CreateThread(NULL, 0 , (LPTHREAD_START_ROUTINE)NativeThreadWrapper::runWin , this, 0, NULL); #elif defined Q_OS_WIN @@ -710,7 +699,7 @@ void NativeThreadWrapper::join() #if defined Q_OS_UNIX pthread_join(nativeThreadHandle, 0); #elif defined Q_OS_WINRT - nativeThreadHandle.join(); + // not supported #elif defined Q_OS_WIN WaitForSingleObject(nativeThreadHandle, INFINITE); CloseHandle(nativeThreadHandle); @@ -766,6 +755,9 @@ void testNativeThreadAdoption(void *) } void tst_QThread::nativeThreadAdoption() { +#ifdef Q_OS_WINRT + QSKIP("Native thread adoption is not supported on WinRT."); +#endif threadAdoptedOk = false; mainThread = QThread::currentThread(); NativeThreadWrapper nativeThread; @@ -789,6 +781,9 @@ void adoptedThreadAffinityFunction(void *arg) void tst_QThread::adoptedThreadAffinity() { +#ifdef Q_OS_WINRT + QSKIP("Native thread adoption is not supported on WinRT."); +#endif QThread *affinity[2] = { 0, 0 }; NativeThreadWrapper thread; @@ -801,10 +796,9 @@ void tst_QThread::adoptedThreadAffinity() void tst_QThread::adoptedThreadSetPriority() { -#if defined(Q_OS_WINRT) - QSKIP("Thread priority is not supported on WinRT"); +#ifdef Q_OS_WINRT + QSKIP("Native thread adoption is not supported on WinRT."); #endif - NativeThreadWrapper nativeThread; nativeThread.setWaitForStop(); nativeThread.startAndWait(); @@ -832,6 +826,9 @@ void tst_QThread::adoptedThreadSetPriority() void tst_QThread::adoptedThreadExit() { +#ifdef Q_OS_WINRT + QSKIP("Native thread adoption is not supported on WinRT."); +#endif NativeThreadWrapper nativeThread; nativeThread.setWaitForStop(); @@ -861,6 +858,9 @@ void adoptedThreadExecFunction(void *) void tst_QThread::adoptedThreadExec() { +#ifdef Q_OS_WINRT + QSKIP("Native thread adoption is not supported on WinRT."); +#endif NativeThreadWrapper nativeThread; nativeThread.start(adoptedThreadExecFunction); nativeThread.join(); @@ -871,6 +871,9 @@ void tst_QThread::adoptedThreadExec() */ void tst_QThread::adoptedThreadFinished() { +#ifdef Q_OS_WINRT + QSKIP("Native thread adoption is not supported on WinRT."); +#endif NativeThreadWrapper nativeThread; nativeThread.setWaitForStop(); nativeThread.startAndWait(); @@ -889,6 +892,9 @@ void tst_QThread::adoptedThreadFinished() void tst_QThread::adoptedThreadExecFinished() { +#ifdef Q_OS_WINRT + QSKIP("Native thread adoption is not supported on WinRT."); +#endif NativeThreadWrapper nativeThread; nativeThread.setWaitForStop(); nativeThread.startAndWait(adoptedThreadExecFunction); @@ -899,14 +905,14 @@ void tst_QThread::adoptedThreadExecFinished() nativeThread.join(); QTestEventLoop::instance().enterLoop(5); -#if defined(Q_OS_WINRT) - QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort); -#endif QVERIFY(!QTestEventLoop::instance().timeout()); } void tst_QThread::adoptMultipleThreads() { +#ifdef Q_OS_WINRT + QSKIP("Native thread adoption is not supported on WinRT."); +#endif #if defined(Q_OS_WIN) // Windows CE is not capable of handling that many threads. On the emulator it is dead with 26 threads already. # if defined(Q_OS_WINCE) @@ -947,6 +953,9 @@ void tst_QThread::adoptMultipleThreads() void tst_QThread::adoptMultipleThreadsOverlap() { +#ifdef Q_OS_WINRT + QSKIP("Native thread adoption is not supported on WinRT."); +#endif #if defined(Q_OS_WIN) // Windows CE is not capable of handling that many threads. On the emulator it is dead with 26 threads already. # if defined(Q_OS_WINCE) diff --git a/tests/auto/corelib/tools/collections/.gitignore b/tests/auto/corelib/tools/collections/.gitignore new file mode 100644 index 0000000000..dcd9d49ec0 --- /dev/null +++ b/tests/auto/corelib/tools/collections/.gitignore @@ -0,0 +1 @@ +tst_collections diff --git a/tests/auto/corelib/tools/collections/collections.pro b/tests/auto/corelib/tools/collections/collections.pro new file mode 100644 index 0000000000..51ea667f58 --- /dev/null +++ b/tests/auto/corelib/tools/collections/collections.pro @@ -0,0 +1,9 @@ +CONFIG += testcase +TARGET = tst_collections +SOURCES += tst_collections.cpp +QT = core testlib +CONFIG += parallel_test + +# This test does not work with strict iterators +DEFINES -= QT_STRICT_ITERATORS +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/tools/collections/tst_collections.cpp b/tests/auto/corelib/tools/collections/tst_collections.cpp new file mode 100644 index 0000000000..33aa1c4888 --- /dev/null +++ b/tests/auto/corelib/tools/collections/tst_collections.cpp @@ -0,0 +1,3670 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +// test the container forwards +#include <QtContainerFwd> + +static QCache<int, int> *cacheX; +static QHash<int, int> *hashX; +static QLinkedList<int> *linkedListX; +static QList<int> *listX; +static QMap<int, int> *mapX; +static QMultiHash<int, int> *multiHashX; +static QMultiMap<int, int> *multiMapX; +static QPair<int, int> *pairX; +static QQueue<int> *queueX; +static QSet<int> *setX; +static QStack<int> *stackX; +static QVarLengthArray<int> *varLengthArrayX; +static QVarLengthArray<int, 512> *varLengthArrayY; +static QVector<int> *vectorX; + +void foo() +{ + cacheX = 0; + hashX = 0; + linkedListX = 0; + listX = 0; + mapX = 0; + multiHashX = 0; + multiMapX = 0; + pairX = 0; + queueX = 0; + setX = 0; + stackX = 0; + varLengthArrayX = 0; + varLengthArrayY = 0; + vectorX = 0; +} + +#include <QtTest/QtTest> + +#include <algorithm> + +#include "qalgorithms.h" +#include "qbitarray.h" +#include "qbytearray.h" +#include "qcache.h" +#include "qhash.h" +#include "qlinkedlist.h" +#include "qlist.h" +#include "qmap.h" +#include "qpair.h" +#include "qregexp.h" +#include "qset.h" +#include "qstack.h" +#include "qstring.h" +#include "qstringlist.h" +#include "qvarlengtharray.h" +#include "qvector.h" +#include "qqueue.h" + +template class QList<int>; + +class tst_Collections : public QObject +{ + Q_OBJECT + +public: + tst_Collections(); + ~tst_Collections(); + +public slots: + void init(); + void cleanup(); +private slots: + void typeinfo(); + void qstring(); + void list(); + void linkedList(); + void vector(); + void byteArray(); + void stack(); + void hash(); + void map(); + void bitArray(); + void cache(); + void regexp(); + void pair(); + void sharableQList(); + void sharableQLinkedList(); + void sharableQVector(); + void sharableQMap(); + void sharableQHash(); + void q_foreach(); + void conversions(); + void javaStyleIterators(); + void constAndNonConstStlIterators(); + void vector_stl_data(); + void vector_stl(); + void list_stl_data(); + void list_stl(); + void linkedlist_stl_data(); + void linkedlist_stl(); + void q_init(); + void pointersize(); + void containerInstantiation(); + void qtimerList(); + void containerTypedefs(); + void forwardDeclared(); + void alignment(); + void QTBUG13079_collectionInsideCollection(); + + void foreach_2(); + void insert_remove_loop(); +}; + +struct LargeStatic { + static int count; + LargeStatic():c(count) { ++count; } + LargeStatic(const LargeStatic& o):c(o.c) { ++count; } + ~LargeStatic() { --count; } + int c; + int data[8]; +}; + +int LargeStatic::count = 0; + +struct Movable { + static int count; + Movable():c(count) { ++count; } + Movable(const Movable& o):c(o.c) { ++count; } + ~Movable() { --count; } + int c; +}; + +int Movable::count = 0; +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE); +QT_END_NAMESPACE + + +struct Pod { + int i1, i2; +}; + +tst_Collections::tst_Collections() +{ +} + +tst_Collections::~tst_Collections() +{ + +} + +void tst_Collections::init() +{ +} + +void tst_Collections::cleanup() +{ +} + +void tst_Collections::typeinfo() +{ + QVERIFY(QTypeInfo<int*>::isPointer); + QVERIFY(!QTypeInfo<int>::isPointer); + QVERIFY(QTypeInfo<QString>::isComplex); + QVERIFY(!QTypeInfo<int>::isComplex); +} + +void tst_Collections::list() +{ + { + QList<int> list; + QVERIFY(list.isEmpty()); + list.append(1); + QVERIFY(list.size() == 1); + + QVERIFY(*list.begin() == 1); + + list.push_back(2); + list += (3); + list << 4 << 5 << 6; + QVERIFY(!list.isEmpty()); + QVERIFY(list.size() == 6); + QVERIFY(list.end() - list.begin() == list.size()); + +#if !defined(Q_CC_MSVC) && !defined(Q_CC_SUN) + QVERIFY(std::binary_search(list.begin(), list.end(), 2) == true); + QVERIFY(std::binary_search(list.begin(), list.end(), 9) == false); +#endif + QVERIFY(qBinaryFind(list.begin(), list.end(), 2) == list.begin() + 1); + QVERIFY(qLowerBound(list.begin(), list.end(), 2) == list.begin() + 1); + QVERIFY(qUpperBound(list.begin(), list.end(), 2) == list.begin() + 2); + QVERIFY(qBinaryFind(list.begin(), list.end(), 9) == list.end()); + QVERIFY(qLowerBound(list.begin(), list.end(), 9) == list.end()); + QVERIFY(qUpperBound(list.begin(), list.end(), 9) == list.end()); + { + int sum = 0; + QListIterator<int> i(list); + while (i.hasNext()) + sum += i.next(); + QVERIFY(sum == 21); + } + + { + QList<int> list1; + list1 << 1 << 2 << 3 << 5 << 7 << 8 << 9; + QList<int> list2 = list1; + + QMutableListIterator<int> i1(list1); + while (i1.hasNext()) { + if (i1.next() % 2 != 0) + i1.remove(); + } + + QMutableListIterator<int> i2(list2); + i2.toBack(); + while (i2.hasPrevious()) { + if (i2.previous() % 2 != 0) + i2.remove(); + } + QVERIFY(list1.size() == 2); + QVERIFY(list2.size() == 2); + QVERIFY(list1 == list2); + } + + { + int sum = 0; + for (int i = 0; i < list.size(); ++i) + sum += list[i]; + QVERIFY(sum == 21); + } + { + int sum = 0; + QList<int>::const_iterator i = list.begin(); + while (i != list.end()) + sum += *i++; + QVERIFY(sum == 21); + } + { + int sum = 0; + QList<int>::ConstIterator i = list.begin(); + while (i != list.end()) + sum += *i++; + QVERIFY(sum == 21); + } + { + QList<int>::Iterator i = list.begin(); + i += 2; + QCOMPARE(*i, 3); + i -= 1; + QCOMPARE(*i, 2); + } + { + QList<int>::ConstIterator i = list.begin(); + i += 2; + QCOMPARE(*i, 3); + i -= 1; + QCOMPARE(*i, 2); + } + { + int sum = 0; + int i; + for (i = 0; i < list.size(); ++i) + list[i] = list[i] +1; + for (i = 0; i < list.size(); ++i) + sum += list[i]; + QVERIFY(sum == 21 + list.size()); + } + { + int sum = 0; + int i; + for (i = 0; i < list.size(); ++i) + --list[i]; + for (i = 0; i < list.size(); ++i) + sum += list[i]; + QVERIFY(sum == 21); + } + { + QMutableListIterator<int> i(list); + while (i.hasNext()) + i.setValue(2*i.next()); + } + { + int sum = 0; + QListIterator<int> i(list); + i.toBack(); + while (i.hasPrevious()) + sum += i.previous(); + QVERIFY(sum == 2*21); + } + { + QMutableListIterator<int> i(list); + i.toBack(); + while (i.hasPrevious()) + i.setValue(2*i.previous()); + } + { + int sum = 0; + QListIterator<int> i(list); + i.toBack(); + while (i.hasPrevious()) + sum += i.previous(); + QVERIFY(sum == 2*2*21); + } + { + QMutableListIterator<int> i(list); + while (i.hasNext()) { + int a = i.next(); + i.insert(a); + } + } + { + int sum = 0; + QList<int>::iterator i = list.begin(); + while (i != list.end()) + sum += *i++; + QVERIFY(sum == 2*2*2*21); + } + { + int duplicates = 0; + QListIterator<int> i(list); + while (i.hasNext()) { + int a = i.next(); + if (i.hasNext() && a == i.peekNext()) + duplicates++; + } + QVERIFY(duplicates == 6); + } + { + int duplicates = 0; + QListIterator<int> i(list); + i.toBack(); + while (i.hasPrevious()) { + int a = i.previous(); + if (i.hasPrevious() && a == i.peekPrevious()) + duplicates++; + } + QVERIFY(duplicates == 6); + } + { + QMutableListIterator<int> i(list); + while (i.hasNext()) { + int a = i.next(); + if (i.hasNext() && + i.peekNext() == a) + i.remove(); + } + } + { + int duplicates = 0; + QMutableListIterator<int> i = list; + i.toBack(); + while (i.hasPrevious()) { + int a = i.previous(); + if (i.hasPrevious() && a == i.peekPrevious()) + duplicates++; + } + QVERIFY(duplicates == 0); + } + { + QVERIFY(list.size() == 6); + QMutableListIterator<int> i = list; + while (i.hasNext()) { + int a = i.peekNext(); + i.insert(42); + QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a); + i.next(); + } + QVERIFY(list.size() == 12); + i.toFront(); + while (i.findNext(42)) + i.remove(); + } + { + QList<int> l; + l << 4 << 8 << 12 << 16 << 20 << 24; + QVERIFY(l == list); + QList<int> copy = list; + list += list; + QVERIFY(l != list && l.size() == list.size()/2 && l == copy); + l += copy; + QVERIFY(l == list); + list = copy; + } + { + QList<int> copy = list; + list << 8; + QVERIFY(list.indexOf(8) == 1); + QVERIFY(list.indexOf(8, list.indexOf(8)+1) == 6); + int a = list.indexOf(8); + QVERIFY(list.count(8) == 2); + int r = list.removeAll(8); + QVERIFY(r == 2); + list.insert(a, 8); + QVERIFY(list == copy); + } + { + QList<QString> list; + list << "one" << "two" << "three" << "four" << "five" << "six"; + while (!list.isEmpty()) + list.removeAll(list.first()); + } + { + QList<QString> list; + list << "one" << "two" << "one" << "two"; + QVERIFY(!list.removeOne("three")); + QVERIFY(list.removeOne("two")); + QCOMPARE(list, QList<QString>() << "one" << "one" << "two");; + QVERIFY(list.removeOne("two")); + QCOMPARE(list, QList<QString>() << "one" << "one"); + QVERIFY(!list.removeOne("two")); + QCOMPARE(list, QList<QString>() << "one" << "one"); + QVERIFY(list.removeOne("one")); + QCOMPARE(list, QList<QString>() << "one"); + QVERIFY(list.removeOne("one")); + QVERIFY(list.isEmpty()); + QVERIFY(!list.removeOne("one")); + QVERIFY(list.isEmpty()); + } + { + QList<int> copy = list; + list << 8; + QVERIFY(list.lastIndexOf(8) == 6); + QVERIFY(list.lastIndexOf(8, list.lastIndexOf(8)-1) == 1); + list = copy; + } + { + QList<int> copy = list; + list.insert(3, 999); + QVERIFY(list[3] == 999); + list.replace(3, 222); + QVERIFY(list[3] == 222); + QVERIFY(list.contains(222) && ! list.contains(999)); + list.removeAt(3); + list = copy; + QVERIFY(list == copy); + } + { + list.clear(); + QVERIFY(list.isEmpty()); + QVERIFY(list.begin() == list.end()); + QListIterator<int> i(list); + QVERIFY(!i.hasNext() && !i.hasPrevious()); + } + { + QList<int> l1; + QList<int> l2; + l1 << 1 << 2 << 3; + l2 << 4 << 5 << 6; + QList<int> l3 = l1 + l2; + l1 += l2; + QVERIFY(l3 == l1); + } + { + QList<int> list; + QVERIFY(list.isEmpty()); + list.append(1); + QList<int> list2; + list2 = list; + list2.clear(); + QVERIFY(list2.size() == 0); + QVERIFY(list.size() == 1); + } + { + QList<int> list; + list.append(1); + list = list; + QVERIFY(list.size() == 1); + } + } + { + QList<void*> list; + list.append(0); + list.append((void*)42); + QCOMPARE(list.size(), 2); + QCOMPARE(list.at(0), (void*)0); + QCOMPARE(list.at(1), (void*)42); + } + + { + QVector<QString> vector(5); + vector[0] = "99"; + vector[4] ="100"; + QList<QString> list = vector.toList(); + + QVERIFY(list.size() == 5); + QVERIFY(list.at(0) == "99"); + QVERIFY(list.at(4) == "100"); + list[0] = "10"; + QVERIFY(list.at(0) == "10"); + QVERIFY(vector.at(0) == "99"); + + } + + { + QList<QString> list; + list.append("Hello"); + + QList<QString>::iterator it = list.begin(); + QVERIFY((*it)[0] == QChar('H')); + QVERIFY(it->constData()[0] == QChar('H')); + it->replace(QChar('H'), QChar('X')); + QVERIFY(list.first() == "Xello"); + + QList<QString>::const_iterator cit = list.constBegin(); + QVERIFY((*cit).toLower() == "xello"); + QVERIFY(cit->toUpper() == "XELLO"); + + cit = list.cbegin(); + QVERIFY((*cit).toLower() == "xello"); + QVERIFY(cit->toUpper() == "XELLO"); + } + + { + QList<int *> list; + QVERIFY(list.value(0) == 0); + int i; + list.append(&i); + QVERIFY(list.value(0) == &i); + } + { + QList<const int *> list; + QVERIFY(list.value(0) == 0); + int i; + list.append(&i); + QVERIFY(list.value(0) == &i); + } + { + QList<int> list; + QVERIFY(list.value(0) == 0); + list.append(10); + QVERIFY(list.value(0) == 10); + } + { + QList<Pod> list; + QCOMPARE(list.value(0).i1, 0); + QCOMPARE(list.value(0).i2, 0); + } + + { + QList<QString> list; + list << "alpha" << "beta"; + list += list; + QVERIFY(list.size() == 4); + QVERIFY(list.at(0) == "alpha"); + QVERIFY(list.at(1) == "beta"); + QVERIFY(list.at(2) == "alpha"); + QVERIFY(list.at(3) == "beta"); + } + + // test endcases for inserting into a qlist + { + QList<QString> list; + list << "foo" << "bar"; + QVERIFY(!list.isEmpty()); + + list.insert(-1, "lessthanzero"); + QCOMPARE(list.at(0), QString("lessthanzero")); + + list.insert(0, "atzero"); + QCOMPARE(list.at(0), QString("atzero")); + + int listCount = list.count(); + list.insert(listCount, "atcount"); + QCOMPARE(list.at(listCount), QString("atcount")); + + listCount = list.count(); + list.insert(listCount + 1, "beyondcount"); + QCOMPARE(list.at(listCount), QString("beyondcount")); + } + + { + QList<int> list1; + list1 << 0 << 1 << 2 << 3; + list1.removeFirst(); + + list1.swap(0, 0); + QVERIFY(list1 == QList<int>() << 1 << 2 << 3); + + list1.swap(1, 1); + QVERIFY(list1 == QList<int>() << 1 << 2 << 3); + + list1.swap(2, 2); + QVERIFY(list1 == QList<int>() << 1 << 2 << 3); + + list1.swap(0, 1); + QVERIFY(list1 == QList<int>() << 2 << 1 << 3); + + list1.swap(0, 2); + QVERIFY(list1 == QList<int>() << 3 << 1 << 2); + + list1.swap(1, 2); + QVERIFY(list1 == QList<int>() << 3 << 2 << 1); + + list1.swap(1, 2); + QVERIFY(list1 == QList<int>() << 3 << 1 << 2); + + QList<QString> list2; + list2 << "1" << "2" << "3"; + + list2.swap(0, 0); + QVERIFY(list2 == QList<QString>() << "1" << "2" << "3"); + + list2.swap(1, 1); + QVERIFY(list2 == QList<QString>() << "1" << "2" << "3"); + + list2.swap(2, 2); + QVERIFY(list2 == QList<QString>() << "1" << "2" << "3"); + + list2.swap(0, 1); + QVERIFY(list2 == QList<QString>() << "2" << "1" << "3"); + + list2.swap(0, 2); + QVERIFY(list2 == QList<QString>() << "3" << "1" << "2"); + + list2.swap(1, 2); + QVERIFY(list2 == QList<QString>() << "3" << "2" << "1"); + + list2.swap(1, 2); + QVERIFY(list2 == QList<QString>() << "3" << "1" << "2"); + + QList<double> list3; + list3 << 1.0 << 2.0 << 3.0; + + list3.swap(0, 0); + QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0); + + list3.swap(1, 1); + QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0); + + list3.swap(2, 2); + QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0); + + list3.swap(0, 1); + QVERIFY(list3 == QList<double>() << 2.0 << 1.0 << 3.0); + + list3.swap(0, 2); + QVERIFY(list3 == QList<double>() << 3.0 << 1.0 << 2.0); + + list3.swap(1, 2); + QVERIFY(list3 == QList<double>() << 3.0 << 2.0 << 1.0); + + list3.swap(1, 2); + QVERIFY(list3 == QList<double>() << 3.0 << 1.0 << 2.0); + } + + // Check what happens when using references to own items. + // Ideally we should run valgrind on this. + { + int i; + + QList<void *> list1; + list1.append(reinterpret_cast<void *>(50)); + + for (i = 1; i < 100; ++i) { + list1.append(list1.at(i - 1)); + list1.prepend(list1.at(i)); + list1.insert(i, list1.at(i - 1)); + list1.insert(i, list1.at(i)); + list1.insert(i, list1.at(i + 1)); + list1.replace(i, list1.at(i - 1)); + list1.replace(i, list1.at(i)); + list1.replace(i, list1.at(i + 1)); + } + QCOMPARE(list1.size(), 496); + for (i = 0; i < list1.size(); ++i) { + QCOMPARE(list1.at(i), reinterpret_cast<void *>(50)); + } + + QList<QString> list2; + list2.append("50"); + + for (i = 1; i < 100; ++i) { + list2.append(list2.at(i - 1)); + list2.prepend(list2.at(i)); + list2.insert(i, list2.at(i - 1)); + list2.insert(i, list2.at(i)); + list2.insert(i, list2.at(i + 1)); + list2.replace(i, list2.at(i - 1)); + list2.replace(i, list2.at(i)); + list2.replace(i, list2.at(i + 1)); + } + QCOMPARE(list2.size(), 496); + for (i = 0; i < list2.size(); ++i) { + QCOMPARE(list2.at(i), QString::fromLatin1("50")); + } + + QList<double> list3; + list3.append(50.0); + + for (i = 1; i < 100; ++i) { + list3.append(list3.at(i - 1)); + list3.prepend(list3.at(i)); + list3.insert(i, list3.at(i - 1)); + list3.insert(i, list3.at(i)); + list3.insert(i, list3.at(i + 1)); + list3.replace(i, list3.at(i - 1)); + list3.replace(i, list3.at(i)); + list3.replace(i, list3.at(i + 1)); + } + QCOMPARE(list3.size(), 496); + for (i = 0; i < list3.size(); ++i) { + QCOMPARE(list3.at(i), 50.0); + } + + QList<QTime> list4; + list4.append(QTime(12, 34, 56)); + + for (i = 1; i < 100; ++i) { + list4.append(list4.at(i - 1)); + list4.prepend(list4.at(i)); + list4.insert(i, list4.at(i - 1)); + list4.insert(i, list4.at(i)); + list4.insert(i, list4.at(i + 1)); + list4.replace(i, list4.at(i - 1)); + list4.replace(i, list4.at(i)); + list4.replace(i, list4.at(i + 1)); + } + QCOMPARE(list4.size(), 496); + for (i = 0; i < list4.size(); ++i) { + QVERIFY(list4.at(i) == QTime(12, 34, 56)); + } + + } + { + QList<int> a; + QCOMPARE(a.startsWith(1), false); + QCOMPARE(a.endsWith(1), false); + a.append(1); + QCOMPARE(a.startsWith(1), true); + QCOMPARE(a.startsWith(2), false); + QCOMPARE(a.endsWith(1), true); + QCOMPARE(a.endsWith(2), false); + a.append(2); + QCOMPARE(a.startsWith(1), true); + QCOMPARE(a.startsWith(2), false); + QCOMPARE(a.endsWith(1), false); + QCOMPARE(a.endsWith(2), true); + } +} + +void tst_Collections::linkedList() +{ + { + QLinkedList<int> list; + QVERIFY(list.isEmpty()); + list.append(1); + list.push_back(2); + list += (3); + list << 4 << 5 << 6; + QVERIFY(!list.isEmpty()); + QVERIFY(list.size() == 6); + { + int sum = 0; + QLinkedListIterator<int> i = list; + while (i.hasNext()) { + sum += i.next(); + } + QVERIFY(sum == 21); + } + { + int sum = 0; + QLinkedList<int>::const_iterator i = list.begin(); + while (i != list.end()) + sum += *i++; + QVERIFY(sum == 21); + } + { + QMutableLinkedListIterator<int> i = list; + while (i.hasNext()) + i.setValue(2*i.next()); + } + { + int sum = 0; + QLinkedListIterator<int> i = list; + i.toBack(); + while (i.hasPrevious()) + sum += i.previous(); + QVERIFY(sum == 2*21); + } + { + QMutableLinkedListIterator<int> i = list; + i.toBack(); + while (i.hasPrevious()) + i.setValue(2*i.previous()); + } + { + int sum = 0; + QLinkedListIterator<int> i = list; + i.toBack(); + while (i.hasPrevious()) + sum += i.previous(); + QVERIFY(sum == 2*2*21); + } + { + QMutableLinkedListIterator<int> i = list; + while (i.hasNext()) { + int a = i.next(); + i.insert(a); + } + } + { + int sum = 0; + QLinkedList<int>::iterator i = list.begin(); + while (i != list.end()) + sum += *i++; + QVERIFY(sum == 2*2*2*21); + } + { + int duplicates = 0; + QLinkedListIterator<int> i = list; + while (i.hasNext()) { + int a = i.next(); + if (i.hasNext() && a == i.peekNext()) + duplicates++; + } + QVERIFY(duplicates == 6); + } + { + int duplicates = 0; + QLinkedListIterator<int> i = list; + i.toBack(); + while (i.hasPrevious()) { + int a = i.previous(); + if (i.hasPrevious() && a == i.peekPrevious()) + duplicates++; + } + QVERIFY(duplicates == 6); + } + { + QMutableLinkedListIterator<int> i = list; + while (i.hasNext()) { + int a = i.next(); + if (i.hasNext() && + i.peekNext() == a) + i.remove(); + } + } + { + int duplicates = 0; + QMutableLinkedListIterator<int> i = list; + i.toBack(); + while (i.hasPrevious()) { + int a = i.previous(); + if (i.hasPrevious() && a == i.peekPrevious()) + duplicates++; + } + QVERIFY(duplicates == 0); + } + { + QVERIFY(list.size() == 6); + QMutableLinkedListIterator<int> i = list; + while (i.hasNext()) { + int a = i.peekNext(); + i.insert(42); + QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a); + i.next(); + } + QVERIFY(list.size() == 12); + i.toFront(); + while (i.findNext(42)) + i.remove(); + } + { + QLinkedList<int> l; + l << 4 << 8 << 12 << 16 << 20 << 24; + QVERIFY(l == list); + QLinkedList<int> copy = list; + list += list; + QVERIFY(l != list && l.size() == list.size()/2 && l == copy); + l += copy; + QVERIFY(l == list); + list = copy; + } + { + QLinkedList<int> copy = list; + list.prepend(999); + list.append(999); + QVERIFY(list.contains(999)); + QVERIFY(list.count(999) == 2); + list.removeAll(999); + QVERIFY(list == copy); + } + { + QLinkedList<QString> list; + list << "one" << "two" << "three" << "four" << "five" << "six"; + while (!list.isEmpty()) + list.removeAll(list.first()); + } + { + QLinkedList<QString> list; + list << "one" << "two" << "one" << "two"; + QVERIFY(!list.removeOne("three")); + QVERIFY(list.removeOne("two")); + QCOMPARE(list, QLinkedList<QString>() << "one" << "one" << "two");; + QVERIFY(list.removeOne("two")); + QCOMPARE(list, QLinkedList<QString>() << "one" << "one"); + QVERIFY(!list.removeOne("two")); + QCOMPARE(list, QLinkedList<QString>() << "one" << "one"); + QVERIFY(list.removeOne("one")); + QCOMPARE(list, QLinkedList<QString>() << "one"); + QVERIFY(list.removeOne("one")); + QVERIFY(list.isEmpty()); + QVERIFY(!list.removeOne("one")); + QVERIFY(list.isEmpty()); + } + { + list.clear(); + QVERIFY(list.isEmpty()); + QVERIFY(list.begin() == list.end()); + QLinkedListIterator<int> i(list); + QVERIFY(!i.hasNext() && !i.hasPrevious()); + } + } + + { + QLinkedList<QString> list; + list.append("Hello"); + + QLinkedList<QString>::iterator it = list.begin(); + QVERIFY((*it)[0] == QChar('H')); + QVERIFY(it->constData()[0] == QChar('H')); + it->replace(QChar('H'), QChar('X')); + QVERIFY(list.first() == "Xello"); + + QLinkedList<QString>::const_iterator cit = list.constBegin(); + QVERIFY((*cit).toLower() == "xello"); + QVERIFY(cit->toUpper() == "XELLO"); + + cit = list.cbegin(); + QVERIFY((*cit).toLower() == "xello"); + QVERIFY(cit->toUpper() == "XELLO"); + } + + { + QLinkedList<QString> list; + list << "alpha" << "beta"; + list += list; + QVERIFY(list.size() == 4); + QVERIFY(*list.begin() == "alpha"); + QVERIFY(*(list.begin() + 1) == "beta"); + QVERIFY(*(list.begin() + 2) == "alpha"); + QVERIFY(*(list.begin() + 3) == "beta"); + } + + { + QLinkedList<int> a; + QCOMPARE(a.startsWith(1), false); + QCOMPARE(a.endsWith(1), false); + a.append(1); + QCOMPARE(a.startsWith(1), true); + QCOMPARE(a.startsWith(2), false); + QCOMPARE(a.endsWith(1), true); + QCOMPARE(a.endsWith(2), false); + a.append(2); + QCOMPARE(a.startsWith(1), true); + QCOMPARE(a.startsWith(2), false); + QCOMPARE(a.endsWith(1), false); + QCOMPARE(a.endsWith(2), true); + } +}; + + +void tst_Collections::vector() +{ + QVector<int> v1; + v1 << 1 << 2 << 3; + QVector<int> v2; + v2 << 4 << 5; + QVector<int> v3; + v3 << 1 << 2 << 3 << 4 << 5; + QVERIFY(v1 + v2 == v3); + + QVector<int> emptyVector; + // emptyVector.remove(3, -3); // Q_ASSERT_X() triggered with "index out of range" message. + QCOMPARE(emptyVector.size(), 0); + + emptyVector.remove(0, 0); + QCOMPARE(emptyVector.size(), 0); + + QVector<int> v4; + v4 << 1 << 2 << 3; + QCOMPARE(v4.size(), 3); + v4.remove(1, 0); + QCOMPARE(v4.size(), 3); + + QVector<int> v; + v.append(2); + QVERIFY(*v.begin() == 2); + v.prepend(1); + + v << 3 << 4 << 5 << 6; + QVERIFY(std::binary_search(v.begin(), v.end(), 2) == true); + QVERIFY(std::binary_search(v.begin(), v.end(), 9) == false); + QVERIFY(qBinaryFind(v.begin(), v.end(), 2) == v.begin() + 1); + QVERIFY(qLowerBound(v.begin(), v.end(), 2) == v.begin() + 1); + QVERIFY(qUpperBound(v.begin(), v.end(), 2) == v.begin() + 2); + QVERIFY(qBinaryFind(v.begin(), v.end(), 9) == v.end()); + QVERIFY(qLowerBound(v.begin(), v.end(), 9) == v.end()); + QVERIFY(qUpperBound(v.begin(), v.end(), 9) == v.end()); + + v.clear(); + v << 1 << 2 << 3; + v.insert(v.begin(), 0); + v.insert(v.end(), 4); + v.insert(v.begin()+2, 9); + + QVector<int> result; + result << 0 << 1 << 9 << 2 << 3 << 4; + + QVERIFY( v == result ); + + v.clear(); + v << 1 << 2 << 3; + v.insert(0, 0); + v.insert(4, 4); + v.insert(2, 9); + + QVERIFY( v == result ); + + QVector<QString> vec; + vec << "foo" << "bar"; + vec.reserve( 512 ); + QVERIFY(vec[0] == "foo"); + QVERIFY(vec[1] == "bar"); + + int initialLargeStaticCount = LargeStatic::count; + { + QVector<LargeStatic> vector; + vector.append(LargeStatic()); + vector.resize(0); + } + QCOMPARE(LargeStatic::count, initialLargeStaticCount); + + { + QVector<QString> vector; + vector << "alpha" << "beta"; + vector += vector; + QVERIFY(vector.size() == 4); + QVERIFY(vector.at(0) == "alpha"); + QVERIFY(vector.at(1) == "beta"); + QVERIFY(vector.at(2) == "alpha"); + QVERIFY(vector.at(3) == "beta"); + } + + int originalLargeStaticCount = LargeStatic::count; + { + QVector<LargeStatic> vector(5); + } + QVERIFY(LargeStatic::count == originalLargeStaticCount); + { + QVector<LargeStatic> vector(5); + QList<LargeStatic> list = vector.toList(); + } + QVERIFY(LargeStatic::count == originalLargeStaticCount); + { + QVector<LargeStatic> vector; + LargeStatic *dummy = 0; + for (int i = 0; i < 10000; ++i) { + delete dummy; + dummy = new LargeStatic; + vector.append(LargeStatic()); + } + delete dummy; + } + QVERIFY(LargeStatic::count == originalLargeStaticCount); + + int originalMovableCount = Movable::count; + { + QVector<Movable> vector(5); + } + QVERIFY(Movable::count == originalMovableCount); + { + QVector<Movable> vector(5); + QList<Movable> list = vector.toList(); + } + QVERIFY(Movable::count == originalMovableCount); + { + QVector<Movable> vector; + Movable *dummy = 0; + for (int i = 0; i < 10000; ++i) { + delete dummy; + dummy = new Movable; + vector.append(Movable()); + } + delete dummy; + } + QVERIFY(Movable::count == originalMovableCount); + + // Check what happens when using references to own items. + // Ideally we should run valgrind on this. + { + int i; + + QVector<void *> vect1; + vect1.append(reinterpret_cast<void *>(50)); + + for (i = 1; i < 100; ++i) { + vect1.append(vect1.at(i - 1)); + vect1.prepend(vect1.at(i)); + vect1.insert(i, vect1.at(i - 1)); + vect1.insert(i, vect1.at(i)); + vect1.insert(i, vect1.at(i + 1)); + vect1.replace(i, vect1.at(i - 1)); + vect1.replace(i, vect1.at(i)); + vect1.replace(i, vect1.at(i + 1)); + } + QCOMPARE(vect1.size(), 496); + for (i = 0; i < vect1.size(); ++i) { + QCOMPARE(vect1.at(i), reinterpret_cast<void *>(50)); + } + + QVector<QString> vect2; + vect2.append("50"); + + for (i = 1; i < 100; ++i) { + vect2.append(vect2.at(i - 1)); + vect2.prepend(vect2.at(i)); + vect2.insert(i, vect2.at(i - 1)); + vect2.insert(i, vect2.at(i)); + vect2.insert(i, vect2.at(i + 1)); + vect2.replace(i, vect2.at(i - 1)); + vect2.replace(i, vect2.at(i)); + vect2.replace(i, vect2.at(i + 1)); + } + QCOMPARE(vect2.size(), 496); + for (i = 0; i < vect2.size(); ++i) { + QCOMPARE(vect2.at(i), QString::fromLatin1("50")); + } + + QVector<double> vect3; + vect3.append(50.0); + + for (i = 1; i < 100; ++i) { + vect3.append(vect3.at(i - 1)); + vect3.prepend(vect3.at(i)); + vect3.insert(i, vect3.at(i - 1)); + vect3.insert(i, vect3.at(i)); + vect3.insert(i, vect3.at(i + 1)); + vect3.replace(i, vect3.at(i - 1)); + vect3.replace(i, vect3.at(i)); + vect3.replace(i, vect3.at(i + 1)); + } + QCOMPARE(vect3.size(), 496); + for (i = 0; i < vect3.size(); ++i) { + QCOMPARE(vect3.at(i), 50.0); + } + + QVector<QTime> vect4; + vect4.append(QTime(12, 34, 56)); + + for (i = 1; i < 100; ++i) { + vect4.append(vect4.at(i - 1)); + vect4.prepend(vect4.at(i)); + vect4.insert(i, vect4.at(i - 1)); + vect4.insert(i, vect4.at(i)); + vect4.insert(i, vect4.at(i + 1)); + vect4.replace(i, vect4.at(i - 1)); + vect4.replace(i, vect4.at(i)); + vect4.replace(i, vect4.at(i + 1)); + } + QCOMPARE(vect4.size(), 496); + for (i = 0; i < vect4.size(); ++i) { + QVERIFY(vect4.at(i) == QTime(12, 34, 56)); + } + } + + // this used to trigger an uninitialized read in valgrind + QVector<char> foo; + foo.resize(144); + + { + QVector<int> a; + QCOMPARE(a.startsWith(1), false); + QCOMPARE(a.endsWith(1), false); + a.append(1); + QCOMPARE(a.startsWith(1), true); + QCOMPARE(a.startsWith(2), false); + QCOMPARE(a.endsWith(1), true); + QCOMPARE(a.endsWith(2), false); + a.append(2); + QCOMPARE(a.startsWith(1), true); + QCOMPARE(a.startsWith(2), false); + QCOMPARE(a.endsWith(1), false); + QCOMPARE(a.endsWith(2), true); + } +} + +void tst_Collections::byteArray() +{ + QByteArray hello = "hello"; + QByteArray ello = "ello"; + QByteArray World = "World"; + QByteArray Wor = "Wor"; + QByteArray helloWorld = "helloWorld"; + QVERIFY(hello + World == helloWorld); + QVERIFY(hello + "World" == helloWorld); + QVERIFY("hello" + World == helloWorld); + + QVERIFY('h' + ello == hello); + QVERIFY(Wor + 'l' + 'd' == "World"); + QVERIFY(hello + World == "helloWorld"); + QVERIFY(hello + "World" == "helloWorld"); + QVERIFY("hello" + World == "helloWorld"); + QVERIFY('h' + ello == "hello"); + QVERIFY(Wor + 'l' + 'd' == "World"); + QVERIFY("helloWorld" == hello + World); + QVERIFY("helloWorld" == hello + "World"); + QVERIFY("helloWorld" == "hello" + World); + QVERIFY("hello" == 'h' + ello); + QVERIFY("World" == Wor + 'l' + 'd'); + + QVERIFY(hello.contains('e')); + QVERIFY (true == hello.contains('e')); + QVERIFY (hello.contains('e') != false); + + QVERIFY(hello.indexOf('e') == 1); + QVERIFY(hello.indexOf('e', -10) == 1); + QVERIFY(hello.indexOf('l') == 2); + QVERIFY(hello.indexOf('l',2) == 2); + QVERIFY(hello.indexOf('l',3) == 3); + + QByteArray large = "000 100 200 300 400 500 600 700 800 900"; + + QVERIFY(large.indexOf("700") == 28); + QVERIFY(large.indexOf("700", 28) == 28); + QVERIFY(large.indexOf("700", 29) == -1); + QVERIFY(large.lastIndexOf("700") == 28); + QVERIFY(large.lastIndexOf("700", 28) == 28); + QVERIFY(large.lastIndexOf("700", 27) == -1); + + QVERIFY(large.contains("200")); + QVERIFY(!large.contains("201")); + QVERIFY(large.contains('3')); + QVERIFY(!large.contains('a')); + + QVERIFY(large.count("00") == 11); + QVERIFY(large.count('3') == 1); + QVERIFY(large.count('0') == 21); + QVERIFY(large.count("0") == 21); + QVERIFY(large.count("200") == 1); + QVERIFY(large.count("201") == 0); + + QVERIFY(hello.left(0) == ""); + QVERIFY(!hello.left(0).isNull()); + QVERIFY(hello.left(1) == "h"); + QVERIFY(hello.left(2) == "he"); + QVERIFY(hello.left(200) == "hello"); + QVERIFY(hello.left(hello.size()) == hello); + QVERIFY(hello.left(hello.size()+1) == hello); + + QVERIFY(hello.right(0) == ""); + QVERIFY(!hello.right(0).isNull()); + QVERIFY(hello.right(1) == "o"); + QVERIFY(hello.right(2) == "lo"); + QVERIFY(hello.right(200) == "hello"); + QVERIFY(hello.right(hello.size()) == hello); + QVERIFY(hello.right(hello.size()+1) == hello); + + QVERIFY(!hello.mid(0, 0).isNull()); + QVERIFY(hello.mid(0, 1) == "h"); + QVERIFY(hello.mid(0, 2) == "he"); + QVERIFY(hello.mid(0, 200) == "hello"); + QVERIFY(hello.mid(0) == "hello"); + QVERIFY(hello.mid(0, hello.size()) == hello); + QVERIFY(hello.mid(0, hello.size()+1) == hello); + + QVERIFY(hello.mid(hello.size()-0) == ""); + QVERIFY(hello.mid(hello.size()-0).isEmpty()); + QVERIFY(!hello.mid(hello.size()-0).isNull()); + QVERIFY(hello.mid(hello.size()-1) == "o"); + QVERIFY(hello.mid(hello.size()-2) == "lo"); + QVERIFY(hello.mid(hello.size()-200) == "hello"); + + QByteArray nullByteArray; + QByteArray nonNullByteArray = ""; + QVERIFY(nullByteArray.left(10).isNull()); + QVERIFY(nullByteArray.mid(0).isNull()); + + QVERIFY(nullByteArray.isEmpty() == nonNullByteArray.isEmpty()); + QVERIFY(nullByteArray.size() == nonNullByteArray.size()); + + QVERIFY(nullByteArray == QByteArray()); // QByteArray() is both null and empty. + QVERIFY(QByteArray() == nullByteArray); + + QVERIFY(nonNullByteArray == QByteArray("")); // QByteArray("") is empty, but not null. + QVERIFY(QByteArray("") == nonNullByteArray); + + QVERIFY(nullByteArray == nonNullByteArray); + QVERIFY(QByteArray() == QByteArray("")); + + QByteArray str = "Hello"; + QByteArray cstr(str.data(), str.size()); + QVERIFY(str == "Hello"); + QVERIFY(cstr == "Hello"); + cstr.clear(); + QVERIFY(str == "Hello"); + QVERIFY(cstr.isEmpty()); + + { + QByteArray ba1("Foo"); + ba1.prepend(ba1); + QCOMPARE(ba1, QByteArray("FooFoo")); + ba1.append(ba1); + QCOMPARE(ba1, QByteArray("FooFooFooFoo")); + ba1.insert(2, ba1); + QCOMPARE(ba1, QByteArray("FoFooFooFooFoooFooFooFoo")); + ba1.replace(3, 3, ba1); + QCOMPARE(ba1, QByteArray("FoFFoFooFooFooFoooFooFooFooooFooFoooFooFooFoo")); + ba1 = "FooFoo"; + ba1.replace(char('F'), ba1); + QCOMPARE(ba1, QByteArray("FooFooooFooFoooo")); + ba1 = "FooFoo"; + ba1.replace(char('o'), ba1); + QCOMPARE(ba1, QByteArray("FFooFooFooFooFFooFooFooFoo")); + + ba1.replace(ba1, "xxx"); + QCOMPARE(ba1, QByteArray("xxx")); + ba1.replace(ba1, QByteArray("yyy")); + QCOMPARE(ba1, QByteArray("yyy")); + ba1 += ba1; + QCOMPARE(ba1, QByteArray("yyyyyy")); + + ba1.remove(1, -1); // do nothing + QCOMPARE(ba1, QByteArray("yyyyyy")); + + ba1.replace(0, -1, "ZZZ"); + QCOMPARE(ba1, QByteArray("ZZZyyyyyy")); + } +}; + +void tst_Collections::stack() +{ + QStack<int> stack; + stack.push(1); + stack.push(2); + stack.push(3); + QVectorIterator<int> i = stack; + i.toBack(); + int sum = 0; + while (i.hasPrevious()) + sum += i.previous(); + QVERIFY(sum == 6); + + sum = 0; + for (QStack<int>::iterator i = stack.begin(); i != stack.end(); ++i) + sum += *i; + QVERIFY(sum == 6); + + while (!stack.isEmpty()) + sum -= stack.pop(); + QVERIFY(sum == 0); +} + +void tst_Collections::hash() +{ + const char *hello = "hello"; + const char *world = "world"; + const char *allo = "allo"; + const char *monde = "monde"; + + { + typedef QHash<QString, QString> Hash; + Hash hash; + QString key; + for (int i = 0; i < 10; ++i) { + key[0] = i + '0'; + for (int j = 0; j < 10; ++j) { + key[1] = j + '0'; + hash.insert(key, "V" + key); + } + } + + for (int i = 0; i < 10; ++i) { + key[0] = i + '0'; + for (int j = 0; j < 10; ++j) { + key[1] = j + '0'; + hash.remove(key); + } + } + } + + { + typedef QHash<int, const char *> Hash; + Hash hash; + hash.insert(1, hello); + hash.insert(2, world); + + QVERIFY(hash.size() == 2); + QVERIFY(!hash.isEmpty()); + + { + Hash hash2 = hash; + hash2 = hash; + hash = hash2; + hash2 = hash2; + hash = hash; + hash2.clear(); + hash2 = hash2; + QVERIFY(hash2.size() == 0); + QVERIFY(hash2.isEmpty()); + } + QVERIFY(hash.size() == 2); + + { + Hash hash2 = hash; + hash2[1] = allo; + hash2[2] = monde; + + QVERIFY(hash2[1] == allo); + QVERIFY(hash2[2] == monde); + QVERIFY(hash[1] == hello); + QVERIFY(hash[2] == world); + + hash2[1] = hash[1]; + hash2[2] = hash[2]; + + QVERIFY(hash2[1] == hello); + QVERIFY(hash2[2] == world); + + hash[1] = hash[1]; + QVERIFY(hash[1] == hello); + } + + { + Hash hash2 = hash; + hash2.detach(); + hash2.remove(1); + QVERIFY(hash2.size() == 1); + hash2.remove(1); + QVERIFY(hash2.size() == 1); + hash2.remove(0); + QVERIFY(hash2.size() == 1); + hash2.remove(2); + QVERIFY(hash2.size() == 0); + QVERIFY(hash.size() == 2); + } + + hash.detach(); + + { + Hash::iterator it1 = hash.find(1); + QVERIFY(it1 != hash.end()); + + Hash::iterator it2 = hash.find(0); + QVERIFY(it2 != hash.begin()); + QVERIFY(it2 == hash.end()); + + *it1 = monde; + QVERIFY(*it1 == monde); + QVERIFY(hash[1] == monde); + + *it1 = hello; + QVERIFY(*it1 == hello); + QVERIFY(hash[1] == hello); + + hash[1] = monde; + QVERIFY(it1.key() == 1); + QVERIFY(it1.value() == monde); + QVERIFY(*it1 == monde); + QVERIFY(hash[1] == monde); + + hash[1] = hello; + QVERIFY(*it1 == hello); + QVERIFY(hash[1] == hello); + } + + { + const Hash hash2 = hash; + + Hash::const_iterator it1 = hash2.find(1); + QVERIFY(it1 != hash2.end()); + QVERIFY(it1.key() == 1); + QVERIFY(it1.value() == hello); + QVERIFY(*it1 == hello); + + Hash::const_iterator it2 = hash2.find(2); + QVERIFY(it1 != it2); + QVERIFY(it1 != hash2.end()); + QVERIFY(it2 != hash2.end()); + + int count = 0; + it1 = hash2.begin(); + while (it1 != hash2.end()) { + count++; + ++it1; + } + QVERIFY(count == 2); + + count = 0; + it1 = hash.begin(); + while (it1 != hash.end()) { + count++; + ++it1; + } + QVERIFY(count == 2); + } + + { + QVERIFY(hash.contains(1)); + QVERIFY(hash.contains(2)); + QVERIFY(!hash.contains(0)); + QVERIFY(!hash.contains(3)); + } + + { + QVERIFY(hash.value(1) == hello); + QVERIFY(hash.value(2) == world); + QVERIFY(hash.value(3) == 0); + QVERIFY(hash.value(1, allo) == hello); + QVERIFY(hash.value(2, allo) == world); + QVERIFY(hash.value(3, allo) == allo); + QVERIFY(hash.value(0, monde) == monde); + } + + { + QHash<int,LargeStatic> hash; + for (int i = 0; i < 10; i++) + hash.insert(i, LargeStatic()); + QVERIFY(LargeStatic::count == 10); + hash.remove(7); + QVERIFY(LargeStatic::count == 9); + + } + QVERIFY(LargeStatic::count == 0); + { + QHash<int, int*> hash; + QVERIFY(((const QHash<int,int*>*) &hash)->operator[](7) == 0); + } + + { + /* + This test relies on a certain implementation of + QHash. If you change the way QHash works internally, + change this test as well. + */ + QHash<int, int> hash; + for (int i = 0; i < 1000; ++i) + hash.insert(i, i); + QVERIFY(hash.capacity() == 1031); + hash.squeeze(); + QVERIFY(hash.capacity() == 521); + + hash.insert(12345, 12345); + QVERIFY(hash.capacity() == 1031); + + for (int j = 0; j < 900; ++j) + hash.remove(j); + QVERIFY(hash.capacity() == 257); + hash.squeeze(); + QVERIFY(hash.capacity() == 67); + hash.reserve(0); + } + } + + { + QHash<int, QString> hash; + hash.insert(0, "Hello"); + + QHash<int, QString>::iterator it = hash.begin(); + QVERIFY((*it)[0] == QChar('H')); + QVERIFY(it->constData()[0] == QChar('H')); + it->replace(QChar('H'), QChar('X')); + QVERIFY(*hash.begin() == "Xello"); + + QHash<int, QString>::const_iterator cit = hash.constBegin(); + QVERIFY((*cit).toLower() == "xello"); + QVERIFY(cit->toUpper() == "XELLO"); + + cit = hash.cbegin(); + QVERIFY((*cit).toLower() == "xello"); + QVERIFY(cit->toUpper() == "XELLO"); + } + + { + QHash<int, QString> hash1, hash2; + hash1.insertMulti(1, "Alpha"); + hash1.insertMulti(1, "Gamma"); + hash2.insertMulti(1, "Beta"); + hash2.insertMulti(1, "Gamma"); + hash2.insertMulti(1, "Gamma"); + + hash1.unite(hash2); + QCOMPARE(hash1.size(), 5); + QCOMPARE(hash1.values(), + (QList<QString>() << "Gamma" << "Gamma" << "Beta" << "Gamma" << "Alpha")); + + hash2 = hash1; + hash2.unite(hash2); + QCOMPARE(hash2.size(), 10); + QCOMPARE(hash2.values(), hash1.values() + hash1.values()); + } +} + +void tst_Collections::map() +{ + const char *hello = "hello"; + const char *world = "world"; + const char *allo = "allo"; + const char *monde = "monde"; + + { + typedef QMap<int, const char *> Map; + Map map; + map.insert(1, hello); + map.insert(2, world); + + QVERIFY(*map.begin() == hello); + + QVERIFY(map.size() == 2); + QVERIFY(!map.isEmpty()); + + { + Map map2 = map; + map2 = map; + map = map2; + map2 = map2; + map = map; + map2.clear(); + map2 = map2; + QVERIFY(map2.size() == 0); + QVERIFY(map2.isEmpty()); + } + QVERIFY(map.size() == 2); + + { + Map map2 = map; + map2[1] = allo; + map2[2] = monde; + + QVERIFY(map2[1] == allo); + QVERIFY(map2[2] == monde); + QVERIFY(map[1] == hello); + QVERIFY(map[2] == world); + + map2[1] = map[1]; + map2[2] = map[2]; + + QVERIFY(map2[1] == hello); + QVERIFY(map2[2] == world); + + map[1] = map[1]; + QVERIFY(map[1] == hello); + } + + { + Map map2 = map; + map2.detach(); + map2.remove(1); + QVERIFY(map2.size() == 1); + map2.remove(1); + QVERIFY(map2.size() == 1); + map2.remove(0); + QVERIFY(map2.size() == 1); + map2.remove(2); + QVERIFY(map2.size() == 0); + QVERIFY(map.size() == 2); + } + + map.detach(); + + { + Map::iterator it1 = map.find(1); + QVERIFY(it1 == map.begin()); + QVERIFY(it1 != map.end()); + + Map::iterator it2 = map.find(0); + QVERIFY(it2 != map.begin()); + QVERIFY(it2 == map.end()); + + *it1 = monde; + QVERIFY(*it1 == monde); + QVERIFY(map[1] == monde); + + *it1 = hello; + QVERIFY(*it1 == hello); + QVERIFY(map[1] == hello); + + map[1] = monde; + QVERIFY(it1.key() == 1); + QVERIFY(it1.value() == monde); + QVERIFY(*it1 == monde); + QVERIFY(map[1] == monde); + + map[1] = hello; + QVERIFY(*it1 == hello); + QVERIFY(map[1] == hello); + + *++it1 = allo; + QVERIFY(*it1 == allo); + QVERIFY(map[2] == allo); + *it1 = world; + + ++it1; + QVERIFY(it1 == map.end()); + + int count = 0; + it1 = map.begin(); + while (it1 != map.end()) { + count++; + ++it1; + } + QVERIFY(count == 2); + } + + { + const Map map2 = map; + + Map::const_iterator it1 = map2.find(1); + QVERIFY(it1 != map2.end()); + QVERIFY(it1.key() == 1); + QVERIFY(it1.value() == hello); + QVERIFY(*it1 == hello); + ++it1; + + Map::const_iterator it2 = map2.find(2); + QVERIFY(it1 == it2); + ++it1; + QVERIFY(it1 == map2.end()); + QVERIFY(it2 != map2.end()); + QVERIFY(it1 != it2); + + int count = 0; + it1 = map2.begin(); + while (it1 != map2.end()) { + count++; + ++it1; + } + QVERIFY(count == 2); + + count = 0; + it1 = map.begin(); + while (it1 != map.end()) { + count++; + ++it1; + } + QVERIFY(count == 2); + } + + { + QVERIFY(map.contains(1)); + QVERIFY(map.contains(2)); + QVERIFY(!map.contains(0)); + QVERIFY(!map.contains(3)); + } + + { + QVERIFY(map.value(1) == hello); + QVERIFY(map.value(2) == world); + QVERIFY(map.value(3) == 0); + QVERIFY(map.value(1, allo) == hello); + QVERIFY(map.value(2, allo) == world); + QVERIFY(map.value(3, allo) == allo); + QVERIFY(map.value(0, monde) == monde); + } + int originalLargeStaticCount = LargeStatic::count; + { + QMap<int,LargeStatic> map; + for (int i = 0; i < 10; i++) + map.insert(i, LargeStatic()); + QVERIFY(LargeStatic::count == (originalLargeStaticCount + 10)); + map.remove(7); + QVERIFY(LargeStatic::count == (originalLargeStaticCount + 9)); + + } + QVERIFY(LargeStatic::count == originalLargeStaticCount); + { + QMap<int, int*> map; + QVERIFY(((const QMap<int,int*>*) &map)->operator[](7) == 0); + } + + { + QMap<int, int> map; + map[0] = 1; + map[1] = 2; + map[2] = 4; + map[3] = 8; + int sum = 0; + int sumkey = 0; + QMapIterator<int,int> i = map; + while (i.hasNext()) { + sum += i.next().value(); + sumkey += i.key(); + } + QVERIFY(sum == 15); + QVERIFY(sumkey == 6); + } + { + QMap<int, int> map; + map[0] = 1; + map[1] = 2; + map[2] = 4; + map[3] = 8; + int sum = 0; + QMutableMapIterator<int,int> i = map; + while (i.hasNext()) + if (i.next().key() == 2) + i.remove(); + i.toFront(); + while (i.hasNext()) { + sum += i.next().value(); + i.setValue(10); + i.value() += 22; + QVERIFY(i.value() == 32); + } + QVERIFY(sum == 11); + } + { + QMap<int, int> map; + map[0] = 1; + QMutableMapIterator<int,int> i(map); + i.toBack(); + while (i.hasPrevious()) { + i.previous(); + QCOMPARE(i.key(), 0); + QCOMPARE(i.value(), 1); + } + } + } + + { + QMultiMap<QString, int> map1; + map1.insert("1", 2); + map1.insert("1", 1); + map1.insert("a", 3); + map1.insert("a", 2); + map1.insert("a", 1); + map1.insert("b", 2); + map1.insert("b", 1); + + QMultiMap<QString, int>::iterator j1, k1; + + j1 = map1.lowerBound("0"); k1 = map1.upperBound("0"); + QVERIFY(j1 == map1.begin() && k1 == j1); + j1 = map1.lowerBound("00"); k1 = map1.upperBound("00"); + QVERIFY(j1 == map1.find("1") && k1 == j1); + j1 = map1.lowerBound("1"); k1 = map1.upperBound("1"); + QVERIFY(j1 == map1.find("1") && --(--k1) == j1); + j1 = map1.lowerBound("11"); k1 = map1.upperBound("11"); + QVERIFY(j1 == map1.find("a") && k1 == j1); + j1 = map1.lowerBound("a"); k1 = map1.upperBound("a"); + QVERIFY(j1 == map1.find("a") && k1 == map1.find("b")); + QVERIFY(j1.value() == 1 && j1.value() == 1); + j1 = map1.lowerBound("aa"); k1 = map1.upperBound("aa"); + QVERIFY(j1 == map1.find("b") && k1 == j1); + QVERIFY(j1.value() == 1); + j1 = map1.lowerBound("b"); k1 = map1.upperBound("b"); + QVERIFY(j1 == map1.find("b") && k1 == map1.end()); + QVERIFY(j1.value() == 1); + j1 = map1.lowerBound("bb"); k1 = map1.upperBound("bb"); + QVERIFY(j1 == map1.end() && k1 == j1); + + const QMultiMap<QString, int> map2 = map1; + QMultiMap<QString, int>::const_iterator j2, k2; + + j2 = map2.lowerBound("0"); k2 = map2.upperBound("0"); + QVERIFY(j2 == map2.begin() && k2 == j2); + j2 = map2.lowerBound("00"); k2 = map2.upperBound("00"); + QVERIFY(j2 == map2.find("1") && k2 == j2); + j2 = map2.lowerBound("1"); k2 = map2.upperBound("1"); + QVERIFY(j2 == map2.find("1") && --(--k2) == j2); + j2 = map2.lowerBound("11"); k2 = map2.upperBound("11"); + QVERIFY(j2 == map2.find("a") && k2 == j2); + j2 = map2.lowerBound("a"); k2 = map2.upperBound("a"); + QVERIFY(j2 == map2.find("a") && k2 == map2.find("b")); + QVERIFY(j2.value() == 1 && j2.value() == 1); + j2 = map2.lowerBound("aa"); k2 = map2.upperBound("aa"); + QVERIFY(j2 == map2.find("b") && k2 == j2); + QVERIFY(j2.value() == 1); + j2 = map2.lowerBound("b"); k2 = map2.upperBound("b"); + QVERIFY(j2 == map2.find("b") && k2 == map2.end()); + QVERIFY(j2.value() == 1); + j2 = map2.lowerBound("bb"); k2 = map2.upperBound("bb"); + QVERIFY(j2 == map2.end() && k2 == j2); + } + + { + QMap<int, QString> map; + map.insert(0, "Hello"); + + QMap<int, QString>::iterator it = map.begin(); + QVERIFY((*it)[0] == QChar('H')); + QVERIFY(it->constData()[0] == QChar('H')); + it->replace(QChar('H'), QChar('X')); + QVERIFY(*map.begin() == "Xello"); + + QMap<int, QString>::const_iterator cit = map.constBegin(); + QVERIFY((*cit).toLower() == "xello"); + QVERIFY(cit->toUpper() == "XELLO"); + + cit = map.cbegin(); + QVERIFY((*cit).toLower() == "xello"); + QVERIFY(cit->toUpper() == "XELLO"); + } + + { + QMap<int, QString> map1, map2; + map1.insertMulti(1, "Alpha"); + map1.insertMulti(1, "Gamma"); + map2.insertMulti(1, "Beta"); + map2.insertMulti(1, "Gamma"); + map2.insertMulti(1, "Gamma"); + + map1.unite(map2); + QCOMPARE(map1.size(), 5); + QCOMPARE(static_cast<QStringList>(map1.values()), + (QStringList() << "Gamma" << "Gamma" << "Beta" << "Gamma" << "Alpha")); + + map2 = map1; + map2.unite(map2); + QCOMPARE(map2.size(), 10); + QCOMPARE(map2.values(), map1.values() + map1.values()); + } +} + +void tst_Collections::qstring() +{ + QString hello = "hello"; + QString ello = "ello"; + QString World = "World"; + QString Wor = "Wor"; + QString helloWorld = "helloWorld"; + + QString s = hello + "World"; + QVERIFY(hello + World == helloWorld); + QVERIFY(hello + "World" == helloWorld); + QVERIFY("hello" + World == helloWorld); + + QVERIFY('h' + ello == hello); + QVERIFY(Wor + 'l' + 'd' == "World"); + QVERIFY(hello + World == "helloWorld"); + QVERIFY(hello + "World" == "helloWorld"); + QVERIFY("hello" + World == "helloWorld"); + QVERIFY('h' + ello == "hello"); + QVERIFY(Wor + 'l' + 'd' == "World"); + QVERIFY("helloWorld" == hello + World); + QVERIFY("helloWorld" == hello + "World"); + QVERIFY("helloWorld" == "hello" + World); + QVERIFY("hello" == 'h' + ello); + QVERIFY("World" == Wor + 'l' + 'd'); + + QVERIFY(hello.contains('e')); + QVERIFY (true == hello.contains('e')); + QVERIFY (hello.contains('e') != false); + + QVERIFY(hello.indexOf('e') == 1); + QVERIFY(hello.indexOf('e', -10) == 1); + QVERIFY(hello.indexOf('l') == 2); + QVERIFY(hello.indexOf('l',2) == 2); + QVERIFY(hello.indexOf('l',3) == 3); + + QString large = "000 100 200 300 400 500 600 700 800 900"; + + QVERIFY(large.indexOf("700") == 28); + QVERIFY(large.indexOf("700", 28) == 28); + QVERIFY(large.indexOf("700", 29) == -1); + QVERIFY(large.lastIndexOf("700") == 28); + QVERIFY(large.lastIndexOf("700", 28) == 28); + QVERIFY(large.lastIndexOf("700", 27) == -1); + + QVERIFY(large.contains("200")); + QVERIFY(!large.contains("201")); + QVERIFY(large.contains('3')); + QVERIFY(!large.contains('a')); + + QVERIFY(large.count("00") == 11); + QVERIFY(large.count('3') == 1); + QVERIFY(large.count('0') == 21); + QVERIFY(large.count("0") == 21); + QVERIFY(large.count("200") == 1); + QVERIFY(large.count("201") == 0); + + QVERIFY(hello.left(0) == ""); + QVERIFY(!hello.left(0).isNull()); + QVERIFY(hello.left(1) == "h"); + QVERIFY(hello.left(2) == "he"); + QVERIFY(hello.left(200) == "hello"); + QVERIFY(hello.left(hello.size()) == hello); + QVERIFY(hello.left(hello.size()+1) == hello); + + QVERIFY(hello.right(0) == ""); + QVERIFY(!hello.right(0).isNull()); + QVERIFY(hello.right(1) == "o"); + QVERIFY(hello.right(2) == "lo"); + QVERIFY(hello.right(200) == "hello"); + QVERIFY(hello.right(hello.size()) == hello); + QVERIFY(hello.right(hello.size()+1) == hello); + + QVERIFY(!hello.mid(0, 0).isNull()); + QVERIFY(hello.mid(0, 1) == "h"); + QVERIFY(hello.mid(0, 2) == "he"); + QVERIFY(hello.mid(0, 200) == "hello"); + QVERIFY(hello.mid(0) == "hello"); + QVERIFY(hello.mid(0, hello.size()) == hello); + QVERIFY(hello.mid(0, hello.size()+1) == hello); + + QVERIFY(hello.mid(hello.size()-0) == ""); + QVERIFY(hello.mid(hello.size()-0).isEmpty()); + QVERIFY(!hello.mid(hello.size()-0).isNull()); + QVERIFY(hello.mid(hello.size()-1) == "o"); + QVERIFY(hello.mid(hello.size()-2) == "lo"); + QVERIFY(hello.mid(hello.size()-200) == "hello"); + + QString null; + QString nonNull = ""; + QVERIFY(null.left(10).isNull()); + QVERIFY(null.mid(0).isNull()); + + QVERIFY(null == QString::null); + QVERIFY(QString::null == null); + QVERIFY(nonNull != QString::null); + QVERIFY(QString::null != nonNull); + QVERIFY(null == nonNull); + QVERIFY(QString::null == QString::null); + + QString fill = "123"; + fill.fill('a'); + QVERIFY(fill == "aaa"); + + s.clear(); + s = hello; + s.append(World); + QVERIFY(s == helloWorld); + s.clear(); + s = World; + s.insert(0,hello); + QVERIFY(s == helloWorld); + s = "012345"; + s.insert(3, 'E'); + QVERIFY(s == "012E345"); + s.insert(3, "INSID"); + QVERIFY(s == "012INSIDE345"); + s = "short"; + s.insert(7, 'E'); + QVERIFY(s == "short E"); + s = "short"; + s.insert(7, "END"); + QVERIFY(s == "short END"); + + QVERIFY(QString::fromLatin1("hello") == "hello"); + + s = "first"; + QVERIFY(s.toLatin1() == "first"); + s = "second"; + QVERIFY(s.toLatin1() == "second"); + s.clear(); + QVERIFY(s.isNull()); + QVERIFY(s.toLatin1().size() == 0); + QVERIFY(s.toLatin1().isEmpty()); + QVERIFY(s.toLatin1().isNull()); + + s = "first-utf8"; + QVERIFY(s.toUtf8() == "first-utf8"); + s = "second-utf8"; + QVERIFY(s.toUtf8() == "second-utf8"); + s.clear(); + QVERIFY(s.isNull()); + QVERIFY(s.toUtf8().size() == 0); + QVERIFY(s.toUtf8().isEmpty()); + QVERIFY(s.toUtf8().isNull()); + + s = "first-utf8"; + QVERIFY(s.toUtf8() == "first-utf8"); + s = "second-utf8"; + QVERIFY(s.toUtf8() == "second-utf8"); + s.clear(); + QVERIFY(s.isNull()); + QVERIFY(s.toUtf8().size() == 0); + QVERIFY(s.toUtf8().isEmpty()); + QVERIFY(s.toUtf8().isNull()); + + s = "first-local8Bit"; + QVERIFY(s.toLocal8Bit() == "first-local8Bit"); + s = "second-local8Bit"; + QVERIFY(s.toLocal8Bit() == "second-local8Bit"); + s.clear(); + QVERIFY(s.isNull()); + QVERIFY(s.toLocal8Bit().size() == 0); + QVERIFY(s.toLocal8Bit().isEmpty()); + + s = "first-ascii"; + QVERIFY(s.toLatin1() == "first-ascii"); + s = "second-ascii"; + QVERIFY(s.toLatin1() == "second-ascii"); + s.clear(); + QVERIFY(s.isNull()); + QVERIFY(s.toLatin1().size() == 0); + QVERIFY(s.toLatin1().isEmpty()); + QVERIFY(s.toLatin1().isNull()); + + s = "ascii"; + s += QChar((uchar) 0xb0); + QVERIFY(s.toUtf8() != s.toLatin1()); + QCOMPARE(s[s.length()-1].unicode(), (ushort)0xb0); + QVERIFY(s.left(s.length()-1) == "ascii"); + + QVERIFY(s == QString::fromUtf8(s.toUtf8().constData())); + + s = "12"; + s.append('3'); + s += '4'; + QVERIFY(s == "1234"); + + s = "repend"; + s.prepend('p'); + QVERIFY(s == "prepend"); + s.prepend("abc "); + QVERIFY(s == "abc prepend"); + + s = " whitespace "; + QVERIFY(s.trimmed() == "whitespace"); + s = " lots of stuff "; + QVERIFY(s.simplified() == "lots of stuff"); + + s = "a hat, a stick, a ski"; + QVERIFY(s[2] == 'h'); + QVERIFY(s[1] < 'b'); + + + s = "12223"; + s.remove(1, 2); + QVERIFY(s == "123"); + + s = "(%1)(%2)"; + s = s.arg("foo").arg(7); + QVERIFY(s == "(foo)(7)"); + + s = "stl rocks"; + std::string stl_string = s.toStdString(); // TODO: std::string stl_string = s does not work. + QVERIFY(s == "stl rocks"); + s = QString::fromStdString(stl_string); // TODO: s = stl_string does not work. + QVERIFY(s == "stl rocks"); + + { + QString str("Bananas"); + QVERIFY(str.startsWith("Ban")); + QVERIFY(false == str.startsWith("Car")); + } + { + QString str("Bananas"); + QVERIFY(str.endsWith("anas")); + QVERIFY(false == str.endsWith("pple")); + } + + + QString str = "Hello"; + QString cstr = QString::fromRawData(str.unicode(), str.length()); + QVERIFY(str == "Hello"); + QVERIFY(cstr == "Hello"); + cstr.clear(); + QVERIFY(str == "Hello"); + QVERIFY(cstr.isEmpty()); + + { + QString str1("Foo"); + str1.prepend(str1); + QCOMPARE(str1, QString("FooFoo")); + str1.append(str1); + QCOMPARE(str1, QString("FooFooFooFoo")); + str1.insert(2, str1); + QCOMPARE(str1, QString("FoFooFooFooFoooFooFooFoo")); + str1.replace(3, 3, str1); + QCOMPARE(str1, QString("FoFFoFooFooFooFoooFooFooFooooFooFoooFooFooFoo")); + str1 = "FooFoo"; + str1.replace(char('F'), str1); + QCOMPARE(str1, QString("FooFooooFooFoooo")); + str1 = "FooFoo"; + str1.replace(char('o'), str1); + QCOMPARE(str1, QString("FFooFooFooFooFFooFooFooFoo")); + + str1 = "Foo"; + str1.replace("Foo", str1); + QCOMPARE(str1, QString("Foo")); + str1.replace(str1, str1); + QCOMPARE(str1, QString("Foo")); + + str1 = "Foo"; + str1.replace("Foo", str1, Qt::CaseInsensitive); + QCOMPARE(str1, QString("Foo")); + str1.replace(str1, str1); + QCOMPARE(str1, QString("Foo")); + + str1 = "FooFoo"; + str1.reserve(100); + str1.replace("oo", str1); + QCOMPARE(str1, QString("FFooFooFFooFoo")); + + str1 = "Bar"; + str1.replace("FooFoo", str1); + QCOMPARE(str1, QString("Bar")); + + str1.replace(str1, "xxx"); + QCOMPARE(str1, QString("xxx")); + str1.replace(str1, QString("yyy")); + QCOMPARE(str1, QString("yyy")); + str1 += str1; + QCOMPARE(str1, QString("yyyyyy")); + } +} + + +void tst_Collections::bitArray() +{ + QBitArray ba(20); + QVERIFY(ba.testBit(17) == false); + ba.setBit(17); + QVERIFY(ba.size() == 20); + QVERIFY(ba.testBit(17)==true); + QVERIFY(!ba.testBit(16)); + ba[4] = true; + QVERIFY(ba.testBit(4)); + QVERIFY(ba[4]); + int sum = 0; + for(int i = 0; i < 20; i++) + sum += ba.testBit(i) ? 1 : 0; + QVERIFY(sum == 2); + + ba = QBitArray(7, true); + QVERIFY(ba.size() == 7); + QVERIFY(ba[5]); + + ba = QBitArray(3); + ba[0] = ba[2] = true; + + QBitArray nba(3); + nba[1] = true; + + QVERIFY(~ba == nba); + +}; + +struct CacheFoo +{ + CacheFoo(int v):val(v) { counter++; } + ~CacheFoo() { counter--; } + int val; + static int counter; + bool isDetached() const { return val != 2; } +}; + +int CacheFoo::counter = 0; + +void tst_Collections::cache() +{ + { + QCache<int, CacheFoo> cache(120); + int i; + for (i = 0; i < 30; i++) { + cache.object(10); + cache.insert(i, new CacheFoo(i), i); + } + + QVERIFY(cache.contains(10)); + QVERIFY(!cache.contains(1)); + QVERIFY(!cache.contains(2)); + delete cache.take(10); + } + { + QCache<int, QString> cache(120); + int i; + QString two; + for (i = 0; i < 30; i++) { + QString s = QString::number(i); + cache.insert(i, new QString(s), i); + if (i == 2) + two = s; + } + QVERIFY(!cache.contains(3)); + QVERIFY(!cache.contains(2)); + } + { + QCache<int, int> cache(100); + cache.insert(2, new int(2)); + *cache[2] = 3; + QVERIFY(*cache.object(2) == 3); + } + + QVERIFY(CacheFoo::counter == 0); + +} + +void tst_Collections::regexp() +{ + QRegExp rx("^\\d\\d?$"); + QVERIFY(rx.indexIn("123") == -1); + QVERIFY(rx.indexIn("-6") == -1); + QVERIFY(rx.indexIn("6") == 0) ; +} + +void tst_Collections::pair() +{ + QPair<double, int> p; + QVERIFY(p.first == 0.0); + QVERIFY(p.second == 0); + + QPair<int, QString> a(1, "Zebra"), b(2, "Ying"), c(3, "Yang"), d(3, "Ying"), e(5, "Alabama"); + QVERIFY(a.first == 1); + QVERIFY(a.second == "Zebra"); + QVERIFY(a == qMakePair(1, QString("Zebra"))); + + QVERIFY(a == a && b == b && c == c && d == d && e == e); + QVERIFY(a != b && a != c && a != d && a != e && b != c && b != d && b != e && c != d && c != e + && d != e); + + QVERIFY(a < b && b < c && c < d && d < e); + QVERIFY(a <= b && b <= c && c <= d && d <= e); + + QVERIFY(e > d && d > c && c > b && b > a); + QVERIFY(e >= d && d >= c && c >= b && b >= a); + + QVERIFY(!(a > b || b > c || c > d || d > e)); + QVERIFY(!(a >= b || b >= c || c >= d || d >= e)); + + QVERIFY(!(e < d || d < c || c < b || b < a)); + QVERIFY(!(e <= d || d <= c || c <= b || b <= a)); + + QVERIFY(a <= a && b <= b && c <= c && d <= d && e <= e); + QVERIFY(!(a < a || b < b || c < c || d < d || e < e)); + + QVERIFY(a >= a && b >= b && c >= c && d >= d && e >= e); + QVERIFY(!(a > a || b > b || c > c || d > d || e > e)); +} + +/* + These test that Java-style mutable iterators don't trash shared + copy (the setSharable() mechanism). +*/ + +template <class Container> +void populate(Container &); + +template <> +void populate(QList<int> &container) +{ + container << 1 << 2 << 4 << 8; +} + +template <> +void populate(QLinkedList<int> &container) +{ + container << 1 << 2 << 4 << 8; +} + +template <> +void populate(QVector<int> &container) +{ + container << 1 << 2 << 4 << 8; +} + +template <> +void populate(QMap<int, int> &container) +{ + container.insert(1, 1); + container.insert(2, 2); + container.insert(4, 4); + container.insert(8, 8); +} + +template <> +void populate(QHash<int, int> &container) +{ + container.insert(1, 1); + container.insert(2, 2); + container.insert(4, 4); + container.insert(8, 8); +} + +template <class Container> +bool isSharable(const Container &container) +{ + Container copy = container; + return !container.isDetached(); +} + +template <class Container> Container newInstance() { + Container container; + populate(container); + if (!container.isEmpty()) + return container; + return Container(); +} + +template <class Container, class ContainerMutableIterator> +void testContainer() +{ + /* + Verify that shared_null's 'sharable' flag is set to true. + */ + { + Container c1; + QVERIFY(!c1.isDetached()); + + Container c2 = c1; + QVERIFY(!c1.isDetached()); + QVERIFY(!c2.isDetached()); + } + + /* + Verify that the 'sharable' flag is true in populated containers. + */ + { + Container c1; + populate(c1); + QVERIFY(c1.size() == 4); + QVERIFY(c1.isDetached()); + + Container c2 = c1; + QVERIFY(c1.size() == 4); + QVERIFY(c2.size() == 4); + QVERIFY(!c1.isDetached()); + QVERIFY(!c2.isDetached()); + } + + /* test that the move operators work properly */ + { + Container c1 = Container(newInstance<Container>()); + QVERIFY(c1.size() == 4); + QVERIFY(c1 == newInstance<Container>()); + c1 = newInstance<Container>(); + QVERIFY(c1.size() == 4); + QVERIFY(c1 == newInstance<Container>()); + Container c2 = qMove(c1); + QVERIFY(c2.size() == 4); + QVERIFY(c2 == newInstance<Container>()); + } +} + +#define TEST_SEQUENTIAL_CONTAINER(Container) \ + testContainer<Q##Container<int>, QMutable##Container##Iterator<int> >() \ + +#define TEST_ASSOCIATIVE_CONTAINER(Container) \ + testContainer<Q##Container<int, int>, QMutable##Container##Iterator<int, int> >() + +void tst_Collections::sharableQList() +{ + TEST_SEQUENTIAL_CONTAINER(List); +} + +void tst_Collections::sharableQLinkedList() +{ + TEST_SEQUENTIAL_CONTAINER(LinkedList); +} + +void tst_Collections::sharableQVector() +{ + TEST_SEQUENTIAL_CONTAINER(Vector); +} + +void tst_Collections::sharableQMap() +{ + TEST_ASSOCIATIVE_CONTAINER(Map); +} + +void tst_Collections::sharableQHash() +{ + TEST_ASSOCIATIVE_CONTAINER(Hash); +} + +static int getList_calls = 0; +QList<int> getList() +{ + ++getList_calls; + QList<int> list; + list << 1 << 2 << 3 << 4 << 5 << 6; + return list; +} + + +void tst_Collections::q_foreach() +{ + QList<int> list; + list << -2 << -1 << 0 << 1 << 2; + + int sum = 0; + int j = 0; + foreach(int i, list) { + QCOMPARE(i, list.at(j)); + sum += i; + ++j; + } + QCOMPARE(sum, 0); + + // again, but without scope + foreach(int i, list) + sum += i; + QCOMPARE(sum, 0); + + foreach(int i, list) { + sum += i; + if (i == 0) + break; + } + QCOMPARE(sum, -3); + + sum = 0; + foreach(int i, list) { + if (i < 0) + continue; + sum += i; + } + QCOMPARE(sum, 3); + + sum = 0; + getList_calls = 0; + foreach(int i, getList()) + sum += i; + QCOMPARE(sum, 21); + QCOMPARE(getList_calls, 1); +} + + +void tst_Collections::conversions() +{ +#define STUFF "A" << "C" << "B" << "A" + + { + QList<QString> list1; + list1 << STUFF; + + QVector<QString> vect1 = list1.toVector(); + QCOMPARE(list1.size(), 4); + QVERIFY(vect1 == (QVector<QString>() << STUFF)); + + QList<QString> list2 = vect1.toList(); + QCOMPARE(list2.size(), 4); + QVERIFY(list2 == (QList<QString>() << STUFF)); + + QSet<QString> set1 = list1.toSet(); + QCOMPARE(set1.size(), 3); + QVERIFY(set1.contains("A")); + QVERIFY(set1.contains("B")); + QVERIFY(set1.contains("C")); + QVERIFY(!set1.contains("D")); + + QList<QString> list3 = set1.toList(); + QCOMPARE(list3.size(), 3); + QVERIFY(list3.contains("A")); + QVERIFY(list3.contains("B")); + QVERIFY(list3.contains("C")); + QVERIFY(!list3.contains("D")); + + QVERIFY(QList<int>().toVector().isEmpty()); + QVERIFY(QList<int>().toSet().isEmpty()); + QVERIFY(QVector<int>().toList().isEmpty()); + QVERIFY(QSet<int>().toList().isEmpty()); + } + + { + QList<QString> list1; + list1 << STUFF; + + QVector<QString> vect1 = QVector<QString>::fromList(list1); + QCOMPARE(list1.size(), 4); + QVERIFY(vect1 == (QVector<QString>() << STUFF)); + + QList<QString> list2 = QList<QString>::fromVector(vect1); + QCOMPARE(list2.size(), 4); + QVERIFY(list2 == (QList<QString>() << STUFF)); + + QSet<QString> set1 = QSet<QString>::fromList(list1); + QCOMPARE(set1.size(), 3); + QVERIFY(set1.contains("A")); + QVERIFY(set1.contains("B")); + QVERIFY(set1.contains("C")); + QVERIFY(!set1.contains("D")); + + QList<QString> list3 = QList<QString>::fromSet(set1); + QCOMPARE(list3.size(), 3); + QVERIFY(list3.contains("A")); + QVERIFY(list3.contains("B")); + QVERIFY(list3.contains("C")); + QVERIFY(!list3.contains("D")); + + QVERIFY(QVector<int>::fromList(QList<int>()).isEmpty()); + QVERIFY(QSet<int>::fromList(QList<int>()).isEmpty()); + QVERIFY(QList<int>::fromVector(QVector<int>()).isEmpty()); + QVERIFY(QList<int>::fromSet(QSet<int>()).isEmpty()); + } +#undef STUFF +} + +void tst_Collections::javaStyleIterators() +{ + QStringList list; + list << "a" << "b" << "c"; + QMutableStringListIterator i(list); + while (i.hasNext()) { + i.next(); + i.setValue(""); + } + while (i.hasPrevious()) { + i.previous(); + QVERIFY(i.value().isEmpty()); + i.value() = "x"; + QCOMPARE(i.value(), QString("x")); + } +} + +template <class Container> +void testLinkedListLikeStlIterators() +{ + Container fake; + typename Container::value_type t; + fake << t; + + typename Container::iterator i1 = fake.begin(), i2 = i1 + 1; + typename Container::const_iterator c1 = i1, c2 = c1 + 1; + + QVERIFY(i1 == i1); + QVERIFY(i1 == c1); + QVERIFY(c1 == i1); + QVERIFY(c1 == c1); + QVERIFY(i2 == i2); + QVERIFY(i2 == c2); + QVERIFY(c2 == i2); + QVERIFY(c2 == c2); + + QVERIFY(i1 != i2); + QVERIFY(i1 != c2); + QVERIFY(c1 != i2); + QVERIFY(c1 != c2); + QVERIFY(i2 != i1); + QVERIFY(i2 != c1); + QVERIFY(c2 != i1); + QVERIFY(c2 != c1); +} + +template <class Container> +void testListLikeStlIterators() +{ + testLinkedListLikeStlIterators<Container>(); + + Container fake; + typename Container::value_type t; + fake << t; + + typename Container::iterator i1 = fake.begin(), i2 = i1 + 1; + typename Container::const_iterator c1 = i1, c2 = c1 + 1; + + QVERIFY(i1 < i2); + QVERIFY(i1 < c2); + QVERIFY(c1 < i2); + QVERIFY(c1 < c2); + QVERIFY(!(i2 < i1)); + QVERIFY(!(i2 < c1)); + QVERIFY(!(c2 < i1)); + QVERIFY(!(c2 < c1)); + QVERIFY(!(i1 < i1)); + QVERIFY(!(i1 < c1)); + QVERIFY(!(c1 < i1)); + QVERIFY(!(c1 < c1)); + QVERIFY(!(i2 < i2)); + QVERIFY(!(i2 < c2)); + QVERIFY(!(c2 < i2)); + QVERIFY(!(c2 < c2)); + + QVERIFY(i2 > i1); + QVERIFY(i2 > c1); + QVERIFY(c2 > i1); + QVERIFY(c2 > c1); + QVERIFY(!(i1 > i2)); + QVERIFY(!(i1 > c2)); + QVERIFY(!(c1 > i2)); + QVERIFY(!(c1 > c2)); + QVERIFY(!(i1 > i1)); + QVERIFY(!(i1 > c1)); + QVERIFY(!(c1 > i1)); + QVERIFY(!(c1 > c1)); + QVERIFY(!(i2 > i2)); + QVERIFY(!(i2 > c2)); + QVERIFY(!(c2 > i2)); + QVERIFY(!(c2 > c2)); + + QVERIFY(!(i1 >= i2)); + QVERIFY(!(i1 >= c2)); + QVERIFY(!(c1 >= i2)); + QVERIFY(!(c1 >= c2)); + QVERIFY(i2 >= i1); + QVERIFY(i2 >= c1); + QVERIFY(c2 >= i1); + QVERIFY(c2 >= c1); + QVERIFY(i1 >= i1); + QVERIFY(i1 >= c1); + QVERIFY(c1 >= i1); + QVERIFY(c1 >= c1); + QVERIFY(i2 >= i2); + QVERIFY(i2 >= c2); + QVERIFY(c2 >= i2); + QVERIFY(c2 >= c2); + + QVERIFY(!(i2 <= i1)); + QVERIFY(!(i2 <= c1)); + QVERIFY(!(c2 <= i1)); + QVERIFY(!(c2 <= c1)); + QVERIFY(i1 <= i2); + QVERIFY(i1 <= c2); + QVERIFY(c1 <= i2); + QVERIFY(c1 <= c2); + QVERIFY(i1 <= i1); + QVERIFY(i1 <= c1); + QVERIFY(c1 <= i1); + QVERIFY(c1 <= c1); + QVERIFY(i2 <= i2); + QVERIFY(i2 <= c2); + QVERIFY(c2 <= i2); + QVERIFY(c2 <= c2); +} + +template <class Container> +void testMapLikeStlIterators() +{ + Container fake; + QString k; + QString t; + fake.insert(k, t); + + typename Container::iterator i1 = fake.begin(), i2 = i1 + 1; + typename Container::const_iterator c1 = i1, c2 = c1 + 1; + + QVERIFY(i1 == i1); + QVERIFY(i1 == c1); + QVERIFY(c1 == i1); + QVERIFY(c1 == c1); + QVERIFY(i2 == i2); + QVERIFY(i2 == c2); + QVERIFY(c2 == i2); + QVERIFY(c2 == c2); + + QVERIFY(i1 != i2); + QVERIFY(i1 != c2); + QVERIFY(c1 != i2); + QVERIFY(c1 != c2); + QVERIFY(i2 != i1); + QVERIFY(i2 != c1); + QVERIFY(c2 != i1); + QVERIFY(c2 != c1); +} + +void tst_Collections::constAndNonConstStlIterators() +{ + testListLikeStlIterators<QList<int> >(); + testListLikeStlIterators<QStringList >(); + testLinkedListLikeStlIterators<QLinkedList<int> >(); + testListLikeStlIterators<QVector<int> >(); + testMapLikeStlIterators<QMap<QString, QString> >(); + testMapLikeStlIterators<QMultiMap<QString, QString> >(); + testMapLikeStlIterators<QHash<QString, QString> >(); + testMapLikeStlIterators<QMultiHash<QString, QString> >(); +} + +void tst_Collections::vector_stl_data() +{ + QTest::addColumn<QStringList>("elements"); + + QTest::newRow("empty") << QStringList(); + QTest::newRow("one") << (QStringList() << "Hei"); + QTest::newRow("two") << (QStringList() << "Hei" << "Hopp"); + QTest::newRow("three") << (QStringList() << "Hei" << "Hopp" << "Sann"); +} + +void tst_Collections::vector_stl() +{ + QFETCH(QStringList, elements); + + QVector<QString> vector; + for (int i = 0; i < elements.count(); ++i) + vector << elements.at(i); + + std::vector<QString> stdVector = vector.toStdVector(); + + QCOMPARE(int(stdVector.size()), elements.size()); + + std::vector<QString>::const_iterator it = stdVector.begin(); + for (uint j = 0; j < stdVector.size() && it != stdVector.end(); ++j, ++it) + QCOMPARE(*it, vector[j]); + + QCOMPARE(QVector<QString>::fromStdVector(stdVector), vector); +} + +void tst_Collections::linkedlist_stl_data() +{ + list_stl_data(); +} + +void tst_Collections::linkedlist_stl() +{ + QFETCH(QStringList, elements); + + QLinkedList<QString> list; + for (int i = 0; i < elements.count(); ++i) + list << elements.at(i); + + std::list<QString> stdList = list.toStdList(); + + QCOMPARE(int(stdList.size()), elements.size()); + + std::list<QString>::const_iterator it = stdList.begin(); + QLinkedList<QString>::const_iterator it2 = list.cbegin(); + for (uint j = 0; j < stdList.size(); ++j, ++it, ++it2) + QCOMPARE(*it, *it2); + + QCOMPARE(QLinkedList<QString>::fromStdList(stdList), list); +} + +void tst_Collections::list_stl_data() +{ + QTest::addColumn<QStringList>("elements"); + + QTest::newRow("empty") << QStringList(); + QTest::newRow("one") << (QStringList() << "Hei"); + QTest::newRow("two") << (QStringList() << "Hei" << "Hopp"); + QTest::newRow("three") << (QStringList() << "Hei" << "Hopp" << "Sann"); +} + +void tst_Collections::list_stl() +{ + QFETCH(QStringList, elements); + + QList<QString> list; + for (int i = 0; i < elements.count(); ++i) + list << elements.at(i); + + std::list<QString> stdList = list.toStdList(); + + QCOMPARE(int(stdList.size()), elements.size()); + + std::list<QString>::const_iterator it = stdList.begin(); + for (uint j = 0; j < stdList.size() && it != stdList.end(); ++j, ++it) + QCOMPARE(*it, list[j]); + + QCOMPARE(QList<QString>::fromStdList(stdList), list); +} + +template <typename T> +T qtInit(T * = 0) +{ + return T(); +} + +void tst_Collections::q_init() +{ + QCOMPARE(qtInit<int>(), 0); + QCOMPARE(qtInit<double>(), 0.0); + QCOMPARE(qtInit<QString>(), QString()); + QCOMPARE(qtInit<int *>(), static_cast<int *>(0)); + QCOMPARE(qtInit<double *>(), static_cast<double *>(0)); + QCOMPARE(qtInit<QString *>(), static_cast<QString *>(0)); + QCOMPARE(qtInit<Pod>().i1, 0); + QCOMPARE(qtInit<Pod>().i2, 0); +} + +void tst_Collections::pointersize() +{ + QCOMPARE(int(sizeof(void *)), QT_POINTER_SIZE); +} + +class LessThanComparable +{ +public: + bool operator<(const LessThanComparable &) const { return true; } +}; + +class EqualsComparable +{ +public: + bool operator==(const EqualsComparable &) const { return true; } +}; + +uint qHash(const EqualsComparable &) +{ + return 0; +} + +/* + The following functions instatiates every member functions in the + Qt containers that requires either operator== or operator<. + They are ordered in a concept inheritance tree: + + Container + MutableIterationContainer + Sequence (QLinkedList) + Random Access (QVector, QList, QQueue, QStack) + Pair Associative (QHash, QMap) + Associative (QSet) +*/ +template <typename ContainerType, typename ValueType> +void instantiateContainer() +{ + const ValueType value = ValueType(); + ContainerType container; + const ContainerType constContainer(container); + + typename ContainerType::const_iterator constIt; + constIt = constContainer.begin(); + constIt = container.cbegin(); + container.constBegin(); + + constIt = constContainer.end(); + constIt = constContainer.cend(); + container.constEnd(); + Q_UNUSED(constIt) + + container.clear(); + container.contains(value); + container.count(); + container.empty(); + container.isEmpty(); + container.size(); + + Q_UNUSED((container != constContainer)); + Q_UNUSED((container == constContainer)); + container = constContainer; +} + +template <typename ContainerType, typename ValueType> +void instantiateMutableIterationContainer() +{ + instantiateContainer<ContainerType, ValueType>(); + ContainerType container; + + typename ContainerType::iterator it; + it = container.begin(); + it = container.end(); + Q_UNUSED(it) + + // QSet lacks count(T). + const ValueType value = ValueType(); + container.count(value); +} + +template <typename ContainerType, typename ValueType> +void instantiateSequence() +{ + instantiateMutableIterationContainer<ContainerType, ValueType>(); + +// QVector lacks removeAll(T) +// ValueType value = ValueType(); +// ContainerType container; +// container.removeAll(value); +} + +template <typename ContainerType, typename ValueType> +void instantiateRandomAccess() +{ + instantiateSequence<ContainerType, ValueType>(); + + ValueType value = ValueType(); + ContainerType container; + container.indexOf(value); + container.lastIndexOf(value); +} + +template <typename ContainerType, typename ValueType> +void instantiateAssociative() +{ + instantiateContainer<ContainerType, ValueType>(); + + const ValueType value = ValueType(); + ContainerType container; + const ContainerType constContainer(container); + + container.reserve(1); + container.capacity(); + container.squeeze(); + + container.remove(value); + container.values(); + + container.unite(constContainer); + container.intersect(constContainer); + container.subtract(constContainer); + + Q_UNUSED((container != constContainer)); + Q_UNUSED((container == constContainer)); + container & constContainer; + container &= constContainer; + container &= value; + container + constContainer; + container += constContainer; + container += value; + container - constContainer; + container -= constContainer; + container -= value; + container | constContainer; + container |= constContainer; + container |= value; +} + +template <typename ContainerType, typename KeyType, typename ValueType> +void instantiatePairAssociative() +{ + instantiateMutableIterationContainer<ContainerType, KeyType>(); + + typename ContainerType::iterator it; + typename ContainerType::const_iterator constIt; + const KeyType key = KeyType(); + const ValueType value = ValueType(); + ContainerType container; + const ContainerType constContainer(container); + + it = container.insert(key, value); + container.erase(it); + container.find(key); + container.constFind(key); + constContainer.find(key); + + container.key(value); + container.keys(); + constContainer.keys(); + container.remove(key); + container.take(key); + container.unite(constContainer); + container.value(key); + container.value(key, value); + container.values(); + container.values(key); + container[key]; + const int foo = constContainer[key]; + Q_UNUSED(foo); +} + +/* + Instantiate all Qt containers using a datatype that + defines the minimum amount of operators. +*/ +void tst_Collections::containerInstantiation() +{ + // Instantiate QHash member functions. + typedef QHash<EqualsComparable, int> Hash; + instantiatePairAssociative<Hash, EqualsComparable, int>(); + + Hash hash; + hash.reserve(1); + hash.capacity(); + hash.squeeze(); + + // Instantiate QMap member functions. + typedef QMap<LessThanComparable, int> Map; + instantiatePairAssociative<Map, LessThanComparable, int>(); + + // Instantiate QSet member functions. + typedef QSet<EqualsComparable> Set; + instantiateAssociative<Set, EqualsComparable>(); + + //Instantiate QLinkedList member functions. + typedef QLinkedList<EqualsComparable> LinkedList; + instantiateSequence<LinkedList, EqualsComparable> (); + { + EqualsComparable value; + LinkedList list; + list.removeAll(value); + } + + //Instantiate QList member functions. + typedef QList<EqualsComparable> List; + instantiateRandomAccess<List, EqualsComparable>(); + { + EqualsComparable value; + List list; + list.removeAll(value); + } + + //Instantiate QVector member functions. + typedef QVector<EqualsComparable> Vector; + instantiateRandomAccess<Vector, EqualsComparable>(); + + //Instantiate QQueue member functions. + typedef QQueue<EqualsComparable> Queue; + instantiateRandomAccess<Queue, EqualsComparable>(); + + //Instantiate QStack member functions. + typedef QStack<EqualsComparable> Stack; + instantiateRandomAccess<Stack, EqualsComparable>(); +} + +void tst_Collections::qtimerList() +{ + QList<double> foo; + const int N = 10000; + + foo.append(99.9); + foo.append(99.9); + foo.append(99.9); + + for(int i = 0; i < N; i++) { + foo.removeFirst(); + foo.insert(1, 99.9); + } + + QList<double>::Iterator end = foo.end(); + for (int i = 0; i < (N / 2) - 10; ++i) { + foo.prepend(99.9); + if (foo.end() != end) + return; + } + QFAIL("QList preallocates too much memory"); +} + +#define QVERIFY_TYPE(Type) QVERIFY(sizeof(Type)) + +template <typename Container> +void testContainerTypedefs(Container container) +{ + Q_UNUSED(container) + { QVERIFY_TYPE(typename Container::value_type); } + { QVERIFY_TYPE(typename Container::iterator); } + { QVERIFY_TYPE(typename Container::const_iterator); } + { QVERIFY_TYPE(typename Container::reference); } + { QVERIFY_TYPE(typename Container::const_reference); } + { QVERIFY_TYPE(typename Container::pointer); } + { QVERIFY_TYPE(typename Container::difference_type); } + { QVERIFY_TYPE(typename Container::size_type); } +} + +template <typename Container> +void testPairAssociativeContainerTypedefs(Container container) +{ + Q_UNUSED(container) + +// TODO: Not sure how to define value_type for our associative containers +// { QVERIFY_TYPE(typename Container::value_type); } +// { QVERIFY_TYPE(typename Container::const_iterator); } +// { QVERIFY_TYPE(typename Container::reference); } +// { QVERIFY_TYPE(typename Container::const_reference); } +// { QVERIFY_TYPE(typename Container::pointer); } + + { QVERIFY_TYPE(typename Container::difference_type); } + { QVERIFY_TYPE(typename Container::size_type); } + { QVERIFY_TYPE(typename Container::iterator); } + { QVERIFY_TYPE(typename Container::key_type); } + { QVERIFY_TYPE(typename Container::mapped_type); } +// TODO +// { QVERIFY_TYPE(typename Container::key_compare); } +// { QVERIFY_TYPE(typename Container::value_comare); } +} + +template <typename Container> +void testSetContainerTypedefs(Container container) +{ + Q_UNUSED(container) + { QVERIFY_TYPE(typename Container::iterator); } + { QVERIFY_TYPE(typename Container::const_iterator); } + { QVERIFY_TYPE(typename Container::reference); } + { QVERIFY_TYPE(typename Container::const_reference); } + { QVERIFY_TYPE(typename Container::pointer); } + { QVERIFY_TYPE(typename Container::difference_type); } + { QVERIFY_TYPE(typename Container::size_type); } + { QVERIFY_TYPE(typename Container::key_type); } +} + +/* + Compile-time test that verifies that the Qt containers + have STL-compatable typedefs. +*/ +void tst_Collections::containerTypedefs() +{ + testContainerTypedefs(QVector<int>()); + testContainerTypedefs(QStack<int>()); + testContainerTypedefs(QList<int>()); + testContainerTypedefs(QLinkedList<int>()); + testContainerTypedefs(QQueue<int>()); + + testPairAssociativeContainerTypedefs(QMap<int, int>()); + testPairAssociativeContainerTypedefs(QMultiMap<int, int>()); + testPairAssociativeContainerTypedefs(QHash<int, int>()); + + testSetContainerTypedefs(QSet<int>()); +} + +class Key1; +class T1; +class T2; + +void tst_Collections::forwardDeclared() +{ + { typedef QHash<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } + { typedef QMultiHash<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } + { typedef QMap<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } + { typedef QMultiMap<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } + { typedef QPair<T1, T2> C; C *x = 0; Q_UNUSED(x) } + { typedef QList<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } + { typedef QLinkedList<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } + { typedef QVector<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) Q_UNUSED(i) Q_UNUSED(j) } + { typedef QStack<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) Q_UNUSED(i) Q_UNUSED(j) } + { typedef QQueue<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) } + { 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) {} + + enum { PreferredAlignment = 4 }; + + 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); } +}; +Q_STATIC_ASSERT(Q_ALIGNOF(Aligned4) % 4 == 0); + +class Q_DECL_ALIGN(128) Aligned128 +{ + char i; +public: + Aligned128(int i = 0) : i(i) {} + + enum { PreferredAlignment = 128 }; + + 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); } +}; +Q_STATIC_ASSERT(Q_ALIGNOF(Aligned128) % 128 == 0); + +template<typename C> +void testVectorAlignment() +{ + typedef typename C::value_type Aligned; + C container; + container.append(Aligned()); + QCOMPARE(quintptr(&container[0]) % Aligned::PreferredAlignment, quintptr(0)); + + for (int i = 0; i < 200; ++i) + container.append(Aligned()); + + for (int i = 0; i < container.size(); ++i) + QCOMPARE(quintptr(&container.at(i)) % Aligned::PreferredAlignment, quintptr(0)); +} + +template<typename C> +void testContiguousCacheAlignment() +{ + typedef typename C::value_type Aligned; + C container(150); + container.append(Aligned()); + QCOMPARE(quintptr(&container[container.firstIndex()]) % Aligned::PreferredAlignment, quintptr(0)); + + for (int i = 0; i < 200; ++i) + container.append(Aligned()); + + for (int i = container.firstIndex(); i < container.lastIndex(); ++i) + QCOMPARE(quintptr(&container.at(i)) % Aligned::PreferredAlignment, quintptr(0)); +} + +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(); + QCOMPARE(quintptr(&it.key()) % Key::PreferredAlignment, quintptr(0)); + QCOMPARE(quintptr(&it.value()) % Value::PreferredAlignment, quintptr(0)); + + // 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) { + QCOMPARE(quintptr(&it.key()) % Key::PreferredAlignment, quintptr(0)); + QCOMPARE(quintptr(&it.value()) % Value::PreferredAlignment, quintptr(0)); + } +} + +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"); +} +#endif + +#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS + +template<template<class> class C> +struct QTBUG13079_Node { + C<QTBUG13079_Node> children; + QString s; + + ~QTBUG13079_Node() { + children.begin(); //play with memory + } +}; +template<template<class> class C> void QTBUG13079_collectionInsideCollectionImpl() +{ + C<QTBUG13079_Node<C> > nodeList; + nodeList << QTBUG13079_Node<C>(); + nodeList.first().s = "parent"; + nodeList.first().children << QTBUG13079_Node<C>(); + nodeList.first().children.first().s = "child"; + + nodeList = nodeList.first().children; + QCOMPARE(nodeList.first().s, QString::fromLatin1("child")); + + nodeList = nodeList.first().children; + QCOMPARE(nodeList.count(), 0); + nodeList << QTBUG13079_Node<C>(); +} + +template<template<class, class> class C> +struct QTBUG13079_NodeAssoc { + C<int, QTBUG13079_NodeAssoc> children; + QString s; + + ~QTBUG13079_NodeAssoc() { + children.begin(); //play with memory + } +}; +template<template<class, class> class C> void QTBUG13079_collectionInsideCollectionAssocImpl() +{ + C<int, QTBUG13079_NodeAssoc<C> > nodeMap; + nodeMap[18] = QTBUG13079_NodeAssoc<C>(); + nodeMap[18].s = "parent"; + nodeMap[18].children[12] = QTBUG13079_NodeAssoc<C>(); + nodeMap[18].children[12].s = "child"; + + nodeMap = nodeMap[18].children; + QCOMPARE(nodeMap[12].s, QString::fromLatin1("child")); + + nodeMap = nodeMap[12].children; + QCOMPARE(nodeMap.count(), 0); + nodeMap[42] = QTBUG13079_NodeAssoc<C>(); +} + + +quint32 qHash(const QTBUG13079_Node<QSet> &) +{ + return 0; +} + +bool operator==(const QTBUG13079_Node<QSet> &a, const QTBUG13079_Node<QSet> &b) +{ + return a.s == b.s && a.children == b.children; +} + +template<template<class> class C> +struct QTBUG13079_NodePtr : QSharedData { + C<QTBUG13079_NodePtr> child; + QTBUG13079_NodePtr *next; + QString s; + + QTBUG13079_NodePtr() : next(0) {} + ~QTBUG13079_NodePtr() { + next = child.data(); //play with memory + } +}; +template<template<class> class C> void QTBUG13079_collectionInsidePtrImpl() +{ + typedef C<QTBUG13079_NodePtr<C> > Ptr; + { + Ptr nodePtr; + nodePtr = Ptr(new QTBUG13079_NodePtr<C>()); + nodePtr->s = "parent"; + nodePtr->child = Ptr(new QTBUG13079_NodePtr<C>()); + nodePtr->child->s = "child"; + nodePtr = nodePtr->child; + QCOMPARE(nodePtr->s, QString::fromLatin1("child")); + nodePtr = nodePtr->child; + QVERIFY(!nodePtr); + } + { + Ptr nodePtr; + nodePtr = Ptr(new QTBUG13079_NodePtr<C>()); + nodePtr->s = "parent"; + nodePtr->next = new QTBUG13079_NodePtr<C>(); + nodePtr->next->s = "next"; + nodePtr = Ptr(nodePtr->next); + QCOMPARE(nodePtr->s, QString::fromLatin1("next")); + nodePtr = Ptr(nodePtr->next); + QVERIFY(!nodePtr); + } +} + +#endif + +void tst_Collections::QTBUG13079_collectionInsideCollection() +{ +#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS + QTBUG13079_collectionInsideCollectionImpl<QVector>(); + QTBUG13079_collectionInsideCollectionImpl<QStack>(); + QTBUG13079_collectionInsideCollectionImpl<QList>(); + QTBUG13079_collectionInsideCollectionImpl<QLinkedList>(); + QTBUG13079_collectionInsideCollectionImpl<QQueue>(); + + { + QSet<QTBUG13079_Node<QSet> > nodeSet; + nodeSet << QTBUG13079_Node<QSet>(); + nodeSet = nodeSet.begin()->children; + QCOMPARE(nodeSet.count(), 0); + } + + QTBUG13079_collectionInsideCollectionAssocImpl<QMap>(); + QTBUG13079_collectionInsideCollectionAssocImpl<QHash>(); + + QTBUG13079_collectionInsidePtrImpl<QSharedPointer>(); + QTBUG13079_collectionInsidePtrImpl<QExplicitlySharedDataPointer>(); + QTBUG13079_collectionInsidePtrImpl<QSharedDataPointer>(); +#endif +} + +template<class Container> void foreach_test_arrays(const Container &container) +{ + typedef typename Container::value_type T; + int i = 0; + QSet <T> set; + foreach(const T & val, container) { + QVERIFY( val == container[i] ); + set << val; + i++; + } + QCOMPARE(set.count(), container.count()); + + //modify the container while iterating. + Container c2 = container; + Container c3; + i = 0; + foreach (T val, c2) { + c3 << val; + c2.insert((i * 89) % c2.size(), T() ); + QVERIFY( val == container.at(i) ); + val = T(); + i++; + } + QVERIFY(c3 == container); +} + + +void tst_Collections::foreach_2() +{ + QStringList strlist = QString::fromLatin1("a,b,c,d,e,f,g,h,ih,kl,mn,op,qr,st,uvw,xyz").split(","); + foreach_test_arrays(strlist); + foreach_test_arrays(QList<QString>(strlist)); + foreach_test_arrays(strlist.toVector()); + + QList<int> intlist; + intlist << 1 << 2 << 3 << 4 <<5 << 6 << 7 << 8 << 9; + foreach_test_arrays(intlist); + foreach_test_arrays(intlist.toVector()); + + QVarLengthArray<int> varl1; + QVarLengthArray<int, 3> varl2; + QVarLengthArray<int, 10> varl3; + foreach(int i, intlist) { + varl1 << i; + varl2 << i; + varl3 << i; + } + QCOMPARE(varl1.count(), intlist.count()); + QCOMPARE(varl2.count(), intlist.count()); + QCOMPARE(varl3.count(), intlist.count()); + foreach_test_arrays(varl1); + foreach_test_arrays(varl2); + foreach_test_arrays(varl3); + + QVarLengthArray<QString> varl4; + QVarLengthArray<QString, 3> varl5; + QVarLengthArray<QString, 18> varl6; + foreach(const QString &str, strlist) { + varl4 << str; + varl5 << str; + varl6 << str; + } + QCOMPARE(varl4.count(), strlist.count()); + QCOMPARE(varl5.count(), strlist.count()); + QCOMPARE(varl6.count(), strlist.count()); + foreach_test_arrays(varl4); + foreach_test_arrays(varl5); + foreach_test_arrays(varl6); +} + +struct IntOrString +{ + int val; + IntOrString(int v) : val(v) { } + IntOrString(const QString &v) : val(v.toInt()) { } + operator int() { return val; } + operator QString() { return QString::number(val); } + operator std::string() { return QString::number(val).toStdString(); } + IntOrString(const std::string &v) : val(QString::fromStdString(v).toInt()) { } +}; + +template<class Container> void insert_remove_loop_impl() +{ + typedef typename Container::value_type T; + Container t; + t.append(T(IntOrString(1))); + t << (T(IntOrString(2))); + t += (T(IntOrString(3))); + t.prepend(T(IntOrString(4))); + t.insert(2, 3 , T(IntOrString(5))); + t.insert(4, T(IntOrString(6))); + t.insert(t.begin() + 2, T(IntOrString(7))); + t.insert(t.begin() + 5, 3, T(IntOrString(8))); + int expect1[] = { 4 , 1 , 7, 5 , 5 , 8, 8, 8, 6, 5, 2 , 3 }; + QCOMPARE(size_t(t.count()), sizeof(expect1)/sizeof(int)); + for (int i = 0; i < t.count(); i++) { + QCOMPARE(t[i], T(IntOrString(expect1[i]))); + } + + Container compare_test1 = t; + t.replace(5, T(IntOrString(9))); + Container compare_test2 = t; + QVERIFY(!(compare_test1 == t)); + QVERIFY( (compare_test1 != t)); + QVERIFY( (compare_test2 == t)); + QVERIFY(!(compare_test2 != t)); + t.remove(7); + t.remove(2, 3); + int expect2[] = { 4 , 1 , 9, 8, 6, 5, 2 , 3 }; + QCOMPARE(size_t(t.count()), sizeof(expect2)/sizeof(int)); + for (int i = 0; i < t.count(); i++) { + QCOMPARE(t[i], T(IntOrString(expect2[i]))); + } + + for (typename Container::iterator it = t.begin(); it != t.end(); ) { + if ( int(IntOrString(*it)) % 2 ) + ++it; + else + it = t.erase(it); + } + + int expect3[] = { 1 , 9, 5, 3 }; + QCOMPARE(size_t(t.count()), sizeof(expect3)/sizeof(int)); + for (int i = 0; i < t.count(); i++) { + QCOMPARE(t[i], T(IntOrString(expect3[i]))); + } + + t.erase(t.begin() + 1, t.end() - 1); + + int expect4[] = { 1 , 3 }; + QCOMPARE(size_t(t.count()), sizeof(expect4)/sizeof(int)); + for (int i = 0; i < t.count(); i++) { + QCOMPARE(t[i], T(IntOrString(expect4[i]))); + } + + t << T(IntOrString(10)) << T(IntOrString(11)) << T(IntOrString(12)) << T(IntOrString(13)); + t << T(IntOrString(14)) << T(IntOrString(15)) << T(IntOrString(16)) << T(IntOrString(17)); + t << T(IntOrString(18)) << T(IntOrString(19)) << T(IntOrString(20)) << T(IntOrString(21)); + for (typename Container::iterator it = t.begin(); it != t.end(); ++it) { + int iv = int(IntOrString(*it)); + if ( iv % 2 ) { + it = t.insert(it, T(IntOrString(iv * iv))); + it = t.insert(it + 2, T(IntOrString(iv * iv + 1))); + } + } + + int expect5[] = { 1, 1, 2, 3*3, 3, 3*3+1, 10, 11*11, 11, 11*11+1, 12 , 13*13, 13, 13*13+1, 14, + 15*15, 15, 15*15+1, 16 , 17*17, 17, 17*17+1 ,18 , 19*19, 19, 19*19+1, 20, 21*21, 21, 21*21+1 }; + QCOMPARE(size_t(t.count()), sizeof(expect5)/sizeof(int)); + for (int i = 0; i < t.count(); i++) { + QCOMPARE(t[i], T(IntOrString(expect5[i]))); + } +} + + +//Add insert(int, int, T) so it has the same interface as QVector and QVarLengthArray for the test. +template<typename T> +struct ExtList : QList<T> { + using QList<T>::insert; + void insert(int before, int n, const T&x) { + while (n--) { + this->insert(before, x ); + } + } + void insert(typename QList<T>::iterator before, int n, const T&x) { + while (n--) { + before = this->insert(before, x); + } + } + + void remove(int i) { + this->removeAt(i); + } + void remove(int i, int n) { + while (n--) { + this->removeAt(i); + } + } +}; + +void tst_Collections::insert_remove_loop() +{ + insert_remove_loop_impl<ExtList<int> >(); + insert_remove_loop_impl<ExtList<QString> >(); + insert_remove_loop_impl<QVector<int> >(); + insert_remove_loop_impl<QVector<QString> >(); + insert_remove_loop_impl<QVarLengthArray<int> >(); + insert_remove_loop_impl<QVarLengthArray<QString> >(); + insert_remove_loop_impl<QVarLengthArray<int, 10> >(); + insert_remove_loop_impl<QVarLengthArray<QString, 10> >(); + insert_remove_loop_impl<QVarLengthArray<int, 3> >(); + insert_remove_loop_impl<QVarLengthArray<QString, 3> >(); + insert_remove_loop_impl<QVarLengthArray<int, 15> >(); + insert_remove_loop_impl<QVarLengthArray<QString, 15> >(); + + insert_remove_loop_impl<ExtList<std::string> >(); + insert_remove_loop_impl<QVector<std::string> >(); + insert_remove_loop_impl<QVarLengthArray<std::string> >(); + insert_remove_loop_impl<QVarLengthArray<std::string, 10> >(); + insert_remove_loop_impl<QVarLengthArray<std::string, 3> >(); + insert_remove_loop_impl<QVarLengthArray<std::string, 15> >(); +} + + + +QTEST_APPLESS_MAIN(tst_Collections) +#include "tst_collections.moc" diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index cdcbd19ae8..8fac232962 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -153,6 +153,8 @@ private slots: #endif void macTypes(); + + void stdString(); }; static const struct StaticByteArrays { @@ -2007,6 +2009,23 @@ void tst_QByteArray::macTypes() #endif } +void tst_QByteArray::stdString() +{ + std::string stdstr( "QByteArray" ); + + const QByteArray stlqt = QByteArray::fromStdString(stdstr); + QCOMPARE(stlqt.length(), int(stdstr.length())); + QCOMPARE(stlqt.data(), stdstr.c_str()); + QCOMPARE(stlqt.toStdString(), stdstr); + + std::string utf8str( "Nøt æscii" ); + const QByteArray u8 = QByteArray::fromStdString(utf8str); + const QByteArray l1 = QString::fromUtf8(u8).toLatin1(); + std::string l1str = l1.toStdString(); + QVERIFY(l1str.length() < utf8str.length()); +} + + const char globalChar = '1'; QTEST_MAIN(tst_QByteArray) diff --git a/tests/auto/corelib/tools/qdate/tst_qdate.cpp b/tests/auto/corelib/tools/qdate/tst_qdate.cpp index 807dcf5cbe..97787e9cbd 100644 --- a/tests/auto/corelib/tools/qdate/tst_qdate.cpp +++ b/tests/auto/corelib/tools/qdate/tst_qdate.cpp @@ -104,6 +104,7 @@ private slots: void longMonthName() const; void standaloneLongMonthName() const; void roundtrip() const; + void qdebug() const; private: QDate defDate() const { return QDate(1900, 1, 1); } QDate invalidDate() const { return QDate(); } @@ -1476,5 +1477,13 @@ void tst_QDate::roundtrip() const } } +void tst_QDate::qdebug() const +{ + QTest::ignoreMessage(QtDebugMsg, "QDate(\"\")"); + qDebug() << QDate(); + QTest::ignoreMessage(QtDebugMsg, "QDate(\"1983-08-07\")"); + qDebug() << QDate(1983, 8, 7); +} + QTEST_APPLESS_MAIN(tst_QDate) #include "tst_qdate.moc" diff --git a/tests/auto/corelib/tools/qregularexpression/.gitignore b/tests/auto/corelib/tools/qregularexpression/.gitignore index c9249e090e..4650b4454e 100644 --- a/tests/auto/corelib/tools/qregularexpression/.gitignore +++ b/tests/auto/corelib/tools/qregularexpression/.gitignore @@ -1,2 +1,3 @@ tst_qregularexpression_alwaysoptimize tst_qregularexpression_defaultoptimize +tst_qregularexpression_forceoptimize diff --git a/tests/auto/corelib/tools/qregularexpression/forceoptimize/forceoptimize.pro b/tests/auto/corelib/tools/qregularexpression/forceoptimize/forceoptimize.pro new file mode 100644 index 0000000000..d34bc9b93d --- /dev/null +++ b/tests/auto/corelib/tools/qregularexpression/forceoptimize/forceoptimize.pro @@ -0,0 +1,8 @@ +CONFIG += testcase parallel_test +TARGET = tst_qregularexpression_forceoptimize +QT = core testlib +HEADERS = ../tst_qregularexpression.h +SOURCES = \ + tst_qregularexpression_forceoptimize.cpp \ + ../tst_qregularexpression.cpp +DEFINES += forceOptimize=true diff --git a/tests/auto/corelib/tools/qregularexpression/forceoptimize/tst_qregularexpression_forceoptimize.cpp b/tests/auto/corelib/tools/qregularexpression/forceoptimize/tst_qregularexpression_forceoptimize.cpp new file mode 100644 index 0000000000..6244aacedf --- /dev/null +++ b/tests/auto/corelib/tools/qregularexpression/forceoptimize/tst_qregularexpression_forceoptimize.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include "../tst_qregularexpression.h" + +class tst_QRegularExpression_ForceOptimize : public tst_QRegularExpression +{ + Q_OBJECT +}; + +QTEST_APPLESS_MAIN(tst_QRegularExpression_ForceOptimize) + +#include "tst_qregularexpression_forceoptimize.moc" diff --git a/tests/auto/corelib/tools/qregularexpression/qregularexpression.pro b/tests/auto/corelib/tools/qregularexpression/qregularexpression.pro index 0cae10112f..c030f04a27 100644 --- a/tests/auto/corelib/tools/qregularexpression/qregularexpression.pro +++ b/tests/auto/corelib/tools/qregularexpression/qregularexpression.pro @@ -1,3 +1,3 @@ TEMPLATE = subdirs -SUBDIRS = defaultoptimize +SUBDIRS = defaultoptimize forceoptimize contains(QT_CONFIG,private_tests):SUBDIRS += alwaysoptimize diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp index 909725f4b8..5fad1bb738 100644 --- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp @@ -48,6 +48,10 @@ #include "tst_qregularexpression.h" +#ifndef forceOptimize +#define forceOptimize false +#endif + struct Match { Match() @@ -329,22 +333,30 @@ void tst_QRegularExpression::gettersSetters() { QRegularExpression re; re.setPattern(pattern); + if (forceOptimize) + re.optimize(); QCOMPARE(re.pattern(), pattern); QCOMPARE(re.patternOptions(), QRegularExpression::NoPatternOption); } { QRegularExpression re; re.setPatternOptions(patternOptions); + if (forceOptimize) + re.optimize(); QCOMPARE(re.pattern(), QString()); QCOMPARE(re.patternOptions(), patternOptions); } { QRegularExpression re(pattern); + if (forceOptimize) + re.optimize(); QCOMPARE(re.pattern(), pattern); QCOMPARE(re.patternOptions(), QRegularExpression::NoPatternOption); } { QRegularExpression re(pattern, patternOptions); + if (forceOptimize) + re.optimize(); QCOMPARE(re.pattern(), pattern); QCOMPARE(re.patternOptions(), patternOptions); } @@ -385,6 +397,8 @@ void tst_QRegularExpression::escape() QFETCH(QString, escaped); QCOMPARE(QRegularExpression::escape(string), escaped); QRegularExpression re(escaped); + if (forceOptimize) + re.optimize(); QCOMPARE(re.isValid(), true); } @@ -415,6 +429,8 @@ void tst_QRegularExpression::validity() QFETCH(QString, pattern); QFETCH(bool, validity); QRegularExpression re(pattern); + if (forceOptimize) + re.optimize(); QCOMPARE(re.isValid(), validity); if (!validity) QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionPrivate::doMatch(): called on an invalid QRegularExpression object"); @@ -501,6 +517,9 @@ void tst_QRegularExpression::patternOptions() QFETCH(QString, subject); QFETCH(Match, match); + if (forceOptimize) + regexp.optimize(); + QRegularExpressionMatch m = regexp.match(subject); consistencyCheck(m); QVERIFY(m == match); @@ -717,6 +736,9 @@ void tst_QRegularExpression::normalMatch() QFETCH(QRegularExpression::MatchOptions, matchOptions); QFETCH(Match, match); + if (forceOptimize) + regexp.optimize(); + { QRegularExpressionMatch m = regexp.match(subject, offset, QRegularExpression::NormalMatch, matchOptions); consistencyCheck(m); @@ -995,6 +1017,9 @@ void tst_QRegularExpression::partialMatch() QFETCH(QRegularExpression::MatchOptions, matchOptions); QFETCH(Match, match); + if (forceOptimize) + regexp.optimize(); + { QRegularExpressionMatch m = regexp.match(subject, offset, matchType, matchOptions); consistencyCheck(m); @@ -1286,6 +1311,10 @@ void tst_QRegularExpression::globalMatch() QFETCH(QRegularExpression::MatchType, matchType); QFETCH(QRegularExpression::MatchOptions, matchOptions); QFETCH(QList<Match>, matchList); + + if (forceOptimize) + regexp.optimize(); + { QRegularExpressionMatchIterator iterator = regexp.globalMatch(subject, offset, matchType, matchOptions); consistencyCheck(iterator); @@ -1320,6 +1349,10 @@ void tst_QRegularExpression::serialize() QFETCH(QString, pattern); QFETCH(QRegularExpression::PatternOptions, patternOptions); QRegularExpression outRe(pattern, patternOptions); + + if (forceOptimize) + outRe.optimize(); + QByteArray buffer; { QDataStream out(&buffer, QIODevice::WriteOnly); @@ -1376,16 +1409,34 @@ void tst_QRegularExpression::operatoreq() { QRegularExpression re1(pattern); QRegularExpression re2(pattern); + + if (forceOptimize) + re1.optimize(); + if (forceOptimize) + re2.optimize(); + verifyEquality(re1, re2); } { QRegularExpression re1(QString(), patternOptions); QRegularExpression re2(QString(), patternOptions); + + if (forceOptimize) + re1.optimize(); + if (forceOptimize) + re2.optimize(); + verifyEquality(re1, re2); } { QRegularExpression re1(pattern, patternOptions); QRegularExpression re2(pattern, patternOptions); + + if (forceOptimize) + re1.optimize(); + if (forceOptimize) + re2.optimize(); + verifyEquality(re1, re2); } } @@ -1414,6 +1465,10 @@ void tst_QRegularExpression::captureCount() { QFETCH(QString, pattern); QRegularExpression re(pattern); + + if (forceOptimize) + re.optimize(); + QTEST(re.captureCount(), "captureCount"); if (!re.isValid()) QCOMPARE(re.captureCount(), -1); @@ -1480,7 +1535,11 @@ void tst_QRegularExpression::captureNames() QFETCH(QString, pattern); QFETCH(StringToIntMap, namedCapturesIndexMap); - const QRegularExpression re(pattern); + QRegularExpression re(pattern); + + if (forceOptimize) + re.optimize(); + QStringList namedCaptureGroups = re.namedCaptureGroups(); int namedCaptureGroupsCount = namedCaptureGroups.size(); @@ -1515,6 +1574,10 @@ void tst_QRegularExpression::pcreJitStackUsage() QFETCH(QString, subject); QRegularExpression re(pattern); + + if (forceOptimize) + re.optimize(); + QVERIFY(re.isValid()); QRegularExpressionMatch match = re.match(subject); consistencyCheck(match); @@ -1541,6 +1604,10 @@ void tst_QRegularExpression::regularExpressionMatch() QFETCH(QString, subject); QRegularExpression re(pattern); + + if (forceOptimize) + re.optimize(); + QVERIFY(re.isValid()); QRegularExpressionMatch match = re.match(subject); consistencyCheck(match); @@ -1580,5 +1647,7 @@ void tst_QRegularExpression::JOptionUsage() QRegularExpression re(pattern); if (isValid && JOptionUsed) QTest::ignoreMessage(QtWarningMsg, qPrintable(warningMessage.arg(pattern))); + if (forceOptimize) + re.optimize(); QCOMPARE(re.isValid(), isValid); } diff --git a/tests/auto/corelib/tools/qscopedvaluerollback/tst_qscopedvaluerollback.cpp b/tests/auto/corelib/tools/qscopedvaluerollback/tst_qscopedvaluerollback.cpp index af82897179..86438caed6 100644 --- a/tests/auto/corelib/tools/qscopedvaluerollback/tst_qscopedvaluerollback.cpp +++ b/tests/auto/corelib/tools/qscopedvaluerollback/tst_qscopedvaluerollback.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -67,14 +67,17 @@ void tst_QScopedValueRollback::leavingScope() { int i = 0; bool b = false; + bool b2 = false; QString s("This is useful"); //test rollback on going out of scope { QScopedValueRollback<int> ri(i); QScopedValueRollback<bool> rb(b); + QScopedValueRollback<bool> rb2(b2, true); QScopedValueRollback<QString> rs(s); QCOMPARE(b, false); + QCOMPARE(b2, true); QCOMPARE(i, 0); QCOMPARE(s, QString("This is useful")); b = true; @@ -85,6 +88,7 @@ void tst_QScopedValueRollback::leavingScope() QCOMPARE(s, QString("Useless")); } QCOMPARE(b, false); + QCOMPARE(b2, false); QCOMPARE(i, 0); QCOMPARE(s, QString("This is useful")); } diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index 5b1a2cf076..ac37b9af2a 100644 --- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp @@ -74,6 +74,7 @@ private slots: void useOfForwardDeclared(); void memoryManagement(); void dropLastReferenceOfForwardDeclared(); + void lock(); void downCast(); void functionCallDownCast(); void upCast(); @@ -111,6 +112,7 @@ private slots: void invalidConstructs(); void qvariantCast(); + void sharedFromThis(); public slots: void cleanup() { safetyCheck(); } @@ -391,12 +393,56 @@ void tst_QSharedPointer::swap() QVERIFY(p2 != control); QVERIFY(p2.isNull()); QVERIFY(*p1 == 42); + + QWeakPointer<int> w1, w2 = control; + + QVERIFY(w1.isNull()); + QVERIFY(!w2.isNull()); + QVERIFY(w2.lock() == control); + QVERIFY(!w1.lock()); + + w1.swap(w2); + QVERIFY(w2.isNull()); + QVERIFY(!w1.isNull()); + QVERIFY(w1.lock() == control); + QVERIFY(!w2.lock()); + + qSwap(w1, w2); + QVERIFY(w1.isNull()); + QVERIFY(w2.lock() == control); + + p1.reset(); + p2.reset(); + control.reset(); + + QVERIFY(w1.isNull()); + QVERIFY(w2.isNull()); } void tst_QSharedPointer::useOfForwardDeclared() { // this just a compile test: use the forward-declared class QSharedPointer<ForwardDeclared> sp; + + // copying should work, too: + QSharedPointer<ForwardDeclared> sp2 = sp; + + // and assignment: + QSharedPointer<ForwardDeclared> sp3; + sp3 = sp; + + // move assignment: + QSharedPointer<ForwardDeclared> sp4; + sp4 = qMove(sp); + + // and move constuction: + QSharedPointer<ForwardDeclared> sp5 = qMove(sp2); + + // swapping: + sp4.swap(sp3); + qSwap(sp4, sp3); + + // and, of course, destruction } @@ -474,6 +520,22 @@ void tst_QSharedPointer::dropLastReferenceOfForwardDeclared() QCOMPARE(forwardDeclaredDestructorRunCount, 1); } +void tst_QSharedPointer::lock() +{ + QSharedPointer<int> sp = QSharedPointer<int>::create(); + QVERIFY(sp); + QWeakPointer<int> wp = sp; + QVERIFY(sp == wp); + QVERIFY(sp == wp.lock()); + QVERIFY(sp == wp.toStrongRef()); + + sp.reset(); + QVERIFY(!wp); + QVERIFY(sp != wp); // this is why op(shared_ptr, weak_ptr) is a bad idea (apart from MT races)... + QVERIFY(sp == wp.lock()); + QVERIFY(sp == wp.toStrongRef()); +} + class DerivedData: public Data { public: @@ -846,6 +908,7 @@ void tst_QSharedPointer::objectCast() ptr.clear(); QVERIFY(ptr.isNull()); QVERIFY(weakptr.toStrongRef().isNull()); + QVERIFY(weakptr.lock().isNull()); // verify that the object casts fail without crash QSharedPointer<OtherObject> otherptr = qSharedPointerObjectCast<OtherObject>(weakptr); @@ -2079,6 +2142,228 @@ void tst_QSharedPointer::qvariantCast() } } +class SomeClass : public QEnableSharedFromThis<SomeClass> +{ +public: + SomeClass() + { + } + + QSharedPointer<SomeClass> getSharedPtr() + { + return sharedFromThis(); + } + + QSharedPointer<const SomeClass> getSharedPtr() const + { + return sharedFromThis(); + } + + Data data; +}; + +void tst_QSharedPointer::sharedFromThis() +{ + const int generations = Data::generationCounter; + const int destructions = Data::destructorCounter; + + { + SomeClass sc; + QSharedPointer<SomeClass> scp = sc.sharedFromThis(); + QVERIFY(scp.isNull()); + QCOMPARE(Data::generationCounter, generations + 1); + QCOMPARE(Data::destructorCounter, destructions); + + QSharedPointer<const SomeClass> const_scp = sc.sharedFromThis(); + QVERIFY(const_scp.isNull()); + QCOMPARE(Data::generationCounter, generations + 1); + QCOMPARE(Data::destructorCounter, destructions); + } + + QCOMPARE(Data::generationCounter, generations + 1); + QCOMPARE(Data::destructorCounter, destructions + 1); + + { + const SomeClass sc; + QSharedPointer<const SomeClass> const_scp = sc.sharedFromThis(); + QVERIFY(const_scp.isNull()); + QCOMPARE(Data::generationCounter, generations + 2); + QCOMPARE(Data::destructorCounter, destructions + 1); + } + + QCOMPARE(Data::generationCounter, generations + 2); + QCOMPARE(Data::destructorCounter, destructions + 2); + + { + SomeClass *sc = new SomeClass; + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + QSharedPointer<SomeClass> scp; + QVERIFY(scp.isNull()); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + scp = sc->sharedFromThis(); + QVERIFY(scp.isNull()); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + scp = QSharedPointer<SomeClass>(sc); + QVERIFY(!scp.isNull()); + QCOMPARE(scp.data(), sc); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + QSharedPointer<SomeClass> scp2; + QVERIFY(scp2.isNull()); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + scp2 = sc->sharedFromThis(); + QVERIFY(!scp2.isNull()); + QVERIFY(scp == scp2); + QCOMPARE(scp2.data(), sc); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + QSharedPointer<const SomeClass> scp3; + QVERIFY(scp3.isNull()); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + scp3 = sc->sharedFromThis(); + QVERIFY(!scp3.isNull()); + QVERIFY(scp == scp3); + QVERIFY(scp2 == scp3); + QCOMPARE(scp3.data(), sc); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + QSharedPointer<SomeClass> scp4; + QVERIFY(scp4.isNull()); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + scp4 = sc->getSharedPtr(); + QVERIFY(!scp4.isNull()); + QVERIFY(scp == scp4); + QVERIFY(scp2 == scp4); + QVERIFY(scp3 == scp4); + QCOMPARE(scp4.data(), sc); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + QSharedPointer<const SomeClass> scp5; + QVERIFY(scp5.isNull()); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + + scp5 = const_cast<const SomeClass *>(sc)->getSharedPtr(); + QVERIFY(!scp4.isNull()); + QVERIFY(scp == scp5); + QVERIFY(scp2 == scp5); + QVERIFY(scp3 == scp5); + QVERIFY(scp4 == scp5); + QCOMPARE(scp5.data(), sc); + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 2); + } + + QCOMPARE(Data::generationCounter, generations + 3); + QCOMPARE(Data::destructorCounter, destructions + 3); + + QSharedPointer<SomeClass> scp; + + QVERIFY(scp.isNull()); + + { + QSharedPointer<SomeClass> scp2(new SomeClass()); + QVERIFY(!scp2.isNull()); + + scp = scp2->sharedFromThis(); + QVERIFY(!scp.isNull()); + + QVERIFY(scp == scp2); + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + } + + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + QVERIFY(!scp.isNull()); + + { + QSharedPointer<const SomeClass> scp2; + scp2 = scp->sharedFromThis(); + QVERIFY(!scp2.isNull()); + + QVERIFY(scp == scp2); + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + } + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + QVERIFY(!scp.isNull()); + + { + QSharedPointer<SomeClass> scp2; + scp2 = scp->getSharedPtr(); + QVERIFY(!scp2.isNull()); + + QVERIFY(scp == scp2); + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + } + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + QVERIFY(!scp.isNull()); + + { + QSharedPointer<const SomeClass> scp2; + scp2 = qSharedPointerConstCast<const SomeClass>(scp)->getSharedPtr(); + QVERIFY(!scp2.isNull()); + + QVERIFY(scp == scp2); + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + } + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + QVERIFY(!scp.isNull()); + + { + QSharedPointer<SomeClass> scp2; + scp2 = scp->sharedFromThis(); + QVERIFY(!scp2.isNull()); + + QVERIFY(scp == scp2); + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + + scp2.clear(); + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + QVERIFY(!scp.isNull()); + QVERIFY(scp2.isNull()); + } + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 3); + QVERIFY(!scp.isNull()); + + scp.clear(); + + QCOMPARE(Data::generationCounter, generations + 4); + QCOMPARE(Data::destructorCounter, destructions + 4); + +} + namespace ReentrancyWhileDestructing { struct IB { diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 95d377b176..37cb3754d3 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -4170,11 +4170,17 @@ void tst_QString::arg() QCOMPARE( s4.arg(Q_INT64_C(9223372036854775807)), // LLONG_MAX QString("[9223372036854775807]") ); + QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"\" , 0"); QCOMPARE( QString().arg(0), QString() ); + QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"\" , 0"); QCOMPARE( QString("").arg(0), QString("") ); + QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \" \" , 0"); QCOMPARE( QString(" ").arg(0), QString(" ") ); + QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"%\" , 0"); QCOMPARE( QString("%").arg(0), QString("%") ); + QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"%%\" , 0"); QCOMPARE( QString("%%").arg(0), QString("%%") ); + QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"%%%\" , 0"); QCOMPARE( QString("%%%").arg(0), QString("%%%") ); QCOMPARE( QString("%%%1%%%2").arg("foo").arg("bar"), QString("%%foo%%bar") ); diff --git a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp index 246560e47f..91501a0106 100644 --- a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp +++ b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp @@ -66,6 +66,7 @@ private slots: void lastIndexOf_regExp(); void streamingOperator(); + void assignmentOperator(); void join() const; void join_data() const; void joinEmptiness() const; @@ -296,9 +297,11 @@ void tst_QStringList::removeDuplicates_data() QTest::addColumn<QString>("before"); QTest::addColumn<QString>("after"); QTest::addColumn<int>("count"); + QTest::addColumn<bool>("detached"); - QTest::newRow("empty-1") << "Hello,Hello" << "Hello" << 1; - QTest::newRow("empty-2") << "Hello,World" << "Hello,World" << 0; + QTest::newRow("empty-1") << "Hello,Hello" << "Hello" << 1 << true; + QTest::newRow("empty-2") << "Hello,World" << "Hello,World" << 0 << false; + QTest::newRow("middle") << "Hello,World,Hello" << "Hello,World" << 1 << true; } void tst_QStringList::removeDuplicates() @@ -306,13 +309,16 @@ void tst_QStringList::removeDuplicates() QFETCH(QString, before); QFETCH(QString, after); QFETCH(int, count); + QFETCH(bool, detached); QStringList lbefore = before.split(','); + const QStringList oldlbefore = lbefore; QStringList lafter = after.split(','); int removed = lbefore.removeDuplicates(); QCOMPARE(removed, count); QCOMPARE(lbefore, lafter); + QCOMPARE(detached, !oldlbefore.isSharedWith(lbefore)); } void tst_QStringList::streamingOperator() @@ -321,8 +327,13 @@ void tst_QStringList::streamingOperator() list << "hei"; list << list << "hopp" << list; + QList<QString> slist = list; + list << slist; + QCOMPARE(list, QStringList() << "hei" << "hei" << "hopp" + << "hei" << "hei" << "hopp" + << "hei" << "hei" << "hopp" << "hei" << "hei" << "hopp"); QStringList list2; @@ -334,6 +345,21 @@ void tst_QStringList::streamingOperator() QCOMPARE(list2 << list3, QStringList() << "adam" << "eva"); } +void tst_QStringList::assignmentOperator() +{ + // compile-only test + + QStringList adam; + adam << "adam"; + QList<QString> eva; + eva << "eva"; + QStringList result; + QStringList &ref1 = (result = adam); + QStringList &ref2 = (result = eva); + Q_UNUSED(ref1); + Q_UNUSED(ref2); +} + void tst_QStringList::join() const { QFETCH(QStringList, input); diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index e6629301f9..6b833681d6 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -102,7 +102,7 @@ void tst_QTimeLine::range() // Verify that you can change the range in the timeLine timeLine.setFrameRange(10, 20); - QSignalSpy spy(&timeLine, SIGNAL(frameChanged(int))); + QSignalSpy spy(&timeLine, &QTimeLine::frameChanged); QVERIFY(spy.isValid()); timeLine.start(); #ifdef Q_OS_WINCE @@ -131,7 +131,7 @@ void tst_QTimeLine::currentTime() { QTimeLine timeLine(2000); timeLine.setUpdateInterval((timeLine.duration()/2) / 33); - QSignalSpy spy(&timeLine, SIGNAL(valueChanged(qreal))); + QSignalSpy spy(&timeLine, &QTimeLine::valueChanged); QVERIFY(spy.isValid()); timeLine.setFrameRange(10, 20); QCOMPARE(timeLine.currentTime(), 0); @@ -202,7 +202,7 @@ void tst_QTimeLine::frameRate() // Default speed timeLine.setUpdateInterval(1000 / 33); - QSignalSpy spy(&timeLine, SIGNAL(frameChanged(int))); + QSignalSpy spy(&timeLine, &QTimeLine::frameChanged); QVERIFY(spy.isValid()); timeLine.start(); QTest::qWait(timeLine.duration()*2); @@ -225,7 +225,7 @@ void tst_QTimeLine::value() QVERIFY(timeLine.currentValue() == 0.0); // Default speed - QSignalSpy spy(&timeLine, SIGNAL(valueChanged(qreal))); + QSignalSpy spy(&timeLine, &QTimeLine::valueChanged); QVERIFY(spy.isValid()); timeLine.start(); QTest::qWait(timeLine.duration()/3); @@ -256,7 +256,7 @@ void tst_QTimeLine::currentFrame() QCOMPARE(timeLine.currentFrame(), 10); // Default speed - QSignalSpy spy(&timeLine, SIGNAL(frameChanged(int))); + QSignalSpy spy(&timeLine, &QTimeLine::frameChanged); QVERIFY(spy.isValid()); timeLine.start(); QTest::qWait(timeLine.duration()/3); @@ -288,7 +288,7 @@ void tst_QTimeLine::loopCount() QCOMPARE(timeLine.loopCount(), 0); // Default speed infiniti looping - QSignalSpy spy(&timeLine, SIGNAL(frameChanged(int))); + QSignalSpy spy(&timeLine, &QTimeLine::frameChanged); QVERIFY(spy.isValid()); timeLine.start(); QTest::qWait(timeLine.duration()); @@ -306,8 +306,8 @@ void tst_QTimeLine::loopCount() timeLine.setFrameRange(0, 2); timeLine.setLoopCount(4); - QSignalSpy finishedSpy(&timeLine, SIGNAL(finished())); - QSignalSpy frameChangedSpy(&timeLine, SIGNAL(frameChanged(int))); + QSignalSpy finishedSpy(&timeLine, &QTimeLine::finished); + QSignalSpy frameChangedSpy(&timeLine, &QTimeLine::frameChanged); QVERIFY(finishedSpy.isValid()); QVERIFY(frameChangedSpy.isValid()); QEventLoop loop; @@ -461,7 +461,7 @@ void tst_QTimeLine::frameChanged() timeLine.setCurveShape(QTimeLine::LinearCurve); timeLine.setFrameRange(0,9); timeLine.setUpdateInterval(800); - QSignalSpy spy(&timeLine, SIGNAL(frameChanged(int))); + QSignalSpy spy(&timeLine, &QTimeLine::frameChanged); QVERIFY(spy.isValid()); // Test what happens when duration expires before all frames are emitted. @@ -492,7 +492,7 @@ void tst_QTimeLine::stopped() QTimeLine timeLine; timeLine.setFrameRange(0, 9); qRegisterMetaType<QTimeLine::State>("QTimeLine::State"); - QSignalSpy spy(&timeLine, SIGNAL(stateChanged(QTimeLine::State))); + QSignalSpy spy(&timeLine, &QTimeLine::stateChanged); QVERIFY(spy.isValid()); timeLine.start(); QTest::qWait(timeLine.duration()*2); @@ -510,7 +510,7 @@ void tst_QTimeLine::finished() { QTimeLine timeLine; timeLine.setFrameRange(0,9); - QSignalSpy spy(&timeLine, SIGNAL(finished())); + QSignalSpy spy(&timeLine, &QTimeLine::finished); QVERIFY(spy.isValid()); timeLine.start(); QTest::qWait(timeLine.duration()*2); @@ -543,7 +543,7 @@ void tst_QTimeLine::multipleTimeLines() // Stopping a timer shouldn't affect the other timers QTimeLine timeLine(200); timeLine.setFrameRange(0,99); - QSignalSpy spy(&timeLine, SIGNAL(finished())); + QSignalSpy spy(&timeLine, &QTimeLine::finished); QVERIFY(spy.isValid()); QTimeLine timeLineKiller; diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index f1efbf0812..575811b2ce 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -178,6 +178,9 @@ private slots: void copyConstructorInt() const; void copyConstructorMovable() const; void copyConstructorCustom() const; + void assignmentInt() const; + void assignmentMovable() const; + void assignmentCustom() const; void addInt() const; void addMovable() const; void addCustom() const; @@ -225,7 +228,9 @@ private slots: void fromListCustom() const; void fromStdVector() const; void indexOf() const; - void insert() const; + void insertInt() const; + void insertMovable() const; + void insertCustom() const; void isEmpty() const; void last() const; void lastIndexOf() const; @@ -296,6 +301,7 @@ private: template<typename T> void eraseReserved() const; template<typename T> void fill() const; template<typename T> void fromList() const; + template<typename T> void insert() const; template<typename T> void prepend() const; template<typename T> void remove() const; template<typename T> void size() const; @@ -441,6 +447,52 @@ void tst_QVector::copyConstructorCustom() const QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } +template <class T> +static inline void testAssignment() +{ + QVector<T> v1(5); + QCOMPARE(v1.size(), 5); + QVERIFY(v1.isDetached()); + + QVector<T> v2(7); + QCOMPARE(v2.size(), 7); + QVERIFY(v2.isDetached()); + + QVERIFY(!v1.isSharedWith(v2)); + + v1 = v2; + + QVERIFY(!v1.isDetached()); + QVERIFY(!v2.isDetached()); + QVERIFY(v1.isSharedWith(v2)); + + const void *const data1 = v1.constData(); + const void *const data2 = v2.constData(); + + QCOMPARE(data1, data2); + + v1.clear(); + + QVERIFY(v2.isDetached()); + QVERIFY(!v1.isSharedWith(v2)); + QCOMPARE((void *)v2.constData(), data2); +} + +void tst_QVector::assignmentInt() const +{ + testAssignment<int>(); +} + +void tst_QVector::assignmentMovable() const +{ + testAssignment<Movable>(); +} + +void tst_QVector::assignmentCustom() const +{ + testAssignment<Custom>(); +} + template<typename T> void tst_QVector::add() const { @@ -1231,32 +1283,87 @@ void tst_QVector::indexOf() const QVERIFY(myvec.indexOf("A", 4) == -1); } +template <typename T> void tst_QVector::insert() const { - QVector<QString> myvec; - myvec << "A" << "B" << "C"; + QVector<T> myvec; + const T + tA = SimpleValue<T>::at(0), + tB = SimpleValue<T>::at(1), + tC = SimpleValue<T>::at(2), + tX = SimpleValue<T>::at(3), + tZ = SimpleValue<T>::at(4), + tT = SimpleValue<T>::at(5), + ti = SimpleValue<T>::at(6); + myvec << tA << tB << tC; + QVector<T> myvec2 = myvec; // first position - QCOMPARE(myvec.at(0), QLatin1String("A")); - myvec.insert(0, QLatin1String("X")); - QCOMPARE(myvec.at(0), QLatin1String("X")); - QCOMPARE(myvec.at(1), QLatin1String("A")); + QCOMPARE(myvec.at(0), tA); + myvec.insert(0, tX); + QCOMPARE(myvec.at(0), tX); + QCOMPARE(myvec.at(1), tA); + + QCOMPARE(myvec2.at(0), tA); + myvec2.insert(myvec2.begin(), tX); + QCOMPARE(myvec2.at(0), tX); + QCOMPARE(myvec2.at(1), tA); // middle - myvec.insert(1, QLatin1String("Z")); - QCOMPARE(myvec.at(0), QLatin1String("X")); - QCOMPARE(myvec.at(1), QLatin1String("Z")); - QCOMPARE(myvec.at(2), QLatin1String("A")); + myvec.insert(1, tZ); + QCOMPARE(myvec.at(0), tX); + QCOMPARE(myvec.at(1), tZ); + QCOMPARE(myvec.at(2), tA); + + myvec2.insert(myvec2.begin() + 1, tZ); + QCOMPARE(myvec2.at(0), tX); + QCOMPARE(myvec2.at(1), tZ); + QCOMPARE(myvec2.at(2), tA); // end - myvec.insert(5, QLatin1String("T")); - QCOMPARE(myvec.at(5), QLatin1String("T")); - QCOMPARE(myvec.at(4), QLatin1String("C")); + myvec.insert(5, tT); + QCOMPARE(myvec.at(5), tT); + QCOMPARE(myvec.at(4), tC); + + myvec2.insert(myvec2.end(), tT); + QCOMPARE(myvec2.at(5), tT); + QCOMPARE(myvec2.at(4), tC); // insert a lot of garbage in the middle - myvec.insert(2, 2, QLatin1String("infinity")); - QCOMPARE(myvec, QVector<QString>() << "X" << "Z" << "infinity" << "infinity" - << "A" << "B" << "C" << "T"); + myvec.insert(2, 2, ti); + QCOMPARE(myvec, QVector<T>() << tX << tZ << ti << ti + << tA << tB << tC << tT); + + myvec2.insert(myvec2.begin() + 2, 2, ti); + QCOMPARE(myvec2, myvec); + + // insert from references to the same container: + myvec.insert(0, 1, myvec[5]); // inserts tB + myvec2.insert(0, 1, myvec2[5]); // inserts tB + QCOMPARE(myvec, QVector<T>() << tB << tX << tZ << ti << ti + << tA << tB << tC << tT); + QCOMPARE(myvec2, myvec); + + myvec.insert(0, 1, const_cast<const QVector<T>&>(myvec)[0]); // inserts tB + myvec2.insert(0, 1, const_cast<const QVector<T>&>(myvec2)[0]); // inserts tB + QCOMPARE(myvec, QVector<T>() << tB << tB << tX << tZ << ti << ti + << tA << tB << tC << tT); + QCOMPARE(myvec2, myvec); +} + +void tst_QVector::insertInt() const +{ + insert<int>(); +} + +void tst_QVector::insertMovable() const +{ + insert<Movable>(); +} + +void tst_QVector::insertCustom() const +{ + insert<Custom>(); } void tst_QVector::isEmpty() const @@ -1321,6 +1428,8 @@ void tst_QVector::mid() const list << "foo" << "bar" << "baz" << "bak" << "buck" << "hello" << "kitty"; QCOMPARE(list.mid(3, 3), QVector<QString>() << "bak" << "buck" << "hello"); + QCOMPARE(list.mid(6, 10), QVector<QString>() << "kitty"); + QCOMPARE(list.mid(-1, 20), list); QCOMPARE(list.mid(4), QVector<QString>() << "buck" << "hello" << "kitty"); } @@ -1386,13 +1495,28 @@ void tst_QVector::remove() const T val1 = SimpleValue<T>::at(1); T val2 = SimpleValue<T>::at(2); T val3 = SimpleValue<T>::at(3); + T val4 = SimpleValue<T>::at(4); + myvec << val1 << val2 << val3; + myvec << val1 << val2 << val3; myvec << val1 << val2 << val3; // remove middle myvec.remove(1); - QCOMPARE(myvec, QVector<T>() << val1 << val3); + QCOMPARE(myvec, QVector<T>() << val1 << val3 << val1 << val2 << val3 << val1 << val2 << val3); + + // removeOne() + QVERIFY(!myvec.removeOne(val4)); + QVERIFY(myvec.removeOne(val2)); + QCOMPARE(myvec, QVector<T>() << val1 << val3 << val1 << val3 << val1 << val2 << val3); + + // removeAll() + QCOMPARE(myvec.removeAll(val4), 0); + QCOMPARE(myvec.removeAll(val1), 3); + QCOMPARE(myvec, QVector<T>() << val3 << val3 << val2 << val3); + QCOMPARE(myvec.removeAll(val2), 1); + QCOMPARE(myvec, QVector<T>() << val3 << val3 << val3); // remove rest - myvec.remove(0, 2); + myvec.remove(0, 3); QCOMPARE(myvec, QVector<T>()); } diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro index 1ef8e77071..352cf88d44 100644 --- a/tests/auto/corelib/tools/tools.pro +++ b/tests/auto/corelib/tools/tools.pro @@ -1,5 +1,6 @@ TEMPLATE=subdirs SUBDIRS=\ + collections \ qalgorithms \ qarraydata \ qarraydata_strictiterators \ diff --git a/tests/auto/corelib/xml/qxmlstream/data/009.ref b/tests/auto/corelib/xml/qxmlstream/data/009.ref index 1de530df1c..12b994eac4 100644 --- a/tests/auto/corelib/xml/qxmlstream/data/009.ref +++ b/tests/auto/corelib/xml/qxmlstream/data/009.ref @@ -24,4 +24,4 @@ Invalid( name="bar" qualifiedName="bar" Attribute( name="attr" namespaceUri="http://example.org/~wilbur" qualifiedName="b:attr" prefix="b" value="2" ) ) -ERROR: Attribute redefined. +ERROR: Attribute 'b:attr' redefined. diff --git a/tests/auto/corelib/xml/qxmlstream/data/010.ref b/tests/auto/corelib/xml/qxmlstream/data/010.ref index 217f4963a1..07def503a5 100644 --- a/tests/auto/corelib/xml/qxmlstream/data/010.ref +++ b/tests/auto/corelib/xml/qxmlstream/data/010.ref @@ -24,4 +24,4 @@ Invalid( name="bar" qualifiedName="bar" Attribute( name="attr" namespaceUri="http://example.org/~wilbur" qualifiedName="b:attr" prefix="b" value="2" ) ) -ERROR: Attribute redefined. +ERROR: Attribute 'b:attr' redefined. diff --git a/tests/auto/corelib/xml/qxmlstream/data/011.ref b/tests/auto/corelib/xml/qxmlstream/data/011.ref index e3945324eb..faa6e75429 100644 --- a/tests/auto/corelib/xml/qxmlstream/data/011.ref +++ b/tests/auto/corelib/xml/qxmlstream/data/011.ref @@ -27,4 +27,4 @@ Invalid( name="bar" qualifiedName="bar" Attribute( name="attr" namespaceUri="http://example.org/~wilbur" qualifiedName="b:attr" prefix="b" value="2" ) ) -ERROR: Attribute redefined. +ERROR: Attribute 'b:attr' redefined. diff --git a/tests/auto/corelib/xml/qxmlstream/data/012.ref b/tests/auto/corelib/xml/qxmlstream/data/012.ref index 7a688b103d..834db97ba6 100644 --- a/tests/auto/corelib/xml/qxmlstream/data/012.ref +++ b/tests/auto/corelib/xml/qxmlstream/data/012.ref @@ -24,4 +24,4 @@ Invalid( name="bar" qualifiedName="bar" Attribute( name="attr" namespaceUri="urn:xyzzy" qualifiedName="b:attr" prefix="b" value="2" ) ) -ERROR: Attribute redefined. +ERROR: Attribute 'b:attr' redefined. diff --git a/tests/auto/corelib/xml/qxmlstream/data/035.ref b/tests/auto/corelib/xml/qxmlstream/data/035.ref index e172fc90e1..cab0158a51 100644 --- a/tests/auto/corelib/xml/qxmlstream/data/035.ref +++ b/tests/auto/corelib/xml/qxmlstream/data/035.ref @@ -13,4 +13,4 @@ Invalid( name="bar" qualifiedName="bar" Attribute( name="attr" namespaceUri="http://example.org/~wilbur" qualifiedName="a:attr" prefix="a" value="2" ) ) -ERROR: Attribute redefined. +ERROR: Attribute 'a:attr' redefined. diff --git a/tests/auto/corelib/xml/qxmlstream/data/036.ref b/tests/auto/corelib/xml/qxmlstream/data/036.ref index 158e7361f9..50939ed7e7 100644 --- a/tests/auto/corelib/xml/qxmlstream/data/036.ref +++ b/tests/auto/corelib/xml/qxmlstream/data/036.ref @@ -13,4 +13,4 @@ Invalid( name="bar" qualifiedName="bar" Attribute( name="attr" namespaceUri="http://example.org/~wilbur" qualifiedName="b:attr" prefix="b" value="2" ) ) -ERROR: Attribute redefined. +ERROR: Attribute 'b:attr' redefined. |