diff options
Diffstat (limited to 'tests/auto')
763 files changed, 38195 insertions, 8194 deletions
diff --git a/tests/auto/baselineexample/baselineexample.pro b/tests/auto/baselineexample/baselineexample.pro new file mode 100644 index 0000000..13f03b8 --- /dev/null +++ b/tests/auto/baselineexample/baselineexample.pro @@ -0,0 +1,18 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2010-12-09T14:55:13 +# +#------------------------------------------------- + +QT += testlib + +TARGET = tst_baselineexample +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +SOURCES += tst_baselineexample.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" + +include($$PWD/../../arthur/common/qbaselinetest.pri) diff --git a/tests/auto/baselineexample/tst_baselineexample.cpp b/tests/auto/baselineexample/tst_baselineexample.cpp new file mode 100644 index 0000000..73657bd --- /dev/null +++ b/tests/auto/baselineexample/tst_baselineexample.cpp @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qbaselinetest.h> +#include <QPushButton> + +class tst_BaselineExample : public QObject +{ + Q_OBJECT + +public: + tst_BaselineExample(); + +private Q_SLOTS: + void testBasicUsage(); + void testMultipleImages(); + void testDataDriven_data(); + void testDataDriven(); + void testDataDrivenChecksum_data(); + void testDataDrivenChecksum(); +}; + + +tst_BaselineExample::tst_BaselineExample() +{ +} + + +void tst_BaselineExample::testBasicUsage() +{ + // Generate an image: + QPushButton b("Press me!"); + b.resize(100, 50); + b.show(); + QTest::qWaitForWindowShown(&b); + QImage img1 = QPixmap::grabWidget(&b).toImage(); + QVERIFY(!img1.isNull()); + + // Compare it to baseline on server: + QBASELINE_CHECK(img1, "button"); +} + + +void tst_BaselineExample::testMultipleImages() +{ + QPushButton b("Press me!"); + b.resize(100, 50); + b.show(); + QTest::qWaitForWindowShown(&b); + QBASELINE_CHECK(QPixmap::grabWidget(&b).toImage(), "text1"); + + b.setText("Kick me!"); + QTest::qWait(50); + QBASELINE_CHECK(QPixmap::grabWidget(&b).toImage(), "text2"); +} + + +void tst_BaselineExample::testDataDriven_data() +{ + QTest::addColumn<QString>("label"); + QBaselineTest::newRow("short") << "Ok!"; + QBaselineTest::newRow("long") << "A really long button text that just does not seem to end"; + QBaselineTest::newRow("empty") << ""; + QBaselineTest::newRow("signs") << "!@#$%^&*()_"; + QBaselineTest::newRow("html") << "<b>BOLD</b>"; +} + + +void tst_BaselineExample::testDataDriven() +{ + QFETCH(QString, label); + QPushButton b(label); + b.resize(100, 50); + b.show(); + QTest::qWaitForWindowShown(&b); + QBASELINE_TEST(QPixmap::grabWidget(&b).toImage()); +} + + +void tst_BaselineExample::testDataDrivenChecksum_data() +{ + QTest::addColumn<QString>("label"); + + const int numItems = 5; + const char *tags[numItems] = {"short", "long", "empty", "signs", "html"}; + const char *labels[numItems] = {"Ok!", "A really long button text that just does not seem to end", "", "!@#$%^&*()_", "<b>BOLD</b>"}; + + for (int i = 0; i<numItems; i++) { + quint16 checksum = qChecksum(labels[i], qstrlen(labels[i])); + QBaselineTest::newRow(tags[i], checksum) << labels[i]; + } +} + + +void tst_BaselineExample::testDataDrivenChecksum() +{ + QFETCH(QString, label); + QPushButton b(label); + b.resize(100, 50); + b.show(); + QTest::qWaitForWindowShown(&b); + QBASELINE_TEST(QPixmap::grabWidget(&b).toImage()); +} + + +QTEST_MAIN(tst_BaselineExample); + +#include "tst_baselineexample.moc" diff --git a/tests/auto/checkxmlfiles/checkxmlfiles.pro b/tests/auto/checkxmlfiles/checkxmlfiles.pro index 319ba9b..ab932f5 100644 --- a/tests/auto/checkxmlfiles/checkxmlfiles.pro +++ b/tests/auto/checkxmlfiles/checkxmlfiles.pro @@ -8,7 +8,7 @@ include (../xmlpatterns.pri) wince*|symbian: { QT += network -addFiles.sources = \ +addFiles.files = \ $$QT_SOURCE_TREE/examples/sql/masterdetail/albumdetails.xml \ $$QT_SOURCE_TREE/examples/xmlpatterns/xquery/globalVariables/globals.gccxml \ $$QT_SOURCE_TREE/doc/src/diagrams/stylesheet/treeview.svg \ diff --git a/tests/auto/collections/collections.pro b/tests/auto/collections/collections.pro index 876e903..8601ff8 100644 --- a/tests/auto/collections/collections.pro +++ b/tests/auto/collections/collections.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_collections.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/collections/tst_collections.cpp b/tests/auto/collections/tst_collections.cpp index 37a3127..00cdec3 100644 --- a/tests/auto/collections/tst_collections.cpp +++ b/tests/auto/collections/tst_collections.cpp @@ -104,13 +104,6 @@ void foo() #include "q3cleanuphandler.h" #endif -// Do not test initialization of pods on msvc6 and msvc 2002 -// This is a known issue -#if defined Q_CC_MSVC && _MSC_VER < 1310 -# define NOPODINITIALIZATION -#endif - - template class QList<int>; //TESTED_FILES= @@ -166,6 +159,9 @@ private slots: void forwardDeclared(); void alignment(); void QTBUG13079_collectionInsideCollection(); + + void foreach_2(); + void insert_remove_loop(); }; struct LargeStatic { @@ -195,10 +191,6 @@ QT_END_NAMESPACE struct Pod { int i1, i2; - -#if defined NOPODINITIALIZATION - Pod() : i1(0), i2(0) { } -#endif }; tst_Collections::tst_Collections() @@ -3448,27 +3440,16 @@ void tst_Collections::containerTypedefs() testSetContainerTypedefs(QSet<int>()); } -#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) -class Key1 -{}; -class T1 -{}; -class T2 -{}; -#else class Key1; class T1; class T2; -#endif 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) } -#if !defined(Q_CC_MSVC_NET) || _MSC_VER >= 1310 { 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) } -#endif #if !defined(Q_CC_RVCT) // RVCT can't handle forward declared template parameters if those are used to declare // class members inside templated class. @@ -3643,7 +3624,7 @@ template<template<class, class> class C> void QTBUG13079_collectionInsideCollect } -static quint32 qHash(const QTBUG13079_Node<QSet> &) +quint32 qHash(const QTBUG13079_Node<QSet> &) { return 0; } @@ -3718,5 +3699,214 @@ void tst_Collections::QTBUG13079_collectionInsideCollection() #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); } +#ifndef QT_NO_STL + operator std::string() { return QString::number(val).toStdString(); } + IntOrString(const std::string &v) : val(QString::fromStdString(v).toInt()) { } +#endif +}; + +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> >(); + +#ifndef QT_NO_STL + 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> >(); +#endif +} + + + QTEST_APPLESS_MAIN(tst_Collections) #include "tst_collections.moc" diff --git a/tests/auto/corelib.pro b/tests/auto/corelib.pro index 531fed2..6810f76 100644 --- a/tests/auto/corelib.pro +++ b/tests/auto/corelib.pro @@ -59,6 +59,7 @@ SUBDIRS=\ qresourceengine \ qringbuffer \ qscopedpointer \ + qscopedvaluerollback \ qsemaphore \ qsequentialanimationgroup \ qset \ @@ -75,6 +76,7 @@ SUBDIRS=\ qstringbuilder4 \ qstringlist \ qstringmatcher \ + qstringref \ qtconcurrentfilter \ qtconcurrentiteratekernel \ qtconcurrentmap \ @@ -100,6 +102,8 @@ SUBDIRS=\ qwritelocker \ selftests \ utf8 \ + qfilesystementry \ + qabstractfileengine symbian:SUBDIRS -= \ qtconcurrentfilter \ diff --git a/tests/auto/dbus.pro b/tests/auto/dbus.pro index e5f87e3..31b46a3 100644 --- a/tests/auto/dbus.pro +++ b/tests/auto/dbus.pro @@ -11,9 +11,9 @@ SUBDIRS=\ qdbusmetatype \ qdbuspendingcall \ qdbuspendingreply \ - qdbusperformance \ qdbusreply \ qdbusservicewatcher \ + qdbustype \ qdbusthreading \ qdbusxmlparser \ diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index 1bcc26f..72c32cb 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -8,6 +8,26 @@ SUBDIRS += \ SUBDIRS += \ examples \ parserstress \ + qdeclarativecomponent \ + qdeclarativecontext \ + qdeclarativeengine \ + qdeclarativeerror \ + qdeclarativefolderlistmodel \ + qdeclarativeinfo \ + qdeclarativelayoutitem \ + qdeclarativelistreference \ + qdeclarativemoduleplugin \ + qdeclarativeparticles \ + qdeclarativepixmapcache \ + qdeclarativeqt \ + qdeclarativeview \ + qdeclarativeviewer \ + qdeclarativexmlhttprequest \ + qmlvisual \ + moduleqt47 + +contains(QT_CONFIG, private_tests) { + SUBDIRS += \ qdeclarativeanchors \ qdeclarativeanimatedimage \ qdeclarativeanimations \ @@ -15,68 +35,47 @@ SUBDIRS += \ qdeclarativebehaviors \ qdeclarativebinding \ qdeclarativeborderimage \ - qdeclarativecomponent \ qdeclarativeconnection \ - qdeclarativecontext \ qdeclarativedebug \ qdeclarativedebugclient \ qdeclarativedebugservice \ qdeclarativedom \ qdeclarativeecmascript \ - qdeclarativeengine \ - qdeclarativeerror \ - qdeclarativefolderlistmodel \ - qdeclarativefontloader \ qdeclarativeflickable \ qdeclarativeflipable \ qdeclarativefocusscope \ + qdeclarativefontloader \ qdeclarativegridview \ qdeclarativeimage \ qdeclarativeimageprovider \ - qdeclarativeinfo \ qdeclarativeinstruction \ qdeclarativeitem \ qdeclarativelanguage \ - qdeclarativelayoutitem \ qdeclarativelistmodel \ - qdeclarativelistreference \ qdeclarativelistview \ qdeclarativeloader \ - qdeclarativemoduleplugin \ qdeclarativemousearea \ - qdeclarativeparticles \ qdeclarativepathview \ qdeclarativepincharea \ - qdeclarativepixmapcache \ qdeclarativepositioners \ qdeclarativeproperty \ qdeclarativepropertymap \ - qdeclarativeqt \ qdeclarativerepeater \ qdeclarativesmoothedanimation \ qdeclarativespringanimation \ + qdeclarativestyledtext \ qdeclarativesqldatabase \ qdeclarativestates \ - qdeclarativestyledtext \ qdeclarativesystempalette \ qdeclarativetext \ qdeclarativetextedit \ qdeclarativetextinput \ qdeclarativetimer \ qdeclarativevaluetypes \ - qdeclarativeview \ - qdeclarativeviewer \ qdeclarativevisualdatamodel \ qdeclarativeworkerscript \ - qdeclarativexmlhttprequest \ qdeclarativexmllistmodel \ - qmlvisual \ - qpacketprotocol \ - moduleqt47 - -contains(QT_CONFIG, webkit) { - SUBDIRS += \ - qdeclarativewebview + qpacketprotocol } contains(QT_CONFIG, opengl): SUBDIRS += qmlshadersplugin diff --git a/tests/auto/declarative/examples/examples.pro b/tests/auto/declarative/examples/examples.pro index 2e243b4..dafc146 100644 --- a/tests/auto/declarative/examples/examples.pro +++ b/tests/auto/declarative/examples/examples.pro @@ -6,10 +6,12 @@ SOURCES += tst_examples.cpp include(../../../../tools/qml/qml.pri) +include(../symbianlibs.pri) + symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/moduleqt47/moduleqt47.pro b/tests/auto/declarative/moduleqt47/moduleqt47.pro index 4ee634e..ff773e8 100644 --- a/tests/auto/declarative/moduleqt47/moduleqt47.pro +++ b/tests/auto/declarative/moduleqt47/moduleqt47.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_moduleqt47.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/parserstress/parserstress.pro b/tests/auto/declarative/parserstress/parserstress.pro index bb1d69f..6ef2432 100644 --- a/tests/auto/declarative/parserstress/parserstress.pro +++ b/tests/auto/declarative/parserstress/parserstress.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_parserstress.cpp symbian: { - importFiles.sources = ..\\..\\qscriptjstestsuite\\tests + importFiles.files = ..\\..\\qscriptjstestsuite\\tests importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeanchors/qdeclarativeanchors.pro b/tests/auto/declarative/qdeclarativeanchors/qdeclarativeanchors.pro index 9798bb6..f09e8d9 100644 --- a/tests/auto/declarative/qdeclarativeanchors/qdeclarativeanchors.pro +++ b/tests/auto/declarative/qdeclarativeanchors/qdeclarativeanchors.pro @@ -4,9 +4,9 @@ SOURCES += tst_qdeclarativeanchors.cpp macx:CONFIG -= app_bundle symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro b/tests/auto/declarative/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro index 0a2f0f2..3d040a6 100644 --- a/tests/auto/declarative/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro +++ b/tests/auto/declarative/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro @@ -5,9 +5,9 @@ SOURCES += tst_qdeclarativeanimatedimage.cpp ../shared/testhttpserver.cpp macx:CONFIG -= app_bundle symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro b/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro index ed47dca..d00d51a 100644 --- a/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro +++ b/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro @@ -4,9 +4,9 @@ SOURCES += tst_qdeclarativeanimations.cpp macx:CONFIG -= app_bundle symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp b/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp index fca4396..c2cfcd8 100644 --- a/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp +++ b/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro b/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro index cfb59ef..7416827 100644 --- a/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro +++ b/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro @@ -4,9 +4,9 @@ SOURCES += tst_qdeclarativebehaviors.cpp macx:CONFIG -= app_bundle symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro b/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro index a7ba2a8..fe12635 100644 --- a/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro +++ b/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativebinding.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeborderimage/qdeclarativeborderimage.pro b/tests/auto/declarative/qdeclarativeborderimage/qdeclarativeborderimage.pro index a21761b..a7463e8 100644 --- a/tests/auto/declarative/qdeclarativeborderimage/qdeclarativeborderimage.pro +++ b/tests/auto/declarative/qdeclarativeborderimage/qdeclarativeborderimage.pro @@ -6,9 +6,9 @@ HEADERS += ../shared/testhttpserver.h SOURCES += tst_qdeclarativeborderimage.cpp ../shared/testhttpserver.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro b/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro index d06ce4f..6f9550d 100644 --- a/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro +++ b/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativeconnection.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp index aa76569..9c20bd6 100644 --- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp +++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp @@ -80,7 +80,7 @@ private: void recursiveCompareObjects(const QDeclarativeDebugObjectReference &a, const QDeclarativeDebugObjectReference &b) const; void recursiveCompareContexts(const QDeclarativeDebugContextReference &a, const QDeclarativeDebugContextReference &b) const; void compareProperties(const QDeclarativeDebugPropertyReference &a, const QDeclarativeDebugPropertyReference &b) const; - + QDeclarativeDebugConnection *m_conn; QDeclarativeEngineDebug *m_dbg; QDeclarativeEngine *m_engine; @@ -112,6 +112,7 @@ private slots: void tst_QDeclarativeDebugContextReference(); void tst_QDeclarativeDebugPropertyReference(); + void setBindingForObject(); void setMethodBody(); void queryObjectTree(); void setBindingInStates(); @@ -133,7 +134,7 @@ QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int conte { QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); - + if (q_engines->engines().count() == 0) return QDeclarativeDebugObjectReference(); QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); @@ -223,7 +224,7 @@ void tst_QDeclarativeDebug::recursiveObjectTest(QObject *o, const QDeclarativeDe QCOMPARE(p.name(), QString::fromUtf8(pmeta.name())); - if (pmeta.type() < QVariant::UserType) // TODO test complex types + if (pmeta.type() > 0 && pmeta.type() < QVariant::UserType) // TODO test complex types QCOMPARE(p.value(), pmeta.read(o)); if (p.name() == "parent") @@ -367,7 +368,7 @@ void tst_QDeclarativeDebug::initTestCase() for (int i=0; i<qml.count(); i++) { QDeclarativeComponent component(m_engine); component.setData(qml[i], QUrl::fromLocalFile("")); - Q_ASSERT(component.isReady()); // fails if bad syntax + QVERIFY(component.isReady()); // fails if bad syntax m_components << qobject_cast<QDeclarativeItem*>(component.create()); } m_rootItem = qobject_cast<QDeclarativeItem*>(m_components.first()); @@ -381,7 +382,7 @@ void tst_QDeclarativeDebug::initTestCase() QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Connection established"); bool ok = m_conn->waitForConnected(); - Q_ASSERT(ok); + QVERIFY(ok); QTRY_VERIFY(QDeclarativeDebugService::hasDebuggingClient()); m_dbg = new QDeclarativeEngineDebug(m_conn, this); QTRY_VERIFY(m_dbg->status() == QDeclarativeEngineDebug::Enabled); @@ -438,7 +439,7 @@ void tst_QDeclarativeDebug::watch_property() QDeclarativeDebugPropertyReference prop = findProperty(obj.properties(), "width"); QDeclarativeDebugPropertyWatch *watch; - + QDeclarativeEngineDebug *unconnected = new QDeclarativeEngineDebug(0); watch = unconnected->addWatch(prop, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Dead); @@ -449,7 +450,7 @@ void tst_QDeclarativeDebug::watch_property() QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Inactive); delete watch; - + watch = m_dbg->addWatch(prop, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Waiting); QCOMPARE(watch->objectDebugId(), obj.debugId()); @@ -481,12 +482,12 @@ void tst_QDeclarativeDebug::watch_object() { QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); - - Q_ASSERT(q_engines->engines().count() > 0); + + QVERIFY(q_engines->engines().count() > 0); QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); - Q_ASSERT(q_context->rootContext().objects().count() > 0); + QVERIFY(q_context->rootContext().objects().count() > 0); QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[0], this); waitForQuery(q_obj); @@ -503,7 +504,7 @@ void tst_QDeclarativeDebug::watch_object() QCOMPARE(watch->state(), QDeclarativeDebugWatch::Dead); delete watch; delete unconnected; - + watch = m_dbg->addWatch(QDeclarativeDebugObjectReference(), this); QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Inactive); @@ -557,7 +558,7 @@ void tst_QDeclarativeDebug::watch_expression() QFETCH(int, incrementCount); int origWidth = m_rootItem->property("width").toInt(); - + QDeclarativeDebugObjectReference obj = findRootObject(); QDeclarativeDebugObjectExpressionWatch *watch; @@ -567,12 +568,12 @@ void tst_QDeclarativeDebug::watch_expression() QCOMPARE(watch->state(), QDeclarativeDebugWatch::Dead); delete watch; delete unconnected; - + watch = m_dbg->addWatch(QDeclarativeDebugObjectReference(), expr, this); QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Inactive); delete watch; - + watch = m_dbg->addWatch(obj, expr, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Waiting); QCOMPARE(watch->objectDebugId(), obj.debugId()); @@ -602,7 +603,7 @@ void tst_QDeclarativeDebug::watch_expression() delete watch; // restore original value and verify spy doesn't get a signal since watch has been removed - m_rootItem->setProperty("width", origWidth); + m_rootItem->setProperty("width", origWidth); QTest::qWait(100); QCOMPARE(spy.count(), expectedSpyCount); @@ -663,7 +664,13 @@ void tst_QDeclarativeDebug::queryAvailableEngines() QCOMPARE(e.name(), m_engine->objectName()); } + // Make query invalid by deleting client + q_engines = m_dbg->queryAvailableEngines(this); + QCOMPARE(q_engines->state(), QDeclarativeDebugQuery::Waiting); + delete m_dbg; + QCOMPARE(q_engines->state(), QDeclarativeDebugQuery::Error); delete q_engines; + m_dbg = new QDeclarativeEngineDebug(m_conn, this); } void tst_QDeclarativeDebug::queryRootContexts() @@ -671,9 +678,10 @@ void tst_QDeclarativeDebug::queryRootContexts() QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); int engineId = q_engines->engines()[0].debugId(); + delete q_engines; QDeclarativeDebugRootContextQuery *q_context; - + QDeclarativeEngineDebug *unconnected = new QDeclarativeEngineDebug(0); q_context = unconnected->queryRootContexts(engineId, this); QCOMPARE(q_context->state(), QDeclarativeDebugQuery::Error); @@ -702,8 +710,13 @@ void tst_QDeclarativeDebug::queryRootContexts() QVERIFY(context.contexts()[0].debugId() >= 0); QCOMPARE(context.contexts()[0].name(), QString("tst_QDeclarativeDebug_childContext")); - delete q_engines; + // Make query invalid by deleting client + q_context = m_dbg->queryRootContexts(engineId, this); + QCOMPARE(q_context->state(), QDeclarativeDebugQuery::Waiting); + delete m_dbg; + QCOMPARE(q_context->state(), QDeclarativeDebugQuery::Error); delete q_context; + m_dbg = new QDeclarativeEngineDebug(m_conn, this); } void tst_QDeclarativeDebug::queryObject() @@ -712,7 +725,7 @@ void tst_QDeclarativeDebug::queryObject() QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); - + QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); QDeclarativeDebugObjectReference rootObject = q_context->rootContext().objects()[0]; @@ -735,7 +748,14 @@ void tst_QDeclarativeDebug::queryObject() delete q_engines; delete q_context; + + // Make query invalid by deleting client + q_obj = recursive ? m_dbg->queryObjectRecursive(rootObject, this) : m_dbg->queryObject(rootObject, this); + QCOMPARE(q_obj->state(), QDeclarativeDebugQuery::Waiting); + delete m_dbg; + QCOMPARE(q_obj->state(), QDeclarativeDebugQuery::Error); delete q_obj; + m_dbg = new QDeclarativeEngineDebug(m_conn, this); // check source as defined in main() QDeclarativeDebugFileReference source = obj.source(); @@ -786,7 +806,7 @@ void tst_QDeclarativeDebug::queryExpressionResult() QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); // check immediate deletion is ok - + QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); int objectId = q_context->rootContext().objects()[0].debugId(); @@ -798,7 +818,7 @@ void tst_QDeclarativeDebug::queryExpressionResult() QCOMPARE(q_expr->state(), QDeclarativeDebugQuery::Error); delete q_expr; delete unconnected; - + q_expr = m_dbg->queryExpressionResult(objectId, expr, this); delete q_expr; @@ -810,7 +830,14 @@ void tst_QDeclarativeDebug::queryExpressionResult() delete q_engines; delete q_context; + + // Make query invalid by deleting client + q_expr = m_dbg->queryExpressionResult(objectId, expr, this); + QCOMPARE(q_expr->state(), QDeclarativeDebugQuery::Waiting); + delete m_dbg; + QCOMPARE(q_expr->state(), QDeclarativeDebugQuery::Error); delete q_expr; + m_dbg = new QDeclarativeEngineDebug(m_conn, this); } void tst_QDeclarativeDebug::queryExpressionResult_data() @@ -937,7 +964,7 @@ void tst_QDeclarativeDebug::tst_QDeclarativeDebugPropertyReference() QDeclarativeDebugObjectQuery *query = m_dbg->queryObject(rootObject, this); waitForQuery(query); QDeclarativeDebugObjectReference obj = query->object(); - delete query; + delete query; QDeclarativeDebugPropertyReference ref = findProperty(obj.properties(), "scale"); QVERIFY(ref.objectDebugId() > 0); @@ -946,7 +973,7 @@ void tst_QDeclarativeDebug::tst_QDeclarativeDebugPropertyReference() QVERIFY(!ref.valueTypeName().isEmpty()); QVERIFY(!ref.binding().isEmpty()); QVERIFY(ref.hasNotifySignal()); - + QDeclarativeDebugPropertyReference copy(ref); QDeclarativeDebugPropertyReference copyAssign; copyAssign = ref; @@ -954,6 +981,77 @@ void tst_QDeclarativeDebug::tst_QDeclarativeDebugPropertyReference() compareProperties(r, ref); } +void tst_QDeclarativeDebug::setBindingForObject() +{ + QDeclarativeDebugObjectReference rootObject = findRootObject(); + QVERIFY(rootObject.debugId() != -1); + QDeclarativeDebugPropertyReference widthPropertyRef = findProperty(rootObject.properties(), "width"); + + QCOMPARE(widthPropertyRef.value(), QVariant(10)); + QCOMPARE(widthPropertyRef.binding(), QString()); + + // + // set literal + // + m_dbg->setBindingForObject(rootObject.debugId(), "width", "15", true); + + rootObject = findRootObject(); + widthPropertyRef = findProperty(rootObject.properties(), "width"); + + QCOMPARE(widthPropertyRef.value(), QVariant(15)); + QCOMPARE(widthPropertyRef.binding(), QString()); + + // + // set expression + // + m_dbg->setBindingForObject(rootObject.debugId(), "width", "height", false); + + rootObject = findRootObject(); + widthPropertyRef = findProperty(rootObject.properties(), "width"); + + QCOMPARE(widthPropertyRef.value(), QVariant(20)); + QCOMPARE(widthPropertyRef.binding(), QString("height")); + + // + // reset + // + m_dbg->resetBindingForObject(rootObject.debugId(), "width"); + + rootObject = findRootObject(); + widthPropertyRef = findProperty(rootObject.properties(), "width"); + + // QCOMPARE(widthPropertyRef.value(), QVariant(0)); // TODO: Shouldn't this work? + QCOMPARE(widthPropertyRef.binding(), QString()); + + // + // set handler + // + rootObject = findRootObject(); + QCOMPARE(rootObject.children().size(), 5); // Rectangle, Text, MouseArea, Component.onCompleted, NonScriptPropertyElement + QDeclarativeDebugObjectReference mouseAreaObject = rootObject.children().at(2); + QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObjectRecursive(mouseAreaObject, this); + waitForQuery(q_obj); + mouseAreaObject = q_obj->object(); + + QCOMPARE(mouseAreaObject.className(), QString("MouseArea")); + + QDeclarativeDebugPropertyReference onEnteredRef = findProperty(mouseAreaObject.properties(), "onEntered"); + + QCOMPARE(onEnteredRef.name(), QString("onEntered")); + QCOMPARE(onEnteredRef.value(), QVariant("{ console.log('hello') }")); + + m_dbg->setBindingForObject(mouseAreaObject.debugId(), "onEntered", "{console.log('hello, world') }", false) ; + + rootObject = findRootObject(); + mouseAreaObject = rootObject.children().at(2); + q_obj = m_dbg->queryObjectRecursive(mouseAreaObject, this); + waitForQuery(q_obj); + mouseAreaObject = q_obj->object(); + onEnteredRef = findProperty(mouseAreaObject.properties(), "onEntered"); + QCOMPARE(onEnteredRef.name(), QString("onEntered")); + QCOMPARE(onEnteredRef.value(), QVariant("{console.log('hello, world') }")); +} + void tst_QDeclarativeDebug::setBindingInStates() { // Check if changing bindings of propertychanges works diff --git a/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp b/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp index 2a28a45..d41cfa3 100644 --- a/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp +++ b/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp @@ -88,7 +88,7 @@ void tst_QDeclarativeDebugClient::initTestCase() QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Connection established"); bool ok = m_conn->waitForConnected(); - Q_ASSERT(ok); + QVERIFY(ok); QTRY_VERIFY(QDeclarativeDebugService::hasDebuggingClient()); QTRY_COMPARE(client.status(), QDeclarativeDebugClient::Enabled); diff --git a/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp b/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp index 4bbb27d..3fa8bba 100644 --- a/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp +++ b/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp @@ -87,7 +87,7 @@ void tst_QDeclarativeDebugService::initTestCase() QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Connection established"); bool ok = m_conn->waitForConnected(); - Q_ASSERT(ok); + QVERIFY(ok); QTRY_VERIFY(QDeclarativeDebugService::hasDebuggingClient()); } diff --git a/tests/auto/declarative/qdeclarativedom/qdeclarativedom.pro b/tests/auto/declarative/qdeclarativedom/qdeclarativedom.pro index 415d4e2..8ac69aa 100644 --- a/tests/auto/declarative/qdeclarativedom/qdeclarativedom.pro +++ b/tests/auto/declarative/qdeclarativedom/qdeclarativedom.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativedom.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml b/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml new file mode 100644 index 0000000..cbbbbf9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml @@ -0,0 +1,11 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyQmlObject { + function test1() { + value = 4.2 + } + function test2() { + value = 7.9 + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro b/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro index 58cad34..69d25a4 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro +++ b/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro @@ -13,9 +13,9 @@ INCLUDEPATH += ../shared # LIBS += -lgcov symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 8df1873..71214a3 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -176,6 +176,7 @@ private slots: void aliasBindingsOverrideTarget(); void aliasWritesOverrideBindings(); void pushCleanContext(); + void realToInt(); void include(); @@ -2161,16 +2162,12 @@ public: ~CppOwnershipReturnValue() { delete value; } Q_INVOKABLE QObject *create() { - Q_ASSERT(value == 0); - value = new QObject; QDeclarativeEngine::setObjectOwnership(value, QDeclarativeEngine::CppOwnership); return value; } Q_INVOKABLE MyQmlObject *createQmlObject() { - Q_ASSERT(value == 0); - MyQmlObject *rv = new MyQmlObject; value = rv; return rv; @@ -3081,6 +3078,18 @@ void tst_qdeclarativeecmascript::pushCleanContext() QCOMPARE(func2.call().toInt32(), 6); } +void tst_qdeclarativeecmascript::realToInt() +{ + QDeclarativeComponent component(&engine, TEST_FILE("realToInt.qml")); + MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); + QVERIFY(object != 0); + + QMetaObject::invokeMethod(object, "test1"); + QCOMPARE(object->value(), int(4)); + QMetaObject::invokeMethod(object, "test2"); + QCOMPARE(object->value(), int(8)); +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" diff --git a/tests/auto/declarative/qdeclarativeflickable/qdeclarativeflickable.pro b/tests/auto/declarative/qdeclarativeflickable/qdeclarativeflickable.pro index be0ba6c..c176e07 100644 --- a/tests/auto/declarative/qdeclarativeflickable/qdeclarativeflickable.pro +++ b/tests/auto/declarative/qdeclarativeflickable/qdeclarativeflickable.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativeflickable.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeflipable/qdeclarativeflipable.pro b/tests/auto/declarative/qdeclarativeflipable/qdeclarativeflipable.pro index 759e80b..3b6d19a 100644 --- a/tests/auto/declarative/qdeclarativeflipable/qdeclarativeflipable.pro +++ b/tests/auto/declarative/qdeclarativeflipable/qdeclarativeflipable.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativeflipable.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro b/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro index 24749c6..eab983f 100644 --- a/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro +++ b/tests/auto/declarative/qdeclarativefocusscope/qdeclarativefocusscope.pro @@ -4,9 +4,9 @@ SOURCES += tst_qdeclarativefocusscope.cpp macx:CONFIG -= app_bundle symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro b/tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro index 91bf4a7..b7e5e5f 100644 --- a/tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro +++ b/tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativefolderlistmodel.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro index 01dca26..357268b 100644 --- a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro +++ b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro @@ -6,9 +6,9 @@ HEADERS += ../shared/testhttpserver.h SOURCES += tst_qdeclarativefontloader.cpp ../shared/testhttpserver.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp index 689c20d..9b2704b 100644 --- a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp +++ b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp @@ -55,13 +55,13 @@ #endif class tst_qdeclarativefontloader : public QObject - { Q_OBJECT public: tst_qdeclarativefontloader(); private slots: + void init(); void noFont(); void namedFont(); void localFont(); @@ -71,8 +71,6 @@ private slots: void failWebFont(); void changeFont(); -private slots: - private: QDeclarativeEngine engine; TestHTTPServer server; @@ -82,7 +80,11 @@ tst_qdeclarativefontloader::tst_qdeclarativefontloader() : server(SERVER_PORT) { server.serveDirectory(SRCDIR "/data"); - Q_ASSERT(server.isValid()); +} + +void tst_qdeclarativefontloader::init() +{ + QVERIFY(server.isValid()); } void tst_qdeclarativefontloader::noFont() diff --git a/tests/auto/declarative/qdeclarativegridview/qdeclarativegridview.pro b/tests/auto/declarative/qdeclarativegridview/qdeclarativegridview.pro index a99a1b9..bc196fb 100644 --- a/tests/auto/declarative/qdeclarativegridview/qdeclarativegridview.pro +++ b/tests/auto/declarative/qdeclarativegridview/qdeclarativegridview.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativegridview.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeimage/qdeclarativeimage.pro b/tests/auto/declarative/qdeclarativeimage/qdeclarativeimage.pro index 244a1e1..a22c8b5 100644 --- a/tests/auto/declarative/qdeclarativeimage/qdeclarativeimage.pro +++ b/tests/auto/declarative/qdeclarativeimage/qdeclarativeimage.pro @@ -6,9 +6,9 @@ HEADERS += ../shared/testhttpserver.h SOURCES += tst_qdeclarativeimage.cpp ../shared/testhttpserver.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro b/tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro index 2c20e7e..423390f 100644 --- a/tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro +++ b/tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativeinfo.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeitem/qdeclarativeitem.pro b/tests/auto/declarative/qdeclarativeitem/qdeclarativeitem.pro index f4901c4..d8007a0 100644 --- a/tests/auto/declarative/qdeclarativeitem/qdeclarativeitem.pro +++ b/tests/auto/declarative/qdeclarativeitem/qdeclarativeitem.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativeitem.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro b/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro index 43c451f..cae85a7 100644 --- a/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro +++ b/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro @@ -12,9 +12,9 @@ HEADERS += ../shared/testhttpserver.h SOURCES += ../shared/testhttpserver.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativelayoutitem/qdeclarativelayoutitem.pro b/tests/auto/declarative/qdeclarativelayoutitem/qdeclarativelayoutitem.pro index 5076e51..d89f16c 100644 --- a/tests/auto/declarative/qdeclarativelayoutitem/qdeclarativelayoutitem.pro +++ b/tests/auto/declarative/qdeclarativelayoutitem/qdeclarativelayoutitem.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativelayoutitem.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro index e90db49..b5c5cf2 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro +++ b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro @@ -6,9 +6,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativelistmodel.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index 263caf3..214b7af 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -115,7 +115,6 @@ int tst_qdeclarativelistmodel::roleFromName(const QDeclarativeListModel *model, if (model->toString(roles[i]) == roleName) return roles[i]; } - Q_ASSERT(false); return -1; } @@ -741,6 +740,7 @@ void tst_qdeclarativelistmodel::get() "}", QUrl()); QDeclarativeListModel *model = qobject_cast<QDeclarativeListModel*>(component.create()); int role = roleFromName(model, roleName); + QVERIFY(role >= 0); QSignalSpy spy(model, SIGNAL(itemsChanged(int, int, QList<int>))); QDeclarativeExpression expr(eng.rootContext(), model, expression); @@ -802,6 +802,7 @@ void tst_qdeclarativelistmodel::get_worker() model.append(sv); model.append(sv); int role = roleFromName(&model, roleName); + QVERIFY(role >= 0); const char *warning = "<Unknown File>: QML ListModel: Cannot add list-type data when modifying or after modification from a worker script"; if (roleValue.type() == QVariant::List || roleValue.type() == QVariant::Map) @@ -893,6 +894,7 @@ void tst_qdeclarativelistmodel::get_nested() int outerListIndex = testData[i].first; QString outerListRoleName = testData[i].second; int outerListRole = roleFromName(model, outerListRoleName); + QVERIFY(outerListRole >= 0); childModel = qobject_cast<QDeclarativeListModel*>(model->data(outerListIndex, outerListRole).value<QObject*>()); QVERIFY(childModel); @@ -905,6 +907,7 @@ void tst_qdeclarativelistmodel::get_nested() QVERIFY(!expr.hasError()); int role = roleFromName(childModel, roleName); + QVERIFY(role >= 0); QCOMPARE(childModel->data(index, role), roleValue); QCOMPARE(spy.count(), 1); diff --git a/tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro b/tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro index 8c99f08..1633ffc 100644 --- a/tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro +++ b/tests/auto/declarative/qdeclarativelistview/qdeclarativelistview.pro @@ -6,9 +6,9 @@ HEADERS += incrementalmodel.h SOURCES += tst_qdeclarativelistview.cpp incrementalmodel.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeloader/qdeclarativeloader.pro b/tests/auto/declarative/qdeclarativeloader/qdeclarativeloader.pro index b07bf9e..1ede509 100644 --- a/tests/auto/declarative/qdeclarativeloader/qdeclarativeloader.pro +++ b/tests/auto/declarative/qdeclarativeloader/qdeclarativeloader.pro @@ -8,9 +8,9 @@ SOURCES += tst_qdeclarativeloader.cpp \ ../shared/testhttpserver.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro index a92d3a2..98cd472 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro +++ b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro @@ -7,9 +7,9 @@ QT += declarative network CONFIG -= app_bundle symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativemousearea/qdeclarativemousearea.pro b/tests/auto/declarative/qdeclarativemousearea/qdeclarativemousearea.pro index 3d39aa8..ed9313f 100644 --- a/tests/auto/declarative/qdeclarativemousearea/qdeclarativemousearea.pro +++ b/tests/auto/declarative/qdeclarativemousearea/qdeclarativemousearea.pro @@ -6,9 +6,9 @@ HEADERS += ../shared/testhttpserver.h SOURCES += tst_qdeclarativemousearea.cpp ../shared/testhttpserver.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeparticles/qdeclarativeparticles.pro b/tests/auto/declarative/qdeclarativeparticles/qdeclarativeparticles.pro index f9ca90f..2cf8268 100644 --- a/tests/auto/declarative/qdeclarativeparticles/qdeclarativeparticles.pro +++ b/tests/auto/declarative/qdeclarativeparticles/qdeclarativeparticles.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativeparticles.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativepathview/qdeclarativepathview.pro b/tests/auto/declarative/qdeclarativepathview/qdeclarativepathview.pro index 04fd26b..e0404c5 100644 --- a/tests/auto/declarative/qdeclarativepathview/qdeclarativepathview.pro +++ b/tests/auto/declarative/qdeclarativepathview/qdeclarativepathview.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativepathview.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro b/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro index 3130364..88871e9 100644 --- a/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro +++ b/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro @@ -10,9 +10,9 @@ HEADERS += ../shared/testhttpserver.h SOURCES += ../shared/testhttpserver.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp index d46e7a9..ead2c4a 100644 --- a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp +++ b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp @@ -82,7 +82,6 @@ private slots: #ifndef QT_NO_CONCURRENT void networkCrash(); #endif - private: QDeclarativeEngine engine; QUrl thisfile; @@ -373,6 +372,7 @@ void createNetworkServer() eventLoop.exec(); } +#ifndef QT_NO_CONCURRENT // QT-3957 void tst_qdeclarativepixmapcache::networkCrash() { @@ -387,6 +387,7 @@ void tst_qdeclarativepixmapcache::networkCrash() } future.cancel(); } +#endif #endif diff --git a/tests/auto/declarative/qdeclarativepositioners/qdeclarativepositioners.pro b/tests/auto/declarative/qdeclarativepositioners/qdeclarativepositioners.pro index 5dc7bb8..27e5948 100644 --- a/tests/auto/declarative/qdeclarativepositioners/qdeclarativepositioners.pro +++ b/tests/auto/declarative/qdeclarativepositioners/qdeclarativepositioners.pro @@ -4,9 +4,9 @@ SOURCES += tst_qdeclarativepositioners.cpp macx:CONFIG -= app_bundle symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro b/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro index 4121a33..1750860 100644 --- a/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro +++ b/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativeproperty.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro b/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro index 9e698fe..4b197eb 100644 --- a/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro +++ b/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro @@ -4,9 +4,9 @@ SOURCES += tst_qdeclarativeqt.cpp macx:CONFIG -= app_bundle symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativerepeater/qdeclarativerepeater.pro b/tests/auto/declarative/qdeclarativerepeater/qdeclarativerepeater.pro index f3ff9ed..5230f69 100644 --- a/tests/auto/declarative/qdeclarativerepeater/qdeclarativerepeater.pro +++ b/tests/auto/declarative/qdeclarativerepeater/qdeclarativerepeater.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativerepeater.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro b/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro index c2d30a0..171f308 100644 --- a/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro +++ b/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro @@ -9,9 +9,9 @@ INCLUDEPATH += ../shared # LIBS += -lgcov symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro b/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro index 872aeb9..1e77d6e 100644 --- a/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro +++ b/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativesmoothedanimation.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro b/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro index 213b262..da477fc 100644 --- a/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro +++ b/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativespringanimation.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro b/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro index 1462c9a..0d335a5 100644 --- a/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro +++ b/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro @@ -6,9 +6,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativesqldatabase.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro b/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro index 2bae041..4a0cc24 100644 --- a/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro +++ b/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativestates.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativetext/qdeclarativetext.pro b/tests/auto/declarative/qdeclarativetext/qdeclarativetext.pro index c1a36fd..290cda3 100644 --- a/tests/auto/declarative/qdeclarativetext/qdeclarativetext.pro +++ b/tests/auto/declarative/qdeclarativetext/qdeclarativetext.pro @@ -10,9 +10,9 @@ HEADERS += ../shared/testhttpserver.h SOURCES += ../shared/testhttpserver.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp b/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp index 30b3d29..0586c45 100644 --- a/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp +++ b/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp @@ -1233,10 +1233,12 @@ void tst_qdeclarativetext::lineHeight() qreal h2 = myText->height(); myText->setLineHeight(2.0); + QEXPECT_FAIL("", "QTBUG-17325", Continue); QVERIFY(myText->height() == h2 * 2.0); myText->setLineHeightMode(QDeclarativeText::FixedHeight); myText->setLineHeight(10); + QEXPECT_FAIL("", "QTBUG-17325", Continue); QCOMPARE(myText->height(), myText->lineCount() * 10.0); delete canvas; diff --git a/tests/auto/declarative/qdeclarativetextedit/qdeclarativetextedit.pro b/tests/auto/declarative/qdeclarativetextedit/qdeclarativetextedit.pro index 4b6bd49..aaf753e 100644 --- a/tests/auto/declarative/qdeclarativetextedit/qdeclarativetextedit.pro +++ b/tests/auto/declarative/qdeclarativetextedit/qdeclarativetextedit.pro @@ -6,9 +6,9 @@ SOURCES += tst_qdeclarativetextedit.cpp ../shared/testhttpserver.cpp HEADERS += ../shared/testhttpserver.h symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativetextinput/qdeclarativetextinput.pro b/tests/auto/declarative/qdeclarativetextinput/qdeclarativetextinput.pro index 8f42448..0fee1c9 100644 --- a/tests/auto/declarative/qdeclarativetextinput/qdeclarativetextinput.pro +++ b/tests/auto/declarative/qdeclarativetextinput/qdeclarativetextinput.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativetextinput.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro b/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro index 90e46d3..59b3526 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro +++ b/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro @@ -8,9 +8,9 @@ SOURCES += tst_qdeclarativevaluetypes.cpp \ testtypes.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeview/qdeclarativeview.pro b/tests/auto/declarative/qdeclarativeview/qdeclarativeview.pro index 21a9195..fc4790d 100644 --- a/tests/auto/declarative/qdeclarativeview/qdeclarativeview.pro +++ b/tests/auto/declarative/qdeclarativeview/qdeclarativeview.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativeview.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro b/tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro index 6189916..8d4b410 100644 --- a/tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro +++ b/tests/auto/declarative/qdeclarativeviewer/qdeclarativeviewer.pro @@ -6,10 +6,12 @@ include(../../../../tools/qml/qml.pri) SOURCES += tst_qdeclarativeviewer.cpp +include(../symbianlibs.pri) + symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro b/tests/auto/declarative/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro index 92e5f60..fe3d794 100644 --- a/tests/auto/declarative/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro +++ b/tests/auto/declarative/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativevisualdatamodel.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativewebview/data/basic.html b/tests/auto/declarative/qdeclarativewebview/data/basic.html deleted file mode 100644 index 22e3e24..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/basic.html +++ /dev/null @@ -1,17 +0,0 @@ -<html> -<head><title>Basic</title> -<link rel="icon" sizes="48x48" href="basic.png"> -<script type="text/javascript"> -<!-- -window.onload = function(){ window.status = "status here"; } -// --> -</script> -</head> -<body leftmargin="0" marginwidth="0"> -<table width="123"> -<tbody> -<tr><td>This is a basic test.</td></tr> -</tbody> -</table> -</body> -</html> diff --git a/tests/auto/declarative/qdeclarativewebview/data/basic.ico b/tests/auto/declarative/qdeclarativewebview/data/basic.ico Binary files differdeleted file mode 100644 index 8f3d05e..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/basic.ico +++ /dev/null diff --git a/tests/auto/declarative/qdeclarativewebview/data/basic.png b/tests/auto/declarative/qdeclarativewebview/data/basic.png Binary files differdeleted file mode 100644 index 35717cc..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/basic.png +++ /dev/null diff --git a/tests/auto/declarative/qdeclarativewebview/data/basic.qml b/tests/auto/declarative/qdeclarativewebview/data/basic.qml deleted file mode 100644 index 73330cd..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/basic.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 1.0 -import QtWebKit 1.0 - -WebView { - url: "basic.html" -} diff --git a/tests/auto/declarative/qdeclarativewebview/data/elements.html b/tests/auto/declarative/qdeclarativewebview/data/elements.html deleted file mode 100644 index 9236867..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/elements.html +++ /dev/null @@ -1,14 +0,0 @@ -<body leftmargin=0 topmargin=0> -<table width="300px" border=1 cellpadding=0 cellspacing=0> -<tr> -<td align=center width=25%%><p>A</p></td> -<td width=75% height=50px> - <table width=100% border=1 cellpadding=0 cellspacing=0> - <tr> - <td align=center width=50% height=50px><p>B</p></td> - <td align=center width=50% height=50px><p>C</p></td> - </tr> - </table> -</td> -</tr> -</table> diff --git a/tests/auto/declarative/qdeclarativewebview/data/elements.qml b/tests/auto/declarative/qdeclarativewebview/data/elements.qml deleted file mode 100644 index b86dd9d..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/elements.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 1.0 -import QtWebKit 1.0 - -WebView { - url: "elements.html" - width: 310 - height: 100 -} diff --git a/tests/auto/declarative/qdeclarativewebview/data/forward.html b/tests/auto/declarative/qdeclarativewebview/data/forward.html deleted file mode 100644 index 62ab62d..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/forward.html +++ /dev/null @@ -1,12 +0,0 @@ -<html> -<head><title>Forward</title> -<link rel="icon" sizes="32x32" href="forward.png"> -</head> -<body leftmargin="0" marginwidth="0"> -<table width="123"> -<tbody> -<tr><td>This is more.</td></tr> -</tbody> -</table> -</body> -</html> diff --git a/tests/auto/declarative/qdeclarativewebview/data/forward.png b/tests/auto/declarative/qdeclarativewebview/data/forward.png Binary files differdeleted file mode 100644 index a82533e..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/forward.png +++ /dev/null diff --git a/tests/auto/declarative/qdeclarativewebview/data/javaScript.html b/tests/auto/declarative/qdeclarativewebview/data/javaScript.html deleted file mode 100644 index 35270bc..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/javaScript.html +++ /dev/null @@ -1,11 +0,0 @@ -<html> -<head><title>JavaScript</title> -<link rel="icon" sizes="48x48" href="basic.png"> -<script type="text/javascript"> -<!-- -window.onload = function(){ window.status = "status here"; } -// --> -</script> -</head> -<body> -This is a JS test. diff --git a/tests/auto/declarative/qdeclarativewebview/data/javaScript.qml b/tests/auto/declarative/qdeclarativewebview/data/javaScript.qml deleted file mode 100644 index 527e3b9..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/javaScript.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 1.0 -import QtWebKit 1.0 - -WebView { - url: "javaScript.html" - javaScriptWindowObjects: [ - QtObject { - property string qmlprop: "qmlvalue" - WebView.windowObjectName: "myjsname" - } - ] -} diff --git a/tests/auto/declarative/qdeclarativewebview/data/loadError.qml b/tests/auto/declarative/qdeclarativewebview/data/loadError.qml deleted file mode 100644 index baab1a0..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/loadError.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 1.0 -import QtWebKit 1.0 - -WebView { - url: "does-not-exist.html" -} diff --git a/tests/auto/declarative/qdeclarativewebview/data/newwindows.html b/tests/auto/declarative/qdeclarativewebview/data/newwindows.html deleted file mode 100644 index dd541f9..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/newwindows.html +++ /dev/null @@ -1,16 +0,0 @@ -<html> -<head> -<script type="text/javascript"> -<!-- -function clickTheLink() -{ - var ev = document.createEvent('MouseEvents'); - ev.initEvent( "click", true, false ); - document.getElementById('thelink').dispatchEvent(ev); -} -// --> -</script> -</head> -<h1>Multiple windows...</h1> - -<a id=thelink target="_blank" href="newwindows.html">Popup!</a> diff --git a/tests/auto/declarative/qdeclarativewebview/data/newwindows.qml b/tests/auto/declarative/qdeclarativewebview/data/newwindows.qml deleted file mode 100644 index e66631d..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/newwindows.qml +++ /dev/null @@ -1,34 +0,0 @@ -// Demonstrates opening new WebViews from HTML - -import QtQuick 1.0 -import QtWebKit 1.0 - -Grid { - columns: 3 - id: pages - height: 300; width: 600 - property int total: 0 - - Component { - id: webViewPage - Rectangle { - width: webView.width - height: webView.height - border.color: "gray" - - WebView { - id: webView - width: 150 // force predictable for test - newWindowComponent: webViewPage - newWindowParent: pages - url: "newwindows.html" - Timer { - interval: 10; running: total<4; repeat: false; - onTriggered: { if (webView.status==WebView.Ready) { total++; webView.evaluateJavaScript("clickTheLink()") } } - } - } - } - } - - Loader { sourceComponent: webViewPage } -} diff --git a/tests/auto/declarative/qdeclarativewebview/data/pixelCache.html b/tests/auto/declarative/qdeclarativewebview/data/pixelCache.html deleted file mode 100644 index 9412674..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/pixelCache.html +++ /dev/null @@ -1,10 +0,0 @@ -<html> -<body topmargin=0 leftmargin=0> -<table width=120 cellpadding=0 cellspacing=0> -<tr><td> -<h1>Pixel Cache</h1> -This test is for the pixel cache. Because this is a long document, -as it scrolls, more of the document will need to be rendered. -If the pixelCacheSize is small, the first parts of the document will -no longer be in the cache when it returns. -</table> diff --git a/tests/auto/declarative/qdeclarativewebview/data/pixelCache.qml b/tests/auto/declarative/qdeclarativewebview/data/pixelCache.qml deleted file mode 100644 index 08e4d65..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/pixelCache.qml +++ /dev/null @@ -1,6 +0,0 @@ -import Test 1.0 - -MyWebView { - anchors.fill: parent - url: "pixelCache.html" -} diff --git a/tests/auto/declarative/qdeclarativewebview/data/propertychanges.qml b/tests/auto/declarative/qdeclarativewebview/data/propertychanges.qml deleted file mode 100644 index db06887..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/propertychanges.qml +++ /dev/null @@ -1,34 +0,0 @@ -import QtQuick 1.0 -import QtWebKit 1.0 - -Item { - width: 240 - height: 160 - Grid { - anchors.fill: parent - objectName: "newWindowParent" - id: newWindowParent - } - - Row { - anchors.fill: parent - id: oldWindowParent - objectName: "oldWindowParent" - } - - Loader { - sourceComponent: webViewComponent - } - Component { - id: webViewComponent - WebView { - id: webView - objectName: "webView" - newWindowComponent: webViewComponent - newWindowParent: oldWindowParent - url: "basic.html" - renderingEnabled: true - pressGrabTime: 200 - } - } -} diff --git a/tests/auto/declarative/qdeclarativewebview/data/sethtml.qml b/tests/auto/declarative/qdeclarativewebview/data/sethtml.qml deleted file mode 100644 index 7889704..0000000 --- a/tests/auto/declarative/qdeclarativewebview/data/sethtml.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 1.0 -import QtWebKit 1.0 - -WebView { - html: "<p>This is a <b>string</b> set on the WebView" -} diff --git a/tests/auto/declarative/qdeclarativewebview/qdeclarativewebview.pro b/tests/auto/declarative/qdeclarativewebview/qdeclarativewebview.pro deleted file mode 100644 index 562a9fb..0000000 --- a/tests/auto/declarative/qdeclarativewebview/qdeclarativewebview.pro +++ /dev/null @@ -1,16 +0,0 @@ -load(qttest_p4) -contains(QT_CONFIG,declarative): QT += declarative -contains(QT_CONFIG,webkit): QT += webkit -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativewebview.cpp - -symbian: { - importFiles.sources = data - importFiles.path = . - DEPLOYMENT = importFiles -} else { - DEFINES += SRCDIR=\\\"$$PWD\\\" -} - -CONFIG += parallel_test diff --git a/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp b/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp deleted file mode 100644 index 6f6b2ab3..0000000 --- a/tests/auto/declarative/qdeclarativewebview/tst_qdeclarativewebview.cpp +++ /dev/null @@ -1,520 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include <qtest.h> -#include <QtTest/QSignalSpy> -#include "../../../shared/util.h" -#include <QtDeclarative/qdeclarativeengine.h> -#include <QtDeclarative/qdeclarativecomponent.h> -#include <private/qdeclarativepositioners_p.h> -#include <QtWebKit/qwebpage.h> -#include <QtWebKit/qwebframe.h> -#include <QtCore/qdir.h> -#include <QtCore/qfile.h> -#include <QtGui/qpainter.h> - -#ifdef Q_OS_SYMBIAN -// In Symbian OS test data is located in applications private dir -#define SRCDIR "." -#endif - -class tst_qdeclarativewebview : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativewebview() {} - -private slots: - void initTestCase(); - void basicProperties(); - void settings(); - void historyNav(); - void multipleWindows(); - void elementAreaAt(); - void loadError(); - void setHtml(); - void javaScript(); - void cleanupTestCase(); - //void pixelCache(); - void newWindowParent(); - void newWindowComponent(); - void renderingEnabled(); - void pressGrabTime(); - -private: - void checkNoErrors(const QDeclarativeComponent& component); - QDeclarativeEngine engine; - QString tmpDir() const - { - static QString tmpd = QDir::tempPath()+"/tst_qdeclarativewebview-" - + QDateTime::currentDateTime().toString(QLatin1String("yyyyMMddhhmmss")); - return tmpd; - } -}; - -void tst_qdeclarativewebview::initTestCase() -{ -} - -static QString strippedHtml(QString html) -{ - html.replace(QRegExp("\\s+"),""); - return html; -} - -static QString fileContents(const QString& filename) -{ - QFile file(filename); - file.open(QIODevice::ReadOnly); - return QString::fromUtf8(file.readAll()); -} - - -static void removeRecursive(const QString& dirname) -{ - QDir dir(dirname); - QFileInfoList entries(dir.entryInfoList(QDir::Dirs|QDir::Files|QDir::NoDotAndDotDot)); - for (int i = 0; i < entries.count(); ++i) - if (entries[i].isDir()) - removeRecursive(entries[i].filePath()); - else - dir.remove(entries[i].fileName()); - QDir().rmdir(dirname); -} - -void tst_qdeclarativewebview::cleanupTestCase() -{ - removeRecursive(tmpDir()); -} - -void tst_qdeclarativewebview::checkNoErrors(const QDeclarativeComponent& component) -{ - // Wait until the component is ready - QTRY_VERIFY(component.isReady() || component.isError()); - - if (component.isError()) { - QList<QDeclarativeError> errors = component.errors(); - for (int ii = 0; ii < errors.count(); ++ii) { - const QDeclarativeError &error = errors.at(ii); - QByteArray errorStr = QByteArray::number(error.line()) + ":" + - QByteArray::number(error.column()) + ":" + - error.description().toUtf8(); - qWarning() << errorStr; - } - } - QVERIFY(!component.isError()); -} - -void tst_qdeclarativewebview::basicProperties() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/basic.qml")); - checkNoErrors(component); - QWebSettings::enablePersistentStorage(tmpDir()); - - QObject *wv = component.create(); - QVERIFY(wv != 0); - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); - QCOMPARE(wv->property("title").toString(),QString("Basic")); - QTRY_COMPARE(qvariant_cast<QPixmap>(wv->property("icon")).width(), 48); - QCOMPARE(qvariant_cast<QPixmap>(wv->property("icon")),QPixmap(SRCDIR "/data/basic.png")); - QCOMPARE(wv->property("statusText").toString(),QString("status here")); - QCOMPARE(strippedHtml(fileContents(SRCDIR "/data/basic.html")), strippedHtml(wv->property("html").toString())); - QCOMPARE(wv->property("preferredWidth").toInt(), 0); - QCOMPARE(wv->property("preferredHeight").toInt(), 0); - QCOMPARE(wv->property("url").toUrl(), QUrl::fromLocalFile(SRCDIR "/data/basic.html")); - QCOMPARE(wv->property("status").toInt(), 1 /*QDeclarativeWebView::Ready*/); - QVERIFY(qvariant_cast<QAction*>(wv->property("reload"))); - QVERIFY(qvariant_cast<QAction*>(wv->property("reload"))->isEnabled()); - QVERIFY(qvariant_cast<QAction*>(wv->property("back"))); - QVERIFY(!qvariant_cast<QAction*>(wv->property("back"))->isEnabled()); - QVERIFY(qvariant_cast<QAction*>(wv->property("forward"))); - QVERIFY(!qvariant_cast<QAction*>(wv->property("forward"))->isEnabled()); - QVERIFY(qvariant_cast<QAction*>(wv->property("stop"))); - QVERIFY(!qvariant_cast<QAction*>(wv->property("stop"))->isEnabled()); - - wv->setProperty("pixelCacheSize", 0); // mainly testing that it doesn't crash or anything! - QCOMPARE(wv->property("pixelCacheSize").toInt(),0); - qvariant_cast<QAction*>(wv->property("reload"))->trigger(); - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); -} - -void tst_qdeclarativewebview::settings() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/basic.qml")); - checkNoErrors(component); - QObject *wv = component.create(); - QVERIFY(wv != 0); - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); - - QObject *s = QDeclarativeProperty(wv,"settings").object(); - QVERIFY(s != 0); - - // merely tests that setting gets stored (in QWebSettings) - // behavioural tests are in WebKit. - for (int b=0; b<=1; ++b) { - bool on = !!b; - - s->setProperty("autoLoadImages", on); - s->setProperty("developerExtrasEnabled", on); - s->setProperty("javaEnabled", on); - s->setProperty("javascriptCanAccessClipboard", on); - s->setProperty("javascriptCanOpenWindows", on); - s->setProperty("javascriptEnabled", on); - s->setProperty("linksIncludedInFocusChain", on); - s->setProperty("localContentCanAccessRemoteUrls", on); - s->setProperty("localStorageDatabaseEnabled", on); - s->setProperty("offlineStorageDatabaseEnabled", on); - s->setProperty("offlineWebApplicationCacheEnabled", on); - s->setProperty("pluginsEnabled", on); - s->setProperty("printElementBackgrounds", on); - s->setProperty("privateBrowsingEnabled", on); - s->setProperty("zoomTextOnly", on); - - QVERIFY(s->property("autoLoadImages") == on); - QVERIFY(s->property("developerExtrasEnabled") == on); - QVERIFY(s->property("javaEnabled") == on); - QVERIFY(s->property("javascriptCanAccessClipboard") == on); - QVERIFY(s->property("javascriptCanOpenWindows") == on); - QVERIFY(s->property("javascriptEnabled") == on); - QVERIFY(s->property("linksIncludedInFocusChain") == on); - QVERIFY(s->property("localContentCanAccessRemoteUrls") == on); - QVERIFY(s->property("localStorageDatabaseEnabled") == on); - QVERIFY(s->property("offlineStorageDatabaseEnabled") == on); - QVERIFY(s->property("offlineWebApplicationCacheEnabled") == on); - QVERIFY(s->property("pluginsEnabled") == on); - QVERIFY(s->property("printElementBackgrounds") == on); - QVERIFY(s->property("privateBrowsingEnabled") == on); - QVERIFY(s->property("zoomTextOnly") == on); - - QVERIFY(s->property("autoLoadImages") == on); - QVERIFY(s->property("developerExtrasEnabled") == on); - QVERIFY(s->property("javaEnabled") == on); - QVERIFY(s->property("javascriptCanAccessClipboard") == on); - QVERIFY(s->property("javascriptCanOpenWindows") == on); - QVERIFY(s->property("javascriptEnabled") == on); - QVERIFY(s->property("linksIncludedInFocusChain") == on); - QVERIFY(s->property("localContentCanAccessRemoteUrls") == on); - QVERIFY(s->property("localStorageDatabaseEnabled") == on); - QVERIFY(s->property("offlineStorageDatabaseEnabled") == on); - QVERIFY(s->property("offlineWebApplicationCacheEnabled") == on); - QVERIFY(s->property("pluginsEnabled") == on); - QVERIFY(s->property("printElementBackgrounds") == on); - QVERIFY(s->property("privateBrowsingEnabled") == on); - QVERIFY(s->property("zoomTextOnly") == on); - } -} - -void tst_qdeclarativewebview::historyNav() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/basic.qml")); - checkNoErrors(component); - QWebSettings::enablePersistentStorage(tmpDir()); - - QObject *wv = component.create(); - QVERIFY(wv != 0); - for (int i=1; i<=2; ++i) { - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); - QCOMPARE(wv->property("title").toString(),QString("Basic")); - QTRY_COMPARE(qvariant_cast<QPixmap>(wv->property("icon")).width(), 48); - QCOMPARE(qvariant_cast<QPixmap>(wv->property("icon")),QPixmap(SRCDIR "/data/basic.png")); - QCOMPARE(wv->property("statusText").toString(),QString("status here")); - QCOMPARE(strippedHtml(fileContents(SRCDIR "/data/basic.html")), strippedHtml(wv->property("html").toString())); - QCOMPARE(wv->property("preferredWidth").toDouble(), 0.0); - QCOMPARE(wv->property("url").toUrl(), QUrl::fromLocalFile(SRCDIR "/data/basic.html")); - QCOMPARE(wv->property("status").toInt(), 1 /*QDeclarativeWebView::Ready*/); - QVERIFY(qvariant_cast<QAction*>(wv->property("reload"))); - QVERIFY(qvariant_cast<QAction*>(wv->property("reload"))->isEnabled()); - QVERIFY(qvariant_cast<QAction*>(wv->property("back"))); - QVERIFY(!qvariant_cast<QAction*>(wv->property("back"))->isEnabled()); - QVERIFY(qvariant_cast<QAction*>(wv->property("forward"))); - QVERIFY(!qvariant_cast<QAction*>(wv->property("forward"))->isEnabled()); - QVERIFY(qvariant_cast<QAction*>(wv->property("stop"))); - QVERIFY(!qvariant_cast<QAction*>(wv->property("stop"))->isEnabled()); - - qvariant_cast<QAction*>(wv->property("reload"))->trigger(); - } - - wv->setProperty("url", QUrl::fromLocalFile(SRCDIR "/data/forward.html")); - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); - QCOMPARE(wv->property("title").toString(),QString("Forward")); - QTRY_COMPARE(qvariant_cast<QPixmap>(wv->property("icon")).width(), 32); - QCOMPARE(qvariant_cast<QPixmap>(wv->property("icon")),QPixmap(SRCDIR "/data/forward.png")); - QCOMPARE(strippedHtml(fileContents(SRCDIR "/data/forward.html")), strippedHtml(wv->property("html").toString())); - QCOMPARE(wv->property("url").toUrl(), QUrl::fromLocalFile(SRCDIR "/data/forward.html")); - QCOMPARE(wv->property("status").toInt(), 1 /*QDeclarativeWebView::Ready*/); - QCOMPARE(wv->property("statusText").toString(),QString("")); - QVERIFY(qvariant_cast<QAction*>(wv->property("reload"))); - QVERIFY(qvariant_cast<QAction*>(wv->property("reload"))->isEnabled()); - QVERIFY(qvariant_cast<QAction*>(wv->property("back"))); - QVERIFY(qvariant_cast<QAction*>(wv->property("back"))->isEnabled()); - QVERIFY(qvariant_cast<QAction*>(wv->property("forward"))); - QVERIFY(!qvariant_cast<QAction*>(wv->property("forward"))->isEnabled()); - QVERIFY(qvariant_cast<QAction*>(wv->property("stop"))); - QVERIFY(!qvariant_cast<QAction*>(wv->property("stop"))->isEnabled()); - - qvariant_cast<QAction*>(wv->property("back"))->trigger(); - - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); - QCOMPARE(wv->property("title").toString(),QString("Basic")); - QCOMPARE(strippedHtml(fileContents(SRCDIR "/data/basic.html")), strippedHtml(wv->property("html").toString())); - QCOMPARE(wv->property("url").toUrl(), QUrl::fromLocalFile(SRCDIR "/data/basic.html")); - QCOMPARE(wv->property("status").toInt(), 1 /*QDeclarativeWebView::Ready*/); - QVERIFY(qvariant_cast<QAction*>(wv->property("reload"))); - QVERIFY(qvariant_cast<QAction*>(wv->property("reload"))->isEnabled()); - QVERIFY(qvariant_cast<QAction*>(wv->property("back"))); - QVERIFY(!qvariant_cast<QAction*>(wv->property("back"))->isEnabled()); - QVERIFY(qvariant_cast<QAction*>(wv->property("forward"))); - QVERIFY(qvariant_cast<QAction*>(wv->property("forward"))->isEnabled()); - QVERIFY(qvariant_cast<QAction*>(wv->property("stop"))); - QVERIFY(!qvariant_cast<QAction*>(wv->property("stop"))->isEnabled()); -} - -void tst_qdeclarativewebview::multipleWindows() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/newwindows.qml")); - checkNoErrors(component); - - QDeclarativeGrid *grid = qobject_cast<QDeclarativeGrid*>(component.create()); - QVERIFY(grid != 0); - QTRY_COMPARE(grid->children().count(), 2+4); // Component, Loader (with 1 WebView), 4 new-window WebViews - QDeclarativeItem* popup = qobject_cast<QDeclarativeItem*>(grid->children().at(2)); // first popup after Component and Loader. - QVERIFY(popup != 0); - QTRY_COMPARE(popup->x(), 150.0); -} - -void tst_qdeclarativewebview::loadError() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/loadError.qml")); - checkNoErrors(component); - QWebSettings::enablePersistentStorage(tmpDir()); - - QObject *wv = component.create(); - QVERIFY(wv != 0); - for (int i=1; i<=2; ++i) { - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); - QCOMPARE(wv->property("title").toString(),QString("")); - QCOMPARE(wv->property("statusText").toString(),QString("")); // HTML 'status bar' text, not error message - QCOMPARE(wv->property("url").toUrl(), QUrl::fromLocalFile(SRCDIR "/data/does-not-exist.html")); // Unlike QWebPage, which loses url - QCOMPARE(wv->property("status").toInt(), 3 /*QDeclarativeWebView::Error*/); - - qvariant_cast<QAction*>(wv->property("reload"))->trigger(); - } -} - -void tst_qdeclarativewebview::setHtml() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/sethtml.qml")); - checkNoErrors(component); - QObject *wv = component.create(); - QVERIFY(wv != 0); - QCOMPARE(wv->property("html").toString(),QString("<html><head></head><body><p>This is a <b>string</b> set on the WebView</p></body></html>")); - - QSignalSpy spy(wv, SIGNAL(htmlChanged())); - wv->setProperty("html", QString("<html><head><title>Basic</title></head><body><p>text</p></body></html>")); - QCOMPARE(spy.count(),1); -} - -void tst_qdeclarativewebview::elementAreaAt() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/elements.qml")); - checkNoErrors(component); - QObject *wv = component.create(); - QVERIFY(wv != 0); - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); - - /* not now it's a plugin... - QCOMPARE(wv->elementAreaAt(40,30,100,100),QRect(1,1,75,54)); // Area A in data/elements.html - QCOMPARE(wv->elementAreaAt(130,30,200,100),QRect(78,3,110,50)); // Area B - QCOMPARE(wv->elementAreaAt(40,30,400,400),QRect(0,0,310,100)); // Whole view - QCOMPARE(wv->elementAreaAt(130,30,280,280),QRect(76,1,223,54)); // Area BC - QCOMPARE(wv->elementAreaAt(130,30,400,400),QRect(0,0,310,100)); // Whole view - */ -} - -void tst_qdeclarativewebview::javaScript() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/javaScript.qml")); - checkNoErrors(component); - QObject *wv = component.create(); - QVERIFY(wv != 0); - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); - /* not now it's a plugin... - QCOMPARE(wv->evaluateJavaScript("123").toInt(), 123); - QCOMPARE(wv->evaluateJavaScript("window.status").toString(), QString("status here")); - QCOMPARE(wv->evaluateJavaScript("window.myjsname.qmlprop").toString(), QString("qmlvalue")); - */ -} - -/* -Cannot be done now that webkit is a plugin - -void tst_qdeclarativewebview::pixelCache() -{ - - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/pixelCache.qml")); - checkNoErrors(component); - MyWebView *wv = qobject_cast<MyWebView*>(component.create()); - QVERIFY(wv != 0); - QTRY_COMPARE(wv->property("progress"), 1.0); - QPixmap pm(150,150); - QPainter p(&pm); - wv->paint(&p,0,0); - const int expected = 120*(150+128); // 120 = width of HTML page, 150=pixmap height, 128=cache extra area - QCOMPARE(wv->property("pixelsPainted"), expected); - wv->paint(&p,0,0); - QCOMPARE(wv->property("pixelsPainted"), expected); // nothing new needed to be painted - wv->setProperty("pixelCacheSize", 0); // clears the cache - wv->paint(&p,0,0); - QCOMPARE(wv->property("pixelsPainted"), expected*2); // everything needed to be painted - // Note that painted things always go into the cache (even if they don't "fit"), - // just that they will be removed if anything else needs to be painted. - wv->setProperty("pixelCacheSize", expected); // won't clear the cache - wv->paint(&p,0,0); - QCOMPARE(wv->property("pixelsPainted"), expected*2); // still there - wv->setProperty("pixelCacheSize", expected-1); // too small - will clear the cache - wv->paint(&p,0,0); - QCOMPARE(wv->property("pixelsPainted"), expected*3); // repainted -} -*/ - -void tst_qdeclarativewebview::newWindowParent() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); - checkNoErrors(component); - QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(component.create()); - QObject *wv = rootItem->findChild<QObject*>("webView"); - QVERIFY(rootItem != 0); - QVERIFY(wv != 0); - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); - - QDeclarativeItem* oldWindowParent = rootItem->findChild<QDeclarativeItem*>("oldWindowParent"); - QCOMPARE(qvariant_cast<QDeclarativeItem*>(wv->property("newWindowParent")), oldWindowParent); - QSignalSpy newWindowParentSpy(wv, SIGNAL(newWindowParentChanged())); - - QDeclarativeItem* newWindowParent = rootItem->findChild<QDeclarativeItem*>("newWindowParent"); - wv->setProperty("newWindowParent", QVariant::fromValue(newWindowParent)); - QVERIFY(newWindowParent); - QVERIFY(oldWindowParent); - QVERIFY(oldWindowParent->childItems().count() == 0); - QCOMPARE(wv->property("newWindowParent"), QVariant::fromValue(newWindowParent)); - QCOMPARE(newWindowParentSpy.count(),1); - - wv->setProperty("newWindowParent", QVariant::fromValue(newWindowParent)); - QCOMPARE(newWindowParentSpy.count(),1); - - wv->setProperty("newWindowParent", QVariant::fromValue((QDeclarativeItem*)0)); - QCOMPARE(newWindowParentSpy.count(),2); -} - -void tst_qdeclarativewebview::newWindowComponent() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); - checkNoErrors(component); - QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(component.create()); - QObject *wv = rootItem->findChild<QObject*>("webView"); - QVERIFY(rootItem != 0); - QVERIFY(wv != 0); - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); - - QDeclarativeComponent substituteComponent(&engine); - substituteComponent.setData("import QtQuick 1.0; WebView { objectName: 'newWebView'; url: 'basic.html'; }", QUrl::fromLocalFile("")); - QSignalSpy newWindowComponentSpy(wv, SIGNAL(newWindowComponentChanged())); - - wv->setProperty("newWindowComponent", QVariant::fromValue(&substituteComponent)); - QCOMPARE(wv->property("newWindowComponent"), QVariant::fromValue(&substituteComponent)); - QCOMPARE(newWindowComponentSpy.count(),1); - - wv->setProperty("newWindowComponent", QVariant::fromValue(&substituteComponent)); - QCOMPARE(newWindowComponentSpy.count(),1); - - wv->setProperty("newWindowComponent", QVariant::fromValue((QDeclarativeComponent*)0)); - QCOMPARE(newWindowComponentSpy.count(),2); -} - -void tst_qdeclarativewebview::renderingEnabled() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); - checkNoErrors(component); - QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(component.create()); - QObject *wv = rootItem->findChild<QObject*>("webView"); - QVERIFY(rootItem != 0); - QVERIFY(wv != 0); - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); - - QVERIFY(wv->property("renderingEnabled").toBool()); - QSignalSpy renderingEnabledSpy(wv, SIGNAL(renderingEnabledChanged())); - - wv->setProperty("renderingEnabled", false); - QVERIFY(!wv->property("renderingEnabled").toBool()); - QCOMPARE(renderingEnabledSpy.count(),1); - - wv->setProperty("renderingEnabled", false); - QCOMPARE(renderingEnabledSpy.count(),1); - - wv->setProperty("renderingEnabled", true); - QCOMPARE(renderingEnabledSpy.count(),2); -} - -void tst_qdeclarativewebview::pressGrabTime() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); - checkNoErrors(component); - QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(component.create()); - QObject *wv = rootItem->findChild<QObject*>("webView"); - QVERIFY(rootItem != 0); - QVERIFY(wv != 0); - QTRY_COMPARE(wv->property("progress").toDouble(), 1.0); - QCOMPARE(wv->property("pressGrabTime").toInt(), 200); - QSignalSpy pressGrabTimeSpy(wv, SIGNAL(pressGrabTimeChanged())); - - wv->setProperty("pressGrabTime", 100); - QCOMPARE(wv->property("pressGrabTime").toInt(), 100); - QCOMPARE(pressGrabTimeSpy.count(),1); - - wv->setProperty("pressGrabTime", 100); - QCOMPARE(pressGrabTimeSpy.count(),1); - - wv->setProperty("pressGrabTime", 0); - QCOMPARE(pressGrabTimeSpy.count(),2); -} - -QTEST_MAIN(tst_qdeclarativewebview) - -#include "tst_qdeclarativewebview.moc" diff --git a/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro b/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro index 2f8f23d..e20c3e6 100644 --- a/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro +++ b/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro @@ -5,9 +5,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativeworkerscript.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro b/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro index 619b239..8aefb8e 100644 --- a/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro +++ b/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro @@ -9,9 +9,9 @@ SOURCES += tst_qdeclarativexmlhttprequest.cpp \ ../shared/testhttpserver.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro index efcea12..64b8267 100644 --- a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro +++ b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro @@ -9,9 +9,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativexmllistmodel.cpp symbian: { - importFiles.sources = data + importFiles.files = data importFiles.path = . - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp index 2074468..7df2dc3 100644 --- a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp +++ b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp @@ -126,7 +126,10 @@ private: QStringList fields = item.split(","); foreach(const QString &field, fields) { QStringList values = field.split("="); - Q_ASSERT(values.count() == 2); + if (values.count() != 2) { + qWarning() << "makeItemXmlAndData: invalid field:" << field; + continue; + } xml += QString("<%1>%2</%1>").arg(values[0], values[1]); if (!modelData) continue; diff --git a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 1726654..d7ca8e6 100644 --- a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -140,9 +140,9 @@ void tst_QMetaObjectBuilder::mocVersionCheck() // whenenver moc changes. Once QMetaObjectBuilder has been // updated, this test can be changed to check for the next version. int version = int(QObject::staticMetaObject.d.data[0]); - QVERIFY(version == 4 || version == 5); + QVERIFY(version == 4 || version == 5 || version == 6); version = int(staticMetaObject.d.data[0]); - QVERIFY(version == 4 || version == 5); + QVERIFY(version == 4 || version == 5 || version == 6); } void tst_QMetaObjectBuilder::create() @@ -546,6 +546,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!nullProp.isUser()); QVERIFY(!nullProp.hasStdCppSet()); QVERIFY(!nullProp.isEnumOrFlag()); + QVERIFY(!nullProp.isConstant()); + QVERIFY(!nullProp.isFinal()); QCOMPARE(nullProp.index(), 0); // Add a property and check its attributes. @@ -563,6 +565,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop1.isUser()); QVERIFY(!prop1.hasStdCppSet()); QVERIFY(!prop1.isEnumOrFlag()); + QVERIFY(!prop1.isConstant()); + QVERIFY(!prop1.isFinal()); QCOMPARE(prop1.index(), 0); QCOMPARE(builder.propertyCount(), 1); @@ -581,6 +585,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); + QVERIFY(!prop2.isConstant()); + QVERIFY(!prop2.isFinal()); QCOMPARE(prop2.index(), 1); QCOMPARE(builder.propertyCount(), 2); @@ -602,6 +608,8 @@ void tst_QMetaObjectBuilder::property() prop1.setUser(true); prop1.setStdCppSet(true); prop1.setEnumOrFlag(true); + prop1.setConstant(true); + prop1.setFinal(true); // Check that prop1 is changed, but prop2 is not. QCOMPARE(prop1.name(), QByteArray("foo")); @@ -616,6 +624,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(prop1.isUser()); QVERIFY(prop1.hasStdCppSet()); QVERIFY(prop1.isEnumOrFlag()); + QVERIFY(prop1.isConstant()); + QVERIFY(prop1.isFinal()); QVERIFY(prop2.isReadable()); QVERIFY(prop2.isWritable()); QCOMPARE(prop2.name(), QByteArray("bar")); @@ -628,6 +638,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); + QVERIFY(!prop2.isConstant()); + QVERIFY(!prop2.isFinal()); // Remove prop1 and check that prop2 becomes index 0. builder.removeProperty(0); @@ -643,6 +655,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); + QVERIFY(!prop2.isConstant()); + QVERIFY(!prop2.isFinal()); QCOMPARE(prop2.index(), 0); // Perform index-based lookup again. @@ -666,6 +680,8 @@ void tst_QMetaObjectBuilder::property() prop2.setUser(false); \ prop2.setStdCppSet(false); \ prop2.setEnumOrFlag(false); \ + prop2.setConstant(false); \ + prop2.setFinal(false); \ } while (0) #define COUNT_FLAGS() \ ((prop2.isReadable() ? 1 : 0) + \ @@ -677,7 +693,9 @@ void tst_QMetaObjectBuilder::property() (prop2.isEditable() ? 1 : 0) + \ (prop2.isUser() ? 1 : 0) + \ (prop2.hasStdCppSet() ? 1 : 0) + \ - (prop2.isEnumOrFlag() ? 1 : 0)) + (prop2.isEnumOrFlag() ? 1 : 0) + \ + (prop2.isConstant() ? 1 : 0) + \ + (prop2.isFinal() ? 1 : 0)) #define CHECK_FLAG(setFunc,isFunc) \ do { \ CLEAR_FLAGS(); \ @@ -696,6 +714,8 @@ void tst_QMetaObjectBuilder::property() CHECK_FLAG(setUser, isUser); CHECK_FLAG(setStdCppSet, hasStdCppSet); CHECK_FLAG(setEnumOrFlag, isEnumOrFlag); + CHECK_FLAG(setConstant, isConstant); + CHECK_FLAG(setFinal, isFinal); // Check that nothing else changed. QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Properties)); @@ -920,9 +940,9 @@ void tst_QMetaObjectBuilder::relatedMetaObject() QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::RelatedMetaObjects)); } -static int smetacall(QMetaObject::Call, int, void **) +static void smetacall(QObject *, QMetaObject::Call, int, void **) { - return 0; + return; } void tst_QMetaObjectBuilder::staticMetacall() diff --git a/tests/auto/declarative/qmlvisual/qmlvisual.pro b/tests/auto/declarative/qmlvisual/qmlvisual.pro index b2c5b4f..416f8d9 100644 --- a/tests/auto/declarative/qmlvisual/qmlvisual.pro +++ b/tests/auto/declarative/qmlvisual/qmlvisual.pro @@ -6,7 +6,7 @@ SOURCES += tst_qmlvisual.cpp symbian: { importFiles.path = . - importFiles.sources = animation \ + importFiles.files = animation \ fillmode \ focusscope \ ListView \ @@ -27,7 +27,7 @@ symbian: { repeater \ selftest_noimages \ webview - DEPLOYMENT = importFiles + DEPLOYMENT += importFiles } else { DEFINES += QT_TEST_SOURCE_DIR=\"\\\"$$PWD\\\"\" } diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index bd95a52..fa3926f 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -185,16 +185,22 @@ QString tst_qmlvisual::toTestScript(const QString &file, Mode mode) if (platformsuffix && (mode == UpdatePlatformVisuals || QFile::exists(testdata+QLatin1String(platformsuffix)+QDir::separator()+testname+".qml"))) { QString platformdir = testdata + QLatin1String(platformsuffix); if (mode == UpdatePlatformVisuals) { - Q_ASSERT(QDir().mkpath(platformdir)); + if (!QDir().mkpath(platformdir)) { + qFatal("Cannot make path %s", qPrintable(platformdir)); + } // Copy from base QDir dir(testdata,testname+".*"); dir.setFilter(QDir::Files); QFileInfoList list = dir.entryInfoList(); for (int i = 0; i < list.size(); ++i) { QFile in(list.at(i).filePath()); - Q_ASSERT(in.open(QIODevice::ReadOnly)); + if (!in.open(QIODevice::ReadOnly)) { + qFatal("Cannot open file %s: %s", qPrintable(in.fileName()), qPrintable(in.errorString())); + } QFile out(platformdir + QDir::separator() + list.at(i).fileName()); - Q_ASSERT(out.open(QIODevice::WriteOnly)); + if (!out.open(QIODevice::WriteOnly)) { + qFatal("Cannot open file %s: %s", qPrintable(out.fileName()), qPrintable(out.errorString())); + } out.write(in.readAll()); } } @@ -234,8 +240,6 @@ QStringList tst_qmlvisual::findQmlFiles(const QDir &d) void action(Mode mode, const QString &file) { - Q_ASSERT(mode != Test); - QString testdata = tst_qmlvisual::toTestScript(file,mode); QStringList arguments; diff --git a/tests/auto/declarative/qperformancetimer/tst_qperformancetimer.cpp b/tests/auto/declarative/qperformancetimer/tst_qperformancetimer.cpp index d6f425e..b29ebe3 100644 --- a/tests/auto/declarative/qperformancetimer/tst_qperformancetimer.cpp +++ b/tests/auto/declarative/qperformancetimer/tst_qperformancetimer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/symbianlibs.pri b/tests/auto/declarative/symbianlibs.pri new file mode 100644 index 0000000..4452f67 --- /dev/null +++ b/tests/auto/declarative/symbianlibs.pri @@ -0,0 +1,9 @@ +#additional libs required for orientation sensor +symbian { + !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) { + LIBS += -lsensrvclient -lsensrvutil + } + contains(QT_CONFIG, s60): { + LIBS += -lavkon -lcone + } +} diff --git a/tests/auto/exceptionsafety/exceptionsafety.pro b/tests/auto/exceptionsafety/exceptionsafety.pro index d162219..52ba9e2 100644 --- a/tests/auto/exceptionsafety/exceptionsafety.pro +++ b/tests/auto/exceptionsafety/exceptionsafety.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_exceptionsafety.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp index cf78977..3cfcc49 100644 --- a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp +++ b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp @@ -60,7 +60,7 @@ QT_USE_NAMESPACE #include "3rdparty/memcheck.h" #endif -class tst_ExceptionSafetyObjects: public QObject +class tst_ExceptionSafety_Objects: public QObject { Q_OBJECT @@ -156,7 +156,7 @@ struct DirCreator : public AbstractTester } }; -void tst_ExceptionSafetyObjects::objects_data() +void tst_ExceptionSafety_Objects::objects_data() { QTest::addColumn<AbstractTester *>("objectCreator"); @@ -164,12 +164,12 @@ void tst_ExceptionSafetyObjects::objects_data() NEWROW(QObject); NEWROW(QBuffer); NEWROW(QFile); + NEWROW(QFSFileEngine); NEWROW(QProcess); NEWROW(QSettings); NEWROW(QThread); NEWROW(QThreadPool); NEWROW(QTranslator); - NEWROW(QFSFileEngine); #define NEWROW2(T, CREATOR) QTest::newRow(#T) << static_cast<AbstractTester *>(new CREATOR) NEWROW2(QBitArray, BitArrayCreator); @@ -177,7 +177,6 @@ void tst_ExceptionSafetyObjects::objects_data() NEWROW2(QCryptographicHash, CryptographicHashCreator); NEWROW2(QDataStream, DataStreamCreator); NEWROW2(QDir, DirCreator); - } // create and destructs an object, and lets each and every allocation @@ -274,9 +273,9 @@ public: } }; -QtMsgHandler tst_ExceptionSafetyObjects::testMessageHandler; +QtMsgHandler tst_ExceptionSafety_Objects::testMessageHandler; -void tst_ExceptionSafetyObjects::safeMessageHandler(QtMsgType type, const char *msg) +void tst_ExceptionSafety_Objects::safeMessageHandler(QtMsgType type, const char *msg) { // this temporarily suspends OOM testing while handling a message int currentIndex = mallocFailIndex; @@ -301,7 +300,7 @@ void debugUnexpected() (*defaultUnexpected)(); } -void tst_ExceptionSafetyObjects::initTestCase() +void tst_ExceptionSafety_Objects::initTestCase() { // set handlers for bad exception cases, you might want to step in and breakpoint the default handlers too defaultTerminate = std::set_terminate(&debugTerminate); @@ -345,17 +344,25 @@ void tst_ExceptionSafetyObjects::initTestCase() QCOMPARE(malloc2Failed, 1); } -void tst_ExceptionSafetyObjects::cleanupTestCase() +void tst_ExceptionSafety_Objects::cleanupTestCase() { qInstallMsgHandler(testMessageHandler); } -void tst_ExceptionSafetyObjects::objects() +void tst_ExceptionSafety_Objects::objects() { + QLatin1String tag = QLatin1String(QTest::currentDataTag()); + if (tag == QLatin1String("QFile") + || tag == QLatin1String("QProcess") + || tag == QLatin1String("QSettings") + || tag == QLatin1String("QThread") + || tag == QLatin1String("QThreadPool")) + QSKIP("This type of object is not currently strongly exception safe", SkipSingle); + QFETCH(AbstractTester *, objectCreator); doOOMTest(*objectCreator, 0); - + delete objectCreator; } @@ -364,7 +371,8 @@ struct WidgetCreator : public AbstractTester { void operator()(QObject *parent) { - Q_ASSERT(!parent || parent->isWidgetType()); + if (parent && !parent->isWidgetType()) + qFatal("%s: parent must be either null or a widget type", Q_FUNC_INFO); QScopedPointer<T> ptr(parent ? new T(static_cast<QWidget *>(parent)) : new T); } }; @@ -374,7 +382,8 @@ template <> struct WidgetCreator<QSizeGrip> : public AbstractTester { void operator()(QObject *parent) { - Q_ASSERT(!parent || parent->isWidgetType()); + if (parent && !parent->isWidgetType()) + qFatal("%s: parent must be either null or a widget type", Q_FUNC_INFO); QScopedPointer<QSizeGrip> ptr(new QSizeGrip(static_cast<QWidget *>(parent))); } }; @@ -384,17 +393,18 @@ template <> struct WidgetCreator<QDesktopWidget> : public AbstractTester { void operator()(QObject *parent) { - Q_ASSERT(!parent || parent->isWidgetType()); + if (parent && !parent->isWidgetType()) + qFatal("%s: parent must be either null or a widget type", Q_FUNC_INFO); QScopedPointer<QDesktopWidget> ptr(new QDesktopWidget()); } }; -void tst_ExceptionSafetyObjects::widgets_data() +void tst_ExceptionSafety_Objects::widgets_data() { #ifdef Q_OS_SYMBIAN // Initialise the S60 rasteriser, which crashes if started while out of memory - QImage image(20, 20, QImage::Format_RGB32); - QPainter p(&image); - p.drawText(0, 15, "foo"); + QImage image(20, 20, QImage::Format_RGB32); + QPainter p(&image); + p.drawText(0, 15, "foo"); #endif QTest::addColumn<AbstractTester *>("widgetCreator"); @@ -405,23 +415,27 @@ void tst_ExceptionSafetyObjects::widgets_data() NEWROW(QWidget); NEWROW(QButtonGroup); - NEWROW(QDesktopWidget); NEWROW(QCheckBox); + NEWROW(QColumnView); NEWROW(QComboBox); NEWROW(QCommandLinkButton); NEWROW(QDateEdit); NEWROW(QDateTimeEdit); + NEWROW(QDesktopWidget); NEWROW(QDial); NEWROW(QDoubleSpinBox); NEWROW(QFocusFrame); NEWROW(QFontComboBox); NEWROW(QFrame); NEWROW(QGroupBox); - NEWROW(QLCDNumber); NEWROW(QLabel); NEWROW(QLCDNumber); NEWROW(QLineEdit); + NEWROW(QListView); + NEWROW(QListWidget); + NEWROW(QMainWindow); NEWROW(QMenu); + NEWROW(QMenuBar); NEWROW(QPlainTextEdit); NEWROW(QProgressBar); NEWROW(QPushButton); @@ -435,28 +449,58 @@ void tst_ExceptionSafetyObjects::widgets_data() NEWROW(QStackedWidget); NEWROW(QStatusBar); NEWROW(QTabBar); + NEWROW(QTableView); + NEWROW(QTableWidget); NEWROW(QTabWidget); NEWROW(QTextBrowser); NEWROW(QTextEdit); NEWROW(QTimeEdit); + NEWROW(QToolBar); NEWROW(QToolBox); NEWROW(QToolButton); - NEWROW(QStatusBar); - NEWROW(QToolBar); - NEWROW(QMenuBar); - NEWROW(QMainWindow); - NEWROW(QWorkspace); - NEWROW(QColumnView); - NEWROW(QListView); - NEWROW(QListWidget); - NEWROW(QTableView); - NEWROW(QTableWidget); NEWROW(QTreeView); NEWROW(QTreeWidget); + NEWROW(QWorkspace); } -void tst_ExceptionSafetyObjects::widgets() -{ +void tst_ExceptionSafety_Objects::widgets() +{ + QLatin1String tag = QLatin1String(QTest::currentDataTag()); + if (tag == QLatin1String("QColumnView") + || tag == QLatin1String("QComboBox") + || tag == QLatin1String("QCommandLinkButton") + || tag == QLatin1String("QDateEdit") + || tag == QLatin1String("QDateTimeEdit") + || tag == QLatin1String("QDesktopWidget") + || tag == QLatin1String("QDoubleSpinBox") + || tag == QLatin1String("QFontComboBox") + || tag == QLatin1String("QGroupBox") + || tag == QLatin1String("QLineEdit") + || tag == QLatin1String("QListView") + || tag == QLatin1String("QListWidget") + || tag == QLatin1String("QMainWindow") + || tag == QLatin1String("QMenu") + || tag == QLatin1String("QMenuBar") + || tag == QLatin1String("QPlainTextEdit") + || tag == QLatin1String("QProgressBar") + || tag == QLatin1String("QPushButton") + || tag == QLatin1String("QScrollArea") + || tag == QLatin1String("QSpinBox") + || tag == QLatin1String("QStackedWidget") + || tag == QLatin1String("QStatusBar") + || tag == QLatin1String("QTableView") + || tag == QLatin1String("QTableWidget") + || tag == QLatin1String("QTabWidget") + || tag == QLatin1String("QTextBrowser") + || tag == QLatin1String("QTextEdit") + || tag == QLatin1String("QTimeEdit") + || tag == QLatin1String("QToolBar") + || tag == QLatin1String("QToolBox") + || tag == QLatin1String("QTreeView") + || tag == QLatin1String("QTreeWidget") + || tag == QLatin1String("QWorkspace")) + QSKIP("This type of widget is not currently strongly exception safe", SkipSingle); + QFETCH(AbstractTester *, widgetCreator); doOOMTest(*widgetCreator, 0, 00000); @@ -547,7 +591,9 @@ struct IntegerMoveable }; int IntegerMoveable::instanceCount = 0; +QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(IntegerMoveable, Q_MOVABLE_TYPE); +QT_END_NAMESPACE template <typename T, template<typename> class Container> void containerInsertTest(QObject*) @@ -720,12 +766,12 @@ static void containerData() QTest::newRow("erase moveable") << static_cast<TestFunction>(containerEraseTest<IntegerMoveable, Container>); } -void tst_ExceptionSafetyObjects::vector_data() +void tst_ExceptionSafety_Objects::vector_data() { containerData<QVector>(); } -void tst_ExceptionSafetyObjects::vector() +void tst_ExceptionSafety_Objects::vector() { QFETCH(TestFunction, testFunction); @@ -736,30 +782,30 @@ void tst_ExceptionSafetyObjects::vector() doOOMTest(testFunction, 0); } -void tst_ExceptionSafetyObjects::list_data() +void tst_ExceptionSafety_Objects::list_data() { containerData<QList>(); } -void tst_ExceptionSafetyObjects::list() +void tst_ExceptionSafety_Objects::list() { QFETCH(TestFunction, testFunction); doOOMTest(testFunction, 0); } -void tst_ExceptionSafetyObjects::linkedList_data() +void tst_ExceptionSafety_Objects::linkedList_data() { containerData<QLinkedList>(); } -void tst_ExceptionSafetyObjects::linkedList() +void tst_ExceptionSafety_Objects::linkedList() { QFETCH(TestFunction, testFunction); doOOMTest(testFunction, 0); } -QTEST_MAIN(tst_ExceptionSafetyObjects) +QTEST_MAIN(tst_ExceptionSafety_Objects) #include "tst_exceptionsafety_objects.moc" #endif // QT_NO_EXCEPTIONS diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 4252ea4..e86a9f7 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -280,7 +280,7 @@ protected: eventsPtr->canceled << g->gestureType(); break; default: - Q_ASSERT(false); + qWarning() << "Unknown GestureState enum value:" << static_cast<int>(g->state()); } } } else if (event->type() == CustomEvent::EventType) { @@ -823,7 +823,7 @@ public: emit gestureCanceled(e->type(), g); break; default: - Q_ASSERT(false); + qWarning() << "Unknown GestureState enum value:" << static_cast<int>(g->state()); } } } else if (event->type() == CustomEvent::EventType) { @@ -1518,17 +1518,20 @@ void tst_Gestures::autoCancelGestures() { class MockWidget : public GestureWidget { public: - MockWidget(const char *name) : GestureWidget(name) { } + MockWidget(const char *name) : GestureWidget(name), badGestureEvents(0) { } bool event(QEvent *event) { if (event->type() == QEvent::Gesture) { QGestureEvent *ge = static_cast<QGestureEvent*>(event); - Q_ASSERT(ge->gestures().count() == 1); // can't use QCOMPARE here... + if (ge->gestures().count() != 1) + ++badGestureEvents; // event should contain exactly one gesture ge->gestures().first()->setGestureCancelPolicy(QGesture::CancelAllInContext); } return GestureWidget::event(event); } + + int badGestureEvents; }; const Qt::GestureType secondGesture = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer); @@ -1563,22 +1566,26 @@ void tst_Gestures::autoCancelGestures() event.serial = CustomGesture::SerialFinishedThreshold; QApplication::sendEvent(child, &event); QCOMPARE(parent.events.all.count(), 2); + QCOMPARE(parent.badGestureEvents, 0); } void tst_Gestures::autoCancelGestures2() { class MockItem : public GestureItem { public: - MockItem(const char *name) : GestureItem(name) { } + MockItem(const char *name) : GestureItem(name), badGestureEvents(0) { } bool event(QEvent *event) { if (event->type() == QEvent::Gesture) { QGestureEvent *ge = static_cast<QGestureEvent*>(event); - Q_ASSERT(ge->gestures().count() == 1); // can't use QCOMPARE here... + if (ge->gestures().count() != 1) + ++badGestureEvents; // event should contain exactly one gesture ge->gestures().first()->setGestureCancelPolicy(QGesture::CancelAllInContext); } return GestureItem::event(event); } + + int badGestureEvents; }; const Qt::GestureType secondGesture = QGestureRecognizer ::registerRecognizer(new CustomGestureRecognizer); @@ -1614,6 +1621,7 @@ void tst_Gestures::autoCancelGestures2() event.serial = CustomGesture::SerialFinishedThreshold; scene.sendEvent(child, &event); QCOMPARE(parent->events.all.count(), 2); + QCOMPARE(parent->badGestureEvents, 0); } void tst_Gestures::graphicsViewParentPropagation() diff --git a/tests/auto/gui.pro b/tests/auto/gui.pro index b2e9e6f..17f56f2 100644 --- a/tests/auto/gui.pro +++ b/tests/auto/gui.pro @@ -2,7 +2,7 @@ # (i.e. QT=core gui network). # The test system is allowed to run these tests before the rest of Qt has # been compiled. -# +# TEMPLATE=subdirs SUBDIRS=\ gestures \ @@ -49,6 +49,7 @@ SUBDIRS=\ qfiledialog \ qfiledialog2 \ qfileiconprovider \ + qfileopenevent \ qfilesystemmodel \ qfocusframe \ qfont \ @@ -57,6 +58,7 @@ SUBDIRS=\ qfontdialog \ qfontmetrics \ qformlayout \ + qglyphrun \ qgraphicsanchorlayout \ qgraphicsanchorlayout1 \ qgraphicseffect \ @@ -82,6 +84,7 @@ SUBDIRS=\ qheaderview \ qicoimageformat \ qicon \ + qidentityproxymodel \ qimageiohandler \ qimagereader \ qimagewriter \ @@ -112,9 +115,6 @@ SUBDIRS=\ qmovie \ qvolatileimage \ qnetworkaccessmanager_and_qprogressdialog \ - qnetworkcachemetadata \ - qnetworkdiskcache \ - qnetworkreply \ qpaintengine \ qpainterpath \ qpainterpathstroker \ @@ -137,6 +137,7 @@ SUBDIRS=\ qpushbutton \ qquaternion \ qradiobutton \ + qrawfont \ qregexpvalidator \ qregion \ qscrollarea \ @@ -166,7 +167,6 @@ SUBDIRS=\ qtabbar \ qtableview \ qtablewidget \ - qtcpserver \ qtcpsocket \ qtessellator \ qtextblock \ @@ -193,7 +193,6 @@ SUBDIRS=\ qtreeview \ qtreewidget \ qtreewidgetitemiterator \ - qudpsocket \ qundogroup \ qundostack \ qvectornd \ diff --git a/tests/auto/guiapplauncher/guiapplauncher.pro b/tests/auto/guiapplauncher/guiapplauncher.pro index 30f5cf4..1fe9c8b 100644 --- a/tests/auto/guiapplauncher/guiapplauncher.pro +++ b/tests/auto/guiapplauncher/guiapplauncher.pro @@ -3,6 +3,7 @@ # ------------------------------------------------- # Link against gui for X11,etc. +load(qttest_p4) DEFINES += SRCDIR=\\\"$$PWD/\\\" TARGET = tst_guiapplauncher diff --git a/tests/auto/guiapplauncher/tst_guiapplauncher.cpp b/tests/auto/guiapplauncher/tst_guiapplauncher.cpp index 4fd8b2b..0683fd1 100644 --- a/tests/auto/guiapplauncher/tst_guiapplauncher.cpp +++ b/tests/auto/guiapplauncher/tst_guiapplauncher.cpp @@ -270,7 +270,7 @@ private: const QSharedPointer<WindowManager> m_wm; }; -// Test mask from enviroment as test lib does not allow options. +// Test mask from environment as test lib does not allow options. static inline unsigned testMask() { unsigned testMask = tst_GuiAppLauncher::TestAll; diff --git a/tests/auto/headers/tst_headers.cpp b/tests/auto/headers/tst_headers.cpp index 39ef5e2..335e832 100644 --- a/tests/auto/headers/tst_headers.cpp +++ b/tests/auto/headers/tst_headers.cpp @@ -177,7 +177,7 @@ void tst_Headers::allSourceFilesData() || sourceFile.endsWith("/src/corelib/global/qconfig.h") || sourceFile.endsWith("/src/corelib/global/qconfig.cpp") || sourceFile.endsWith("/src/tools/uic/qclass_lib_map.h") - || sourceFile.endsWith("src/network/access/qnetworkcookiejartlds_p.h") + || sourceFile.endsWith("src/corelib/io/qurltlds_p.h") ) continue; @@ -243,6 +243,10 @@ void tst_Headers::licenseCheck() QCOMPARE(content.at(i++), QString("**")); if (sourceFile.endsWith("/tests/auto/modeltest/dynamictreemodel.cpp") || sourceFile.endsWith("/tests/auto/modeltest/dynamictreemodel.h") + || sourceFile.endsWith("/src/gui/itemviews/qidentityproxymodel.h") + || sourceFile.endsWith("/src/gui/itemviews/qidentityproxymodel.cpp") + || sourceFile.endsWith("/doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp") + || sourceFile.endsWith("/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp") || sourceFile.endsWith("/src/network/kernel/qnetworkproxy_p.h")) { // These files are not copyrighted by Nokia. diff --git a/tests/auto/lancelot/.gitignore b/tests/auto/lancelot/.gitignore new file mode 100644 index 0000000..0a70416 --- /dev/null +++ b/tests/auto/lancelot/.gitignore @@ -0,0 +1 @@ +tst_lancelot diff --git a/tests/auto/lancelot/lancelot.pro b/tests/auto/lancelot/lancelot.pro new file mode 100644 index 0000000..11beb7e --- /dev/null +++ b/tests/auto/lancelot/lancelot.pro @@ -0,0 +1,13 @@ +load(qttest_p4) +QT += xml svg +contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2):QT += opengl + +SOURCES += tst_lancelot.cpp \ + $$PWD/../../arthur/common/paintcommands.cpp +HEADERS += $$PWD/../../arthur/common/paintcommands.h +RESOURCES += $$PWD/../../arthur/common/images.qrc + +include($$PWD/../../arthur/common/qbaselinetest.pri) + +!symbian:!wince*:DEFINES += SRCDIR=\\\"$$PWD\\\" +linux-g++-maemo:DEFINES += USE_RUNTIME_DIR diff --git a/tests/auto/lancelot/scripts/aliasing.qps b/tests/auto/lancelot/scripts/aliasing.qps new file mode 100644 index 0000000..59878f9 --- /dev/null +++ b/tests/auto/lancelot/scripts/aliasing.qps @@ -0,0 +1,156 @@ + +path_moveTo convexPath 25 0 +path_lineTo convexPath 50 50 +path_lineTo convexPath 25 25 +path_lineTo convexPath 0 50 +path_closeSubpath convexPath + +pixmap_load border.png pixmap + +setRenderHint LineAntialiasing false +translate 10 10 + +begin_block drawing + setPen black 1 + setBrush 7f7fff + drawPath convexPath + + setFont "monospace" 8 + setPen black + drawText 0 68 "QwErTy@" + + + setPen black 1 + setBrush 7f7fff + drawRect 0 80 10 5 + + setPen black 1 + setBrush noBrush + drawRect 20 80 10 5 + + setPen noPen + setBrush 7f7fff + drawRect 40 80 10 5 + + + setPen black 2 + setBrush 7f7fff + drawRect 0 90 10 5 + + setPen black 2 + setBrush noBrush + drawRect 20 90 10 5 + + setPen noPen + setBrush 7f7fff + drawRect 40 90 10 5 + + + setPen black 3 + setBrush 7f7fff + drawRect 0 100 10 5 + + setPen black 3 + setBrush noBrush + drawRect 20 100 10 5 + + setPen noPen + setBrush 7f7fff + drawRect 40 100 10 5 + + + setPen black 1 + setBrush noBrush + drawLine 10 110 20 120 + drawLine 30 120 40 110 + + setPen black 2 + setBrush noBrush + drawLine 10 120 20 130 + drawLine 30 130 40 120 + + setPen black 3 + setBrush noBrush + drawLine 10 130 20 140 + drawLine 30 140 40 130 + + drawPixmap pixmap 0 150 + + setRenderHint SmoothPixmapTransform false + drawPixmap pixmap 20 150 15 15 0 0 10 10 + +end_block + +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +drawText 15 185 "0.0" + +resetMatrix +translate 70.2 10.2 +setRenderHint LineAntialiasing false +repeat_block drawing +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +translate -0.2 -0.2 +drawText 15 185 "0.2" + + +resetMatrix +translate 130.4 10.4 +setRenderHint LineAntialiasing false +repeat_block drawing +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +translate -0.4 -0.4 +drawText 15 185 "0.4" + + +resetMatrix +translate 190.5 10.5 +setRenderHint LineAntialiasing false +repeat_block drawing +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +translate -0.5 -0.5 +drawText 15 185 "0.5" + + +resetMatrix +translate 250.6 10.6 +setRenderHint LineAntialiasing false +repeat_block drawing +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +translate -0.6 -0.6 +drawText 15 185 "0.6" + + +resetMatrix +translate 310.8 10.8 +setRenderHint LineAntialiasing false +repeat_block drawing +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +translate -0.8 -0.8 +drawText 15 185 "0.8" + + +resetMatrix +translate 371 11 +setRenderHint LineAntialiasing false +repeat_block drawing +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +drawText 15 185 "1.0" + + +resetMatrix +drawText 430 95 "Aliased" +drawText 430 275 "Anti-Aliased"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/arcs.qps b/tests/auto/lancelot/scripts/arcs.qps new file mode 100644 index 0000000..8a7a468 --- /dev/null +++ b/tests/auto/lancelot/scripts/arcs.qps @@ -0,0 +1,68 @@ +# Version: 1 +# CheckVsReference: 5 + +setRenderHint LineAntialiasing + +setPen red + +drawEllipse 0 0 600 400 + +path_moveTo arcs 300 200 +path_arcTo arcs 0 0 600 400 0 10 +path_closeSubpath arcs + +path_moveTo arcs 300 200 +path_arcTo arcs 0 0 600 400 20 30 +path_closeSubpath arcs + +path_moveTo arcs 300 200 +path_arcTo arcs 0 0 600 400 60 45 +path_closeSubpath arcs + +path_moveTo arcs 300 200 +path_arcTo arcs 0 0 600 400 115 60 +path_closeSubpath arcs + +path_moveTo arcs 300 200 +path_arcTo arcs 0 0 600 400 180 90 +path_closeSubpath arcs + +path_moveTo arcs 590 200 +path_arcTo arcs 10 10 580 380 0 360 +path_closeSubpath arcs + +path_moveTo arcs 300 200 +path_arcTo arcs 20 20 560 360 0 -10 +path_closeSubpath arcs + +path_moveTo arcs 300 200 +path_arcTo arcs 20 20 560 360 -20 -30 +path_closeSubpath arcs + +path_moveTo arcs 300 200 +path_arcTo arcs 20 20 560 360 -60 -45 +path_closeSubpath arcs + +path_moveTo arcs 300 200 +path_arcTo arcs 20 20 560 360 -115 -60 +path_closeSubpath arcs + +path_moveTo arcs 300 200 +path_arcTo arcs 20 20 560 360 -180 -90 +path_closeSubpath arcs + +setPen black 1 solidline +setBrush #3f00ff00 +drawPath arcs + +# Then again with a matrix set... +translate 200 400 +rotate 10 +scale 0.5 0.5 +setPen red +setBrush nobrush +drawEllipse 0 0 600 400 + +setPen black 1 solidline +setBrush #3f0000ff +drawPath arcs
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/arcs2.qps b/tests/auto/lancelot/scripts/arcs2.qps new file mode 100644 index 0000000..411ff08 --- /dev/null +++ b/tests/auto/lancelot/scripts/arcs2.qps @@ -0,0 +1,47 @@ +# Version: 1 +# CheckVsReference: 5 + +drawArc 100 100 100 100 0 1440 +drawArc 100 100 100 100 1440 1440 +drawArc 100 100 100 100 2880 1440 +drawArc 100 100 100 100 4320 1440 + +drawArc 100 200 100 100 0 -1440 +drawArc 100 200 100 100 -1440 -1440 +drawArc 100 200 100 100 -2880 -1440 +drawArc 100 200 100 100 -4320 -1440 + +drawArc 200 100 100 100 720 1440 +drawArc 200 100 100 100 2160 1440 +drawArc 200 100 100 100 3600 1440 +drawArc 200 100 100 100 5040 1440 + +drawArc 200 200 100 100 -720 -1440 +drawArc 200 200 100 100 -2160 -1440 +drawArc 200 200 100 100 -3600 -1440 +drawArc 200 200 100 100 -5040 -1440 + + +drawArc 300 100 100 100 3840 480 +drawArc 300 200 100 100 -3840 -480 + +drawArc 300 100 100 100 1600 1340 + +setPen black +drawArc 400 100 200 200 0 5760 +setPen white +drawArc 400 100 200 200 960 960 +drawArc 400 100 200 200 2880 960 +drawArc 400 100 200 200 4800 960 + +setPen black +drawArc 100 350 300 300 160 5760 +drawArc 100 350 300 300 320 5760 +drawArc 100 350 300 300 1920 5760 +drawArc 100 350 300 300 2080 5760 +drawArc 100 350 300 300 3680 5760 +drawArc 100 350 300 300 3840 5760 +drawArc 100 350 300 300 5440 5760 +drawArc 100 350 300 300 5600 5760 +setPen white +drawArc 100 350 300 300 0 5760 diff --git a/tests/auto/lancelot/scripts/background.qps b/tests/auto/lancelot/scripts/background.qps new file mode 100644 index 0000000..000cfcd --- /dev/null +++ b/tests/auto/lancelot/scripts/background.qps @@ -0,0 +1,136 @@ +# Version: 1 +# CheckVsReference: 5% + +translate 10 30 +setBackground 7f7fff +setBackgroundMode Transparent +setPen ff7f7f + +path_moveTo path 0 0 +path_lineTo path 25 0 +path_cubicTo path 50 0 25 25 25 50 +path_lineTo path 0 50 + +bitmap_load bitmap.png bitmap + +begin_block drawing + save + drawRect 0 0 50 50 + + translate 60 0 + drawEllipse 0 0 50 50 + + translate 60 0 + drawPolygon [0 0 50 0 25 50 25 25] + + translate 60 0 + drawPath path + + translate 60 0 + drawPie 0 0 50 50 1440 2000 + + translate 60 0 + drawChord 0 0 50 50 1440 2000 + + translate 60 0 + drawLine 0 0 50 0 + drawLine 0 0 50 50 + drawLine 0 0 0 50 + + translate 60 0 + drawPolyline [0 0 50 0 25 50 25 25] + + translate 60 0 + drawArc 0 0 50 50 1440 2000 + + translate 60 0 + drawText 0 10 "Jambi-Bambi" + + translate 80 0 + drawPixmap bitmap 0 0 + restore + + save + setRenderHint Antialiasing + translate 5 55 + drawRect 0 0 50 50 + + translate 60 0 + drawEllipse 0 0 50 50 + + translate 60 0 + drawPolygon [0 0 50 0 25 50 25 25] + + translate 60 0 + drawPath path + + translate 60 0 + drawPie 0 0 50 50 1440 2000 + + translate 60 0 + drawChord 0 0 50 50 1440 2000 + + translate 60 0 + drawLine 0 0 50 0 + drawLine 0 0 50 50 + drawLine 0 0 0 50 + + translate 60 0 + drawPolyline [0 0 50 0 25 50 25 25] + + translate 60 0 + drawArc 0 0 50 50 1440 2000 + + translate 60 0 + drawText 0 10 "Jambi-Bambi" + + translate 80 0 + drawPixmap bitmap 0 0 + restore +end_block + +translate 0 160 +setBackgroundMode Transparent +setPen ff7f7f 0 dotline flatcap beveljoin +repeat_block drawing + +translate 0 160 +setBackgroundMode Opaque +setPen ff7f7f 0 dotline flatcap beveljoin +repeat_block drawing + +translate 0 160 +setBackgroundMode Transparent +setPen ff7f7f 4 dashline flatcap beveljoin +repeat_block drawing + +translate 0 160 +setBackgroundMode OpaqueMode +setPen ff7f7f 4 dashline flatcap beveljoin +repeat_block drawing + +resetMatrix + +translate 5 5 + +setBrush nobrush +setPen black +setBackgroundMode transparent +drawText 10 15 "TransparentMode with solid 0-width pen" +drawRect 0 0 685 135 + +translate 0 160 +drawText 10 15 "TransparentMode with dotted 0-width pen" +drawRect 0 0 685 135 + +translate 0 160 +drawText 10 15 "OpaqueMode with dotted 0-width pen" +drawRect 0 0 685 135 + +translate 0 160 +drawText 10 15 "TransparentMode with dotted 4-width pen" +drawRect 0 0 685 135 + +translate 0 160 +drawText 10 15 "OpaqueMode with solid 4-width pen" +drawRect 0 0 685 135 diff --git a/tests/auto/lancelot/scripts/background_brush.qps b/tests/auto/lancelot/scripts/background_brush.qps new file mode 100644 index 0000000..ca1f944 --- /dev/null +++ b/tests/auto/lancelot/scripts/background_brush.qps @@ -0,0 +1,5 @@ +# Version: 1 +# CheckVsReference: 5% + +setBrush #00ff00 crosspattern +import "background.qps"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/beziers.qps b/tests/auto/lancelot/scripts/beziers.qps new file mode 100644 index 0000000..9b47cd0 --- /dev/null +++ b/tests/auto/lancelot/scripts/beziers.qps @@ -0,0 +1,147 @@ +# Version: 1 +# CheckVsReference: 5% + + +setRenderHint LineAntialiasing + +translate 20 20 +path_moveTo fullSize 0 0 +path_cubicTo fullSize 200 100 -100 100 100 0 + +path_moveTo fullSize 0 200 +path_cubicTo fullSize 0 100 100 100 100 200 + +path_moveTo fullSize 0 250 +path_cubicTo fullSize 50 200 50 200 100 250 +drawPath fullSize + +translate 110 0 +scale 10 10 +path_moveTo medSize 0 0 +path_cubicTo medSize 20 10 -10 10 10 0 + +path_moveTo medSize 0 20 +path_cubicTo medSize 0 10 10 10 10 20 + +path_moveTo medSize 0 25 +path_cubicTo medSize 5 20 5 20 10 25 +drawPath medSize + +resetMatrix +translate 240 20 +scale 100 100 +path_moveTo smallSize 0 0 +path_cubicTo smallSize 2 1 -1 1 1 0 + +path_moveTo smallSize 0 2 +path_cubicTo smallSize 0 1 1 1 1 2 + +path_moveTo smallSize 0 2.5 +path_cubicTo smallSize 0.5 2 0.5 2 1 2.5 +drawPath smallSize + +resetMatrix +translate 20 300 +drawPath medSize + +resetMatrix +translate 250 -100 +path_moveTo maxSize 0 500 +path_cubicTo maxSize 1000 0 -500 0 500 500 +drawPath maxSize + +setRenderHint Antialiasing off +resetMatrix + +path_moveTo path1 0 0 +path_cubicTo path1 10 10 0 10 10 0 + +path_moveTo path2 0 0 +path_cubicTo path2 15 15 -5 15 10 0 + +path_moveTo path3 0 0 +path_cubicTo path3 20 20 -10 20 10 0 + +path_moveTo path4 0 0 +path_cubicTo path4 0 5 10 10 0 15 + +path_moveTo path5 0 10 +path_cubicTo path5 10 10 -10 20 0 0 + +path_moveTo path6 0 0 +path_cubicTo path6 10 5 -10 10 0 15 + +setPen black 2 +setBrush nobrush + +translate 10 500 +scale 3 3 +begin_block paths +save +drawPath path1 +translate 20 0 +drawPath path2 +translate 20 0 +drawPath path3 +translate 20 0 +drawPath path4 +translate 20 0 +drawPath path5 +translate 20 0 +drawPath path6 +restore +end_block + +setPen nopen +setBrush black + +translate 0 20 +repeat_block paths + +setRenderHint Antialiasing + +setPen black 2 +setBrush nobrush + +translate 120 -20 +repeat_block paths + +setPen nopen +setBrush black + +translate 0 20 +repeat_block paths + +resetMatrix +path_moveTo miterPath 20 0 +path_cubicTo miterPath 20 20 0 0 1 0 +path_lineTo miterPath -1 -0.2 + +setBrush nobrush + +translate 50 660 +scale 5 5 + +setPen black 4 solidline flatcap miterjoin +drawPath miterPath +setPen red 0 +drawPath miterPath + +path_moveTo miterPath2 21 0.2 +path_lineTo miterPath2 19 0 +path_cubicTo miterPath2 20 0 0 20 0 0 + +translate 30 0 +setPen black 4 solidline flatcap miterjoin +drawPath miterPath2 +setPen red 0 +drawPath miterPath2 + +path_moveTo wonkyPath 0 0 +path_cubicTo wonkyPath 5 15 20 0 17 0 + +translate 30 0 +setPen black 4 solidline flatcap miterjoin +drawPath wonkyPath +setPen red 0 +drawPath wonkyPath diff --git a/tests/auto/lancelot/scripts/bitmaps.qps b/tests/auto/lancelot/scripts/bitmaps.qps new file mode 100644 index 0000000..a816b9d --- /dev/null +++ b/tests/auto/lancelot/scripts/bitmaps.qps @@ -0,0 +1,166 @@ +# Version: 1 +# CheckVsReference: 5% + + +#setRenderHint SmoothPixmapTransform + +translate 10 50 +setBackground ff7f7f +setPen 3f3f9f + +bitmap_load dome_mono.png the_pixmap + +save + # Draw with opaque pen/bg in transparent/opaque mode + setBackgroundMode Transparent + drawPixmap the_pixmap 0 0 + setBackgroundMode Opaque + drawPixmap the_pixmap 110 0 + + translate 220 0 + + # Draw with alpha pen/bg in transparent/opaque mode + save + setBackground 7fff7f7f + setPen 7f3f3f9f + setBackgroundMode Transparent + drawPixmap the_pixmap 0 0 + setBackgroundMode Opaque + drawPixmap the_pixmap 110 0 + restore + + translate 220 0 + + # Draw with rotated opaque pen/bg in transparent/opaque mode + setBackgroundMode Transparent + save + translate 50 50 + rotate 10 + translate -50 -50 + drawPixmap the_pixmap 0 0 + restore + setBackgroundMode Opaque + translate 110 0 + save + translate 50 50 + rotate 10 + translate -50 -50 + drawPixmap the_pixmap 0 0 + restore +restore + +translate 0 150 + +save + setBackgroundMode Transparent + drawTiledPixmap the_pixmap 0 0 200 100 + setBackgroundMode Opaque + drawTiledPixmap the_pixmap 210 0 200 100 + + translate 440 -10 + save + rotate 10 + drawTiledPixmap the_pixmap 0 0 200 100 + restore +restore + +translate 0 150 +save + setBackgroundMode Transparent + drawTiledPixmap the_pixmap 0 0 200 100 10 20 + setBackgroundMode Opaque + drawTiledPixmap the_pixmap 210 0 200 100 10 20 + + translate 440 -10 + save + rotate 10 + drawTiledPixmap the_pixmap 0 0 200 100 10 20 + restore +restore + + +pixmap_setMask the_pixmap mask_100.png +drawPixmap the_pixmap 0 150 +setBackgroundMode Opaque +drawPixmap the_pixmap 110 150 + +translate 220 150 +save + translate 50 50 + rotate 10 + translate -50 -50 + setBackgroundMode Transparent + drawPixmap the_pixmap 0 0 +restore + +translate 110 0 +save + translate 50 50 + rotate 10 + translate -50 -50 + setBackgroundMode Opaque + drawPixmap the_pixmap 0 0 +restore + +resetMatrix +translate 10 650 +bitmap_load dome_mono.png the_bitmap +setBackgroundMode Transparent + +begin_block draw_subrected + drawPixmap the_bitmap 0 0 50 50 0 0 50 50 + drawPixmap the_bitmap 50 0 50 50 50 0 50 50 + drawPixmap the_bitmap 0 50 50 50 0 50 50 50 + drawPixmap the_bitmap 50 50 50 50 50 50 50 50 +end_block + +translate 110 0 +setBackgroundMode Opaque +repeat_block draw_subrected + +translate 110 0 +save + translate 20 -10 + rotate 10 + setBackgroundMode Transparent + repeat_block draw_subrected +restore + +translate 110 0 +save + translate 20 -10 + rotate 10 + setBackgroundMode Opaque + repeat_block draw_subrected +restore + +# Some helpful texts + +resetMatrix +setPen black +drawText 10 40 "Transparent" +drawText 120 40 "Opaque" +drawText 230 40 "Trans w/alpha" +drawText 340 40 "Opaque w/alpha" +drawText 450 40 "Trans w/xform" +drawText 560 40 "Opaque w/xform" + +drawText 10 190 "Transparent tiled" +drawText 220 190 "Opaque tiled" +drawText 440 190 "Opaque w/xform" + +drawText 10 340 "Transparent tiled w/offset" +drawText 220 340 "Opaque tiled w/offset" +drawText 440 340 "Opaque w/xform w/offset" + +drawText 10 490 "Trans masked" +drawText 120 490 "Opaque masked" +drawText 230 490 "masked w/xform" +drawText 340 490 "masked w/xform" + +drawText 10 640 "Subrected" +drawText 110 640 "Subrected opaque" +drawText 220 640 "subrect w/xform" +drawText 330 640 "subrect w/xform opaque" + + diff --git a/tests/auto/lancelot/scripts/borderimage.qps b/tests/auto/lancelot/scripts/borderimage.qps new file mode 100644 index 0000000..ebd4f4d --- /dev/null +++ b/tests/auto/lancelot/scripts/borderimage.qps @@ -0,0 +1,120 @@ +# Version: 1 +# CheckVsReference: 10% + +image_load borderimage.png borderimage +translate -128 -128 +begin_block draw_border +# top +drawImage borderimage 0 0 16 16 0 0 16 16 +drawImage borderimage 16 0 36 16 16 0 32 16 +drawImage borderimage 52 0 16 16 48 0 16 16 +# sides +drawImage borderimage 0 16 16 16 0 16 16 32 +drawImage borderimage 52 16 16 16 48 16 16 32 +#bottom +drawImage borderimage 0 32 16 16 0 48 16 16 +drawImage borderimage 16 32 36 16 16 48 32 16 +drawImage borderimage 52 32 16 16 48 48 16 16 +end_block draw_border +resetMatrix +begin_block draw_column +translate 1 1 +repeat_block draw_border +translate 0.1 64.1 +repeat_block draw_border +translate 0.1 64.1 +repeat_block draw_border +translate 0.1 64.1 +repeat_block draw_border +translate 0.1 64.1 +repeat_block draw_border +translate 0.1 64.1 +repeat_block draw_border +translate 0.1 64.1 +repeat_block draw_border +translate 0.1 64.1 +repeat_block draw_border +translate 0.1 64.1 +repeat_block draw_border +translate 0.1 64.1 +repeat_block draw_border +end_block draw_column +setRenderHint Antialiasing +resetMatrix +translate 72 0 +repeat_block draw_column +resetMatrix +scale 1.25 1.25 +translate 144 0 +repeat_block draw_border +resetMatrix +scale 1.25 1.25 +translate 246 0 +rotate 30 +repeat_block draw_border +setRenderHint SmoothPixmapTransform +resetMatrix +scale 1.25 1.25 +translate 144 120 +repeat_block draw_border +resetMatrix +scale 1.25 1.25 +translate 246 120 +rotate 30 +repeat_block draw_border +resetMatrix +translate 215 260 +scale 3.55 3.55 +rotate 30 +repeat_block draw_border +resetMatrix +setRenderHint SmoothPixmapTransform off +setRenderHint Antialiasing off +translate 480 627 +rotate 180 +repeat_block draw_column +resetMatrix +setRenderHint Antialiasing +translate 552 627 +rotate 180 +repeat_block draw_column +resetMatrix +setRenderHint Antialiasing off +translate 200.1 520.1 +begin_block one_pixel_border +drawImage borderimage 0 0 16 16 0 0 16 16 +drawImage borderimage 16 0 64 16 16 0 1 1 +drawImage borderimage 80 0 16 16 48 0 16 16 +drawImage borderimage 0 16 16 64 16 0 1 1 +drawImage borderimage 80 16 16 64 16 0 1 1 +drawImage borderimage 0 80 16 16 0 48 16 16 +drawImage borderimage 16 80 64 16 16 0 1 1 +drawImage borderimage 80 80 16 16 48 48 16 16 +end_block one_pixel_border +resetMatrix +translate 205.1 626.1 +scale 0.4 0.4 +repeat_block one_pixel_border +resetMatrix +translate 255.1 624.1 +scale 0.4 0.4 +rotate 10 +repeat_block one_pixel_border +resetMatrix +setPen red +drawRect 0 0 70 680 +drawText 10 670 "aa off" +drawRect 72 0 70 680 +drawText 80 670 "aa on" +drawRect 409 0 70 680 +drawText 419 650 "rot 180" +drawText 419 670 "aa off" +drawRect 481 0 70 680 +drawText 491 650 "rot 180" +drawText 491 670 "aa on" +drawRect 164 0 224 124 +drawText 174 114 "smoothpixmaptransform off" +drawRect 164 128 224 134 +drawText 174 252 "smoothpixmaptransform on" +drawRect 200 520 97 188 +drawText 210 698 "1x1 edges"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/brush_pens.qps b/tests/auto/lancelot/scripts/brush_pens.qps new file mode 100644 index 0000000..b9a2bc0 --- /dev/null +++ b/tests/auto/lancelot/scripts/brush_pens.qps @@ -0,0 +1,104 @@ +# Version: 1 +# CheckVsReference: 5% + +path_addRect p 0 0 75 75 +path_addEllipse p 25 25 75 75 + +translate 10 10 + +begin_block setup_gradient + gradient_clearStops + gradient_appendStop 0 red + gradient_appendStop 0.1 blue + gradient_appendStop 0.2 yellow + gradient_appendStop 0.3 cyan + gradient_appendStop 0.4 magenta + gradient_appendStop 0.5 green + gradient_appendStop 0.6 black + gradient_appendStop 0.7 indianred + gradient_appendStop 0.8 white + gradient_appendStop 0.9 orange + gradient_appendStop 1 blue + gradient_setLinear 0 0 100 100 +end_block + +setPen brush 0 +setBrush nobrush + +begin_block drawing + save + drawLine 0 0 100 100 + + translate 0 100 + drawPath p + + translate 0 110 + drawRect 0 0 100 100 + + translate 0 110 + drawPolyline [0 0 100 0 50 50] + + drawPoint 40 40 + drawPoint 41 40 + drawPoint 42 40 + drawPoint 43 40 + drawPoint 44 40 + drawPoint 45 40 + drawPoint 46 40 + drawPoint 47 40 + drawPoint 48 40 + drawPoint 49 40 + drawPoint 50 40 + + restore +end_block + +save + translate 110 0 + save + setRenderHint Antialiasing + repeat_block drawing + restore + + setBrush dome_rgb32.png + setPen brush 0 + setBrush nobrush + + translate 110 0 + repeat_block drawing + + translate 110 0 + save + setRenderHint Antialiasing + repeat_block drawing + restore +restore + +translate 0 0 + +save + repeat_block setup_gradient + setPen brush 5 + setBrush nobrush + translate 0 350 + repeat_block drawing + + translate 110 0 + save + setRenderHint Antialiasing + repeat_block drawing + restore + + setBrush dome_rgb32.png + setPen brush 5 + setBrush nobrush + + translate 110 0 + repeat_block drawing + + translate 110 0 + save + setRenderHint Antialiasing + repeat_block drawing + restore +restore
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/brushes.qps b/tests/auto/lancelot/scripts/brushes.qps new file mode 100644 index 0000000..82cbff4 --- /dev/null +++ b/tests/auto/lancelot/scripts/brushes.qps @@ -0,0 +1,79 @@ +# Version: 1 +# CheckVsReference: 5% + +# Fill the background +drawRect 0 0 width height + +setRenderHint Antialiasing +setRenderHint SmoothPixmapTransform + +translate 10 10 +# Draw all the pattern types as 40x40 rects using green, transparent background +begin_block drawrects +setBrush green Dense1Pattern +drawRect 0 0 40 40 +setBrush green Dense2Pattern +drawRect 40 0 40 40 +setBrush green Dense3Pattern +drawRect 80 0 40 40 +setBrush green Dense4Pattern +drawRect 120 0 40 40 +setBrush green Dense5Pattern +drawRect 160 0 40 40 +setBrush green Dense6Pattern +drawRect 200 0 40 40 +setBrush green Dense7Pattern +drawRect 240 0 40 40 +setBrush green HorPattern +drawRect 280 0 40 40 +setBrush green VerPattern +drawRect 320 0 40 40 +setBrush green CrossPattern +drawRect 360 0 40 40 +setBrush green BDiagPattern +drawRect 400 0 40 40 +setBrush green FDiagPattern +drawRect 440 0 40 40 +setBrush green DiagCrossPattern +drawRect 480 0 40 40 +setBrush green SolidPattern +drawRect 520 0 40 40 +setBrush green NoBrush +drawRect 560 0 40 40 +gradient_setLinear 0 0 0 40 +drawRect 600 0 40 40 +setBrush face.png +drawRect 640 0 80 40 +end_block + +# Switch to opaque mode +setBackground #7fff7f +setBackgroundMode OpaqueMode +translate 0 50 + +# Draw all the pattern types as 40x40 rects using green, opaque background +repeat_block drawrects + +translate 50 50 +rotate 10 + + +setBackgroundMode TransparentMode +repeat_block drawrects +setBackgroundMode OpaqueMode +translate 0 40 +repeat_block drawrects + + +setBrush dot.png +setPen nopen +resetMatrix +drawRect 0 200 50 50 +drawRect 50 200 50 50 + +setPen red +setBrushOrigin 0 250 +drawRect 0 250 50 50 +setBrushOrigin 50 250 +drawRect 50 250 50 50 + diff --git a/tests/auto/lancelot/scripts/clippaths.qps b/tests/auto/lancelot/scripts/clippaths.qps new file mode 100644 index 0000000..fba8978 --- /dev/null +++ b/tests/auto/lancelot/scripts/clippaths.qps @@ -0,0 +1,60 @@ +# Version: 1 +# CheckVsReference: 5% + +path_addRect hor 0 0 50 10 +path_addRect ver 0 0 10 50 + +translate 10 10 +setPen NoPen + +begin_block clipping +save + + setBrush 0x7f7fff + save + setClipPath hor + drawRect 0 0 100 100 + + setClipPath ver IntersectClip + setBrush black CrossPattern + drawRect 0 0 100 100 + restore + + translate 100 0 + save + setClipPath hor + drawRect 0 0 100 100 + + setClipPath ver ReplaceClip + setBrush black CrossPattern + drawRect 0 0 100 100 + restore + + translate 100 0 + save + setClipPath hor + drawRect 0 0 100 100 + + setClipPath ver UniteClip + setBrush black CrossPattern + drawRect 0 0 100 100 + restore + +restore +end_block + +translate 300 0 +setRenderHint Antialiasing +repeat_block clipping + +translate -300 100 +setRenderHint Antialiasing false +scale 1.2 1.2 +repeat_block clipping + +translate 300 0 +setRenderHint Antialiasing +setRenderHint SmoothPixmapTransform +repeat_block clipping + + diff --git a/tests/auto/lancelot/scripts/clipping.qps b/tests/auto/lancelot/scripts/clipping.qps new file mode 100644 index 0000000..3694ff2 --- /dev/null +++ b/tests/auto/lancelot/scripts/clipping.qps @@ -0,0 +1,182 @@ +# Version: 1 +# CheckVsReference: 5% + +region_addRect clip 50 0 90 190 +region_addRect clip 0 50 180 90 + +region_addRect clip2 30 30 60 60 + +region_addRect clip3 10 10 60 60 + +path_cubicTo path 90 0 50 50 90 90 +path_cubicTo path 0 90 50 50 0 0 + +path_addRect path2 0 0 90 90 +path_moveTo path2 90 45 +path_arcTo path2 0 0 90 90 0 -360 + +path_addRect emptypath 0 0 0 0 +region_addRect emptyregion 0 0 0 0 + +# Normal clip rect +setClipRect 0 0 50 150 +begin_block repaint +save +setBrush red +setPen nopen +resetMatrix +region_getClipRegion tmpclip +path_getClipPath tmpclippath +drawRect 0 0 width height +setBrush #3f0000ff +setClipRegion tmpclip +drawRect 0 0 width height +setClipPath tmpclippath +setBrush #3f00ff00 +drawRect 0 0 width height +restore +end_block + +# Rotated clip rect +translate 100 0 +rotate 10 +setClipRect 0 0 50 150 +repeat_block repaint + +# simple clip region +resetMatrix +translate 0 200 +setClipRegion clip +repeat_block repaint + +# simle rotated clip region +translate 250 -10 +rotate 10 +setClipRegion clip +repeat_block repaint + +# verify that clip is not xformed with painter +resetMatrix +translate 200 0 +setClipRegion clip +rotate 30 +setBrush red +setPen nopen +drawRect 0 0 width height + +resetMatrix +translate 0 400 +save +setClipRegion clip +setClipRegion clip2 IntersectClip +repeat_block repaint +translate 0 100 +rotate 10 +setClipRegion clip +setClipRegion clip2 IntersectClip +restore + +translate 100 0 +save +setClipRegion clip3 +setClipRegion clip2 UniteClip +repeat_block repaint +translate 0 100 +rotate 10 +setClipRegion clip3 +setClipRegion clip2 UniteClip +repeat_block repaint +restore + +translate 100 0 +save +setClipPath path +repeat_block repaint +translate 50 100 +rotate 45 +setClipPath path +repeat_block repaint +restore + +translate 100 0 +save +setClipPath path +setClipPath path2 IntersectClip +repeat_block repaint +translate 0 100 +rotate 10 +setClipPath path +setClipPath path2 IntersectClip +repeat_block repaint +restore + +translate 100 0 +save +setClipPath path +setClipPath path2 UniteClip +repeat_block repaint +translate 0 100 +rotate 10 +setClipPath path +setClipPath path2 UniteClip +repeat_block repaint +restore + +translate 100 0 +save +setClipPath path +setClipRegion clip3 IntersectClip +repeat_block repaint +translate 0 100 +rotate 10 +setClipRegion clip3 +setClipPath path IntersectClip +repeat_block repaint +restore + +translate 100 0 +save +setClipPath path +setClipRegion clip3 UniteClip +repeat_block repaint +translate 0 100 +rotate 10 +setClipRegion clip3 +setClipPath path UniteClip +repeat_block repaint +restore + +# test that an empty region is not drawn. +resetMatrix +setClipRegion emptyregion +setBrush #3f00ff00 +drawRect 0 0 300 300 +drawText 50 50 "Text should be clipped away by region" +setClipping false + +setClipPath emptypath +setBrush #3fffff00 +drawRect 50 50 300 300 +drawText 70 80 "Text should be clipped away by path" + +# Test that we can extract a clipregion when a matrix is set too +resetMatrix +translate 500 10 +scale 2 1 +setBrush blue +setClipping false +rotate 5 +drawRect 0 0 100 100 +setClipRect 0 0 100 100 +resetMatrix +rotate 10 +region_getClipRegion xclip +setClipRegion xclip +resetMatrix +setBrush #7f00ff00 +drawRect 0 0 width height + +# the below used to assert in debug mode +setClipRect 10 10 20 20 +setClipping false +setClipping true
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/clipping_state.qps b/tests/auto/lancelot/scripts/clipping_state.qps new file mode 100644 index 0000000..a29d373 --- /dev/null +++ b/tests/auto/lancelot/scripts/clipping_state.qps @@ -0,0 +1,47 @@ +# Version: 1 +# CheckVsReference: 5% + +path_addRect path1 10 10 50 50 +path_addRect path2 30 30 50 50 +# enable/disable a clip path +setPen nopen +setBrush red +setClipPath path1 +setClipPath path2 UniteClip +drawRect 0 0 100 100 +setClipping false +setBrush #630000ff +drawRect 0 0 100 100 +setClipping true +setBrush #6300ff00 +drawRect 0 0 100 100 +# enable/disable noclip +translate 150 0 +setClipPath path1 NoClip +setClipping false +setBrush #630000ff +drawRect 0 0 100 100 +setClipping true +setBrush #6300ff00 +drawRect 25 25 50 50 +# enable/disable full clipping +translate 150 0 +path_addRect path3 0 0 10 10 +path_addRect path4 20 20 10 10 +setClipPath path3 +setClipPath path4 IntersectClip +setClipping false +setBrush #630000ff +drawRect 0 0 100 100 +setClipping true +setBrush #6300ff00 +drawRect 25 25 50 50 +# disable clipping followed by setClipRect +translate 150 0 +setClipRect 0 0 50 50 ReplaceClip +setClipping false +setBrush #630000ff +drawRect 0 0 100 100 +setClipRect 25 25 75 75 IntersectClip +setBrush #6300ff00 +drawRect 25 25 50 50
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/cliprects.qps b/tests/auto/lancelot/scripts/cliprects.qps new file mode 100644 index 0000000..0d28b03 --- /dev/null +++ b/tests/auto/lancelot/scripts/cliprects.qps @@ -0,0 +1,59 @@ +# Version: 1 +# CheckVsReference: 5% + + + +translate 10 10 +setPen NoPen + +begin_block clipping +save + + setBrush 0x7f7fff + save + setClipRect 0 0 50 10 + drawRect 0 0 100 100 + + setClipRect 0 0 10 50 IntersectClip + setBrush black CrossPattern + drawRect 0 0 100 100 + restore + + translate 100 0 + save + setClipRect 0 0 50 10 + drawRect 0 0 100 100 + + setClipRect 0 0 10 50 ReplaceClip + setBrush black CrossPattern + drawRect 0 0 100 100 + restore + + translate 100 0 + save + setClipRect 0 0 50 10 + drawRect 0 0 100 100 + + setClipRect 0 0 10 50 UniteClip + setBrush black CrossPattern + drawRect 0 0 100 100 + restore + +restore +end_block + +translate 300 0 +setRenderHint Antialiasing +repeat_block clipping + +translate -300 100 +setRenderHint Antialiasing false +scale 1.2 1.2 +repeat_block clipping + +translate 300 0 +setRenderHint Antialiasing +setRenderHint SmoothPixmapTransform +repeat_block clipping + + diff --git a/tests/auto/lancelot/scripts/conical_gradients.qps b/tests/auto/lancelot/scripts/conical_gradients.qps new file mode 100644 index 0000000..2e897b1 --- /dev/null +++ b/tests/auto/lancelot/scripts/conical_gradients.qps @@ -0,0 +1,85 @@ +# Version: 1 +# CheckVsReference: 5% + +path_addRect path 300 0 80 80 +path_addEllipse path 340 40 60 60 + +setRenderHint Antialiasing + +setPen black + +begin_block gradients +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 1 cyan + +gradient_setConical 40 40 50 +drawRect 0 0 100 100 + +gradient_setConical 140 40 230 +drawEllipse 100 0 100 100 + +gradient_clearStops +gradient_appendStop 0 3f7f7fff +gradient_appendStop 0.5 dfdfffff +gradient_appendStop 1 7f00007f + +gradient_setConical 240 40 50 +drawPolygon [200 0 290 0 250 99] + +gradient_setConical 340 40 230 +drawPath path + +end_block + +translate 0 100 +scale 1 2 +repeat_block gradients + +resetMatrix +translate 0 300 +brushTranslate 30 0 +brushScale 0.9 0.9 +brushRotate 20 +repeat_block gradients + +# Some helpful info perhaps? +resetMatrix +setPen black + +drawText 410 50 "No XForm" +drawText 410 200 "scale 1x2" +drawText 410 300 "brush transform" +drawText 10 450 "50 deg" +drawText 110 450 "230 deg" +drawText 210 450 "50 deg w/alpha " +drawText 310 450 "230 deg w/alpha" + +setPen 3f000000 +setBrush nobrush + +begin_block ellipse_draw + setClipRect 0 0 100 100 + drawEllipse 35 35 11 11 + save + translate 40 40 + rotate -50 + drawLine -100 0 100 0 + restore + translate 100 0 +end_block + +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw + +resetMatrix +translate 0 100 +scale 1 2 +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/conical_gradients_perspectives.qps b/tests/auto/lancelot/scripts/conical_gradients_perspectives.qps new file mode 100644 index 0000000..a9c14f1 --- /dev/null +++ b/tests/auto/lancelot/scripts/conical_gradients_perspectives.qps @@ -0,0 +1,64 @@ +# Version: 1 +# CheckVsReference: 5% + + +setRenderHint Antialiasing + +setPen #00ff00 + +translate 10 10 +# standard draw +begin_block gradient +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 0.9 cyan +gradient_appendStop 1 red + +gradient_setSpread PadSpread +gradient_setConical 140 140 100 +drawRect 0 0 300 300 +end_block gradient + +# Rotation w/o smooth xform +save +translate 350 0 +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 50 0 200 300 300 300 0 + repeat_block gradient +restore +restore + +translate 0 320 + +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 0 100 300 200 300 300 0 + repeat_block gradient +restore + +save +translate 350 0 +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 0 0 300 300 250 300 50 + repeat_block gradient +restore +restore + + +resetMatrix +setPen black +translate 125 20 +drawText 0 0 "No transform" +translate 350 0 +drawText 0 0 "Left Tilted" +resetMatrix +translate 125 350 +drawText 0 0 "Bottom Tilted" +translate 350 0 +drawText 0 0 "Right Tilted" +translate 120 0
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/dashes.qps b/tests/auto/lancelot/scripts/dashes.qps new file mode 100644 index 0000000..649f56c --- /dev/null +++ b/tests/auto/lancelot/scripts/dashes.qps @@ -0,0 +1,268 @@ +# Version: 1 +# CheckVsReference: 5% + +translate 20 20 + +begin_block draw +save + save + setPen black 1 SolidLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 1 SolidLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 1 SolidLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + + setPen black 2 SolidLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 2 SolidLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 2 SolidLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + + setPen black 6 SolidLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 6 SolidLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 6 SolidLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + restore + + + translate 100 0 + save + setPen black 1 DotLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 1 DotLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 1 DotLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + + setPen black 2 DotLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 2 DotLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 2 DotLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + + setPen black 6 DotLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 6 DotLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 6 DotLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + restore + + translate 100 0 + save + setPen black 1 DashLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 1 DashLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 1 DashLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + + setPen black 2 DashLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 2 DashLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 2 DashLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + + setPen black 6 DashLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 6 DashLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 6 DashLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + restore + + translate 100 0 + + save + setPen black 1 DashDotLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 1 DashDotLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 1 DashDotLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + + setPen black 2 DashDotLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 2 DashDotLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 2 DashDotLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + + setPen black 6 DashDotLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 6 DashDotLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 6 DashDotLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + restore + + translate 100 0 + + save + setPen black 1 DashDotDotLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 1 DashDotDotLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 1 DashDotDotLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + + setPen black 2 DashDotDotLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 2 DashDotDotLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 2 DashDotDotLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + + setPen black 4 DashDotDotLine FlatCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 4 DashDotDotLine SquareCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 4 DashDotDotLine RoundCap BevelJoin + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + restore + + translate 100 0 + + save + setPen black 1 SolidLine FlatCap BevelJoin + pen_setDashPattern [1 4 9 4 27 4] + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 1 SolidLine SquareCap BevelJoin + pen_setDashPattern [1 4 9 4 27 4] + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 1 SolidLine RoundCap BevelJoin + pen_setDashPattern [1 4 9 4 27 4] + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + + setPen black 2 SolidLine FlatCap BevelJoin + pen_setDashPattern [1 4 9 4 27 4] + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 2 SolidLine SquareCap BevelJoin + pen_setDashPattern [1 4 9 4 27 4] + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 2 SolidLine RoundCap BevelJoin + pen_setDashPattern [1 4 9 4 27 4] + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + + setPen black 4 SolidLine FlatCap BevelJoin + pen_setDashPattern [1 4 9 4 27 4] + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 4 SolidLine SquareCap BevelJoin + pen_setDashPattern [1 4 9 4 27 4] + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + setPen black 4 SolidLine RoundCap BevelJoin + pen_setDashPattern [1 4 9 4 27 4] + drawPolyline [0 0 80 0 80 30 40 20 0 30] + translate 0 40 + restore + +restore +end_block + +translate 0 400 +setRenderHint Antialiasing +repeat_block draw + +translate 0 -20 +drawText 30 0 "Solid" + +translate 100 0 +drawText 20 0 "DotLine" + +translate 100 0 +drawText 10 0 "DashLine" + +translate 100 0 +drawText 0 0 "DashDotLine" + +translate 100 0 +drawText 0 0 "DashDotDotLine" + +translate 100 0 +drawText 0 0 "CustomDashLine" + +resetMatrix + +translate 620 40 + +begin_block width_and_caps_texts + drawText 0 0 "Width=1, FlatCap" + translate 0 40 + drawText 0 0 "Width=1, SquareCap" + translate 0 40 + drawText 0 0 "Width=1, RoundCap" + translate 0 40 + drawText 0 0 "Width=2, FlatCap" + translate 0 40 + drawText 0 0 "Width=2, SquareCap" + translate 0 40 + drawText 0 0 "Width=2, RoundCap" + translate 0 40 + drawText 0 0 "Width=6, FlatCap" + translate 0 40 + drawText 0 0 "Width=6, SqareCap" + translate 0 40 + drawText 0 0 "Width=6, RoundCap" +end_block + +translate 0 80 +repeat_block width_and_caps_texts
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/degeneratebeziers.qps b/tests/auto/lancelot/scripts/degeneratebeziers.qps new file mode 100644 index 0000000..fb223d5 --- /dev/null +++ b/tests/auto/lancelot/scripts/degeneratebeziers.qps @@ -0,0 +1,10 @@ +# Version: 1 +# CheckVsReference: 5% + +path_moveTo degenerate 3427.0918499999997948 3872.1318999999998596 +path_cubicTo degenerate 3427.0918499999997948 3872.1318999999994048 4729.4590867905308187 5176.8613451144155988 5389.9325499999995372 5837.8072499999998399 + +scale 0.05 0.05 +translate -2500 -3000 +setPen black 800 +drawPath degenerate
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/deviceclipping.qps b/tests/auto/lancelot/scripts/deviceclipping.qps new file mode 100644 index 0000000..cedfc1e --- /dev/null +++ b/tests/auto/lancelot/scripts/deviceclipping.qps @@ -0,0 +1,48 @@ +# Version: 1 +# CheckVsReference: 5% + +setBrush 0xff7f7f +setPen 0x7f0000 + +path_moveTo path -1000000 10000 +path_cubicTo path 100 100 100 150 150 400 +path_closeSubpath path + +begin_block drawing + + drawPath ellipse + + drawLine -1000000 200 200 200 + drawLine 200 -1000000 200 200 + drawLine 200 200 1000000 200 + drawLine 200 200 200 1000000 + drawLine -1000000 -1000000 200 200 + + drawPolygon [-1000000 100 100 -1000000 100 100] + drawRect 300 -500000 1000000 1000000 + + drawPath path + +end_block + +save +translate 20 20 +setBrush #0x7f7f7fff +setPen #0x7f00007f +repeat_block drawing + +translate 20 20 +setRenderHint Antialiasing +setBrush #0x7f7fff7f +setPen #0x7f007f00 +repeat_block drawing +restore + +setPen 0x00007f 2 +setRenderHint Antialiasing + +drawLine 0 -200 200 200 + +setPen 0x007f00 10 + +drawLine 0 -200 200 0
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/drawpoints.qps b/tests/auto/lancelot/scripts/drawpoints.qps new file mode 100644 index 0000000..c02cd85 --- /dev/null +++ b/tests/auto/lancelot/scripts/drawpoints.qps @@ -0,0 +1,101 @@ +# Version: 1 +# CheckVsReference: 5% + +#setRenderHint Antialiasing + +setPen red 0 solidline +begin_block points +drawPoint 00 00 +drawPoint 10 00 +drawPoint 20 00 +drawPoint 30 00 +drawPoint 40 00 +drawPoint 50 00 +drawPoint 00 10 +drawPoint 10 10 +drawPoint 20 10 +drawPoint 30 10 +drawPoint 40 10 +drawPoint 50 10 +drawPoint 00 20 +drawPoint 10 20 +drawPoint 20 20 +drawPoint 30 20 +drawPoint 40 20 +drawPoint 50 20 +drawPoint 00 30 +drawPoint 10 30 +drawPoint 20 30 +drawPoint 30 30 +drawPoint 40 30 +drawPoint 50 30 +drawPoint 00 40 +drawPoint 10 40 +drawPoint 20 40 +drawPoint 30 40 +drawPoint 40 40 +drawPoint 50 40 +drawPoint 00 50 +drawPoint 10 50 +drawPoint 20 50 +drawPoint 30 50 +drawPoint 40 50 +drawPoint 50 50 +end_block points + +translate 100 0 +setPen blue 1 solidline +repeat_block points + +translate 100 0 +setPen green 5 solidline roundcap +repeat_block points + +resetMatrix + +translate 0 100 +scale 3 3 +setPen red 0 solidline roundcap +repeat_block points + +translate 60 0 +setPen blue 1 solidline roundcap +repeat_block points + +translate 60 0 +setPen green 5 solidline roundcap +repeat_block points + +resetMatrix + +translate 0 300 +scale 3 3 +setPen red 0 solidline flatcap +repeat_block points + +translate 60 0 +setPen blue 1 solidline flatcap +repeat_block points + +translate 60 0 +setPen green 5 solidline flatcap +repeat_block points + +resetMatrix +translate 10 500 +setPen black 1 solidline flatcap +drawPoint 0 0 +setPen black 2 solidline flatcap +drawPoint 3 0 +setPen black 3 solidline flatcap +drawPoint 8 0 +setPen black 4 solidline flatcap +drawPoint 15 0 +setPen black 5 solidline flatcap +drawPoint 24 0 +setPen black 6 solidline flatcap +drawPoint 35 0 +setPen black 7 solidline flatcap +drawPoint 48 0 +setPen black 8 solidline flatcap +drawPoint 63 0
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/ellipses.qps b/tests/auto/lancelot/scripts/ellipses.qps new file mode 100644 index 0000000..e2cffd7 --- /dev/null +++ b/tests/auto/lancelot/scripts/ellipses.qps @@ -0,0 +1,86 @@ +# Version: 1 +# CheckVsReference: 5% + + +surface_begin 0 0 600 600 +translate 0 50 + +setPen nopen +setBrush 0x7f000000 +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 1 cyan + +gradient_setSpread PadSpread +gradient_setRadial 20 20 220 200 + +drawEllipse 10 10 80 80 +drawEllipse 50 50 120 90 + +translate 100 0 +brushTranslate 40 20 +brushScale 0.25 0.25 + +setPen black + +drawEllipse 10 10 80 80 +setOpacity 0.5 +setCompositionMode SourceIn +drawEllipse 50 50 120 90 +setOpacity 1.0 +setRenderHint Antialiasing +setCompositionMode Xor +brushTranslate 70 0 +translate 100 0 +drawEllipse 10 10 80 80 + +setPen nopen +drawEllipse 50 50 120 90 + +setOpacity 0.7 +setBrush red +translate 100 0 +setCompositionMode SourceOver + +drawEllipse 10 10 80 80 + +setOpacity 0.6 +setPen black 5.0 +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 1 cyan + +gradient_setSpread PadSpread +gradient_setLinear 20 20 120 100 +drawEllipse 50 50 120 90 + + +translate 100 0 + +setOpacity 1.0 +drawEllipse 10 10 80 80 + +setCompositionMode SourceIn +setOpacity 0.7 +setPen black 3.0 +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 1 cyan + +gradient_setSpread PadSpread +gradient_setLinear 50 50 80 90 +drawEllipse 50 50 120 90 + +surface_end + +drawText 200 220 "Testing Ellipse drawing with varios combinations" +drawText 200 240 "of features such as brushes, pens and composition modes"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/filltest.qps b/tests/auto/lancelot/scripts/filltest.qps new file mode 100644 index 0000000..2eeba2e --- /dev/null +++ b/tests/auto/lancelot/scripts/filltest.qps @@ -0,0 +1,413 @@ +# Version: 1 +# CheckVsReference: 5% + +setPen nopen +setBrush red +translate 0 4 +begin_block polys +drawPolygon [0 0 2 -2 4 0] +drawPolygon [0 2 2 4 4 2] +end_block polys +translate 6 .5 +repeat_block polys +translate 6.5 0 +repeat_block polys +translate 6 .5 +repeat_block polys + +resetMatrix + +translate 0 12 +setPen black +drawPolygon [0 0 5 0 5 5 0 5] + +translate 10 0 +setPen nopen +drawPolygon [0 0 5 0 5 5 0 5] + +translate 10 0 +drawPolygon [0 0 5 0 5 5 0 5] + +setBrush black +path_addRect stroke -.5 -.5 6 6 +path_addRect stroke .5 .5 4 4 +drawPath stroke + +resetMatrix + +translate 0 65 + +setPen red +drawText 0 0 "path" +drawText 40 0 "rect" +drawText 80 0 "img" +drawText 120 0 "pix" +drawText 160 0 "brush" +setPen nopen + +translate 0 5 + +image_load border.png img +pixmap_load border.png pix + +path_addRect rect 0 0 10 10 +begin_block rects +drawPath rect +drawRect 40 0 10 10 +drawImage img 80 0 +drawPixmap pix 120 0 +setBrush border.png +drawRect 160 0 10 10 +setBrush black +end_block rects + +setPen red +drawText 180 10 "0.0" +setPen nopen + +translate 0.1 20 +repeat_block rects +setPen red +drawText 180 10 "0.1" +setPen nopen +translate 0.1 20 +repeat_block rects +setPen red +drawText 180 10 "0.2" +setPen nopen +translate 0.1 20 +repeat_block rects +setPen red +drawText 180 10 "0.3" +setPen nopen +translate 0.1 20 +repeat_block rects +setPen red +drawText 180 10 "0.4" +setPen nopen +translate 0.1 20 +repeat_block rects +setPen red +drawText 180 10 "0.5" +setPen nopen +translate 0.1 20 +repeat_block rects +setPen red +drawText 180 10 "0.6" +setPen nopen +translate 0.1 20 +repeat_block rects +setPen red +drawText 180 10 "0.7" +setPen nopen +translate 0.1 20 +repeat_block rects +setPen red +drawText 180 10 "0.8" +setPen nopen +translate 0.1 20 +repeat_block rects +setPen red +drawText 180 10 "0.9" +setPen nopen +translate 0.1 20 +repeat_block rects +setPen red +drawText 180 10 "1.0" +setPen nopen + +resetMatrix + +translate 0 400 + +setPen red +drawText 0 10 "path" +drawText 0 30 "rect" +drawText 0 50 "img" +drawText 0 70 "pix" +drawText 0 90 "brush" +drawText 0 110 "stroke" +drawText 0 130 "scale" +drawText 0 170 "rotate" +setPen nopen + +translate 50 0 + +begin_block rects +drawPath rect +drawRect 0 20 10 10 +drawImage img 0 40 +drawPixmap pix 0 60 +save +setBrush border.png +drawRect 0 80 10 10 +translate 0 100 +setBrush red +setPen black +drawRect 0 0 10 10 +setBrush border.png +setPen nopen +translate 0 20 +scale 2 2 +drawRect 0 0 10 10 +translate 10 20 +rotate 90 +drawRect 0 0 10 10 +restore +end_block rects + +setPen red +drawText -5 -10 "0.0" +setPen nopen + +translate 40 0.1 +repeat_block rects +setPen red +drawText -5 -10 "0.1" +setPen nopen +translate 40 0.1 +repeat_block rects +setPen red +drawText -5 -10 "0.2" +setPen nopen +translate 40 0.1 +repeat_block rects +setPen red +drawText -5 -10 "0.3" +setPen nopen +translate 40 0.1 +repeat_block rects +setPen red +drawText -5 -10 "0.4" +setPen nopen +translate 40 0.1 +repeat_block rects +setPen red +drawText -5 -10 "0.5" +setPen nopen +translate 40 0.1 +repeat_block rects +setPen red +drawText -5 -10 "0.6" +setPen nopen +translate 40 0.1 +repeat_block rects +setPen red +drawText -5 -10 "0.7" +setPen nopen +translate 40 0.1 +repeat_block rects +setPen red +drawText -5 -10 "0.8" +setPen nopen +translate 40 0.1 +repeat_block rects +setPen red +drawText -5 -10 "0.9" +setPen nopen +translate 40 0.1 +repeat_block rects +setPen red +drawText -5 -10 "1.0" +setPen nopen + +resetMatrix + +translate 0 620 + +setPen red +drawText 0 10 "path" +setPen nopen + +path_addRect rect2 -5 -5 10 10 + +translate 55 5 +drawPath rect2 + +translate 20 0 +rotate 10 +drawPath rect2 +rotate -10 +translate 20 0 +rotate 20 +drawPath rect2 +rotate -20 +translate 20 0 +rotate 30 +drawPath rect2 +rotate -30 +translate 20 0 +rotate 40 +drawPath rect2 +rotate -40 +translate 20 0 +rotate 50 +drawPath rect2 +rotate -50 +translate 20 0 +rotate 60 +drawPath rect2 +rotate -60 +translate 20 0 +rotate 70 +drawPath rect2 +rotate -70 +translate 20 0 +rotate 80 +drawPath rect2 +rotate -80 +translate 20 0 +rotate 90 +drawPath rect2 +rotate -90 + +resetMatrix + +translate 0 600 + +setPen red +drawText 0 10 "rect" +setPen nopen + +translate 55 5 +drawRect -5 -5 10 10 + +translate 20 0 +rotate 10 +drawRect -5 -5 10 10 +rotate -10 +translate 20 0 +rotate 20 +drawRect -5 -5 10 10 +rotate -20 +translate 20 0 +rotate 30 +drawRect -5 -5 10 10 +rotate -30 +translate 20 0 +rotate 40 +drawRect -5 -5 10 10 +rotate -40 +translate 20 0 +rotate 50 +drawRect -5 -5 10 10 +rotate -50 +translate 20 0 +rotate 60 +drawRect -5 -5 10 10 +rotate -60 +translate 20 0 +rotate 70 +drawRect -5 -5 10 10 +rotate -70 +translate 20 0 +rotate 80 +drawRect -5 -5 10 10 +rotate -80 +translate 20 0 +rotate 90 +drawRect -5 -5 10 10 +rotate -90 + +resetMatrix +path_addRect vertical 0.1 0.1 0.2 10 + +translate 0 320 +drawPath vertical +translate 2.2 0 +drawPath vertical +translate 2.2 0 +drawPath vertical +translate 2.2 0 +drawPath vertical +translate 2.2 0 +drawPath vertical + +resetMatrix +path_addRect horizontal 0.1 0.1 10 0.2 + +translate 0 340 +drawPath horizontal +translate 0 2.2 +drawPath horizontal +translate 0 2.2 +drawPath horizontal +translate 0 2.2 +drawPath horizontal +translate 0 2.2 +drawPath horizontal + +setOpacity 0.8 +resetMatrix + +translate 0.1 24.7 +translate 400 0 +#rotate 88.8 +rotate 89.9 +setBrush red +drawPolygon [0 0 300 0 0 173] +setBrush green +drawPolygon [0 173 300 0 300 173] + +resetMatrix + +translate 410 24 +path_lineTo left 0 273 +path_lineTo left 300 273 +path_cubicTo left 50 273 250 0 0 0 + +path_cubicTo right 250 0 50 273 300 273 +path_lineTo right 300 0 + +translate 310 0 +rotate 90 +setBrush red +drawPath left +setBrush green +drawPath right + +resetMatrix +translate 0.1 680.1 +setPen red +setOpacity 1 +drawText 115 -20 "0.1" +drawText 0 0 "pixmap w/ opacity" +setOpacity 0.6 +drawPixmap pix 120 -10 +translate 0 20 +setOpacity 1 +drawText 0 0 "image w/ opacity" +setOpacity 0.6 +drawImage img 120 -10 + +resetMatrix +path_lineTo fillpath 0 50 +path_lineTo fillpath 50 50 +path_moveTo fillpath 70 50 +path_lineTo fillpath 70 100 +path_lineTo fillpath 40 100 +translate 500 400 +drawPath fillpath + +resetMatrix +path_moveTo vectorarne 50 10 +path_lineTo vectorarne 50 50 +path_lineTo vectorarne 100 50 +path_addEllipse vectorarne 350 20 230 230 +path_moveTo vectorarne 500 500 +path_cubicTo vectorarne 20 20 250 30 50 150 +translate 500 550 +scale 0.4 0.4 +setRenderHint antialiasing +drawPath vectorarne + +resetMatrix +translate 200 730 +setRenderHint antialiasing off +setOpacity 1 +setPen red +drawText 0 0 "outline/fill consistency" +setPen red +setBrush green +translate 80 -30 +drawPolygon [13.6965 -99.1837 -71.4767 13.823 32.4596 -33.1847]
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/gradients.qps b/tests/auto/lancelot/scripts/gradients.qps new file mode 100644 index 0000000..eb3cda9 --- /dev/null +++ b/tests/auto/lancelot/scripts/gradients.qps @@ -0,0 +1,44 @@ +# Version: 1 +# CheckVsReference: 5% + +drawText 75 20 "Linear" +drawText 176 20 "Radial" +drawText 277 20 "Conical" +translate 0 30 +drawText 0 50 "AA off" +drawText 0 151 "AA on" + +setPen nopen + +gradient_clearStops +gradient_appendStop 0 0x00000000 +gradient_appendStop 0.001 red +gradient_appendStop 0.2 blue +gradient_appendStop 0.4 yellow +gradient_appendStop 0.6 cyan +gradient_appendStop 0.8 green +gradient_appendStop 0.999 red +gradient_appendStop 1 0x00000000 + +gradient_setSpread PadSpread +gradient_setCoordinateMode ObjectBoundingMode + +begin_block row +save +gradient_setLinear 0.1 0.0 0.9 0.0 +drawRect 50 0 100 100 + +gradient_setRadial 0.5 0.5 0.5 0.5 0.5 +translate 101 0 +drawRect 50 0 100 100 + +gradient_setConical 0.5 0.5 45 +translate 101 0 +drawRect 50 0 100 100 +restore +end_block row + +setRenderHint Antialiasing + +translate 0 101 +repeat_block row
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/hinting.qps b/tests/auto/lancelot/scripts/hinting.qps new file mode 100644 index 0000000..7ce21b2 --- /dev/null +++ b/tests/auto/lancelot/scripts/hinting.qps @@ -0,0 +1,26 @@ +translate 10 50 +setFont "sansserif" 10 +drawText 0 0 "Default hinting:" +setFont "times" 12 normal normal default +drawText 0 20 "The quick brown fox jumps over the lazy dog" + +translate 0 50 +setFont "sansserif" 10 +drawText 0 0 "No hinting:" +setFont "times" 12 normal normal none +drawText 0 20 "The quick brown fox jumps over the lazy dog" + +translate 0 50 +setFont "sansserif" 10 +drawText 0 0 "Vertical hinting:" +setFont "times" 12 normal normal vertical +drawText 0 20 "The quick brown fox jumps over the lazy dog" + +translate 0 50 +setFont "sansserif" 10 +drawText 0 0 "Full hinting:" +setFont "times" 12 normal normal full +drawText 0 20 "The quick brown fox jumps over the lazy dog" + + +# Note: there is also the textlayout_draw command which might be interesting here. diff --git a/tests/auto/lancelot/scripts/image_formats.qps b/tests/auto/lancelot/scripts/image_formats.qps new file mode 100644 index 0000000..d817d04 --- /dev/null +++ b/tests/auto/lancelot/scripts/image_formats.qps @@ -0,0 +1,81 @@ +# Version: 1 +# CheckVsReference: 5% + + +image_load dome_argb32.png the_pixmap +image_convertToFormat the_pixmap the_pixmap ARGB32_Premultiplied + +begin_block draw_stuff + save + image_convertToFormat the_pixmap converted ARGB32_Premultiplied + drawImage converted 0 0 + translate 0 110 + + image_convertToFormat the_pixmap converted ARGB32 + drawImage converted 0 0 + translate 0 110 + + image_convertToFormat the_pixmap converted RGB32 + drawImage converted 0 0 + translate 0 110 + + image_convertToFormat the_pixmap converted Indexed8 + drawImage converted 0 0 + translate 0 110 + + image_convertToFormat the_pixmap converted MonoLSB + drawImage converted 0 0 + translate 0 110 + + image_convertToFormat the_pixmap converted Mono + drawImage converted 0 0 + translate 0 110 + restore +end_block + + +image_load dome_argb32.png the_pixmap +translate 110 0 +repeat_block draw_stuff + + +image_load dome_rgb32.png the_pixmap +translate 110 0 +repeat_block draw_stuff + +image_load dome_indexed.png the_pixmap +translate 110 0 +repeat_block draw_stuff + + +image_load dome_mono.png the_pixmap +translate 110 0 +repeat_block draw_stuff + +image_load dome_mono_palette.png the_pixmap +translate 110 0 +repeat_block draw_stuff + +image_load dome_indexed_mask.png the_pixmap +translate 110 0 +repeat_block draw_stuff + + +# helpful texts +resetMatrix +setPen black + +drawText 10 670 "ARGB32_PM" +drawText 120 670 "ARGB32" +drawText 230 670 "RGB32" +drawText 340 670 "Indexed" +drawText 450 670 "Mono" +drawText 560 670 "Mono w/lut" +drawText 670 670 "Indexed w/mask" + +drawText 770 50 "ARGB32_PM" +drawText 770 160 "ARGB32" +drawText 770 270 "RGB32" +drawText 770 380 "Indexed" +drawText 770 490 "MonoLSB" +drawText 770 600 "Mono"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/images.qps b/tests/auto/lancelot/scripts/images.qps new file mode 100644 index 0000000..3f89240 --- /dev/null +++ b/tests/auto/lancelot/scripts/images.qps @@ -0,0 +1,106 @@ +# Version: 1 +# CheckVsReference: 5% + + +setRenderHint Antialiasing + +setPen #00ff00 + +image_load dome_argb32.png the_image +begin_block draw_stuff + +save + + # standard draw + drawImage the_image 0 0 + + # sub recting + translate 120 0 + drawImage the_image 0 0 40 40 0 0 40 40 + drawImage the_image 60 0 40 40 60 0 40 40 + drawImage the_image 0 60 40 40 0 60 40 40 + drawImage the_image 60 60 40 40 60 60 40 40 + drawImage the_image 0 40 40 20 0 40 40 20 + drawImage the_image 60 40 40 20 60 40 40 20 + drawImage the_image 40 0 20 100 40 0 20 100 + + # subrecting w/scale + translate 120 0 + drawImage the_image 0 0 50 50 0 0 25 25 + drawImage the_image 50 0 50 50 25 0 25 25 + drawImage the_image 0 50 50 50 0 25 25 25 + drawImage the_image 50 50 50 50 25 25 25 25 + + # subrecting w/scale & smooth xform + translate 120 0 + setRenderHint SmoothPixmapTransformation + drawImage the_image 0 0 50 50 0 0 25 25 + drawImage the_image 50 0 50 50 25 0 25 25 + drawImage the_image 0 50 50 50 0 25 25 25 + drawImage the_image 50 50 50 50 25 25 25 25 + + + # Rotation w/o smooth xform + translate 120 0 + save + setRenderHint SmoothPixmapTransform off + rotate 10 + drawImage the_image 0 0 + restore + + # Rotation w smooth xform + translate 120 0 + save + setRenderHint SmoothPixmapTransform + rotate 10 + drawImage the_image 0 0 + restore + +restore + +end_block + + +translate 0 120 +image_load dome_rgb32.png the_image +repeat_block draw_stuff + +translate 0 120 +image_load dome_indexed.png the_image +repeat_block draw_stuff + +translate 0 120 +image_load dome_indexed_mask.png the_image +repeat_block draw_stuff + +translate 0 120 +image_load dome_mono.png the_image +repeat_block draw_stuff + + +resetMatrix +translate 700 60 +setPen black +drawText 0 0 "32 bit w/alpha" +translate 0 120 +drawText 0 0 "32 bit w/o alpha" +translate 0 120 +drawText 0 0 "8 bit indexed" +translate 0 120 +drawText 0 0 "8 bit indexed w/mask" +translate 0 120 +drawText 0 0 "1 bit" +resetMatrix +translate 0 600 +drawText 0 0 "normal" +translate 120 0 +drawText 0 0 "subrect" +translate 120 0 +drawText 0 0 "subrect scale" +translate 120 0 +drawText 0 0 "subrect scale smooth" +translate 120 0 +drawText 0 0 "xform" +translate 120 0 +drawText 0 0 "smooth xform" +translate 120 0
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/images2.qps b/tests/auto/lancelot/scripts/images2.qps new file mode 100644 index 0000000..5159abc --- /dev/null +++ b/tests/auto/lancelot/scripts/images2.qps @@ -0,0 +1,145 @@ +# Version: 1 +# CheckVsReference: 5% + +image_load dome_argb32.png the_image +begin_block draw_stuff + +save + # standard draw + drawImage the_image 0 0 + + # flip x + translate 220 0 + scale -1 1 + drawImage the_image 0 0 + scale -1 1 + + # flip y + translate 20 100 + scale 1 -1 + drawImage the_image 0 0 + scale 1 -1 + + # flip x and y + translate 220 0 + scale -1 -1 + drawImage the_image 0 0 + scale -1 -1 + + # flip y and scale + translate 20 10 + save + scale 1 -1.1 + drawImage the_image 0 0 + restore + + # flip y and scale + translate 220 -110 + save + scale -1.1 0.9 + drawImage the_image 0 0 + restore +restore +end_block + +setRenderHint Antialiasing + +resetMatrix +translate 0 120 +repeat_block draw_stuff + +resetMatrix +translate 720 60 +setPen black +drawText 0 0 "aliased" +translate 0 120 +drawText 0 0 "antialiased" +resetMatrix +translate 0 260 +drawText 0 0 "normal" +translate 120 0 +drawText 0 0 "flip x" +translate 120 0 +drawText 0 0 "flip y" +translate 120 0 +drawText 0 0 "flip x and y" +translate 120 0 +drawText 0 0 "flip y and scale" +translate 120 0 +drawText 0 0 "flip x and scale" +translate 120 0 + +setRenderHint SmoothPixmapTransform + +resetMatrix +translate 20 300 +drawImage border.png 0 0 100 100 1 1 8 8 +drawText 0 -5 "subrect color bleeding" +translate 0 120 +drawImage border.png 0 0 100 100 0 0 10 10 + +image_load sign.png the_image +resetMatrix +drawText 240 300 "drawImage() with varying sx/sy offsets" +translate 0 10 +drawRect 240 300 50 50 +drawImage the_image 240 300 50 50 20 0 80 80 +drawRect 300 300 50 50 +drawImage the_image 300 300 50 50 -20 0 80 80 +drawRect 240 370 50 50 +drawImage the_image 240 370 50 50 0 20 80 80 +drawRect 300 370 50 50 +drawImage the_image 300 370 50 50 0 -20 80 80 + +pixmap_load sign.png the_pixmap +translate 220 0 +translate 0 -10 +drawText 240 300 "drawPixmap() with varying sx/sy offsets" +translate 0 10 +drawRect 240 300 50 50 +drawPixmap the_pixmap 240 300 50 50 20 0 80 80 +drawRect 300 300 50 50 +drawPixmap the_pixmap 300 300 50 50 -20 0 80 80 +drawRect 240 370 50 50 +drawPixmap the_pixmap 240 370 50 50 0 20 80 80 +drawRect 300 370 50 50 +drawPixmap the_pixmap 300 370 50 50 0 -20 80 80 + + +resetMatrix +translate 0 170 +drawText 240 300 "drawImage() with varying sx/sy offsets" +translate 0 10 +drawRect 240 300 50 50 +drawImage the_image 240 300 50 50 50 0 50 50 +drawRect 300 300 50 50 +drawImage the_image 300 300 50 50 -20 0 50 50 +drawRect 240 370 50 50 +drawImage the_image 240 370 50 50 0 50 50 50 +drawRect 300 370 50 50 +drawImage the_image 300 370 50 50 0 -20 50 50 + +resetMatrix +translate 220 170 +drawText 240 300 "drawPixmap() with varying sx/sy offsets" +translate 0 10 +drawRect 240 300 50 50 +drawPixmap the_pixmap 240 300 50 50 50 0 50 50 +drawRect 300 300 50 50 +drawPixmap the_pixmap 300 300 50 50 -20 0 50 50 +drawRect 240 370 50 50 +drawPixmap the_pixmap 240 370 50 50 0 50 50 50 +drawRect 300 370 50 50 +drawPixmap the_pixmap 300 370 50 50 0 -20 50 50 + +resetMatrix +drawText 10 620 "drawImage/Pixmap() with negative x/y and sx/sy" +setPen red + +translate 20 640 +drawImage the_image -10 -10 -1 -1 -10 -10 0 0 +drawRect 0 0 80 80 + +translate 100 0 +drawPixmap the_pixmap -10 -10 -1 -1 -10 -10 0 0 +drawRect 0 0 80 80 diff --git a/tests/auto/lancelot/scripts/join_cap_styles.qps b/tests/auto/lancelot/scripts/join_cap_styles.qps new file mode 100644 index 0000000..ed823f5 --- /dev/null +++ b/tests/auto/lancelot/scripts/join_cap_styles.qps @@ -0,0 +1,63 @@ +# Version: 1 +# CheckVsReference: 5% + + +setRenderHint Antialiasing + +path_moveTo p 20 20 +path_cubicTo p 100 20 100 180 180 100 +path_lineTo p 20 180 +path_lineTo p 180 20 + +setPen black 20 solidline roundcap roundjoin +drawPath p +setPen red +drawPath p + +translate 200 0 +setPen black 20 solidline roundcap miterjoin +drawPath p +setPen red +drawPath p + +translate 200 0 +setPen black 20 solidline roundcap beveljoin +drawPath p +setPen red +drawPath p + +translate -400 200 +setPen black 20 solidline squarecap roundjoin +drawPath p +setPen red +drawPath p + +translate 200 0 +setPen black 20 solidline squarecap miterjoin +drawPath p +setPen red +drawPath p + +translate 200 0 +setPen black 20 solidline squarecap beveljoin +drawPath p +setPen red +drawPath p + +translate -400 200 +setPen black 20 solidline flatcap roundjoin +drawPath p +setPen red +drawPath p + +translate 200 0 +setPen black 20 solidline flatcap miterjoin +drawPath p +setPen red +drawPath p + +translate 200 0 +setPen black 20 solidline flatcap beveljoin +drawPath p +setPen red +drawPath p
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/join_cap_styles_duplicate_control_points.qps b/tests/auto/lancelot/scripts/join_cap_styles_duplicate_control_points.qps new file mode 100644 index 0000000..b463014 --- /dev/null +++ b/tests/auto/lancelot/scripts/join_cap_styles_duplicate_control_points.qps @@ -0,0 +1,68 @@ +# Version: 1 +# CheckVsReference: 1% (0 0 600 650) + + +setRenderHint Antialiasing + +path_moveTo p 40 70 +path_lineTo p 20 70 +path_cubicTo p 20 70 40 20 80 80 + +path_moveTo p 20 120 +path_cubicTo p 50 60 80 110 80 110 +path_lineTo p 60 110 + +scale 2 2 + +setPen black 10 solidline roundcap roundjoin +drawPath p +setPen red +drawPath p + +translate 100 0 +setPen black 10 solidline roundcap miterjoin +drawPath p +setPen red +drawPath p + +translate 100 0 +setPen black 10 solidline roundcap beveljoin +drawPath p +setPen red +drawPath p + +translate -200 100 +setPen black 10 solidline squarecap roundjoin +drawPath p +setPen red +drawPath p + +translate 100 0 +setPen black 10 solidline squarecap miterjoin +drawPath p +setPen red +drawPath p + +translate 100 0 +setPen black 10 solidline squarecap beveljoin +drawPath p +setPen red +drawPath p + +translate -200 100 +setPen black 10 solidline flatcap roundjoin +drawPath p +setPen red +drawPath p + +translate 100 0 +setPen black 10 solidline flatcap miterjoin +drawPath p +setPen red +drawPath p + +translate 100 0 +setPen black 10 solidline flatcap beveljoin +drawPath p +setPen red +drawPath p
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/linear_gradients.qps b/tests/auto/lancelot/scripts/linear_gradients.qps new file mode 100644 index 0000000..b1b8dd6 --- /dev/null +++ b/tests/auto/lancelot/scripts/linear_gradients.qps @@ -0,0 +1,144 @@ +# Version: 1 +# CheckVsReference: 2% (0 0 600 750) + +path_addRect path 400 0 80 80 +path_addEllipse path 440 40 60 60 + +setRenderHint Antialiasing + +setPen black + +begin_block gradients +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 1 cyan + +gradient_setSpread PadSpread +gradient_setLinear 20 20 70 70 +drawRect 0 0 100 100 + +gradient_setSpread ReflectSpread +gradient_setLinear 120 20 170 70 +drawEllipse 100 0 100 100 + +gradient_setSpread RepeatSpread +gradient_setLinear 220 20 270 70 +drawRoundRect 200 0 100 100 + +gradient_clearStops +gradient_appendStop 0 3f7f7fff +gradient_appendStop 0.5 dfdfffff +gradient_appendStop 1 7f00007f + +gradient_setSpread PadSpread +gradient_setLinear 320 20 340 40 +drawPolygon [300 0 390 0 350 99] + +gradient_setSpread ReflectSpread +gradient_setLinear 420 20 440 40 +drawPath path + +gradient_setSpread RepeatSpread +gradient_setLinear 520 20 540 40 +drawPie 500 0 100 100 720 4320 +end_block + +translate 0 100 +scale 1 2 +repeat_block gradients + +resetMatrix +translate 0 300 +brushTranslate 30 0 +brushScale 0.9 0.9 +brushRotate 20 +repeat_block gradients + +# Vertical gradient tests +resetMatrix +setBrush noBrush +translate 0 400 + +begin_block vertical_gradients +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 1 cyan + +gradient_setSpread PadSpread +gradient_setLinear 20 20 20 70 +drawRect 0 0 100 100 + +gradient_setSpread ReflectSpread +gradient_setLinear 120 20 120 70 +drawEllipse 100 0 100 100 + +gradient_setSpread RepeatSpread +gradient_setLinear 220 20 220 70 +drawRoundRect 200 0 100 100 + +gradient_clearStops +gradient_appendStop 0 3f7f7fff +gradient_appendStop 0.5 dfdfffff +gradient_appendStop 1 7f00007f + +gradient_setSpread PadSpread +gradient_setLinear 320 20 320 40 +drawPolygon [300 0 390 0 350 99] + +gradient_setSpread ReflectSpread +gradient_setLinear 420 20 420 40 +drawPath path + +gradient_setSpread RepeatSpread +gradient_setLinear 520 20 520 40 +drawPie 500 0 100 100 720 4320 +end_block + +translate 0 100 +scale 1 1.5 +repeat_block vertical_gradients + +resetMatrix +translate 0 650 +brushTranslate 30 0 +brushScale 0.9 0.9 +brushRotate 20 +repeat_block vertical_gradients + +# Some helpful info perhaps? +resetMatrix +setPen black +# gradient line indicators +drawLine 20 20 70 70 +drawLine 120 20 170 70 +drawLine 220 20 270 70 +drawLine 320 20 340 40 +drawLine 420 20 440 40 +drawLine 520 20 540 40 + +drawLine 20 140 70 240 +drawLine 120 140 170 240 +drawLine 220 140 270 240 +drawLine 320 140 340 180 +drawLine 420 140 440 180 +drawLine 520 140 540 180 + +drawText 610 50 "No XForm" +drawText 610 200 "scale 1x2" +drawText 610 350 "brush transform" +drawText 610 450 "vertical brush" +drawText 610 570 "vertical brush scale 1x1.5" +drawText 610 700 "vertical brush transform" + +drawText 10 780 "Pad" +drawText 110 780 "Reflect" +drawText 210 780 "Repeat" +drawText 310 780 "Pad w/alpha" +drawText 410 780 "Reflect w/alpha" +drawText 510 780 "Repeat w/alpha"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/linear_gradients_perspectives.qps b/tests/auto/lancelot/scripts/linear_gradients_perspectives.qps new file mode 100644 index 0000000..3ea39fb --- /dev/null +++ b/tests/auto/lancelot/scripts/linear_gradients_perspectives.qps @@ -0,0 +1,62 @@ +# Version: 1 + + +setRenderHint Antialiasing + +setPen #00ff00 + +translate 10 10 +# standard draw +begin_block gradient +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 1 cyan + +gradient_setSpread PadSpread +gradient_setLinear 10 10 290 290 +drawRect 0 0 300 300 +end_block gradient + +# Rotation w/o smooth xform +save +translate 350 0 +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 50 0 200 300 300 300 0 + repeat_block gradient +restore +restore + +translate 0 320 + +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 0 100 300 200 300 300 0 + repeat_block gradient +restore + +save +translate 350 0 +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 0 0 300 300 250 300 50 + repeat_block gradient +restore +restore + + +resetMatrix +setPen black +translate 125 20 +drawText 0 0 "No transform" +translate 350 0 +drawText 0 0 "Left Tilted" +resetMatrix +translate 125 350 +drawText 0 0 "Bottom Tilted" +translate 350 0 +drawText 0 0 "Right Tilted" +translate 120 0
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/linear_resolving_gradients.qps b/tests/auto/lancelot/scripts/linear_resolving_gradients.qps new file mode 100644 index 0000000..779760c --- /dev/null +++ b/tests/auto/lancelot/scripts/linear_resolving_gradients.qps @@ -0,0 +1,66 @@ +# Version: 2 +# CheckVsReference: 2% (0 0 500 400) + +setRenderHint Antialiasing + +setPen black + +begin_block gradients +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 1 cyan + +gradient_setSpread PadSpread +gradient_setCoordinateMode ObjectBoundingMode +gradient_setLinear 0.2 0.2 0.7 0.7 +drawRect 0 0 100 100 + +gradient_setSpread ReflectSpread +gradient_setLinear 0.2 0.2 0.7 0.7 +drawEllipse 100 0 100 100 + +gradient_setSpread RepeatSpread +gradient_setLinear 0.2 0.2 0.7 0.7 +drawRoundRect 200 0 100 100 + +gradient_clearStops +gradient_appendStop 0 3f7f7fff +gradient_appendStop 0.5 dfdfffff +gradient_appendStop 1 7f00007f + +gradient_setSpread PadSpread +gradient_setLinear 0.2 0.2 0.8 0.4 +drawPolygon [300 0 400 0 350 100] + +gradient_setSpread RepeatSpread +gradient_setLinear 0.2 0.2 0.4 0.4 +drawPie 400 0 100 100 0 4320 +end_block + +translate 0 100 +scale 1 2 +repeat_block gradients + +resetMatrix +translate 0 300 +brushTranslate 30 0 +brushScale 0.9 0.9 +brushRotate 20 +repeat_block gradients + +# Some helpful info perhaps? +resetMatrix +setPen black + +drawText 510 50 "No XForm" +drawText 510 200 "scale 1x2" +drawText 510 350 "brush transform" + +drawText 10 450 "Pad" +drawText 110 450 "Reflect" +drawText 210 450 "Repeat" +drawText 310 450 "Pad w/alpha" +drawText 410 450 "Repeat w/alpha"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/lineconsistency.qps b/tests/auto/lancelot/scripts/lineconsistency.qps new file mode 100644 index 0000000..0b40577 --- /dev/null +++ b/tests/auto/lancelot/scripts/lineconsistency.qps @@ -0,0 +1,72 @@ +# Version: 1 + +begin_block draw +setPen red +drawPolygon [1.1 1 3.3 30.6 23.1 39.2 38.9 6.5] +setPen black +drawLine 1.1 1 3.3 30.6 +drawLine 3.3 30.6 23.1 39.2 +drawLine 23.1 39.2 38.9 6.5 +drawLine 38.9 6.5 1.1 1 +end_block draw +drawText 0 60 "0.0 aligned" +translate 0.1 80.1 +repeat_block draw +drawText 0 60 "0.1 aligned" +translate 0.1 80.1 +repeat_block draw +drawText 0 60 "0.2 aligned" +translate 0.1 80.1 +repeat_block draw +drawText 0 60 "0.3 aligned" +translate 0.1 80.1 +repeat_block draw +drawText 0 60 "0.4 aligned" +translate 0.1 80.1 +repeat_block draw +drawText 0 60 "0.5 aligned" +translate 0.1 80.1 +repeat_block draw +drawText 0 60 "0.6 aligned" +translate 0.1 80.1 +repeat_block draw +drawText 0 60 "0.7 aligned" +translate 0.1 80.1 +repeat_block draw +drawText 0 60 "0.8 aligned" +translate 0.1 80.1 +repeat_block draw +drawText 0 60 "0.9 aligned" + +resetMatrix +translate 100 0 +setPen black +drawText 0 20 "Line and text, 0.0 aligned" +drawLine 0 21 160 21 +translate 0 40.1 +drawText 0 20 "Line and text, 0.1 aligned" +drawLine 0 21 160 21 +translate 0 40.1 +drawText 0 20 "Line and text, 0.2 aligned" +drawLine 0 21 160 21 +translate 0 40.1 +drawText 0 20 "Line and text, 0.3 aligned" +drawLine 0 21 160 21 +translate 0 40.1 +drawText 0 20 "Line and text, 0.4 aligned" +drawLine 0 21 160 21 +translate 0 40.1 +drawText 0 20 "Line and text, 0.5 aligned" +drawLine 0 21 160 21 +translate 0 40.1 +drawText 0 20 "Line and text, 0.6 aligned" +drawLine 0 21 160 21 +translate 0 40.1 +drawText 0 20 "Line and text, 0.7 aligned" +drawLine 0 21 160 21 +translate 0 40.1 +drawText 0 20 "Line and text, 0.8 aligned" +drawLine 0 21 160 21 +translate 0 40.1 +drawText 0 20 "Line and text, 0.9 aligned" +drawLine 0 21 160 21
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/linedashes.qps b/tests/auto/lancelot/scripts/linedashes.qps new file mode 100644 index 0000000..ee7d18b --- /dev/null +++ b/tests/auto/lancelot/scripts/linedashes.qps @@ -0,0 +1,94 @@ +# Version: 1 + +translate 10 10 + +setPen 0xffff0000 0 solidline squarecap +translate 50 50 +begin_block draw_lines + save + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + restore +end_block + +setPen 0xffff0000 0 dotline squarecap +translate 100 0 +repeat_block draw_lines +setPen 0xffff0000 0 dashdotline squarecap +translate 100 0 +repeat_block draw_lines +setPen 0xffff0000 0 dashdotdotline squarecap +translate 100 0 +repeat_block draw_lines +setPen 0xffff0000 0 dashline squarecap +translate 100 0 +repeat_block draw_lines
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/linedashes2.qps b/tests/auto/lancelot/scripts/linedashes2.qps new file mode 100644 index 0000000..1dc4fd3 --- /dev/null +++ b/tests/auto/lancelot/scripts/linedashes2.qps @@ -0,0 +1,154 @@ +# Version: 1 +# CheckVsReference: 5% (0 0 800 800) + +translate -30 10 + +setPen 0xffff0000 0 dashline squarecap +pen_setDashPattern [10 5] + +save +translate 100 100 +begin_block lines +drawLine 100 100 200 100 +drawLine 100 100 200 200 +drawLine 100 100 100 200 +end_block + +setPen 0xffff0000 2 dashline squarecap +translate 150 0 +repeat_block lines +restore + +save +save +begin_block horizontal +drawLine 0 0 50 0 +drawLine 3 10 53 10 +drawLine 6 20 56 20 +drawLine 9 30 59 30 + +translate 0 50 + +drawLine 0 0 50 5 +drawLine 3 10 53 15 +drawLine 6 20 56 25 +drawLine 9 30 59 35 + +translate 0 50 + +drawLine 0 0 50 -5 +drawLine 3 10 53 5 +drawLine 6 20 56 15 +drawLine 9 30 59 25 +end_block +restore + +save +translate 80 0 +repeat_block horizontal +restore +save +translate 800 0 +repeat_block horizontal +restore + +translate 180 -40 +save +begin_block vertical +drawLine 0 0 0 50 +drawLine 10 3 10 53 +drawLine 20 6 20 56 +drawLine 30 9 30 59 + +translate 50 0 + +drawLine 0 0 5 50 +drawLine 10 3 15 53 +drawLine 20 6 25 56 +drawLine 30 9 35 59 + +translate 50 0 + +drawLine 0 0 -5 50 +drawLine 10 3 5 53 +drawLine 20 6 15 56 +drawLine 30 9 25 59 +end_block +restore + +save +translate 0 80 +repeat_block vertical +restore +translate 0 800 +repeat_block vertical +restore + +translate 0 200 + +setPen 0xffff0000 2 dashline squarecap +save +repeat_block horizontal +restore +save +translate 80 0 +repeat_block horizontal +restore +save +translate 780 0 +repeat_block horizontal +restore + +translate 360 -240 +save +repeat_block vertical +restore +save +translate 0 80 +repeat_block vertical +restore +translate 0 780 +repeat_block vertical + +resetMatrix +translate 40 400 +setPen 0xffff0000 5 dashdotline flatcap +pen_setDashPattern [1 1 4 1 1 4] +pen_setDashOffset -4 +drawLine 0 0 300 0 +translate 0 8 +pen_setDashOffset -2 +drawLine 0 0 300 0 +translate 0 8 +pen_setDashOffset 0 +drawLine 0 0 300 0 +translate 0 8 +pen_setDashOffset 2 +drawLine 0 0 300 0 +translate 0 8 +pen_setDashOffset 4 +drawLine 0 0 300 0 +translate 0 8 +pen_setDashOffset 6 +drawLine 0 0 300 0 +translate 0 8 +pen_setDashOffset 8 +drawLine 0 0 300 0 +translate 0 8 +pen_setDashOffset 10 +drawLine 0 0 300 0 +translate 0 8 +pen_setDashOffset 12 +drawLine 0 0 300 0 +translate 0 8 +pen_setDashOffset 14 +drawLine 0 0 300 0 +translate 0 8 +pen_setDashOffset 16 +drawLine 0 0 300 0 + +resetMatrix +setPen black 3 dashdotline +pen_setCosmetic true +translate 0 -150 +drawLine 500 160 500 410
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/linedashes2_aa.qps b/tests/auto/lancelot/scripts/linedashes2_aa.qps new file mode 100644 index 0000000..c818ab6 --- /dev/null +++ b/tests/auto/lancelot/scripts/linedashes2_aa.qps @@ -0,0 +1,5 @@ +# Version: 1 +# CheckVsReference: 1% (0 0 800 800) + +setRenderHint LineAntialiasing +import "linedashes2.qps"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/lines.qps b/tests/auto/lancelot/scripts/lines.qps new file mode 100644 index 0000000..c0daffb --- /dev/null +++ b/tests/auto/lancelot/scripts/lines.qps @@ -0,0 +1,558 @@ +# Version: 1 +# CheckVsReference: 5% (0 0 310 425) + + +translate 10 10 + +begin_block draw_lines + save + translate 50 50 + + save + setPen 0x7fff0000 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + restore + + # and then draw the lines the other direction + save + setPen 0x7f0000ff + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + rotate 10 + drawLine 50 0 10 0 + restore + + # and now with a clip + save + setClipRect -30 -30 60 60 + setPen 0x7f00ff00 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + rotate 10 + drawLine 10 0 50 0 + restore + + restore +end_block + +save + translate 100 0 + scale 2 2 + repeat_block draw_lines +restore + +translate 0 10 + +save + translate 0 200 + setRenderHint Antialiasing + repeat_block draw_lines +restore + +save + translate 100 200 + scale 2 2 + setRenderHint Antialiasing + repeat_block draw_lines +restore + +translate 320 0 + +setPen black 0 solidline squarecap + +begin_block lines + +# 0 -> 45 degress +drawLine 100 100 200 90 +drawLine 100 100 200 80 +drawLine 100 100 200 70 +drawLine 100 100 200 60 +drawLine 100 100 200 50 +drawLine 100 100 200 40 +drawLine 100 100 200 30 +drawLine 100 100 200 20 +drawLine 100 100 200 10 + +# 45 +drawLine 100 100 200 0 + +# 45 -> 90 +drawLine 100 100 190 0 +drawLine 100 100 180 0 +drawLine 100 100 170 0 +drawLine 100 100 160 0 +drawLine 100 100 150 0 +drawLine 100 100 140 0 +drawLine 100 100 130 0 +drawLine 100 100 120 0 +drawLine 100 100 110 0 + +# 90 +drawLine 100 100 100 0 + +# 90 -> 135 +drawLine 100 100 90 0 +drawLine 100 100 80 0 +drawLine 100 100 70 0 +drawLine 100 100 60 0 +drawLine 100 100 50 0 +drawLine 100 100 40 0 +drawLine 100 100 30 0 +drawLine 100 100 20 0 +drawLine 100 100 10 0 + +# 135 +drawLine 100 100 0 0 + +# 135 -> 180 degress +drawLine 100 100 0 10 +drawLine 100 100 0 20 +drawLine 100 100 0 30 +drawLine 100 100 0 40 +drawLine 100 100 0 50 +drawLine 100 100 0 60 +drawLine 100 100 0 70 +drawLine 100 100 0 80 +drawLine 100 100 0 90 + +# 180 +drawLine 100 100 0 100 + +# 180 -> 225 +drawLine 100 100 0 110 +drawLine 100 100 0 120 +drawLine 100 100 0 130 +drawLine 100 100 0 140 +drawLine 100 100 0 150 +drawLine 100 100 0 160 +drawLine 100 100 0 170 +drawLine 100 100 0 180 +drawLine 100 100 0 190 + +# 225 +drawLine 100 100 0 200 + +# 225 -> 270 +drawLine 100 100 10 200 +drawLine 100 100 20 200 +drawLine 100 100 30 200 +drawLine 100 100 40 200 +drawLine 100 100 50 200 +drawLine 100 100 60 200 +drawLine 100 100 70 200 +drawLine 100 100 80 200 +drawLine 100 100 90 200 + +# 270 +drawLine 100 100 100 200 + +# 270 -> 315 degrees +drawLine 100 100 110 200 +drawLine 100 100 120 200 +drawLine 100 100 130 200 +drawLine 100 100 140 200 +drawLine 100 100 150 200 +drawLine 100 100 160 200 +drawLine 100 100 170 200 +drawLine 100 100 180 200 +drawLine 100 100 190 200 + +# 315 +drawLine 100 100 200 200 + +# 315 -> 360 degress +drawLine 100 100 200 100 +drawLine 100 100 200 110 +drawLine 100 100 200 120 +drawLine 100 100 200 130 +drawLine 100 100 200 140 +drawLine 100 100 200 150 +drawLine 100 100 200 160 +drawLine 100 100 200 170 +drawLine 100 100 200 180 +drawLine 100 100 200 190 + +end_block + + +setRenderHint Antialiasing +setPen 0x7fff0000 +translate 0.5 0.5 +repeat_block lines + +setPen 0x000000 8 +translate 20 240 +drawText 0 0 "Steep slopes:" + +translate 0 10 + +drawLine 0 0 -8 400 +translate 20 0 +drawLine 0 0 -7 400 +translate 20 0 +drawLine 0 0 -6 400 +translate 20 0 +drawLine 0 0 -5 400 +translate 20 0 +drawLine 0 0 -4 400 +translate 20 0 +drawLine 0 0 -3 400 +translate 20 0 +drawLine 0 0 -2 400 +translate 20 0 +drawLine 0 0 -1 400 +translate 20 0 +drawLine 0 0 0 400 +translate 20 0 +drawLine 0 0 1 400 +translate 20 0 +drawLine 0 0 2 400 +translate 20 0 +drawLine 0 0 3 400 +translate 20 0 +drawLine 0 0 4 400 +translate 20 0 +drawLine 0 0 5 400 +translate 20 0 +drawLine 0 0 6 400 +translate 20 0 +drawLine 0 0 7 400 +translate 20 0 +drawLine 0 0 8 400 + +resetMatrix + +translate 20 450 + +drawText 0 0 "Zero length lines:" + +translate 0 20 +drawText 100 10 "Square cap" +save +begin_block points +setPen 0x000000 1 solidline squarecap +drawLine 0 0 0 0 +setPen 0x000000 2 solidline squarecap +drawLine 8 0 8 0 +setPen 0x000000 3 solidline squarecap +drawLine 16 0 16 0 +setPen 0x000000 4 solidline squarecap +drawLine 24 0 24 0 +setPen 0x000000 5 solidline squarecap +drawLine 32 0 32 0 +setPen 0x000000 6 solidline squarecap +drawLine 40 0 40 0 +setPen 0x000000 7 solidline squarecap +drawLine 48 0 48 0 +setPen 0x000000 8 solidline squarecap +drawLine 57 0 57 0 +setPen 0x000000 9 solidline squarecap +drawLine 67 0 67 0 +setPen 0x000000 10 solidline squarecap +drawLine 78 0 78 0 +end_block points +restore + +translate 0 12 +setRenderHint Antialiasing off +repeat_block points +setRenderHint Antialiasing + +translate 0 20 +drawText 100 10 "Round cap" +save +begin_block points2 +setPen 0x000000 1 solidline roundcap +drawLine 0 0 0 0 +setPen 0x000000 2 solidline roundcap +drawLine 8 0 8 0 +setPen 0x000000 3 solidline roundcap +drawLine 16 0 16 0 +setPen 0x000000 4 solidline roundcap +drawLine 24 0 24 0 +setPen 0x000000 5 solidline roundcap +drawLine 32 0 32 0 +setPen 0x000000 6 solidline roundcap +drawLine 40 0 40 0 +setPen 0x000000 7 solidline roundcap +drawLine 48 0 48 0 +setPen 0x000000 8 solidline roundcap +drawLine 57 0 57 0 +setPen 0x000000 9 solidline roundcap +drawLine 67 0 67 0 +setPen 0x000000 10 solidline roundcap +drawLine 78 0 78 0 +end_block points2 +restore + +translate 0 12 +setRenderHint Antialiasing off +repeat_block points2 +setRenderHint Antialiasing + +translate 0 20 +drawText 100 10 "Flat cap" +save +begin_block points3 +setPen 0x000000 1 solidline flatcap +drawLine 0 0 0 0 +setPen 0x000000 2 solidline flatcap +drawLine 8 0 8 0 +setPen 0x000000 3 solidline flatcap +drawLine 16 0 16 0 +setPen 0x000000 4 solidline flatcap +drawLine 24 0 24 0 +setPen 0x000000 5 solidline flatcap +drawLine 32 0 32 0 +setPen 0x000000 6 solidline flatcap +drawLine 40 0 40 0 +setPen 0x000000 7 solidline flatcap +drawLine 48 0 48 0 +setPen 0x000000 8 solidline flatcap +drawLine 57 0 57 0 +setPen 0x000000 9 solidline flatcap +drawLine 67 0 67 0 +setPen 0x000000 10 solidline flatcap +drawLine 78 0 78 0 +end_block points3 +restore + +translate 0 12 +setRenderHint Antialiasing off +repeat_block points3 + +resetMatrix +translate -220 667.226 +drawText 230 -80 "Task 194266 (should see only one line):" +setPen black +drawRect 230.5 -70.5 122 12 +setRenderHint Antialiasing +setPen red +drawLine 236.842105263 -63.775117299 247.368421053 -63.775437504 + +setRenderHint Antialiasing off +resetMatrix +translate 10 640 +setPen black +drawText 0 -10 "Task 207147 (should see two lines):" +drawRect 0.5 0.5 64 64 +setRenderHint Antialiasing +setPen red + +drawLine 4.5 4.5 4.5001 60.5 +drawLine 4.5 4.5 60.5 4.5001 + +setRenderHint Antialiasing off +resetMatrix +translate 10 730 +setPen black +drawText 0 -10 "Task 229459 (should see one diagonal line):" +drawRect 0.5 0.5 64 64 +setPen red 2 solidline flatcap + +setClipRect 2 2 63 63 +drawLine 1.5 1.5 33560000 33560000
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/lines2.qps b/tests/auto/lancelot/scripts/lines2.qps new file mode 100644 index 0000000..af6ad65 --- /dev/null +++ b/tests/auto/lancelot/scripts/lines2.qps @@ -0,0 +1,179 @@ +# Version: 1 +# CheckVsReference: 5% + +translate 10 20 +drawText 0 0 "Thin lines" + +translate 60 70 + +save +begin_block lines +translate 0 -60 +translate 0 5 +setPen 0x000000 0.05 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.1 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.15 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.2 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.25 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.3 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.35 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.2 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.25 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.5 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.55 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.6 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.65 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.7 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.75 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.8 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.85 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.9 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 0.95 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.05 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.1 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.15 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.2 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.25 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.3 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.35 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.2 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.25 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.5 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.55 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.6 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.65 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.7 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.75 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.8 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.85 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.9 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 1.95 +drawLine -60 -2 60 2 +translate 0 5 +setPen 0x000000 2 +drawLine -60 -2 60 2 +end_block +restore + +save +translate 150 0 +scale -1 1 +repeat_block lines +restore + +save +translate 80 220 +rotate 90 +repeat_block lines +restore + +save +translate 80 370 +rotate 90 +scale -1 1 +repeat_block lines +restore + +setRenderHint Antialiasing + +translate 300 0 + +save +repeat_block lines +restore + +save +translate 150 0 +scale -1 1 +repeat_block lines +restore + +save +translate 80 220 +rotate 90 +repeat_block lines +restore + +save +translate 80 370 +rotate 90 +scale -1 1 +repeat_block lines +restore
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/pathfill.qps b/tests/auto/lancelot/scripts/pathfill.qps new file mode 100644 index 0000000..821b468 --- /dev/null +++ b/tests/auto/lancelot/scripts/pathfill.qps @@ -0,0 +1,38 @@ +# Version: 1 +# CheckVsReference: 1% (0 0 850 420) + +setPen afff0000 4 + +setBrush dome_rgb32.png +drawEllipse 10 10 200 200 + +setBrush dome_argb32.png +drawEllipse 220 10 200 200 + +setPen NoPen + +setBrush dome_rgb32.png +drawEllipse 10 220 200 200 + +setBrush dome_argb32.png +drawEllipse 220 220 200 200 + +setBrushOrigin -30 -30 + +setPen afff0000 4 +setBrush dome_rgb32.png +drawEllipse 430 10 200 200 + +setBrush dome_argb32.png +drawEllipse 640 10 200 200 + +setPen NoPen +setBrush dome_rgb32.png +drawEllipse 430 220 200 200 + +setBrush dome_argb32.png +drawEllipse 640 220 200 200 + +setPen black +drawText 150 450 "No offset RGB/ARGB" +drawText 550 450 "-30 offset RGB/ARGB"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/paths.qps b/tests/auto/lancelot/scripts/paths.qps new file mode 100644 index 0000000..083026e --- /dev/null +++ b/tests/auto/lancelot/scripts/paths.qps @@ -0,0 +1,34 @@ +# Version: 1 + +setPen black +setBrush 7f7fff + +path_moveTo star 50 0 +path_lineTo star 30 90 +path_lineTo star 100 60 +path_lineTo star 0 20 +path_lineTo star 80 100 + +setFont "times" 50 +path_addText text 0 50 "ABCD, 1234, abcd, #¤%&" + +path_addRect rectncircle 0 0 75 75 +path_addEllipse rectncircle 25 25 75 75 +path_setFillRule rectncircle winding + +path_moveTo curve 100 0 +path_cubicTo curve 100 100 50 50 0 100 + +begin_block drawing +drawPath star +translate 100 0 +drawPath rectncircle +translate 100 0 +drawPath curve +translate -200 100 +drawPath text +end_block + +translate 50 100 +rotate 10 +repeat_block drawing diff --git a/tests/auto/lancelot/scripts/paths_aa.qps b/tests/auto/lancelot/scripts/paths_aa.qps new file mode 100644 index 0000000..4812e2f --- /dev/null +++ b/tests/auto/lancelot/scripts/paths_aa.qps @@ -0,0 +1,4 @@ +# Version: 1 + +setRenderHint LineAntialiasing +import "paths.qps" diff --git a/tests/auto/lancelot/scripts/pens.qps b/tests/auto/lancelot/scripts/pens.qps new file mode 100644 index 0000000..c72636d --- /dev/null +++ b/tests/auto/lancelot/scripts/pens.qps @@ -0,0 +1,133 @@ +# Version: 1 +# CheckVsReference: 1% (0 0 800 800) + + +translate 10 10 + +begin_block penstyles +setPen black 0 solidline flatcap +drawLine 0 0 100 0 +setPen black 0 dashline flatcap +drawLine 100 0 100 40 +setPen black 0 dotline flatcap +drawLine 100 40 200 0 +setPen black 0 dashdotline flatcap +drawLine 200 0 300 0 +setPen black 0 dashdotdotline flatcap +drawLine 300 0 400 40 + +translate 0 50 +setPen blue 2 solidline flatcap +drawLine 0 0 100 0 +setPen blue 2 dashline flatcap +drawLine 100 0 100 40 +setPen blue 2 dotline flatcap +drawLine 100 40 200 0 +setPen blue 2 dashdotline flatcap +drawLine 200 0 300 0 +setPen blue 2 dashdotdotline flatcap +drawLine 300 0 400 40 + +translate 0 50 +setPen red 5 solidline flatcap +drawLine 0 0 100 0 +setPen red 5 dashline flatcap +drawLine 100 0 100 40 +setPen red 5 dotline flatcap +drawLine 100 40 200 0 +setPen red 5 dashdotline flatcap +drawLine 200 0 300 0 +setPen red 5 dashdotdotline flatcap +drawLine 300 0 400 40 +end_block + +translate 0 50 +scale 1 2 +repeat_block penstyles + + +# Test cap styles +resetMatrix +translate 420 10 +setPen green 5 dashdotline flatcap +drawLine 0 0 200 0 +setPen green 5 dashdotline roundcap +drawLine 0 20 200 20 +setPen green 5 dashdotline squarecap +drawLine 0 40 200 40 + + +# Test join styles +resetMatrix +translate 420 80 +setBrush nobrush +begin_block joinstyles +setPen orange 10 solidline flatcap miterjoin +drawPolyline [ 0 0 80 0 80 80 0 80 ] + +translate 0 100 +setPen aquamarine 10 solidline squarecap beveljoin +drawPolyline [ 0 0 80 0 80 80 0 80 ] + +translate 0 100 +setPen purple 10 solidline roundcap roundjoin +drawPolyline [ 0 0 80 0 80 80 0 80 ] +end_block + +translate 130 -200 +scale 2 1 +rotate 1 +repeat_block joinstyles + +# transparent lines +resetMatrix +translate 10 400 +setPen #7f000000 +drawLine 0 0 50 0 +setPen #7f000000 1 SolidLine +drawLine 0 10 50 10 +setPen #7f000000 5 SolidLine +drawLine 0 20 50 20 +setPen #7f000000 10 SolidLine +drawLine 0 30 50 30 +setPen #7f000000 +drawLine 0 0 0 50 +setPen #7f000000 1 SolidLine +drawLine 10 0 10 50 +setPen #7f000000 5 SolidLine +drawLine 20 0 20 50 +setPen #7f000000 10 SolidLine +drawLine 30 0 30 50 + +# pen styles +resetMatrix +translate 0 500 +setPen black 0 DashLine +drawLine 20 20 100 20 +translate 0 10 +setPen black 0 DotLine +drawLine 20 20 100 20 +translate 0 10 +setPen black 0 DashDotLine +drawLine 20 20 100 20 +translate 0 10 +setPen black 0 DashDotDotLine +drawLine 20 20 100 20 + +# scaling ellipse +resetMatrix +setPen black 0.008 DashLine +translate 250 550 +rotate 30 +scale 250 250 +drawEllipse -0.4 -0.4 0.8 0.8 + +# scaling path +path_addEllipse star -0.3 -0.3 0.6 0.6 + +resetMatrix +setPen black 0.008 DashLine +translate 250 550 +rotate 30 +scale 250 250 +drawPath star diff --git a/tests/auto/lancelot/scripts/pens_aa.qps b/tests/auto/lancelot/scripts/pens_aa.qps new file mode 100644 index 0000000..066cac3 --- /dev/null +++ b/tests/auto/lancelot/scripts/pens_aa.qps @@ -0,0 +1,6 @@ +# Version: 1 +# CheckVsReference: 1% (0 0 800 800) + +setRenderHint LineAntialiasing + +import "pens.qps"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/pens_cosmetic.qps b/tests/auto/lancelot/scripts/pens_cosmetic.qps new file mode 100644 index 0000000..d1a60d1 --- /dev/null +++ b/tests/auto/lancelot/scripts/pens_cosmetic.qps @@ -0,0 +1,110 @@ +# Version: 1 +# CheckVsReference: 1% (0 0 585 470) + +path_addEllipse path 22 0 7 7 +path_addRect path 25 5 4 4 + +translate 20 20 + +begin_block lines + save + drawLine 0 0 10 10 + drawLine 2 0 10 0 + drawLine 0 2 0 10 + drawPolygon [12 0 20 0 15 10] + drawPath path + drawEllipse 32 0 8 8 + drawPoint 36 4 + + translate 100 0 + save + scale 4 1 + drawLine 0 0 10 10 + drawLine 2 0 10 0 + drawLine 0 2 0 10 + drawPolygon [12 0 20 0 15 10] + drawPath path + drawEllipse 32 0 8 8 + drawPoint 36 4 + restore + + translate 200 0 + save + scale 1 4 + drawLine 0 0 10 10 + drawLine 2 0 10 0 + drawLine 0 2 0 10 + drawPolygon [12 0 20 0 15 10] + drawPath path + drawEllipse 32 0 8 8 + drawPoint 36 4 + restore + + translate 100 0 + save + scale 4 4 + drawLine 0 0 10 10 + drawLine 2 0 10 0 + drawLine 0 2 0 10 + drawPolygon [12 0 20 0 15 10] + drawPath path + drawEllipse 32 0 8 8 + drawPoint 36 4 + restore + restore +end_block + +drawText 580 15 "non-cosmetic, 0-width" +translate 0 50 + +setPen black 2 +repeat_block lines +drawText 580 15 "non-cosmetic, 2-width" + +translate 0 20 +translate 0 50 +setPen black 0 +pen_setCosmetic true +repeat_block lines +drawText 580 15 "cosmetic, 0-width" + +translate 0 50 +setPen black 2 +pen_setCosmetic true +repeat_block lines +drawText 580 15 "cosmetic, 2-width" + + +setRenderHint Antialiasing +translate 0 20 + +translate 0 50 +setPen black 0 +repeat_block lines +drawText 580 15 "non-cosmetic, 0-width" + +translate 0 50 + +setPen black 2 +repeat_block lines +drawText 580 15 "non-cosmetic, 2-width" + +translate 0 20 +translate 0 50 +setPen black 0 +pen_setCosmetic true +repeat_block lines +drawText 580 15 "cosmetic, 0-width" + +translate 0 50 +setPen black 2 +pen_setCosmetic true +repeat_block lines +drawText 580 15 "cosmetic, 2-width" + + +translate 0 70 +drawText 0 0 "scale(1, 1)" +drawText 150 0 "scale(4, 1)" +drawText 300 0 "scale(1, 4)" +drawText 450 0 "scale(4, 4)"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/perspectives.qps b/tests/auto/lancelot/scripts/perspectives.qps new file mode 100644 index 0000000..0b903e5 --- /dev/null +++ b/tests/auto/lancelot/scripts/perspectives.qps @@ -0,0 +1,72 @@ +# Version: 1 + + +setRenderHint Antialiasing + +setPen #00ff00 + +image_load image.png the_image + +translate 10 10 +# standard draw +drawImage the_image 0 0 + +# Rotation w/o smooth xform +save +translate 350 0 +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 50 0 200 300 300 300 0 + drawImage the_image 0 0 +restore +restore + +translate 0 320 + +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 0 100 300 200 300 300 0 + drawImage the_image 0 0 +restore + +save +translate 350 0 +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 0 0 300 300 250 300 50 + drawImage the_image 0 0 +restore +restore + +setRenderHint SmoothPixmapTransform on +setBrush red +setPen black +resetMatrix +translate 100 720 +rotate_y 85 +scale 7 0.01 +drawRect -150 -150 300 300 + +resetMatrix +setBrush gam030.png +setPen black 30 +translate 700 700 +rotate_y -85 +scale 7 0.01 +drawRect -150 -150 300 300 + +resetMatrix +setPen black +translate 125 20 +drawText 0 0 "No transform" +translate 350 0 +drawText 0 0 "Left Tilted" +resetMatrix +translate 125 350 +drawText 0 0 "Bottom Tilted" +translate 350 0 +drawText 0 0 "Right Tilted" +translate 120 0 +resetMatrix +translate 300 760 +drawText 0 0 "Perspective Clipping"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/perspectives2.qps b/tests/auto/lancelot/scripts/perspectives2.qps new file mode 100644 index 0000000..2f6d1d6 --- /dev/null +++ b/tests/auto/lancelot/scripts/perspectives2.qps @@ -0,0 +1,309 @@ +# Version: 1 + +setRenderHint Antialiasing + +image_load zebra.png zebra_png + +image_convertToFormat zebra_png zebra ARGB32_Premultiplied + +translate 75 100 +# standard draw +begin_block row +drawImage zebra -50 -50 + +translate 90 0 +save +rotate_y 50 +drawImage zebra -50 -50 +restore + +translate 65 0 +save +rotate_y 60 +drawImage zebra -50 -50 +restore + +translate 50 0 +save +rotate_y 70 +drawImage zebra -50 -50 +restore + +translate 30 0 +save +rotate_y 80 +drawImage zebra -50 -50 +restore + +translate 24 0 +save +rotate_y 82 +drawImage zebra -50 -50 +restore + +translate 20 0 +save +rotate_y 84 +drawImage zebra -50 -50 +restore + +translate 16 0 +save +rotate_y 86 +drawImage zebra -50 -50 +restore + +translate 12 0 +save +rotate_y 87 +drawImage zebra -50 -50 +restore + +translate 8 0 +save +rotate_y 88 +drawImage zebra -50 -50 +restore + +translate 6 0 +save +rotate_y 89 +drawImage zebra -50 -50 +restore + +translate 6 0 +save +rotate_y 91 +drawImage zebra -50 -50 +restore + +translate 6 0 +save +rotate_y 92 +drawImage zebra -50 -50 +restore + +translate 8 0 +save +rotate_y 93 +drawImage zebra -50 -50 +restore + +translate 12 0 +save +rotate_y 94 +drawImage zebra -50 -50 +restore + +translate 16 0 +save +rotate_y 96 +drawImage zebra -50 -50 +restore + +translate 20 0 +save +rotate_y 98 +drawImage zebra -50 -50 +restore + +translate 24 0 +save +rotate_y 100 +drawImage zebra -50 -50 +restore + +translate 30 0 +save +rotate_y 110 +drawImage zebra -50 -50 +restore + +translate 50 0 +save +rotate_y 120 +drawImage zebra -50 -50 +restore + +translate 65 0 +save +rotate_y 130 +drawImage zebra -50 -50 +restore + +translate 90 0 +save +rotate_y 180 +drawImage zebra -50 -50 +restore +end_block + +resetMatrix +translate 75 280 +setRenderHint SmoothPixmapTransform +repeat_block row + +resetMatrix +setPen black +translate 300 20 +drawText 0 0 "Fast Pixmap Transform" +resetMatrix +translate 300 210 +drawText 0 0 "Smooth Pixmap Transform" + +resetMatrix +translate 0 400 + +image_load dome_argb32.png the_pixmap + +image_convertToFormat the_pixmap dome ARGB32 + +setRenderHint SmoothPixmapTransform false + +translate 75 100 +# standard draw +begin_block row +drawImage dome -50 -50 + +translate 90 0 +save +rotate_y 50 +drawImage dome -50 -50 +restore + +translate 65 0 +save +rotate_y 60 +drawImage dome -50 -50 +restore + +translate 50 0 +save +rotate_y 70 +drawImage dome -50 -50 +restore + +translate 30 0 +save +rotate_y 80 +drawImage dome -50 -50 +restore + +translate 24 0 +save +rotate_y 82 +drawImage dome -50 -50 +restore + +translate 20 0 +save +rotate_y 84 +drawImage dome -50 -50 +restore + +translate 16 0 +save +rotate_y 86 +drawImage dome -50 -50 +restore + +translate 12 0 +save +rotate_y 87 +drawImage dome -50 -50 +restore + +translate 8 0 +save +rotate_y 88 +drawImage dome -50 -50 +restore + +translate 6 0 +save +rotate_y 89 +drawImage dome -50 -50 +restore + +translate 6 0 +save +rotate_y 91 +drawImage dome -50 -50 +restore + +translate 6 0 +save +rotate_y 92 +drawImage dome -50 -50 +restore + +translate 8 0 +save +rotate_y 93 +drawImage dome -50 -50 +restore + +translate 12 0 +save +rotate_y 94 +drawImage dome -50 -50 +restore + +translate 16 0 +save +rotate_y 96 +drawImage dome -50 -50 +restore + +translate 20 0 +save +rotate_y 98 +drawImage dome -50 -50 +restore + +translate 24 0 +save +rotate_y 100 +drawImage dome -50 -50 +restore + +translate 30 0 +save +rotate_y 110 +drawImage dome -50 -50 +restore + +translate 50 0 +save +rotate_y 120 +drawImage dome -50 -50 +restore + +translate 65 0 +save +rotate_y 130 +drawImage dome -50 -50 +restore + +translate 90 0 +save +rotate_y 180 +drawImage dome -50 -50 +restore +end_block + +resetMatrix +translate 0 400 +translate 75 280 +setRenderHint SmoothPixmapTransform +repeat_block row + +resetMatrix +setPen black +translate 0 400 +translate 300 20 +drawText 0 0 "Fast Pixmap Transform" +resetMatrix +translate 0 400 +translate 300 210 +drawText 0 0 "Smooth Pixmap Transform"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/pixmap_rotation.qps b/tests/auto/lancelot/scripts/pixmap_rotation.qps new file mode 100644 index 0000000..2f1ffb5 --- /dev/null +++ b/tests/auto/lancelot/scripts/pixmap_rotation.qps @@ -0,0 +1,30 @@ +# Version: 1 +# CheckVsReference: 0% (0 0 440 220) + +translate 120 120 + +begin_block drawing +save + rotate 90 + drawPixmap solid.png 0 0 + + rotate 90 + drawPixmap solid.png 0 0 + + rotate 90 + drawPixmap solid.png 0 0 + + rotate 90 + drawPixmap solid.png 0 0 +restore +end_block + +resetMatrix + +translate 340 120 +repeat_block drawing + +resetMatrix + +drawText 50 240 "Normal X form" +drawText 270 240 "Smooth xform"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/pixmap_scaling.qps b/tests/auto/lancelot/scripts/pixmap_scaling.qps new file mode 100644 index 0000000..651896f --- /dev/null +++ b/tests/auto/lancelot/scripts/pixmap_scaling.qps @@ -0,0 +1,224 @@ +# Version: 1 +# CheckVsReference: 0% (0 30 600 70) +# CheckVsReference: 0% (290 130 280 60) +# CheckVsReference: 0% (0 180 250 90) + +# Hurra! Force line endings (?) + +translate 5 25 +setFont "arial" 8 + +save + drawText 15 0 "opaque image" + translate 50 50 + save + translate 1 1 + scale 20 20 + drawImage solid2x2.png 0 0 + restore + save + translate -1 1 + scale -20 20 + drawImage solid2x2.png 0 0 + restore + save + translate 1 -1 + scale 20 -20 + drawImage solid2x2.png 0 0 + restore + save + translate -1 -1 + scale -20 -20 + drawImage solid2x2.png 0 0 + restore + + +restore + +save + translate 150 0 + drawText 15 0 "alpha image" + translate 50 50 + save + translate 1 1 + scale 20 20 + drawImage alpha2x2.png 0 0 + restore + save + translate -1 1 + scale -20 20 + drawImage alpha2x2.png 0 0 + restore + save + translate 1 -1 + scale 20 -20 + drawImage alpha2x2.png 0 0 + restore + save + translate -1 -1 + scale -20 -20 + drawImage alpha2x2.png 0 0 + restore +restore + + +save + translate 0 150 + drawText 15 0 "solid pixmap" + translate 50 50 + save + translate 1 1 + scale 20 20 + drawPixmap solid2x2.png 0 0 + restore + save + translate -1 1 + scale -20 20 + drawPixmap solid2x2.png 0 0 + restore + save + translate 1 -1 + scale 20 -20 + drawPixmap solid2x2.png 0 0 + restore + save + translate -1 -1 + scale -20 -20 + drawPixmap solid2x2.png 0 0 + restore +restore + + +save + translate 150 150 + drawText 15 0 "alpha pixmap" + translate 50 50 + save + translate 1 1 + scale 20 20 + drawPixmap alpha2x2.png 0 0 + restore + save + translate -1 1 + scale -20 20 + drawPixmap alpha2x2.png 0 0 + restore + save + translate 1 -1 + scale 20 -20 + drawPixmap alpha2x2.png 0 0 + restore + save + translate -1 -1 + scale -20 -20 + drawPixmap alpha2x2.png 0 0 + restore +restore + + +save + translate 300 10 + save + drawText 0 -10 "subrect solid image" + drawImage solid2x2.png 0 0 50 5 0 0.0 2 0.2 + drawImage solid2x2.png 0 5 50 5 0 0.2 2 0.2 + drawImage solid2x2.png 0 10 50 5 0 0.4 2 0.2 + drawImage solid2x2.png 0 15 50 5 0 0.6 2 0.2 + drawImage solid2x2.png 0 20 50 5 0 0.8 2 0.2 + drawImage solid2x2.png 0 25 50 5 0 1.0 2 0.2 + drawImage solid2x2.png 0 30 50 5 0 1.2 2 0.2 + drawImage solid2x2.png 0 35 50 5 0 1.4 2 0.2 + drawImage solid2x2.png 0 40 50 5 0 1.6 2 0.2 + drawImage solid2x2.png 0 45 50 5 0 1.8 2 0.2 + translate 60 0 + drawImage solid2x2.png 0 0 5 50 0.0 0 0.2 2 + drawImage solid2x2.png 5 0 5 50 0.2 0 0.2 2 + drawImage solid2x2.png 10 0 5 50 0.4 0 0.2 2 + drawImage solid2x2.png 15 0 5 50 0.6 0 0.2 2 + drawImage solid2x2.png 20 0 5 50 0.8 0 0.2 2 + drawImage solid2x2.png 25 0 5 50 1.0 0 0.2 2 + drawImage solid2x2.png 30 0 5 50 1.2 0 0.2 2 + drawImage solid2x2.png 35 0 5 50 1.4 0 0.2 2 + drawImage solid2x2.png 40 0 5 50 1.6 0 0.2 2 + drawImage solid2x2.png 45 0 5 50 1.8 0 0.2 2 + restore + + save + translate 150 0 + drawText 0 -10 "subrect solid image" + drawImage alpha2x2.png 0 0 50 5 0 0.0 2 0.2 + drawImage alpha2x2.png 0 5 50 5 0 0.2 2 0.2 + drawImage alpha2x2.png 0 10 50 5 0 0.4 2 0.2 + drawImage alpha2x2.png 0 15 50 5 0 0.6 2 0.2 + drawImage alpha2x2.png 0 20 50 5 0 0.8 2 0.2 + drawImage alpha2x2.png 0 25 50 5 0 1.0 2 0.2 + drawImage alpha2x2.png 0 30 50 5 0 1.2 2 0.2 + drawImage alpha2x2.png 0 35 50 5 0 1.4 2 0.2 + drawImage alpha2x2.png 0 40 50 5 0 1.6 2 0.2 + drawImage alpha2x2.png 0 45 50 5 0 1.8 2 0.2 + translate 60 0 + drawImage alpha2x2.png 0 0 5 50 0.0 0 0.2 2 + drawImage alpha2x2.png 5 0 5 50 0.2 0 0.2 2 + drawImage alpha2x2.png 10 0 5 50 0.4 0 0.2 2 + drawImage alpha2x2.png 15 0 5 50 0.6 0 0.2 2 + drawImage alpha2x2.png 20 0 5 50 0.8 0 0.2 2 + drawImage alpha2x2.png 25 0 5 50 1.0 0 0.2 2 + drawImage alpha2x2.png 30 0 5 50 1.2 0 0.2 2 + drawImage alpha2x2.png 35 0 5 50 1.4 0 0.2 2 + drawImage alpha2x2.png 40 0 5 50 1.6 0 0.2 2 + drawImage alpha2x2.png 45 0 5 50 1.8 0 0.2 2 + restore + + save + translate 0 100 + drawText 0 -10 "subrect alpha pixmap" + drawPixmap solid2x2.png 0 0 50 5 0 0.0 2 0.2 + drawPixmap solid2x2.png 0 5 50 5 0 0.2 2 0.2 + drawPixmap solid2x2.png 0 10 50 5 0 0.4 2 0.2 + drawPixmap solid2x2.png 0 15 50 5 0 0.6 2 0.2 + drawPixmap solid2x2.png 0 20 50 5 0 0.8 2 0.2 + drawPixmap solid2x2.png 0 25 50 5 0 1.0 2 0.2 + drawPixmap solid2x2.png 0 30 50 5 0 1.2 2 0.2 + drawPixmap solid2x2.png 0 35 50 5 0 1.4 2 0.2 + drawPixmap solid2x2.png 0 40 50 5 0 1.6 2 0.2 + drawPixmap solid2x2.png 0 45 50 5 0 1.8 2 0.2 + translate 60 0 + drawPixmap solid2x2.png 0 0 5 50 0.0 0 0.2 2 + drawPixmap solid2x2.png 5 0 5 50 0.2 0 0.2 2 + drawPixmap solid2x2.png 10 0 5 50 0.4 0 0.2 2 + drawPixmap solid2x2.png 15 0 5 50 0.6 0 0.2 2 + drawPixmap solid2x2.png 20 0 5 50 0.8 0 0.2 2 + drawPixmap solid2x2.png 25 0 5 50 1.0 0 0.2 2 + drawPixmap solid2x2.png 30 0 5 50 1.2 0 0.2 2 + drawPixmap solid2x2.png 35 0 5 50 1.4 0 0.2 2 + drawPixmap solid2x2.png 40 0 5 50 1.6 0 0.2 2 + drawPixmap solid2x2.png 45 0 5 50 1.8 0 0.2 2 + restore + + save + translate 150 100 + drawText 0 -10 "subrect alpha pixmap" + drawPixmap alpha2x2.png 0 0 50 5 0 0.0 2 0.2 + drawPixmap alpha2x2.png 0 5 50 5 0 0.2 2 0.2 + drawPixmap alpha2x2.png 0 10 50 5 0 0.4 2 0.2 + drawPixmap alpha2x2.png 0 15 50 5 0 0.6 2 0.2 + drawPixmap alpha2x2.png 0 20 50 5 0 0.8 2 0.2 + drawPixmap alpha2x2.png 0 25 50 5 0 1.0 2 0.2 + drawPixmap alpha2x2.png 0 30 50 5 0 1.2 2 0.2 + drawPixmap alpha2x2.png 0 35 50 5 0 1.4 2 0.2 + drawPixmap alpha2x2.png 0 40 50 5 0 1.6 2 0.2 + drawPixmap alpha2x2.png 0 45 50 5 0 1.8 2 0.2 + translate 60 0 + drawPixmap alpha2x2.png 0 0 5 50 0.0 0 0.2 2 + drawPixmap alpha2x2.png 5 0 5 50 0.2 0 0.2 2 + drawPixmap alpha2x2.png 10 0 5 50 0.4 0 0.2 2 + drawPixmap alpha2x2.png 15 0 5 50 0.6 0 0.2 2 + drawPixmap alpha2x2.png 20 0 5 50 0.8 0 0.2 2 + drawPixmap alpha2x2.png 25 0 5 50 1.0 0 0.2 2 + drawPixmap alpha2x2.png 30 0 5 50 1.2 0 0.2 2 + drawPixmap alpha2x2.png 35 0 5 50 1.4 0 0.2 2 + drawPixmap alpha2x2.png 40 0 5 50 1.6 0 0.2 2 + drawPixmap alpha2x2.png 45 0 5 50 1.8 0 0.2 2 + restore + +restore
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/pixmap_subpixel.qps b/tests/auto/lancelot/scripts/pixmap_subpixel.qps new file mode 100644 index 0000000..908f7c3 --- /dev/null +++ b/tests/auto/lancelot/scripts/pixmap_subpixel.qps @@ -0,0 +1,117 @@ +# Version: 1 +# CheckVsReference: 5% + + +translate 50 50 + +# Pixmaps at 0.1 offset, unclipped +begin_block draw_pixmaps +save + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 + drawPixmap border.png 0 0 + translate 20.1 0.1 +restore +end_block + +# Tiled pixmaps at 0.1 offsets, unclipped +translate 0 50 +begin_block draw_tiled +save + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 + drawTiledPixmap border.png 0 0 16 16 0 0 + translate 20.1 0.1 +restore +end_block + + +path_moveTo clip 0 0 +path_lineTo clip width 0 +path_lineTo clip width 400 +path_lineTo clip 0 height +setClipPath clip + +translate 0 50 +# Pixmaps at 0.1 offset, clipped +repeat_block draw_pixmaps + + +# Tiled pixmaps at 0.1 offsets... +translate 0 50 +repeat_block draw_tiled + diff --git a/tests/auto/lancelot/scripts/pixmaps.qps b/tests/auto/lancelot/scripts/pixmaps.qps new file mode 100644 index 0000000..8e60997 --- /dev/null +++ b/tests/auto/lancelot/scripts/pixmaps.qps @@ -0,0 +1,106 @@ +# Version: 1 +# CheckVsReference: 1% (0 0 690 580) + + +setRenderHint Antialiasing + +setPen #00ff00 + +pixmap_load dome_argb32.png the_pixmap +begin_block draw_stuff + +save + + # standard draw + drawPixmap the_pixmap 0 0 + + # sub recting + translate 120 0 + drawPixmap the_pixmap 0 0 40 40 0 0 40 40 + drawPixmap the_pixmap 60 0 40 40 60 0 40 40 + drawPixmap the_pixmap 0 60 40 40 0 60 40 40 + drawPixmap the_pixmap 60 60 40 40 60 60 40 40 + drawPixmap the_pixmap 0 40 40 20 0 40 40 20 + drawPixmap the_pixmap 60 40 40 20 60 40 40 20 + drawPixmap the_pixmap 40 0 20 100 40 0 20 100 + + # subrecting w/scale + translate 120 0 + drawPixmap the_pixmap 0 0 50 50 0 0 25 25 + drawPixmap the_pixmap 50 0 50 50 25 0 25 25 + drawPixmap the_pixmap 0 50 50 50 0 25 25 25 + drawPixmap the_pixmap 50 50 50 50 25 25 25 25 + + # subrecting w/scale & smooth xform + translate 120 0 + setRenderHint SmoothPixmapTransformation + drawPixmap the_pixmap 0 0 50 50 0 0 25 25 + drawPixmap the_pixmap 50 0 50 50 25 0 25 25 + drawPixmap the_pixmap 0 50 50 50 0 25 25 25 + drawPixmap the_pixmap 50 50 50 50 25 25 25 25 + + + # Rotation w/o smooth xform + translate 120 0 + save + setRenderHint SmoothPixmapTransform off + rotate 10 + drawPixmap the_pixmap 0 0 + restore + + # Rotation w smooth xform + translate 120 0 + save + setRenderHint SmoothPixmapTransform + rotate 10 + drawPixmap the_pixmap 0 0 + restore + +restore + +end_block + + +translate 0 120 +pixmap_load dome_rgb32.png the_pixmap +repeat_block draw_stuff + +translate 0 120 +pixmap_load dome_indexed.png the_pixmap +repeat_block draw_stuff + +translate 0 120 +pixmap_load dome_indexed_mask.png the_pixmap +repeat_block draw_stuff + +translate 0 120 +pixmap_load dome_mono.png the_pixmap +repeat_block draw_stuff + + +resetMatrix +translate 700 60 +setPen black +drawText 0 0 "32 bit w/alpha" +translate 0 120 +drawText 0 0 "32 bit w/o alpha" +translate 0 120 +drawText 0 0 "8 bit indexed" +translate 0 120 +drawText 0 0 "8 bit indexed w/mask" +translate 0 120 +drawText 0 0 "1 bit" +resetMatrix +translate 0 600 +drawText 0 0 "normal" +translate 120 0 +drawText 0 0 "subrect" +translate 120 0 +drawText 0 0 "subrect scale" +translate 120 0 +drawText 0 0 "subrect scale smooth" +translate 120 0 +drawText 0 0 "xform" +translate 120 0 +drawText 0 0 "smooth xform" +translate 120 0
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/porter_duff.qps b/tests/auto/lancelot/scripts/porter_duff.qps new file mode 100644 index 0000000..166e48a --- /dev/null +++ b/tests/auto/lancelot/scripts/porter_duff.qps @@ -0,0 +1,251 @@ +# Version: 1 +# CheckVsReference: 5% + + +translate 0 50 + +surface_begin 0 0 100 100 + +begin_block predraw +setRenderHint Antialiasing +setPen nopen +setBrush 0x7f000000 +drawEllipse 10 10 80 80 +end_block + +setCompositionMode SourceOver + +begin_block postdraw + + +setBrush 0x1fff0000 +drawRect 0 0 50 50 + +setBrush 0xdf00ff00 +drawRect 50 50 50 50 + +setBrush 0x7f0000ff +drawEllipse 30 30 40 40 + +# a black rectangle around +setCompositionMode SourceOver +setPen black +setBrush nobrush +drawRect 0.5 0.5 99 99 + +end_block +surface_end + + +# Destination over +surface_begin 100 0 100 100 +repeat_block predraw +setCompositionMode DestinationOver +repeat_block postdraw +surface_end + + +# Clear +surface_begin 200 0 100 100 +repeat_block predraw +setCompositionMode Clear +repeat_block postdraw +surface_end + + +# Source +surface_begin 300 0 100 100 +repeat_block predraw +setCompositionMode Source +repeat_block postdraw +surface_end + + +# Destination +surface_begin 400 0 100 100 +repeat_block predraw +setCompositionMode Destination +repeat_block postdraw +surface_end + + +# Source In +surface_begin 500 0 100 100 +repeat_block predraw +setCompositionMode SourceIn +repeat_block postdraw +surface_end + +translate 0 50 + +# Destination In +surface_begin 0 100 100 100 +repeat_block predraw +setCompositionMode DestinationIn +repeat_block postdraw +surface_end + + +# Source Out +surface_begin 100 100 100 100 +repeat_block predraw +setCompositionMode SourceOut +repeat_block postdraw +surface_end + + +# Destination Out +surface_begin 200 100 100 100 +repeat_block predraw +setCompositionMode DestinationOut +repeat_block postdraw +surface_end + + +# SourceAtop +surface_begin 300 100 100 100 +repeat_block predraw +setCompositionMode SourceAtop +repeat_block postdraw +surface_end + + +# DestinationAtop +surface_begin 400 100 100 100 +repeat_block predraw +setCompositionMode DestinationAtop +repeat_block postdraw +surface_end + + +# Xor +surface_begin 500 100 100 100 +repeat_block predraw +setCompositionMode Xor +repeat_block postdraw +surface_end + +translate 0 50 + +# Plus +surface_begin 0 200 100 100 +repeat_block predraw +setCompositionMode Plus +repeat_block postdraw +surface_end + + +# Multiply +surface_begin 100 200 100 100 +repeat_block predraw +setCompositionMode Multiply +repeat_block postdraw +surface_end + + +# Screen +surface_begin 200 200 100 100 +repeat_block predraw +setCompositionMode Screen +repeat_block postdraw +surface_end + + +# Overlay +surface_begin 300 200 100 100 +repeat_block predraw +setCompositionMode Overlay +repeat_block postdraw +surface_end + + +# Darken +surface_begin 400 200 100 100 +repeat_block predraw +setCompositionMode Darken +repeat_block postdraw +surface_end + + +# Lighten +surface_begin 500 200 100 100 +repeat_block predraw +setCompositionMode Lighten +repeat_block postdraw +surface_end + +translate 0 50 + +# ColorDodge +surface_begin 0 300 100 100 +repeat_block predraw +setCompositionMode ColorDodge +repeat_block postdraw +surface_end + + +# Multiply +surface_begin 100 300 100 100 +repeat_block predraw +setCompositionMode ColorBurn +repeat_block postdraw +surface_end + + +# Screen +surface_begin 200 300 100 100 +repeat_block predraw +setCompositionMode HardLight +repeat_block postdraw +surface_end + + +# Overlay +surface_begin 300 300 100 100 +repeat_block predraw +setCompositionMode SoftLight +repeat_block postdraw +surface_end + + +# Darken +surface_begin 400 300 100 100 +repeat_block predraw +setCompositionMode Difference +repeat_block postdraw +surface_end + + +# Lighten +surface_begin 500 300 100 100 +repeat_block predraw +setCompositionMode Exclusion +repeat_block postdraw +surface_end + +resetMatrix + +drawText 0 50 "SourceOver" +drawText 100 50 "DestinationOver" +drawText 200 50 "Clear" +drawText 300 50 "Source" +drawText 400 50 "Destination" +drawText 500 50 "SourceIn" +drawText 0 200 "DestinationIn" +drawText 100 200 "SourceOut" +drawText 200 200 "DestinationOut" +drawText 300 200 "SourceAtop" +drawText 400 200 "DestinationAtop" +drawText 500 200 "Xor" +drawText 0 350 "Plus" +drawText 100 350 "Multiply" +drawText 200 350 "Screen" +drawText 300 350 "Overlay" +drawText 400 350 "Darken" +drawText 500 350 "Lighten" +drawText 0 500 "ColorDodge" +drawText 100 500 "ColorBurn" +drawText 200 500 "HardLight" +drawText 300 500 "SoftLight" +drawText 400 500 "Difference" +drawText 500 500 "Exclusion"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/porter_duff2.qps b/tests/auto/lancelot/scripts/porter_duff2.qps new file mode 100644 index 0000000..a792d9b --- /dev/null +++ b/tests/auto/lancelot/scripts/porter_duff2.qps @@ -0,0 +1,261 @@ +# Version: 1 +# CheckVsReference: 1% (0 50 600 100) +# CheckVsReference: 1% (0 200 600 100) +# CheckVsReference: 1% (0 350 600 100) +# CheckVsReference: 1% (0 500 600 100) + +translate 0 50 + +surface_begin 0 0 100 100 + +begin_block predraw +setRenderHint Antialiasing +setPen nopen +gradient_clearStops +gradient_appendStop 0 efff0000 +gradient_appendStop 0.5 dfffff00 +gradient_appendStop 1 ef00ff00 + +gradient_setSpread PadSpread +gradient_setLinear 10 10 90 90 +drawEllipse 10 10 80 80 +end_block + +setCompositionMode SourceOver + +begin_block postdraw + +gradient_clearStops +gradient_appendStop 0 afff0000 +gradient_appendStop 0.5 cf0000ff +gradient_appendStop 1 bf00ff00 + +gradient_setSpread PadSpread +gradient_setLinear 0 0 100 0 +drawEllipse 10 10 30 30 +drawEllipse 10 60 30 30 +drawEllipse 60 60 30 30 +drawEllipse 60 10 30 30 +drawEllipse 35 35 30 30 + +# a black rectangle around +setCompositionMode SourceOver +setPen black +setBrush nobrush +drawRect 0.5 0.5 99 99 + +end_block +surface_end + +# Destination over +surface_begin 100 0 100 100 +repeat_block predraw +setCompositionMode DestinationOver +repeat_block postdraw +surface_end + + +# Clear +surface_begin 200 0 100 100 +repeat_block predraw +setCompositionMode Clear +repeat_block postdraw +surface_end + + +# Source +surface_begin 300 0 100 100 +repeat_block predraw +setCompositionMode Source +repeat_block postdraw +surface_end + + +# Destination +surface_begin 400 0 100 100 +repeat_block predraw +setCompositionMode Destination +repeat_block postdraw +surface_end + + +# Source In +surface_begin 500 0 100 100 +repeat_block predraw +setCompositionMode SourceIn +repeat_block postdraw +surface_end + +translate 0 50 + +# Destination In +surface_begin 0 100 100 100 +repeat_block predraw +setCompositionMode DestinationIn +repeat_block postdraw +surface_end + + +# Source Out +surface_begin 100 100 100 100 +repeat_block predraw +setCompositionMode SourceOut +repeat_block postdraw +surface_end + + +# Destination Out +surface_begin 200 100 100 100 +repeat_block predraw +setCompositionMode DestinationOut +repeat_block postdraw +surface_end + + +# SourceAtop +surface_begin 300 100 100 100 +repeat_block predraw +setCompositionMode SourceAtop +repeat_block postdraw +surface_end + + +# DestinationAtop +surface_begin 400 100 100 100 +repeat_block predraw +setCompositionMode DestinationAtop +repeat_block postdraw +surface_end + + +# Xor +surface_begin 500 100 100 100 +repeat_block predraw +setCompositionMode Xor +repeat_block postdraw +surface_end + +translate 0 50 + +# Plus +surface_begin 0 200 100 100 +repeat_block predraw +setCompositionMode Plus +repeat_block postdraw +surface_end + + +# Multiply +surface_begin 100 200 100 100 +repeat_block predraw +setCompositionMode Multiply +repeat_block postdraw +surface_end + + +# Screen +surface_begin 200 200 100 100 +repeat_block predraw +setCompositionMode Screen +repeat_block postdraw +surface_end + + +# Overlay +surface_begin 300 200 100 100 +repeat_block predraw +setCompositionMode Overlay +repeat_block postdraw +surface_end + + +# Darken +surface_begin 400 200 100 100 +repeat_block predraw +setCompositionMode Darken +repeat_block postdraw +surface_end + + +# Lighten +surface_begin 500 200 100 100 +repeat_block predraw +setCompositionMode Lighten +repeat_block postdraw +surface_end + +translate 0 50 + +# ColorDodge +surface_begin 0 300 100 100 +repeat_block predraw +setCompositionMode ColorDodge +repeat_block postdraw +surface_end + + +# Multiply +surface_begin 100 300 100 100 +repeat_block predraw +setCompositionMode ColorBurn +repeat_block postdraw +surface_end + + +# Screen +surface_begin 200 300 100 100 +repeat_block predraw +setCompositionMode HardLight +repeat_block postdraw +surface_end + + +# Overlay +surface_begin 300 300 100 100 +repeat_block predraw +setCompositionMode SoftLight +repeat_block postdraw +surface_end + + +# Darken +surface_begin 400 300 100 100 +repeat_block predraw +setCompositionMode Difference +repeat_block postdraw +surface_end + + +# Lighten +surface_begin 500 300 100 100 +repeat_block predraw +setCompositionMode Exclusion +repeat_block postdraw +surface_end + +resetMatrix + +drawText 0 50 "SourceOver" +drawText 100 50 "DestinationOver" +drawText 200 50 "Clear" +drawText 300 50 "Source" +drawText 400 50 "Destination" +drawText 500 50 "SourceIn" +drawText 0 200 "DestinationIn" +drawText 100 200 "SourceOut" +drawText 200 200 "DestinationOut" +drawText 300 200 "SourceAtop" +drawText 400 200 "DestinationAtop" +drawText 500 200 "Xor" +drawText 0 350 "Plus" +drawText 100 350 "Multiply" +drawText 200 350 "Screen" +drawText 300 350 "Overlay" +drawText 400 350 "Darken" +drawText 500 350 "Lighten" +drawText 0 500 "ColorDodge" +drawText 100 500 "ColorBurn" +drawText 200 500 "HardLight" +drawText 300 500 "SoftLight" +drawText 400 500 "Difference" +drawText 500 500 "Exclusion"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/primitives.qps b/tests/auto/lancelot/scripts/primitives.qps new file mode 100644 index 0000000..f44ba27 --- /dev/null +++ b/tests/auto/lancelot/scripts/primitives.qps @@ -0,0 +1,184 @@ +# Version: 1#Version: 1 +# CheckVsReference: 5% + + +# CheckVsReference: 5% + +setBrush #ff7f7fff +setPen black 1 solidline +translate 20 20 +begin_block testblock +save +drawRect 0 0 10 10 +drawRect 20 0 20 10 +drawRect 0 20 10 20 +drawRect 20 20 20 20 +translate 50 0 +setPen NoPen +drawRect 0 0 10 10 +drawRect 20 0 20 10 +drawRect 0 20 10 20 +drawRect 20 20 20 20 +restore +save +translate 0 50 +drawEllipse 0 0 10 10 +drawEllipse 20 0 20 10 +drawEllipse 0 20 10 20 +drawEllipse 20 20 20 20 +translate 50 0 +setPen NoPen +drawEllipse 0 0 10 10 +drawEllipse 20 0 20 10 +drawEllipse 0 20 10 20 +drawEllipse 20 20 20 20 +restore +save +translate 0 100 +drawPolygon [ 0 0 30 0 30 30 10 30 10 10 40 10 40 40 0 40 ] +save +translate 0 50 +drawPolygon [ 0 0 30 0 30 30 10 30 10 10 40 10 40 40 0 40 ] Winding +translate 0 45 +drawPolyline [ 0 0 50 0 25 25 ] +restore +setPen NoPen +translate 50 0 +drawPolygon [ 0 0 30 0 30 30 10 30 10 10 40 10 40 40 0 40 ] +save +translate 0 50 +drawPolygon [ 0 0 30 0 30 30 10 30 10 10 40 10 40 40 0 40 ] Winding +restore +save +translate -20 100 +drawPie 0 0 50 50 0 1500 +restore +restore +end_block +setPen black 1 SolidLine FlatCap +translate 200 0 +scale 2 1 +rotate 10 +repeat_block testblock +resetMatrix +translate 0 250 +setBrush 7f7f7fff +translate 20 20 +repeat_block testblock +setPen black 1 SolidLine FlatCap +translate 200 0 +scale 2 1 +rotate 10 +repeat_block testblock +resetMatrix +save +setRenderHint LineAntialiasing +setBrush 7f7fff +translate 20 500 +repeat_block testblock +translate 200 0 +scale 2 1 +rotate 10 +repeat_block testblock +restore +setRenderHint LineAntialiasing false +translate 420 20 +begin_block lines +drawLine 0 0 100 0 +drawLine 0 0 100 10 +drawLine 0 0 100 20 +drawLine 0 0 100 30 +drawLine 0 0 100 40 +drawLine 0 0 100 50 +drawLine 0 0 100 60 +drawLine 0 0 100 70 +drawLine 0 0 100 80 +drawLine 0 0 100 90 +drawLine 0 0 100 100 +drawLine 0 0 90 100 +drawLine 0 0 80 100 +drawLine 0 0 70 100 +drawLine 0 0 60 100 +drawLine 0 0 50 100 +drawLine 0 0 40 100 +drawLine 0 0 30 100 +drawLine 0 0 20 100 +drawLine 0 0 10 100 +drawLine 0 0 0 100 +end_block +setRenderHint LineAntialiasing +translate 0 120 +repeat_block lines +translate 0 120 +scale 5 2 +repeat_block lines +resetMatrix +translate 420 500 +begin_block roundedrects +save +drawRoundedRect 0 0 50 30 5 5 +translate 60 0 +drawRoundedRect 0 0 50 30 7.5 7.5 +translate 60 0 +drawRoundedRect 0 0 50 30 10 10 +translate 60 0 +drawRoundedRect 0 0 50 30 12.5 12.5 +translate 60 0 +drawRoundedRect 0 0 50 30 15 15 +restore +save +translate 0 40 +drawRoundedRect 0 0 50 30 20 20 RelativeSize +translate 60 0 +drawRoundedRect 0 0 50 30 40 40 RelativeSize +translate 60 0 +drawRoundedRect 0 0 50 30 60 60 RelativeSize +translate 60 0 +drawRoundedRect 0 0 50 30 80 80 RelativeSize +translate 60 0 +drawRoundedRect 0 0 50 30 100 100 RelativeSize +restore +end_block +translate 0.5 80.5 +repeat_block roundedrects +translate -0.5 79.5 +setRenderHint Antialiasing off +repeat_block roundedrects +resetMatrix +setRenderHint Antialiasing off +setPen black 1 +begin_block drawShapes +translate 550.5 25 +rotate 45 +setBrush nobrush +drawEllipse -10 -10 20 20 +drawLine 10 0 50 0 +drawRect 50 -7 14 14 +resetMatrix +end_block +setPen black 2 +translate 25 0 +repeat_block drawShapes +setPen black 3 +translate 50 0 +repeat_block drawShapes +setPen black 4 +translate 75 0 +repeat_block drawShapes +resetMatrix +setRenderHint Antialiasing off +setPen nopen +translate 550 100 +setBrush #7f7f7fff +drawRect -0.5 -0.5 21 21 +setBrush red +drawEllipse 0 0 20 20 +setBrush nobrush +setPen black +drawEllipse 0 0 20 20 +translate 25 0 +setPen nopen +setBrush #7f7f7fff +drawRect 0 0 20 20 +setBrush red +drawEllipse 0 0 20 20
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/radial_gradients.qps b/tests/auto/lancelot/scripts/radial_gradients.qps new file mode 100644 index 0000000..b55df8b --- /dev/null +++ b/tests/auto/lancelot/scripts/radial_gradients.qps @@ -0,0 +1,99 @@ +# Version: 1 +# CheckVsReference: 5% (0 0 600 400) + +path_addRect path 400 0 80 80 +path_addEllipse path 440 40 60 60 + +setRenderHint Antialiasing + +setPen black + +begin_block gradients +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 1 cyan + +gradient_setSpread PadSpread +gradient_setRadial 20 20 50 40 40 +drawRect 0 0 100 100 + +gradient_setSpread ReflectSpread +gradient_setRadial 120 20 50 140 40 +drawEllipse 100 0 100 100 + +gradient_setSpread RepeatSpread +gradient_setRadial 220 20 50 240 40 +drawRoundRect 200 0 100 100 + +gradient_clearStops +gradient_appendStop 0 3f7f7fff +gradient_appendStop 0.5 dfdfffff +gradient_appendStop 1 7f00007f + +gradient_setSpread PadSpread +gradient_setRadial 320 20 50 340 40 +drawPolygon [300 0 390 0 350 99] + +gradient_setSpread ReflectSpread +gradient_setRadial 420 20 50 440 40 +drawPath path + +gradient_setSpread RepeatSpread +gradient_setRadial 520 20 50 540 40 +drawPie 500 0 100 100 720 4320 +end_block + +translate 0 100 +scale 1 2 +repeat_block gradients + +resetMatrix +translate 0 300 +brushTranslate 30 0 +brushScale 0.9 0.9 +brushRotate 20 +repeat_block gradients + +# Some helpful info perhaps? +resetMatrix +setPen black + +drawText 610 50 "No XForm" +drawText 610 200 "scale 1x2" +drawText 610 300 "brush transform" +drawText 10 450 "Pad" +drawText 110 450 "Reflect" +drawText 210 450 "Repeat" +drawText 310 450 "Pad w/alpha" +drawText 410 450 "Reflect w/alpha" +drawText 510 450 "Repeat w/alpha" + +# Radius and focal indicators +setPen 3f000000 +setBrush nobrush + +begin_block ellipse_draw +setClipRect 0 0 100 100 +drawEllipse -30 -30 100 100 +drawEllipse 35 35 11 11 +translate 100 0 +end_block + +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw + +resetMatrix +translate 0 100 +scale 1 2 +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/radial_gradients_perspectives.qps b/tests/auto/lancelot/scripts/radial_gradients_perspectives.qps new file mode 100644 index 0000000..4557354 --- /dev/null +++ b/tests/auto/lancelot/scripts/radial_gradients_perspectives.qps @@ -0,0 +1,62 @@ +# Version: 1 + + +setRenderHint Antialiasing + +setPen #00ff00 + +translate 10 10 +# standard draw +begin_block gradient +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 1 cyan + +gradient_setSpread PadSpread +gradient_setRadial 110 100 230 230 240 +drawRect 0 0 300 300 +end_block gradient + +# Rotation w/o smooth xform +save +translate 350 0 +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 50 0 200 300 300 300 0 + repeat_block gradient +restore +restore + +translate 0 320 + +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 0 100 300 200 300 300 0 + repeat_block gradient +restore + +save +translate 350 0 +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 0 0 300 300 250 300 50 + repeat_block gradient +restore +restore + + +resetMatrix +setPen black +translate 125 20 +drawText 0 0 "No transform" +translate 350 0 +drawText 0 0 "Left Tilted" +resetMatrix +translate 125 350 +drawText 0 0 "Bottom Tilted" +translate 350 0 +drawText 0 0 "Right Tilted" +translate 120 0
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/rasterops.qps b/tests/auto/lancelot/scripts/rasterops.qps new file mode 100644 index 0000000..21f943b --- /dev/null +++ b/tests/auto/lancelot/scripts/rasterops.qps @@ -0,0 +1,87 @@ +# Version: 1 +# CheckVsReference: 5% + +setPen NoPen + +setBrush black +drawRect 10 10 60 500 + +setCompositionMode SourceOrDestination +translate 20 20 + +begin_block drawShape + setBrush 0xffff0000 + drawEllipse 5 5 30 30 + setBrush 0xff00ff00 + drawRect 0 0 20 20 + setBrush 0xff0000ff + drawRect 20 20 20 20 +end_block + +begin_block loop + setCompositionMode SourceAndDestination + translate 0 50 +repeat_block drawShape + +setCompositionMode SourceXorDestination +translate 0 50 +repeat_block drawShape + +setCompositionMode NotSourceAndNotDestination +translate 0 50 +repeat_block drawShape + +setCompositionMode NotSourceOrNotDestination +translate 0 50 +repeat_block drawShape + +setCompositionMode NotSourceXorDestination +translate 0 50 +repeat_block drawShape + +setCompositionMode NotSource +translate 0 50 +repeat_block drawShape + +setCompositionMode NotSourceAndDestination +translate 0 50 +repeat_block drawShape + +setCompositionMode SourceAndNotDestination +translate 0 50 +repeat_block drawShape +end_block + +resetMatrix +setCompositionMode Source +setBrush white +drawRect 100 10 60 500 +translate 110 20 +repeat_block loop + +resetMatrix +setCompositionMode Source +translate 190 20 +repeat_block loop + +resetMatrix +setPen black +setCompositionMode SourceOver +translate 250 45 +drawText 20 0 "Or ROP" +translate 0 50 +drawText 20 0 "And ROP" +translate 0 50 +drawText 20 0 "Xor ROP" +translate 0 50 +drawText 20 0 "Nor ROP" +translate 0 50 +drawText 20 0 "Nand ROP" +translate 0 50 +drawText 0 0 "NSrcXorDst ROP" +translate 0 50 +drawText 20 0 "NSrc ROP" +translate 0 50 +drawText 0 0 "NSrcAndDst ROP" +translate 0 50 +drawText 0 0 "SrcAndNDst ROP"
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/sizes.qps b/tests/auto/lancelot/scripts/sizes.qps new file mode 100644 index 0000000..268808e --- /dev/null +++ b/tests/auto/lancelot/scripts/sizes.qps @@ -0,0 +1,150 @@ +# Version: 1 +# CheckVsReference: 5% + +setPen NoPen +setBrush black + +translate 10 10 + +begin_block testblock +drawRect 0 0 10 10 +drawRect 20 0 11 11 +drawRect 40 0 12 12 +drawRect 60 0 13 13 +drawRect 80 0 14 14 +drawRect 100 0 15 15 +drawRect 120 0 16 16 +drawRect 140 0 17 17 +drawRect 160 0 18 18 +drawRect 180 0 19 19 +# qt3_drawRect 200 0 10 10 +# qt3_drawRect 220 0 11 11 +# qt3_drawRect 240 0 12 12 +# qt3_drawRect 260 0 13 13 +# qt3_drawRect 280 0 14 14 +# qt3_drawRect 300 0 15 15 +# qt3_drawRect 320 0 16 16 +# qt3_drawRect 340 0 17 17 +# qt3_drawRect 360 0 18 18 +# qt3_drawRect 380 0 19 19 + +drawEllipse 0 20 10 10 +drawEllipse 20 20 11 11 +drawEllipse 40 20 12 12 +drawEllipse 60 20 13 13 +drawEllipse 80 20 14 14 +drawEllipse 100 20 15 15 +drawEllipse 120 20 16 16 +drawEllipse 140 20 17 17 +drawEllipse 160 20 18 18 +drawEllipse 180 20 19 19 +# qt3_drawEllipse 200 20 10 10 +# qt3_drawEllipse 220 20 11 11 +# qt3_drawEllipse 240 20 12 12 +# qt3_drawEllipse 260 20 13 13 +# qt3_drawEllipse 280 20 14 14 +# qt3_drawEllipse 300 20 15 15 +# qt3_drawEllipse 320 20 16 16 +# qt3_drawEllipse 340 20 17 17 +# qt3_drawEllipse 360 20 18 18 +# qt3_drawEllipse 380 20 19 19 + +drawRoundRect 0 40 10 10 +drawRoundRect 20 40 11 11 +drawRoundRect 40 40 12 12 +drawRoundRect 60 40 13 13 +drawRoundRect 80 40 14 14 +drawRoundRect 100 40 15 15 +drawRoundRect 120 40 16 16 +drawRoundRect 140 40 17 17 +drawRoundRect 160 40 18 18 +drawRoundRect 180 40 19 19 +# qt3_drawRoundRect 200 40 10 10 +# qt3_drawRoundRect 220 40 11 11 +# qt3_drawRoundRect 240 40 12 12 +# qt3_drawRoundRect 260 40 13 13 +# qt3_drawRoundRect 280 40 14 14 +# qt3_drawRoundRect 300 40 15 15 +# qt3_drawRoundRect 320 40 16 16 +# qt3_drawRoundRect 340 40 17 17 +# qt3_drawRoundRect 360 40 18 18 +# qt3_drawRoundRect 380 40 19 19 + +drawPie 0 60 10 10 0 4320 +drawPie 20 60 11 11 0 4320 +drawPie 40 60 12 12 0 4320 +drawPie 60 60 13 13 0 4320 +drawPie 80 60 14 14 0 4320 +drawPie 100 60 15 15 0 4320 +drawPie 120 60 16 16 0 4320 +drawPie 140 60 17 17 0 4320 +drawPie 160 60 18 18 0 4320 +drawPie 180 60 19 19 0 4320 +# qt3_drawPie 200 60 10 10 0 4320 +# qt3_drawPie 220 60 11 11 0 4320 +# qt3_drawPie 240 60 12 12 0 4320 +# qt3_drawPie 260 60 13 13 0 4320 +# qt3_drawPie 280 60 14 14 0 4320 +# qt3_drawPie 300 60 15 15 0 4320 +# qt3_drawPie 320 60 16 16 0 4320 +# qt3_drawPie 340 60 17 17 0 4320 +# qt3_drawPie 360 60 18 18 0 4320 +# qt3_drawPie 380 60 19 19 0 4320 + +drawArc 0 80 10 10 0 4320 +drawArc 20 80 11 11 0 4320 +drawArc 40 80 12 12 0 4320 +drawArc 60 80 13 13 0 4320 +drawArc 80 80 14 14 0 4320 +drawArc 100 80 15 15 0 4320 +drawArc 120 80 16 16 0 4320 +drawArc 140 80 17 17 0 4320 +drawArc 160 80 18 18 0 4320 +drawArc 180 80 19 19 0 4320 +# qt3_drawArc 200 80 10 10 0 4320 +# qt3_drawArc 220 80 11 11 0 4320 +# qt3_drawArc 240 80 12 12 0 4320 +# qt3_drawArc 260 80 13 13 0 4320 +# qt3_drawArc 280 80 14 14 0 4320 +# qt3_drawArc 300 80 15 15 0 4320 +# qt3_drawArc 320 80 16 16 0 4320 +# qt3_drawArc 340 80 17 17 0 4320 +# qt3_drawArc 360 80 18 18 0 4320 +# qt3_drawArc 380 80 19 19 0 4320 + +drawChord 0 100 10 10 0 4320 +drawChord 20 100 11 11 0 4320 +drawChord 40 100 12 12 0 4320 +drawChord 60 100 13 13 0 4320 +drawChord 80 100 14 14 0 4320 +drawChord 100 100 15 15 0 4320 +drawChord 120 100 16 16 0 4320 +drawChord 140 100 17 17 0 4320 +drawChord 160 100 18 18 0 4320 +drawChord 180 100 19 19 0 4320 +# qt3_drawChord 200 100 10 10 0 4320 +# qt3_drawChord 220 100 11 11 0 4320 +# qt3_drawChord 240 100 12 12 0 4320 +# qt3_drawChord 260 100 13 13 0 4320 +# qt3_drawChord 280 100 14 14 0 4320 +# qt3_drawChord 300 100 15 15 0 4320 +# qt3_drawChord 320 100 16 16 0 4320 +# qt3_drawChord 340 100 17 17 0 4320 +# qt3_drawChord 360 100 18 18 0 4320 +# qt3_drawChord 380 100 19 19 0 4320 + +end_block + +setPen red +translate 0 150 +repeat_block testblock + +setRenderHint LineAntialiasing + +setPen nopen +translate 0 150 +repeat_block testblock + +setPen red +translate 0 150 +repeat_block testblock diff --git a/tests/auto/lancelot/scripts/text.qps b/tests/auto/lancelot/scripts/text.qps new file mode 100644 index 0000000..d7ee832 --- /dev/null +++ b/tests/auto/lancelot/scripts/text.qps @@ -0,0 +1,124 @@ +# Version: 1 + +drawText -5 5 "Text that is drawn outside the bounds..." + +translate 20 20 +begin_block text_drawing +save + setFont "sansserif" 10 normal + drawText 0 20 "sansserif 10pt, normal" + + setFont "sansserif" 12 normal + drawText 0 40 "sansserif 12pt, normal" + + setFont "sansserif" 10 bold + drawText 0 60 "sansserif 12pt, bold" + + setFont "sansserif" 10 bold italic + drawText 0 80 "sansserif 10pt, bold italic" + + + translate 0 100 + setPen #7fff0000 + + setFont "sansserif" 10 normal + drawText 0 20 "alpha sansserif 10pt, normal" + + setFont "sansserif" 12 normal + drawText 0 40 "alpha sansserif 12pt, normal" + + setFont "sansserif" 10 bold + drawText 0 60 "alpha sansserif 12pt, bold" + + setFont "sansserif" 10 bold italic + drawText 0 80 "alpha sansserif 10pt, bold italic" + + + translate 0 100 + setPen black + save + scale 0.9 0.9 + + setFont "sansserif" 10 normal + drawText 0 20 "scaled sansserif 10pt, normal" + + setFont "sansserif" 12 normal + drawText 0 40 "scaled sansserif 12pt, normal" + + setFont "sansserif" 10 bold + drawText 0 60 "scaled sansserif 12pt, bold" + + setFont "sansserif" 10 bold italic + drawText 0 80 "scaled sansserif 10pt, bold italic" + restore + + translate 0 100 + setPen black + save + translate 200 90 + rotate 185 + + setFont "sansserif" 10 normal + drawText 0 20 "scaled sansserif 10pt, normal" + + setFont "sansserif" 12 normal + drawText 0 40 "scaled sansserif 12pt, normal" + + setFont "sansserif" 10 bold + drawText 0 60 "scaled sansserif 12pt, bold" + + setFont "sansserif" 10 bold italic + drawText 0 80 "scaled sansserif 10pt, bold italic" + restore + + translate 0 100 + gradient_appendStop 0 red + gradient_appendStop 0.5 #00ff00 + gradient_appendStop 1 blue + gradient_setLinear 0 0 200 0 + setPen brush + + setFont "sansserif" 10 normal + drawText 0 0 "gradient sansserif 10pt, normal" + + setFont "sansserif" 12 normal + drawText 0 20 "gradient sansserif 12pt, normal" + + setFont "sansserif" 10 bold + drawText 0 40 "gradient sansserif 12pt, bold" + + setFont "sansserif" 10 bold italic + drawText 0 60 "gradient sansserif 10pt, bold italic" +restore +end_block + +translate 250 0 +drawText 25 520 "clipped to rectangle" +save + setPen #3f000000 + setBrush nobrush + drawRect 20 0 100 500 + setClipRect 20 0 100 500 + setPen black + repeat_block text_drawing +restore + +translate 150 0 +drawText 25 520 "clipped to path" +save + path_moveTo clip 20 0 + path_cubicTo clip 0 200 40 400 20 400 + path_lineTo clip 30 500 + path_lineTo clip 30 0 + path_lineTo clip 40 0 + path_lineTo clip 40 500 + path_lineTo clip 120 500 + path_lineTo clip 120 0 + path_lineTo clip 20 0 + setPen #3f000000 + setBrush nobrush + drawPath clip + setClipPath clip + setPen black + repeat_block text_drawing +restore
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/text_perspectives.qps b/tests/auto/lancelot/scripts/text_perspectives.qps new file mode 100644 index 0000000..4c74306 --- /dev/null +++ b/tests/auto/lancelot/scripts/text_perspectives.qps @@ -0,0 +1,102 @@ +# Version: 1 + + +setRenderHint Antialiasing + +setPen black + +translate 10 10 +# standard draw +begin_block text +setBrush gray +drawRect 0 0 300 300 + +setFont "times" 3 +drawText 10 10 "Hello World...." + +setFont "times" 4 +drawText 10 20 "Hello World...." + +setFont "times" 5 +drawText 10 30 "Hello World...." + +setFont "times" 6 +drawText 10 40 "Hello World...." + +setFont "times" 7 +drawText 10 50 "Hello World...." + +setFont "times" 8 +drawText 10 60 "Hello World...." + +setFont "times" 9 +drawText 10 70 "Hello World...." + +setFont "times" 10 +drawText 10 80 "Hello World...." + +setFont "times" 16 +drawText 10 100 "Hello World...." + +setFont "times" 17 +drawText 10 120 "Hello World...." + +setFont "times" 18 +drawText 10 140 "Hello World...." + +setFont "times" 20 +drawText 10 160 "Hello World...." + +setFont "times" 22 +drawText 10 180 "Hello World...." + +setFont "times" 24 +drawText 10 205 "Hello World...." + +setFont "times" 26 +drawText 10 230 "Hello World...." + +setFont "times" 32 +drawText 10 260 "Hello World...." +end_block text + +# Rotation w/o smooth xform +save +translate 350 0 +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 50 0 200 300 300 300 0 + repeat_block text +restore +restore + +translate 0 320 + +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 0 100 300 200 300 300 0 + repeat_block text +restore + +save +translate 350 0 +save + setRenderHint SmoothPixmapTransform on + mapQuadToQuad 0 0 0 300 300 300 300 0 0 0 0 300 300 250 300 50 + repeat_block text +restore +restore + + +resetMatrix +setPen black +translate 125 20 +drawText 0 0 "No transform" +translate 350 0 +drawText 0 0 "Left Tilted" +resetMatrix +translate 125 350 +drawText 0 0 "Bottom Tilted" +translate 350 0 +drawText 0 0 "Right Tilted" +translate 120 0
\ No newline at end of file diff --git a/tests/auto/lancelot/scripts/tiled_pixmap.qps b/tests/auto/lancelot/scripts/tiled_pixmap.qps new file mode 100644 index 0000000..9cb5e0d --- /dev/null +++ b/tests/auto/lancelot/scripts/tiled_pixmap.qps @@ -0,0 +1,84 @@ +# Version: 1 +# CheckVsReference: 5% (0 0 639 638) + + +translate 0 10 +setRenderHint Antialiasing + +pixmap_load dome_argb32 the_pixmap + +begin_block draw_stuff +save + + # Standard draw + drawTiledPixmap the_pixmap 0 0 150 100 0 0 + + # Standard draw with offset + translate 160 0 + drawTiledPixmap the_pixmap 0 0 150 100 25 25 + + # xformed + translate 160 0 + save + translate 10 -10 + rotate 10 + setRenderHint SmoothPixmapTransform false + drawTiledPixmap the_pixmap 0 0 150 100 25 25 + restore + + # xformed with smooth xform + translate 160 0 + save + translate 10 -10 + rotate 10 + setRenderHint SmoothPixmapTransform + drawTiledPixmap the_pixmap 0 0 150 100 25 25 + restore +restore +end_block + +translate 0 120 +pixmap_load dome_rgb32 the_pixmap +repeat_block draw_stuff + + +translate 0 120 +pixmap_load dome_indexed the_pixmap +repeat_block draw_stuff + + +translate 0 120 +pixmap_load dome_indexed_mask the_pixmap +repeat_block draw_stuff + + +translate 0 120 +pixmap_load dome_mono the_pixmap +repeat_block draw_stuff + + +################################################################################ +# Some helpful text... +# + +resetMatrix +translate 650 80 +drawText 0 0 "32 bit w/alpha" +translate 0 120 +drawText 0 0 "32 bit w/o alpha" +translate 0 120 +drawText 0 0 "8 bit indexed" +translate 0 120 +drawText 0 0 "8 bit indexed w/mask" +translate 0 120 +drawText 0 0 "1 bit" + +resetMatrix +translate 10 630 +drawText 0 0 "normal" +translate 160 0 +drawText 0 0 "offset" +translate 160 0 +drawText 0 0 "xformed" +translate 160 0 +drawText 0 0 "smooth xformed" diff --git a/tests/auto/lancelot/tst_lancelot.cpp b/tests/auto/lancelot/tst_lancelot.cpp new file mode 100644 index 0000000..cba5fab --- /dev/null +++ b/tests/auto/lancelot/tst_lancelot.cpp @@ -0,0 +1,344 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <paintcommands.h> +#include <QPainter> +#include <QLibraryInfo> +#include <baselineprotocol.h> +#include <QHash> + +#ifndef QT_NO_OPENGL +#include <QtOpenGL> +#endif + +#ifndef SRCDIR +#define SRCDIR "." +#endif + +class tst_Lancelot : public QObject +{ +Q_OBJECT + +public: + tst_Lancelot(); + + static bool simfail; + +private: + enum GraphicsEngine { + Raster = 0, + OpenGL = 1 + }; + + bool setupTestSuite(const QStringList& blacklist); + void runTestSuite(GraphicsEngine engine, QImage::Format format); + ImageItem render(const ImageItem &item, GraphicsEngine engine, QImage::Format format); + void paint(QPaintDevice *device, const QStringList &script, const QString &filePath); + + BaselineProtocol proto; + ImageItemList baseList; + QHash<QString, QStringList> scripts; + bool dryRunMode; + QString scriptsDir; + +private slots: + void initTestCase(); + void cleanupTestCase() {} + + void testRasterARGB32PM_data(); + void testRasterARGB32PM(); + void testRasterRGB32_data(); + void testRasterRGB32(); + void testRasterRGB16_data(); + void testRasterRGB16(); + +#ifndef QT_NO_OPENGL + void testOpenGL_data(); + void testOpenGL(); +#endif +}; + +bool tst_Lancelot::simfail = false; + +tst_Lancelot::tst_Lancelot() +{ +} + +void tst_Lancelot::initTestCase() +{ + // Check and setup the environment. We treat failures because of test environment + // (e.g. script files not found) as just warnings, and not QFAILs, to avoid false negatives + // caused by environment or server instability + +#if defined(Q_OS_SOMEPLATFORM) + QSKIP("This test is not supported on this platform.", SkipAll); +#endif + if (!proto.connect(QLatin1String("tst_Lancelot"), &dryRunMode)) + QSKIP(qPrintable(proto.errorMessage()), SkipAll); + +#if defined(USE_RUNTIME_DIR) + scriptsDir = QCoreApplication::applicationDirPath() + "/scripts/"; +#else + scriptsDir = SRCDIR "/scripts/"; +#endif + QDir qpsDir(scriptsDir); + QStringList files = qpsDir.entryList(QStringList() << QLatin1String("*.qps"), QDir::Files | QDir::Readable); + if (files.isEmpty()) { + QWARN("No qps script files found in " + qpsDir.path().toLatin1()); + QSKIP("Aborted due to errors.", SkipAll); + } + + baseList.resize(files.count()); + ImageItemList::iterator it = baseList.begin(); + foreach(const QString& fileName, files) { + QFile file(scriptsDir + fileName); + file.open(QFile::ReadOnly); + QByteArray cont = file.readAll(); + scripts.insert(fileName, QString::fromLatin1(cont).split(QLatin1Char('\n'), QString::SkipEmptyParts)); + it->itemName = fileName; + it->itemChecksum = qChecksum(cont.constData(), cont.size()); + it++; + } +} + + +void tst_Lancelot::testRasterARGB32PM_data() +{ + QStringList localBlacklist; + if (!setupTestSuite(localBlacklist)) + QSKIP("Communication with baseline image server failed.", SkipAll); +} + + +void tst_Lancelot::testRasterARGB32PM() +{ + runTestSuite(Raster, QImage::Format_ARGB32_Premultiplied); +} + + +void tst_Lancelot::testRasterRGB32_data() +{ + QStringList localBlacklist; + if (!setupTestSuite(localBlacklist)) + QSKIP("Communication with baseline image server failed.", SkipAll); +} + + +void tst_Lancelot::testRasterRGB32() +{ + runTestSuite(Raster, QImage::Format_RGB32); +} + + +void tst_Lancelot::testRasterRGB16_data() +{ + QStringList localBlacklist; + if (!setupTestSuite(localBlacklist)) + QSKIP("Communication with baseline image server failed.", SkipAll); +} + + +void tst_Lancelot::testRasterRGB16() +{ + runTestSuite(Raster, QImage::Format_RGB16); +} + + +#ifndef QT_NO_OPENGL +void tst_Lancelot::testOpenGL_data() +{ + QStringList localBlacklist = QStringList() << QLatin1String("rasterops.qps"); + if (!setupTestSuite(localBlacklist)) + QSKIP("Communication with baseline image server failed.", SkipAll); +} + + +void tst_Lancelot::testOpenGL() +{ + bool ok = false; + QGLWidget glWidget; + if (glWidget.isValid() && glWidget.format().directRendering() + && ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) + || (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0)) + && QGLFramebufferObject::hasOpenGLFramebufferObjects()) + { + glWidget.makeCurrent(); + if (!QByteArray((const char *)glGetString(GL_VERSION)).contains("Mesa")) + ok = true; + } + if (ok) + runTestSuite(OpenGL, QImage::Format_RGB32); + else + QSKIP("System under test does not meet preconditions for GL testing. Skipping.", SkipAll); +} +#endif + + +bool tst_Lancelot::setupTestSuite(const QStringList& blacklist) +{ + QTest::addColumn<ImageItem>("baseline"); + + ImageItemList itemList(baseList); + if (!proto.requestBaselineChecksums(QTest::currentTestFunction(), &itemList)) { + QWARN(qPrintable(proto.errorMessage())); + return false; + } + + foreach(const ImageItem& item, itemList) { + if (!blacklist.contains(item.itemName)) + QTest::newRow(item.itemName.toLatin1()) << item; + } + return true; +} + + +void tst_Lancelot::runTestSuite(GraphicsEngine engine, QImage::Format format) +{ + QFETCH(ImageItem, baseline); + + if (baseline.status == ImageItem::IgnoreItem) + QSKIP("Blacklisted by baseline server.", SkipSingle); + + ImageItem rendered = render(baseline, engine, format); + static int consecutiveErrs = 0; + if (rendered.image.isNull()) { // Assume an error in the test environment, not Qt + QWARN("Error: Failed to render image."); + if (++consecutiveErrs < 3) { + QSKIP("Aborted due to errors.", SkipSingle); + } else { + consecutiveErrs = 0; + QSKIP("Too many errors, skipping rest of testfunction.", SkipAll); + } + } else { + consecutiveErrs = 0; + } + + + if (baseline.status == ImageItem::BaselineNotFound) { + if (!proto.submitNewBaseline(rendered, 0)) + QWARN("Failed to submit new baseline: " + proto.errorMessage().toLatin1()); + QSKIP("Baseline not found; new baseline created.", SkipSingle); + } + + if (!baseline.imageChecksums.contains(rendered.imageChecksums.at(0))) { + QByteArray serverMsg; + if (!proto.submitMismatch(rendered, &serverMsg)) + serverMsg = "Failed to submit mismatching image to server."; + if (dryRunMode) + qDebug() << "Dryrun mode, ignoring detected mismatch." << serverMsg; + else + QFAIL("Rendered image differs from baseline. Report:\n " + serverMsg); + } +} + + +ImageItem tst_Lancelot::render(const ImageItem &item, GraphicsEngine engine, QImage::Format format) +{ + ImageItem res = item; + res.imageChecksums.clear(); + res.image = QImage(); + QString filePath = scriptsDir + item.itemName; + QStringList script = scripts.value(item.itemName); + + if (engine == Raster) { + QImage img(800, 800, format); + paint(&img, script, QFileInfo(filePath).absoluteFilePath()); // eh yuck (filePath stuff) + res.image = img; + res.imageChecksums.append(ImageItem::computeChecksum(img)); +#ifndef QT_NO_OPENGL + } else if (engine == OpenGL) { + QGLWidget glWidget; + if (glWidget.isValid()) { + glWidget.makeCurrent(); + QGLFramebufferObjectFormat fboFormat; + fboFormat.setSamples(16); + fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil); + QGLFramebufferObject fbo(800, 800, fboFormat); + paint(&fbo, script, QFileInfo(filePath).absoluteFilePath()); // eh yuck (filePath stuff) + res.image = fbo.toImage().convertToFormat(format); + res.imageChecksums.append(ImageItem::computeChecksum(res.image)); + } +#endif + } + + return res; +} + +void tst_Lancelot::paint(QPaintDevice *device, const QStringList &script, const QString &filePath) +{ + QPainter p(device); + PaintCommands pcmd(script, 800, 800); + //pcmd.setShouldDrawText(false); + pcmd.setType(ImageType); + pcmd.setPainter(&p); + pcmd.setFilePath(filePath); + pcmd.runCommands(); + p.end(); + + if (simfail) { + QPainter p2(device); + p2.setPen(QPen(QBrush(Qt::cyan), 3, Qt::DashLine)); + p2.drawLine(200, 200, 600, 600); + p2.drawLine(600, 200, 200, 600); + simfail = false; + } +} + +#define main rmain +QTEST_MAIN(tst_Lancelot) +#undef main + +int main(int argc, char *argv[]) +{ + char *fargv[20]; + int fargc = 0; + for (int i = 0; i < qMin(argc, 19); i++) { + if (!qstrcmp(argv[i], "-simfail")) + tst_Lancelot::simfail = true; + else + fargv[fargc++] = argv[i]; + } + fargv[fargc] = 0; + return rmain(fargc, fargv); +} + +#include "tst_lancelot.moc" diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/main.js b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/main.js new file mode 100644 index 0000000..aa510c1 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/main.js @@ -0,0 +1,29 @@ +// No context specified, default should be used. +qsTr("One"); +QT_TR_NOOP("Two"); + +// TRANSLATOR Foo +qsTr("Three"); +QT_TR_NOOP("Four"); + +// TRANSLATOR Bar +qsTr("Five"); + +/* + TRANSLATOR Baz + This is a comment to the translator. +*/ +QT_TR_NOOP("Six"); + +// TRANSLATOR Foo.Bar +qsTr("Seven"); + +/* TRANSLATOR Bar::Baz */ +QT_TR_NOOP("Eight"); + +// qsTranslate() context is not affected. +qsTranslate("Foo", "Nine"); + +// Empty context. +// TRANSLATOR +qsTr("Ten"); diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.pro new file mode 100644 index 0000000..d549039 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.pro @@ -0,0 +1,3 @@ +SOURCES += main.js + +TRANSLATIONS = project.ts diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.ts.result new file mode 100644 index 0000000..18407b2 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parsejscontexts/project.ts.result @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0"> +<context> + <name></name> + <message> + <location filename="main.js" line="29"/> + <source>Ten</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Bar</name> + <message> + <location filename="main.js" line="10"/> + <source>Five</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Bar::Baz</name> + <message> + <location filename="main.js" line="22"/> + <source>Eight</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Baz</name> + <message> + <location filename="main.js" line="12"/> + <source></source> + <comment>This is a comment to the translator.</comment> + <translation></translation> + </message> + <message> + <location filename="main.js" line="16"/> + <source>Six</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Foo</name> + <message> + <location filename="main.js" line="6"/> + <source>Three</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="7"/> + <source>Four</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="25"/> + <source>Nine</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Foo.Bar</name> + <message> + <location filename="main.js" line="19"/> + <source>Seven</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>main</name> + <message> + <location filename="main.js" line="2"/> + <source>One</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="3"/> + <source>Two</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> diff --git a/tests/auto/macnativeevents/expectedeventlist.cpp b/tests/auto/macnativeevents/expectedeventlist.cpp index 0b75f3e..d603f82 100644 --- a/tests/auto/macnativeevents/expectedeventlist.cpp +++ b/tests/auto/macnativeevents/expectedeventlist.cpp @@ -49,7 +49,9 @@ ExpectedEventList::ExpectedEventList(QObject *target) : QObject(target), eventCount(0) { target->installEventFilter(this); - debug = !qgetenv("NATIVEDEBUG").isEmpty(); + debug = qgetenv("NATIVEDEBUG").toInt(); + if (debug > 0) + qDebug() << "Debug level sat to:" << debug; } ExpectedEventList::~ExpectedEventList() @@ -104,14 +106,17 @@ void ExpectedEventList::compareMouseEvents(QEvent *received, QEvent *expected) && (e1->globalPos() == e2->globalPos()) && (e1->button() == e2->button()) && (e1->buttons() == e2->buttons()) - && (e1->modifiers() == e2->modifiers())) + && (e1->modifiers() == e2->modifiers())) { + if (debug > 0) + qDebug() << " Received (OK):" << e1 << e1->globalPos(); return; // equal + } // INVARIANT: The two events are not equal. So we fail. Depending // on whether debug mode is no or not, we let QTest fail. Otherwise // we let the test continue for debugging puposes. int eventListNr = eventCount - eventList.size(); - if (!debug) { + if (debug == 0) { qWarning() << "Expected event" << eventListNr << "differs from received event:"; QCOMPARE(e1->pos(), e2->pos()); QCOMPARE(e1->globalPos(), e2->globalPos()); @@ -135,14 +140,17 @@ void ExpectedEventList::compareKeyEvents(QEvent *received, QEvent *expected) if (e1->key() == e2->key() && (e1->modifiers() == e2->modifiers()) && (e1->count() == e2->count()) - && (e1->isAutoRepeat() == e2->isAutoRepeat())) + && (e1->isAutoRepeat() == e2->isAutoRepeat())) { + if (debug > 0) + qDebug() << " Received (OK):" << e1 << QKeySequence(e1->key()).toString(QKeySequence::NativeText); return; // equal + } // INVARIANT: The two events are not equal. So we fail. Depending // on whether debug mode is no or not, we let QTest fail. Otherwise // we let the test continue for debugging puposes. int eventListNr = eventCount - eventList.size(); - if (!debug) { + if (debug == 0) { qWarning() << "Expected event" << eventListNr << "differs from received event:"; QCOMPARE(e1->key(), e2->key()); QCOMPARE(e1->modifiers(), e2->modifiers()); @@ -150,18 +158,19 @@ void ExpectedEventList::compareKeyEvents(QEvent *received, QEvent *expected) QCOMPARE(e1->isAutoRepeat(), e2->isAutoRepeat()); } else { qWarning() << "*** FAIL *** : Expected event" << eventListNr << "differs from received event:"; - qWarning() << "Received:" << e1 << e1->key(); - qWarning() << "Expected:" << e2 << e2->key(); + qWarning() << "Received:" << e1 << QKeySequence(e1->key()).toString(QKeySequence::NativeText); + qWarning() << "Expected:" << e2 << QKeySequence(e2->key()).toString(QKeySequence::NativeText); } } bool ExpectedEventList::eventFilter(QObject *, QEvent *received) { - if (debug) + if (debug > 1) qDebug() << received; if (eventList.isEmpty()) return false; + bool eat = false; QEvent *expected = eventList.first(); if (expected->type() == received->type()) { eventList.removeFirst(); @@ -175,11 +184,13 @@ bool ExpectedEventList::eventFilter(QObject *, QEvent *received) case QEvent::NonClientAreaMouseButtonDblClick: case QEvent::NonClientAreaMouseMove: { compareMouseEvents(received, expected); + eat = true; break; } case QEvent::KeyPress: case QEvent::KeyRelease: { compareKeyEvents(received, expected); + eat = true; break; } case QEvent::Resize: { @@ -198,6 +209,6 @@ bool ExpectedEventList::eventFilter(QObject *, QEvent *received) QAbstractEventDispatcher::instance()->interrupt(); } - return false; + return eat; } diff --git a/tests/auto/macnativeevents/expectedeventlist.h b/tests/auto/macnativeevents/expectedeventlist.h index af29962..e3fef2d 100644 --- a/tests/auto/macnativeevents/expectedeventlist.h +++ b/tests/auto/macnativeevents/expectedeventlist.h @@ -51,7 +51,7 @@ class ExpectedEventList : public QObject { QList<QEvent *> eventList; QBasicTimer timer; - bool debug; + int debug; int eventCount; void timerEvent(QTimerEvent *); diff --git a/tests/auto/macnativeevents/nativeeventlist.cpp b/tests/auto/macnativeevents/nativeeventlist.cpp index d2b9edb..8c7f609 100644 --- a/tests/auto/macnativeevents/nativeeventlist.cpp +++ b/tests/auto/macnativeevents/nativeeventlist.cpp @@ -47,7 +47,8 @@ NativeEventList::NativeEventList(int defaultWaitMs) , wait(false) , defaultWaitMs(defaultWaitMs) { - QString multiplier = qgetenv("NATIVEDEBUG"); + debug = qgetenv("NATIVEDEBUG").toInt(); + QString multiplier = qgetenv("NATIVEDEBUGSPEED"); if (!multiplier.isEmpty()) setTimeMultiplier(multiplier.toFloat()); } @@ -61,8 +62,11 @@ NativeEventList::~NativeEventList() void NativeEventList::sendNextEvent() { QNativeEvent *e = eventList.at(currIndex).second; - if (e) + if (e) { + if (debug > 0) + qDebug() << "Sending:" << *e; QNativeInput::sendNativeEvent(*e); + } waitNextEvent(); } diff --git a/tests/auto/macnativeevents/nativeeventlist.h b/tests/auto/macnativeevents/nativeeventlist.h index ce67cc7..6bebca1 100644 --- a/tests/auto/macnativeevents/nativeeventlist.h +++ b/tests/auto/macnativeevents/nativeeventlist.h @@ -76,6 +76,7 @@ private: int currIndex; bool wait; int defaultWaitMs; + int debug; }; #endif diff --git a/tests/auto/macnativeevents/qnativeevents_mac.cpp b/tests/auto/macnativeevents/qnativeevents_mac.cpp index fc2d381..8987a8d 100644 --- a/tests/auto/macnativeevents/qnativeevents_mac.cpp +++ b/tests/auto/macnativeevents/qnativeevents_mac.cpp @@ -54,11 +54,11 @@ static Qt::KeyboardModifiers getModifiersFromQuartzEvent(CGEventRef inEvent) if (flags & kCGEventFlagMaskShift || flags & kCGEventFlagMaskAlphaShift) m |= Qt::ShiftModifier; if (flags & kCGEventFlagMaskControl) - m |= Qt::MetaModifier; + m |= Qt::ControlModifier; if (flags & kCGEventFlagMaskAlternate) m |= Qt::AltModifier; if (flags & kCGEventFlagMaskCommand) - m |= Qt::ControlModifier; + m |= Qt::MetaModifier; return m; } @@ -67,11 +67,11 @@ static void setModifiersFromQNativeEvent(CGEventRef inEvent, const QNativeEvent CGEventFlags flags = 0; if (event.modifiers.testFlag(Qt::ShiftModifier)) flags |= kCGEventFlagMaskShift; - if (event.modifiers.testFlag(Qt::MetaModifier)) + if (event.modifiers.testFlag(Qt::ControlModifier)) flags |= kCGEventFlagMaskControl; if (event.modifiers.testFlag(Qt::AltModifier)) flags |= kCGEventFlagMaskAlternate; - if (event.modifiers.testFlag(Qt::ControlModifier)) + if (event.modifiers.testFlag(Qt::MetaModifier)) flags |= kCGEventFlagMaskCommand; CGEventSetFlags(inEvent, flags); } diff --git a/tests/auto/macnativeevents/tst_macnativeevents.cpp b/tests/auto/macnativeevents/tst_macnativeevents.cpp index b964399..66807fc 100644 --- a/tests/auto/macnativeevents/tst_macnativeevents.cpp +++ b/tests/auto/macnativeevents/tst_macnativeevents.cpp @@ -48,6 +48,7 @@ #include "qnativeevents.h" #include "nativeeventlist.h" #include "expectedeventlist.h" +#include <Carbon/Carbon.h> #ifdef Q_OS_MAC @@ -73,6 +74,10 @@ private slots: void testChildWindowInFrontOfStaysOnTopParentWindow(); #endif void testKeyPressOnToplevel(); + void testModifierShift(); + void testModifierAlt(); + void testModifierCtrl(); + void testModifierCtrlWithDontSwapCtrlAndMeta(); }; void tst_MacNativeEvents::testMouseMoveLocation() @@ -417,6 +422,108 @@ void tst_MacNativeEvents::testKeyPressOnToplevel() QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); } +void tst_MacNativeEvents::testModifierShift() +{ + QWidget w; + w.show(); + + NativeEventList native; + native.append(new QNativeModifierEvent(Qt::ShiftModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, true, Qt::ShiftModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, false, Qt::ShiftModifier)); + native.append(new QNativeModifierEvent(Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_Shift, Qt::NoModifier)); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::ShiftModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::ShiftModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_Shift, Qt::ShiftModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::testModifierAlt() +{ + QWidget w; + w.show(); + + NativeEventList native; + native.append(new QNativeModifierEvent(Qt::AltModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, true, Qt::AltModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, false, Qt::AltModifier)); + native.append(new QNativeModifierEvent(Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_Alt, Qt::NoModifier)); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::AltModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::AltModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_Alt, Qt::AltModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::testModifierCtrl() +{ + // On Mac, we switch the Command and Control modifier by default, so that Command + // means Meta, and Control means Command. Lets check that this works: + QWidget w; + w.show(); + + QVERIFY(kControlUnicode == QKeySequence(Qt::Key_Meta).toString(QKeySequence::NativeText)[0]); + QVERIFY(kCommandUnicode == QKeySequence(Qt::Key_Control).toString(QKeySequence::NativeText)[0]); + + NativeEventList native; + native.append(new QNativeModifierEvent(Qt::ControlModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, true, Qt::ControlModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, false, Qt::ControlModifier)); + native.append(new QNativeModifierEvent(Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_Meta, Qt::NoModifier)); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::MetaModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::MetaModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_Meta, Qt::MetaModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); +} + +void tst_MacNativeEvents::testModifierCtrlWithDontSwapCtrlAndMeta() +{ + // On Mac, we switch the Command and Control modifier by default, so that Command + // means Meta, and Control means Command. Lets check that the flag to swith off + // this behaviour works. While working on this test I realized that we actually + // don't (and never have) respected this flag for raw key events. Only for + // menus, through QKeySequence. I don't want to change this behaviour now, at + // least not until someone complains. So I choose to let the test just stop + // any unintended regressions instead. If we decide to resepect the the flag at one + // point, fix the test. + QCoreApplication::setAttribute(Qt::AA_MacDontSwapCtrlAndMeta); + QWidget w; + w.show(); + + QVERIFY(kCommandUnicode == QKeySequence(Qt::Key_Meta).toString(QKeySequence::NativeText)[0]); + QVERIFY(kControlUnicode == QKeySequence(Qt::Key_Control).toString(QKeySequence::NativeText)[0]); + + NativeEventList native; + native.append(new QNativeModifierEvent(Qt::ControlModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, true, Qt::ControlModifier)); + native.append(new QNativeKeyEvent(QNativeKeyEvent::Key_A, false, Qt::ControlModifier)); + native.append(new QNativeModifierEvent(Qt::NoModifier)); + + ExpectedEventList expected(&w); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_Meta, Qt::NoModifier)); + expected.append(new QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::ControlModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::ControlModifier)); + expected.append(new QKeyEvent(QEvent::KeyRelease, Qt::Key_Meta, Qt::ControlModifier)); + + native.play(); + QVERIFY2(expected.waitForAllEvents(), "the test did not receive all expected events!"); + QCoreApplication::setAttribute(Qt::AA_MacDontSwapCtrlAndMeta, false); +} + #include "tst_macnativeevents.moc" QTEST_MAIN(tst_MacNativeEvents) diff --git a/tests/auto/mediaobject/mediaobject.pro b/tests/auto/mediaobject/mediaobject.pro index 1fc76a2..23ec56b 100755 --- a/tests/auto/mediaobject/mediaobject.pro +++ b/tests/auto/mediaobject/mediaobject.pro @@ -15,7 +15,7 @@ wince*{ } symbian:{ - addFiles.sources = media/test.sdp + addFiles.files = media/test.sdp addFiles.path = media DEPLOYMENT += addFiles LIBS += -lCommDb -lconnmon diff --git a/tests/auto/moc/moc.pro b/tests/auto/moc/moc.pro index a89ff07..4fb9ac4 100644 --- a/tests/auto/moc/moc.pro +++ b/tests/auto/moc/moc.pro @@ -17,7 +17,7 @@ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-n escapes-in-string-literals.h cstyle-enums.h qprivateslots.h gadgetwithnoenums.h \ dir-in-include-path.h single_function_keyword.h task192552.h task189996.h \ task234909.h task240368.h pure-virtual-signals.h -if(*-g++*|*-icc*):!irix-*:!win32-*: HEADERS += os9-newlines.h win-newlines.h +if(*-g++*|*-icc*|*-clang|*-llvm):!irix-*:!win32-*: HEADERS += os9-newlines.h win-newlines.h SOURCES += tst_moc.cpp QT += sql network svg diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp index 58e7391..f3107b9 100644 --- a/tests/auto/moc/tst_moc.cpp +++ b/tests/auto/moc/tst_moc.cpp @@ -493,7 +493,12 @@ private slots: void QTBUG5590_dummyProperty(); void QTBUG12260_defaultTemplate(); void notifyError(); + void QTBUG17635_invokableAndProperty(); void revisions(); + void warnings_data(); + void warnings(); + void privateClass(); + signals: void sigWithUnsignedArg(unsigned foo); void sigWithSignedArg(signed foo); @@ -512,6 +517,7 @@ private: private: QString qtIncludePath; + class PrivateClass; }; void tst_Moc::initTestCase() @@ -1386,6 +1392,31 @@ void tst_Moc::notifyError() #endif } +class QTBUG_17635_InvokableAndProperty : public QObject +{ + Q_OBJECT +public: + Q_PROPERTY(int numberOfEggs READ numberOfEggs) + Q_PROPERTY(int numberOfChickens READ numberOfChickens) + Q_INVOKABLE QString getEgg(int index) { return QString::fromLatin1("Egg"); } + Q_INVOKABLE QString getChicken(int index) { return QString::fromLatin1("Chicken"); } + int numberOfEggs() { return 2; } + int numberOfChickens() { return 4; } +}; + +void tst_Moc::QTBUG17635_invokableAndProperty() +{ + //Moc used to fail parsing Q_INVOKABLE if they were dirrectly following a Q_PROPERTY; + QTBUG_17635_InvokableAndProperty mc; + QString val; + QMetaObject::invokeMethod(&mc, "getEgg", Q_RETURN_ARG(QString, val), Q_ARG(int, 10)); + QCOMPARE(val, QString::fromLatin1("Egg")); + QMetaObject::invokeMethod(&mc, "getChicken", Q_RETURN_ARG(QString, val), Q_ARG(int, 10)); + QCOMPARE(val, QString::fromLatin1("Chicken")); + QVERIFY(mc.metaObject()->indexOfProperty("numberOfEggs") != -1); + QVERIFY(mc.metaObject()->indexOfProperty("numberOfChickens") != -1); +} + // If changed, update VersionTestNotify below class VersionTest : public QObject { @@ -1498,8 +1529,145 @@ void tst_Moc::revisions() revisions_T<VersionTestNotify>(); } -QTEST_APPLESS_MAIN(tst_Moc) -#include "tst_moc.moc" +void tst_Moc::warnings_data() +{ + QTest::addColumn<QByteArray>("input"); + QTest::addColumn<QStringList>("args"); + QTest::addColumn<int>("exitCode"); + QTest::addColumn<QString>("expectedStdOut"); + QTest::addColumn<QString>("expectedStdErr"); + + // empty input should result in "no relevant classes" note + QTest::newRow("No relevant classes") + << QByteArray(" ") + << QStringList() + << 0 + << QString() + << QString("standard input:0: Note: No relevant classes found. No output generated."); + + // passing "-nn" should suppress "no relevant classes" note + QTest::newRow("-nn") + << QByteArray(" ") + << (QStringList() << "-nn") + << 0 + << QString() + << QString(); + + // passing "-nw" should also suppress "no relevant classes" note + QTest::newRow("-nw") + << QByteArray(" ") + << (QStringList() << "-nw") + << 0 + << QString() + << QString(); + + // This should output a warning + QTest::newRow("Invalid property warning") + << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };") + << QStringList() + << 0 + << QString("IGNORE_ALL_STDOUT") + << QString("standard input:1: Warning: Property declaration x has no READ accessor function. The property will be invalid."); + + // Passing "-nn" should NOT suppress the warning + QTest::newRow("Invalid property warning") + << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };") + << (QStringList() << "-nn") + << 0 + << QString("IGNORE_ALL_STDOUT") + << QString("standard input:1: Warning: Property declaration x has no READ accessor function. The property will be invalid."); + + // Passing "-nw" should suppress the warning + QTest::newRow("Invalid property warning") + << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };") + << (QStringList() << "-nw") + << 0 + << QString("IGNORE_ALL_STDOUT") + << QString(); + + // This should output an error + QTest::newRow("Does not inherit QObject") + << QByteArray("class X { Q_OBJECT };") + << QStringList() + << 1 + << QString() + << QString("standard input:1: Error: Class contains Q_OBJECT macro but does not inherit from QObject"); + + // "-nn" should not suppress the error + QTest::newRow("Does not inherit QObject with -nn") + << QByteArray("class X { Q_OBJECT };") + << (QStringList() << "-nn") + << 1 + << QString() + << QString("standard input:1: Error: Class contains Q_OBJECT macro but does not inherit from QObject"); + + // "-nw" should not suppress the error + QTest::newRow("Does not inherit QObject with -nn") + << QByteArray("class X { Q_OBJECT };") + << (QStringList() << "-nw") + << 1 + << QString() + << QString("standard input:1: Error: Class contains Q_OBJECT macro but does not inherit from QObject"); +} + +void tst_Moc::warnings() +{ +#ifdef MOC_CROSS_COMPILED + QSKIP("Not tested when cross-compiled", SkipAll); +#endif + + QFETCH(QByteArray, input); + QFETCH(QStringList, args); + QFETCH(int, exitCode); + QFETCH(QString, expectedStdOut); + QFETCH(QString, expectedStdErr); + +#ifdef Q_CC_MSVC + // for some reasons, moc compiled with MSVC uses a different output format + QRegExp lineNumberRe(":(\\d+):"); + lineNumberRe.setMinimal(true); + expectedStdErr.replace(lineNumberRe, "(\\1):"); +#endif + + QProcess proc; + proc.start("moc", args); + QVERIFY(proc.waitForStarted()); + + QCOMPARE(proc.write(input), qint64(input.size())); + + proc.closeWriteChannel(); + + QVERIFY(proc.waitForFinished()); + + QCOMPARE(proc.exitCode(), exitCode); + QCOMPARE(proc.exitStatus(), QProcess::NormalExit); + + // magic value "IGNORE_ALL_STDOUT" ignores stdout + if (expectedStdOut != "IGNORE_ALL_STDOUT") + QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardOutput()).trimmed(), expectedStdOut); + QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()).trimmed(), expectedStdErr); + + } + +class tst_Moc::PrivateClass : public QObject { + Q_PROPERTY(int someProperty READ someSlot WRITE someSlot2) +Q_OBJECT +Q_SIGNALS: + void someSignal(); +public Q_SLOTS: + int someSlot() { return 1; } + void someSlot2(int) {} +public: + Q_INVOKABLE PrivateClass() {} +}; + +void tst_Moc::privateClass() +{ + QVERIFY(PrivateClass::staticMetaObject.indexOfConstructor("PrivateClass()") == 0); + QVERIFY(PrivateClass::staticMetaObject.indexOfSignal("someSignal()") > 0); +} +QTEST_APPLESS_MAIN(tst_Moc) +#include "tst_moc.moc" diff --git a/tests/auto/modeltest/dynamictreemodel.cpp b/tests/auto/modeltest/dynamictreemodel.cpp index 1afe09e..2f8bb0a 100644 --- a/tests/auto/modeltest/dynamictreemodel.cpp +++ b/tests/auto/modeltest/dynamictreemodel.cpp @@ -44,6 +44,7 @@ #include <QtCore/QHash> #include <QtCore/QList> #include <QtCore/QTimer> +#include <QtCore/QDebug> DynamicTreeModel::DynamicTreeModel(QObject *parent) @@ -66,9 +67,11 @@ QModelIndex DynamicTreeModel::index(int row, int column, const QModelIndex &pare const qint64 grandParent = findParentId(parent.internalId()); if (grandParent >= 0) { QList<QList<qint64> > parentTable = m_childItems.value(grandParent); - Q_ASSERT(parent.column() < parentTable.size()); + if (parent.column() >= parentTable.size()) + qFatal("%s: parent.column() must be less than parentTable.size()", Q_FUNC_INFO); QList<qint64> parentSiblings = parentTable.at(parent.column()); - Q_ASSERT(parent.row() < parentSiblings.size()); + if (parent.row() >= parentSiblings.size()) + qFatal("%s: parent.row() must be less than parentSiblings.size()", Q_FUNC_INFO); } if (childIdColumns.size() == 0) @@ -189,7 +192,8 @@ QModelIndex ModelChangeCommand::findIndex(QList<int> rows) while (i.hasNext()) { parent = m_model->index(i.next(), col, parent); - Q_ASSERT(parent.isValid()); + if (!parent.isValid()) + qFatal("%s: parent must be valid", Q_FUNC_INFO); } return parent; } diff --git a/tests/auto/modeltest/modeltest.cpp b/tests/auto/modeltest/modeltest.cpp index e1e4094..e30d1f6 100644 --- a/tests/auto/modeltest/modeltest.cpp +++ b/tests/auto/modeltest/modeltest.cpp @@ -45,8 +45,6 @@ #include "modeltest.h" #include <QtTest/QtTest> -#undef Q_ASSERT -#define Q_ASSERT QVERIFY Q_DECLARE_METATYPE ( QModelIndex ) @@ -55,7 +53,8 @@ Q_DECLARE_METATYPE ( QModelIndex ) */ ModelTest::ModelTest ( QAbstractItemModel *_model, QObject *parent ) : QObject ( parent ), model ( _model ), fetchingMore ( false ) { - Q_ASSERT ( model ); + if (!model) + qFatal("%s: model must not be null", Q_FUNC_INFO); connect ( model, SIGNAL ( columnsAboutToBeInserted ( const QModelIndex &, int, int ) ), this, SLOT ( runAllTests() ) ); @@ -118,15 +117,15 @@ void ModelTest::runAllTests() */ void ModelTest::nonDestructiveBasicTest() { - Q_ASSERT ( model->buddy ( QModelIndex() ) == QModelIndex() ); + QVERIFY( model->buddy ( QModelIndex() ) == QModelIndex() ); model->canFetchMore ( QModelIndex() ); - Q_ASSERT ( model->columnCount ( QModelIndex() ) >= 0 ); - Q_ASSERT ( model->data ( QModelIndex() ) == QVariant() ); + QVERIFY( model->columnCount ( QModelIndex() ) >= 0 ); + QVERIFY( model->data ( QModelIndex() ) == QVariant() ); fetchingMore = true; model->fetchMore ( QModelIndex() ); fetchingMore = false; Qt::ItemFlags flags = model->flags ( QModelIndex() ); - Q_ASSERT ( flags == Qt::ItemIsDropEnabled || flags == 0 ); + QVERIFY( flags == Qt::ItemIsDropEnabled || flags == 0 ); model->hasChildren ( QModelIndex() ); model->hasIndex ( 0, 0 ); model->headerData ( 0, Qt::Horizontal ); @@ -135,8 +134,8 @@ void ModelTest::nonDestructiveBasicTest() QVariant cache; model->match ( QModelIndex(), -1, cache ); model->mimeTypes(); - Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() ); - Q_ASSERT ( model->rowCount() >= 0 ); + QVERIFY( model->parent ( QModelIndex() ) == QModelIndex() ); + QVERIFY( model->rowCount() >= 0 ); QVariant variant; model->setData ( QModelIndex(), variant, -1 ); model->setHeaderData ( -1, Qt::Horizontal, QVariant() ); @@ -158,17 +157,17 @@ void ModelTest::rowCount() // check top row QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); int rows = model->rowCount ( topIndex ); - Q_ASSERT ( rows >= 0 ); + QVERIFY( rows >= 0 ); if ( rows > 0 ) - Q_ASSERT ( model->hasChildren ( topIndex ) == true ); + QVERIFY( model->hasChildren ( topIndex ) ); QModelIndex secondLevelIndex = model->index ( 0, 0, topIndex ); if ( secondLevelIndex.isValid() ) { // not the top level // check a row count where parent is valid rows = model->rowCount ( secondLevelIndex ); - Q_ASSERT ( rows >= 0 ); + QVERIFY( rows >= 0 ); if ( rows > 0 ) - Q_ASSERT ( model->hasChildren ( secondLevelIndex ) == true ); + QVERIFY( model->hasChildren ( secondLevelIndex ) ); } // The models rowCount() is tested more extensively in checkChildren(), @@ -182,12 +181,12 @@ void ModelTest::columnCount() { // check top row QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); - Q_ASSERT ( model->columnCount ( topIndex ) >= 0 ); + QVERIFY( model->columnCount ( topIndex ) >= 0 ); // check a column count where parent is valid QModelIndex childIndex = model->index ( 0, 0, topIndex ); if ( childIndex.isValid() ) - Q_ASSERT ( model->columnCount ( childIndex ) >= 0 ); + QVERIFY( model->columnCount ( childIndex ) >= 0 ); // columnCount() is tested more extensively in checkChildren(), // but this catches the big mistakes @@ -200,19 +199,19 @@ void ModelTest::hasIndex() { // qDebug() << "hi"; // Make sure that invalid values returns an invalid index - Q_ASSERT ( model->hasIndex ( -2, -2 ) == false ); - Q_ASSERT ( model->hasIndex ( -2, 0 ) == false ); - Q_ASSERT ( model->hasIndex ( 0, -2 ) == false ); + QVERIFY( !model->hasIndex ( -2, -2 ) ); + QVERIFY( !model->hasIndex ( -2, 0 ) ); + QVERIFY( !model->hasIndex ( 0, -2 ) ); int rows = model->rowCount(); int columns = model->columnCount(); // check out of bounds - Q_ASSERT ( model->hasIndex ( rows, columns ) == false ); - Q_ASSERT ( model->hasIndex ( rows + 1, columns + 1 ) == false ); + QVERIFY( !model->hasIndex ( rows, columns ) ); + QVERIFY( !model->hasIndex ( rows + 1, columns + 1 ) ); if ( rows > 0 ) - Q_ASSERT ( model->hasIndex ( 0, 0 ) == true ); + QVERIFY( model->hasIndex ( 0, 0 ) ); // hasIndex() is tested more extensively in checkChildren(), // but this catches the big mistakes @@ -225,9 +224,9 @@ void ModelTest::index() { // qDebug() << "i"; // Make sure that invalid values returns an invalid index - Q_ASSERT ( model->index ( -2, -2 ) == QModelIndex() ); - Q_ASSERT ( model->index ( -2, 0 ) == QModelIndex() ); - Q_ASSERT ( model->index ( 0, -2 ) == QModelIndex() ); + QVERIFY( model->index ( -2, -2 ) == QModelIndex() ); + QVERIFY( model->index ( -2, 0 ) == QModelIndex() ); + QVERIFY( model->index ( 0, -2 ) == QModelIndex() ); int rows = model->rowCount(); int columns = model->columnCount(); @@ -236,13 +235,13 @@ void ModelTest::index() return; // Catch off by one errors - Q_ASSERT ( model->index ( rows, columns ) == QModelIndex() ); - Q_ASSERT ( model->index ( 0, 0 ).isValid() == true ); + QVERIFY( model->index ( rows, columns ) == QModelIndex() ); + QVERIFY( model->index ( 0, 0 ).isValid() ); // Make sure that the same index is *always* returned QModelIndex a = model->index ( 0, 0 ); QModelIndex b = model->index ( 0, 0 ); - Q_ASSERT ( a == b ); + QVERIFY( a == b ); // index() is tested more extensively in checkChildren(), // but this catches the big mistakes @@ -256,7 +255,7 @@ void ModelTest::parent() // qDebug() << "p"; // Make sure the model wont crash and will return an invalid QModelIndex // when asked for the parent of an invalid index. - Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() ); + QVERIFY( model->parent ( QModelIndex() ) == QModelIndex() ); if ( model->rowCount() == 0 ) return; @@ -269,13 +268,13 @@ void ModelTest::parent() // Common error test #1, make sure that a top level index has a parent // that is a invalid QModelIndex. QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); - Q_ASSERT ( model->parent ( topIndex ) == QModelIndex() ); + QVERIFY( model->parent ( topIndex ) == QModelIndex() ); // Common error test #2, make sure that a second level index has a parent // that is the first level index. if ( model->rowCount ( topIndex ) > 0 ) { QModelIndex childIndex = model->index ( 0, 0, topIndex ); - Q_ASSERT ( model->parent ( childIndex ) == topIndex ); + QVERIFY( model->parent ( childIndex ) == topIndex ); } // Common error test #3, the second column should NOT have the same children @@ -285,7 +284,7 @@ void ModelTest::parent() if ( model->rowCount ( topIndex1 ) > 0 ) { QModelIndex childIndex = model->index ( 0, 0, topIndex ); QModelIndex childIndex1 = model->index ( 0, 0, topIndex1 ); - Q_ASSERT ( childIndex != childIndex1 ); + QVERIFY( childIndex != childIndex1 ); } // Full test, walk n levels deep through the model making sure that all @@ -325,47 +324,47 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) int columns = model->columnCount ( parent ); if ( rows > 0 ) - Q_ASSERT ( model->hasChildren ( parent ) ); + QVERIFY( model->hasChildren ( parent ) ); // Some further testing against rows(), columns(), and hasChildren() - Q_ASSERT ( rows >= 0 ); - Q_ASSERT ( columns >= 0 ); + QVERIFY( rows >= 0 ); + QVERIFY( columns >= 0 ); if ( rows > 0 ) - Q_ASSERT ( model->hasChildren ( parent ) == true ); + QVERIFY( model->hasChildren ( parent ) ); //qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows // << "columns:" << columns << "parent column:" << parent.column(); - Q_ASSERT ( model->hasIndex ( rows + 1, 0, parent ) == false ); + QVERIFY( !model->hasIndex ( rows + 1, 0, parent ) ); for ( int r = 0; r < rows; ++r ) { if ( model->canFetchMore ( parent ) ) { fetchingMore = true; model->fetchMore ( parent ); fetchingMore = false; } - Q_ASSERT ( model->hasIndex ( r, columns + 1, parent ) == false ); + QVERIFY( !model->hasIndex ( r, columns + 1, parent ) ); for ( int c = 0; c < columns; ++c ) { - Q_ASSERT ( model->hasIndex ( r, c, parent ) == true ); + QVERIFY( model->hasIndex ( r, c, parent ) ); QModelIndex index = model->index ( r, c, parent ); // rowCount() and columnCount() said that it existed... - Q_ASSERT ( index.isValid() == true ); + QVERIFY( index.isValid() ); // index() should always return the same index when called twice in a row QModelIndex modifiedIndex = model->index ( r, c, parent ); - Q_ASSERT ( index == modifiedIndex ); + QVERIFY( index == modifiedIndex ); // Make sure we get the same index if we request it twice in a row QModelIndex a = model->index ( r, c, parent ); QModelIndex b = model->index ( r, c, parent ); - Q_ASSERT ( a == b ); + QVERIFY( a == b ); // Some basic checking on the index that is returned - Q_ASSERT ( index.model() == model ); - Q_ASSERT ( index.row() == r ); - Q_ASSERT ( index.column() == c ); + QVERIFY( index.model() == model ); + QCOMPARE( index.row(), r ); + QCOMPARE( index.column(), c ); // While you can technically return a QVariant usually this is a sign - // of an bug in data() Disable if this really is ok in your model. -// Q_ASSERT ( model->data ( index, Qt::DisplayRole ).isValid() == true ); + // of a bug in data(). Disable if this really is ok in your model. +// QVERIFY( model->data ( index, Qt::DisplayRole ).isValid() ); // If the next test fails here is some somewhat useful debug you play with. @@ -380,8 +379,7 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) } // Check that we can get back our real parent. -// qDebug() << model->parent ( index ) << parent ; - Q_ASSERT ( model->parent ( index ) == parent ); + QCOMPARE( model->parent ( index ), parent ); // recursively go down the children if ( model->hasChildren ( index ) && currentDepth < 10 ) { @@ -391,7 +389,7 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) // make sure that after testing the children that the index doesn't change. QModelIndex newerIndex = model->index ( r, c, parent ); - Q_ASSERT ( index == newerIndex ); + QVERIFY( index == newerIndex ); } } } @@ -402,68 +400,68 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) void ModelTest::data() { // Invalid index should return an invalid qvariant - Q_ASSERT ( !model->data ( QModelIndex() ).isValid() ); + QVERIFY( !model->data ( QModelIndex() ).isValid() ); if ( model->rowCount() == 0 ) return; // A valid index should have a valid QVariant data - Q_ASSERT ( model->index ( 0, 0 ).isValid() ); + QVERIFY( model->index ( 0, 0 ).isValid() ); // shouldn't be able to set data on an invalid index - Q_ASSERT ( model->setData ( QModelIndex(), QLatin1String ( "foo" ), Qt::DisplayRole ) == false ); + QVERIFY( !model->setData ( QModelIndex(), QLatin1String ( "foo" ), Qt::DisplayRole ) ); // General Purpose roles that should return a QString QVariant variant = model->data ( model->index ( 0, 0 ), Qt::ToolTipRole ); if ( variant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QString> ( variant ) ); + QVERIFY( qVariantCanConvert<QString> ( variant ) ); } variant = model->data ( model->index ( 0, 0 ), Qt::StatusTipRole ); if ( variant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QString> ( variant ) ); + QVERIFY( qVariantCanConvert<QString> ( variant ) ); } variant = model->data ( model->index ( 0, 0 ), Qt::WhatsThisRole ); if ( variant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QString> ( variant ) ); + QVERIFY( qVariantCanConvert<QString> ( variant ) ); } // General Purpose roles that should return a QSize variant = model->data ( model->index ( 0, 0 ), Qt::SizeHintRole ); if ( variant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QSize> ( variant ) ); + QVERIFY( qVariantCanConvert<QSize> ( variant ) ); } // General Purpose roles that should return a QFont QVariant fontVariant = model->data ( model->index ( 0, 0 ), Qt::FontRole ); if ( fontVariant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QFont> ( fontVariant ) ); + QVERIFY( qVariantCanConvert<QFont> ( fontVariant ) ); } // Check that the alignment is one we know about QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole ); if ( textAlignmentVariant.isValid() ) { int alignment = textAlignmentVariant.toInt(); - Q_ASSERT ( alignment == ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) ); + QCOMPARE( alignment, ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) ); } // General Purpose roles that should return a QColor QVariant colorVariant = model->data ( model->index ( 0, 0 ), Qt::BackgroundColorRole ); if ( colorVariant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QColor> ( colorVariant ) ); + QVERIFY( qVariantCanConvert<QColor> ( colorVariant ) ); } colorVariant = model->data ( model->index ( 0, 0 ), Qt::TextColorRole ); if ( colorVariant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QColor> ( colorVariant ) ); + QVERIFY( qVariantCanConvert<QColor> ( colorVariant ) ); } // Check that the "check state" is one we know about. QVariant checkStateVariant = model->data ( model->index ( 0, 0 ), Qt::CheckStateRole ); if ( checkStateVariant.isValid() ) { int state = checkStateVariant.toInt(); - Q_ASSERT ( state == Qt::Unchecked || - state == Qt::PartiallyChecked || - state == Qt::Checked ); + QVERIFY( state == Qt::Unchecked || + state == Qt::PartiallyChecked || + state == Qt::Checked ); } } @@ -494,7 +492,7 @@ void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, in void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) { Changing c = insert.pop(); - Q_ASSERT ( c.parent == parent ); + QVERIFY( c.parent == parent ); // qDebug() << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize // << "parent=" << model->data ( parent ).toString() << "current rowcount of parent=" << model->rowCount ( parent ); @@ -504,8 +502,8 @@ void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) // } // qDebug(); - Q_ASSERT ( c.oldSize + ( end - start + 1 ) == model->rowCount ( parent ) ); - Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); + QVERIFY( c.oldSize + ( end - start + 1 ) == model->rowCount ( parent ) ); + QVERIFY( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); if (c.next != model->data(model->index(end + 1, 0, c.parent))) { qDebug() << start << end; @@ -514,7 +512,7 @@ void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent)); } - Q_ASSERT ( c.next == model->data ( model->index ( end + 1, 0, c.parent ) ) ); + QVERIFY( c.next == model->data ( model->index ( end + 1, 0, c.parent ) ) ); } void ModelTest::layoutAboutToBeChanged() @@ -527,7 +525,7 @@ void ModelTest::layoutChanged() { for ( int i = 0; i < changing.count(); ++i ) { QPersistentModelIndex p = changing[i]; - Q_ASSERT ( p == model->index ( p.row(), p.column(), p.parent() ) ); + QVERIFY( p == model->index ( p.row(), p.column(), p.parent() ) ); } changing.clear(); } @@ -557,10 +555,10 @@ void ModelTest::rowsRemoved ( const QModelIndex & parent, int start, int end ) { qDebug() << "rr" << parent << start << end; Changing c = remove.pop(); - Q_ASSERT ( c.parent == parent ); - Q_ASSERT ( c.oldSize - ( end - start + 1 ) == model->rowCount ( parent ) ); - Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); - Q_ASSERT ( c.next == model->data ( model->index ( start, 0, c.parent ) ) ); + QVERIFY( c.parent == parent ); + QVERIFY( c.oldSize - ( end - start + 1 ) == model->rowCount ( parent ) ); + QVERIFY( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); + QVERIFY( c.next == model->data ( model->index ( start, 0, c.parent ) ) ); } diff --git a/tests/auto/modeltest/tst_modeltest.cpp b/tests/auto/modeltest/tst_modeltest.cpp index cfaf210..aba0894 100644 --- a/tests/auto/modeltest/tst_modeltest.cpp +++ b/tests/auto/modeltest/tst_modeltest.cpp @@ -201,8 +201,10 @@ class ObservingObject : public QObject Q_OBJECT public: ObservingObject(AccessibleProxyModel *proxy, QObject *parent = 0) - : QObject(parent), - m_proxy(proxy) + : QObject(parent) + , m_proxy(proxy) + , storePersistentFailureCount(0) + , checkPersistentFailureCount(0) { connect(m_proxy, SIGNAL(layoutAboutToBeChanged()), SLOT(storePersistent())); connect(m_proxy, SIGNAL(layoutChanged()), SLOT(checkPersistent())); @@ -215,8 +217,14 @@ public slots: for (int row = 0; row < m_proxy->rowCount(parent); ++row) { QModelIndex proxyIndex = m_proxy->index(row, 0, parent); QModelIndex sourceIndex = m_proxy->mapToSource(proxyIndex); - Q_ASSERT(proxyIndex.isValid()); - Q_ASSERT(sourceIndex.isValid()); + if (!proxyIndex.isValid()) { + qWarning("%s: Invalid proxy index", Q_FUNC_INFO); + ++storePersistentFailureCount; + } + if (!sourceIndex.isValid()) { + qWarning("%s: invalid source index", Q_FUNC_INFO); + ++storePersistentFailureCount; + } m_persistentSourceIndexes.append(sourceIndex); m_persistentProxyIndexes.append(proxyIndex); if (m_proxy->hasChildren(proxyIndex)) @@ -226,12 +234,24 @@ public slots: void storePersistent() { - foreach(const QModelIndex &idx, m_persistentProxyIndexes) - Q_ASSERT(idx.isValid()); // This is called from layoutAboutToBeChanged. Persistent indexes should be valid - - Q_ASSERT(m_proxy->persistent().isEmpty()); + // This method is called from layoutAboutToBeChanged. Persistent indexes should be valid + foreach(const QModelIndex &idx, m_persistentProxyIndexes) + if (!idx.isValid()) { + qWarning("%s: persistentProxyIndexes contains invalid index", Q_FUNC_INFO); + ++storePersistentFailureCount; + } + + if (!m_proxy->persistent().isEmpty()) { + qWarning("%s: proxy should have no persistent indexes when storePersistent called", + Q_FUNC_INFO); + ++storePersistentFailureCount; + } storePersistent(QModelIndex()); - Q_ASSERT(!m_proxy->persistent().isEmpty()); + if (m_proxy->persistent().isEmpty()) { + qWarning("%s: proxy should have persistent index after storePersistent called", + Q_FUNC_INFO); + ++storePersistentFailureCount; + } } void checkPersistent() @@ -243,7 +263,10 @@ public slots: for (int row = 0; row < m_persistentProxyIndexes.size(); ++row) { QModelIndex updatedProxy = m_persistentProxyIndexes.at(row); QModelIndex updatedSource = m_persistentSourceIndexes.at(row); - QCOMPARE(m_proxy->mapToSource(updatedProxy), updatedSource); + if (m_proxy->mapToSource(updatedProxy) != updatedSource) { + qWarning("%s: check failed at row %d", Q_FUNC_INFO, row); + ++checkPersistentFailureCount; + } } m_persistentSourceIndexes.clear(); m_persistentProxyIndexes.clear(); @@ -253,6 +276,9 @@ private: AccessibleProxyModel *m_proxy; QList<QPersistentModelIndex> m_persistentSourceIndexes; QList<QPersistentModelIndex> m_persistentProxyIndexes; +public: + int storePersistentFailureCount; + int checkPersistentFailureCount; }; void tst_ModelTest::moveSourceItems() @@ -280,6 +306,9 @@ void tst_ModelTest::moveSourceItems() moveCommand->setDestAncestors(QList<int>() << 1); moveCommand->setDestRow(0); moveCommand->doCommand(); + + QCOMPARE(observer.storePersistentFailureCount, 0); + QCOMPARE(observer.checkPersistentFailureCount, 0); } void tst_ModelTest::testResetThroughProxy() @@ -302,6 +331,9 @@ void tst_ModelTest::testResetThroughProxy() ModelResetCommand *resetCommand = new ModelResetCommand(model, this); resetCommand->setNumCols(0); resetCommand->doCommand(); + + QCOMPARE(observer.storePersistentFailureCount, 0); + QCOMPARE(observer.checkPersistentFailureCount, 0); } diff --git a/tests/auto/network.pro b/tests/auto/network.pro index 7d83054..e4cecce 100644 --- a/tests/auto/network.pro +++ b/tests/auto/network.pro @@ -16,15 +16,18 @@ SUBDIRS=\ qhttpnetworkconnection \ qhttpnetworkreply \ qhttpsocketengine \ - qnativesocketengine \ + platformsocketengine \ qnetworkaccessmanager \ qnetworkaddressentry \ + qnetworkcachemetadata \ qnetworkconfiguration \ qnetworkconfigurationmanager \ qnetworkcookie \ qnetworkcookiejar \ + qnetworkdiskcache \ qnetworkinterface \ qnetworkproxy \ + qnetworkreply \ qnetworkrequest \ qnetworksession \ qobjectperformance \ @@ -35,13 +38,17 @@ SUBDIRS=\ qsslerror \ qsslkey \ qsslsocket \ + qsslsocket_onDemandCertificates_member \ + qsslsocket_onDemandCertificates_static \ + qtcpserver \ + qudpsocket \ # qnetworkproxyfactory \ # Uses a hardcoded proxy configuration !contains(QT_CONFIG, private_tests): SUBDIRS -= \ qauthenticator \ qhttpnetworkconnection \ qhttpnetworkreply \ - qnativesocketengine \ + platformsocketengine \ qsocketnotifier \ qsocks5socketengine \ diff --git a/tests/auto/networkselftest/networkselftest.pro b/tests/auto/networkselftest/networkselftest.pro index 3e680d8..2742fcb 100644 --- a/tests/auto/networkselftest/networkselftest.pro +++ b/tests/auto/networkselftest/networkselftest.pro @@ -4,12 +4,12 @@ SOURCES += tst_networkselftest.cpp QT = core network wince*: { - addFiles.sources = rfc3252.txt + addFiles.files = rfc3252.txt addFiles.path = . DEPLOYMENT += addFiles DEFINES += SRCDIR=\\\"\\\" } else:symbian { - addFiles.sources = rfc3252.txt + addFiles.files = rfc3252.txt addFiles.path = . DEPLOYMENT += addFiles TARGET.CAPABILITY = NetworkServices ReadUserData diff --git a/tests/auto/networkselftest/tst_networkselftest.cpp b/tests/auto/networkselftest/tst_networkselftest.cpp index 516bd37..b2ce5ca 100644 --- a/tests/auto/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/networkselftest/tst_networkselftest.cpp @@ -42,6 +42,14 @@ #include <QtTest/QtTest> #include <QtNetwork/QtNetwork> +#include <time.h> + +#ifndef QT_NO_BEARERMANAGEMENT +#include <QtNetwork/qnetworkconfigmanager.h> +#include <QtNetwork/qnetworkconfiguration.h> +#include <QtNetwork/qnetworksession.h> +#endif + #ifdef Q_OS_SYMBIAN // In Symbian OS test data is located in applications private dir // Current path (C:\private\<UID>) contains only ascii chars @@ -62,6 +70,7 @@ public: QHostAddress serverIpAddress(); private slots: + void initTestCase(); void hostTest(); void dnsResolution_data(); void dnsResolution(); @@ -72,17 +81,29 @@ private slots: // specific protocol tests void ftpServer(); + void ftpProxyServer(); void imapServer(); void httpServer(); + void httpServerFiles_data(); + void httpServerFiles(); + void httpServerCGI_data(); + void httpServerCGI(); void httpsServer(); void httpProxy(); void httpProxyBasicAuth(); void httpProxyNtlmAuth(); void socks5Proxy(); void socks5ProxyAuth(); + void smbServer(); // ssl supported test void supportsSsl(); +private: +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkConfigurationManager *netConfMan; + QNetworkConfiguration networkConfiguration; + QScopedPointer<QNetworkSession> networkSession; +#endif }; class Chat @@ -158,7 +179,7 @@ static QString prettyByteArray(const QByteArray &array) static bool doSocketRead(QTcpSocket *socket, int minBytesAvailable, int timeout = 4000) { - QTime timer; + QElapsedTimer timer; timer.start(); forever { if (socket->bytesAvailable() >= minBytesAvailable) @@ -346,6 +367,26 @@ QHostAddress tst_NetworkSelfTest::serverIpAddress() return cachedIpAddress; } +void tst_NetworkSelfTest::initTestCase() +{ +#ifndef QT_NO_BEARERMANAGEMENT + netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + networkConfiguration = netConfMan->defaultConfiguration(); + if (networkConfiguration.isValid()) { + networkSession.reset(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); + } +#endif +} + void tst_NetworkSelfTest::hostTest() { // this is a localhost self-test @@ -410,6 +451,8 @@ void tst_NetworkSelfTest::remotePortsOpen_data() QTest::newRow("http-proxy-auth-ntlm") << 3130; QTest::newRow("socks5-proxy") << 1080; QTest::newRow("socks5-proxy-auth") << 1081; + QTest::newRow("ftp-proxy") << 2121; + QTest::newRow("smb") << 139; } void tst_NetworkSelfTest::remotePortsOpen() @@ -457,20 +500,53 @@ void tst_NetworkSelfTest::fileLineEndingTest() QVERIFY2(!lineEndingType.compare("LF"), QString("Reference file %1 has %2 as line ending - Git checkout issue !?!").arg(referenceName, lineEndingType).toLocal8Bit()); } -static QList<Chat> ftpChat() +static QList<Chat> ftpChat(const QByteArray &userSuffix = QByteArray()) { - return QList<Chat>() << Chat::expect("220") + QList<Chat> rv; + rv << Chat::expect("220") << Chat::discardUntil("\r\n") - << Chat::send("USER anonymous\r\n") + << Chat::send("USER anonymous" + userSuffix + "\r\n") << Chat::expect("331") << Chat::discardUntil("\r\n") << Chat::send("PASS user@hostname\r\n") << Chat::expect("230") << Chat::discardUntil("\r\n") - << Chat::send("QUIT\r\n") - << Chat::expect("221") + + << Chat::send("CWD pub\r\n") + << Chat::expect("250") + << Chat::discardUntil("\r\n") + << Chat::send("CWD dir-not-readable\r\n") + << Chat::expect("550") + << Chat::discardUntil("\r\n") + << Chat::send("PWD\r\n") + << Chat::expect("257 \"/pub\"\r\n") + << Chat::send("SIZE file-not-readable.txt\r\n") + << Chat::expect("213 41\r\n") + << Chat::send("CWD qxmlquery\r\n") + << Chat::expect("250") << Chat::discardUntil("\r\n") - << Chat::RemoteDisconnect; + + << Chat::send("CWD /qtest\r\n") + << Chat::expect("250") + << Chat::discardUntil("\r\n") + << Chat::send("SIZE bigfile\r\n") + << Chat::expect("213 519240\r\n") + << Chat::send("SIZE rfc3252\r\n") + << Chat::expect("213 25962\r\n") + << Chat::send("SIZE rfc3252.txt\r\n") + << Chat::expect("213 25962\r\n") +// << Chat::send("SIZE nonASCII/german_\344\366\374\304\326\334\337\r\n") +// << Chat::expect("213 40\r\n") + + << Chat::send("QUIT\r\n"); +#ifdef Q_OS_SYMBIAN + if (userSuffix.length() == 0) // received but unacknowledged packets are discarded by TCP RST, so this doesn't work with frox proxy +#endif + rv << Chat::expect("221") + << Chat::discardUntil("\r\n"); + + rv << Chat::RemoteDisconnect; + return rv; } void tst_NetworkSelfTest::ftpServer() @@ -478,6 +554,11 @@ void tst_NetworkSelfTest::ftpServer() netChat(21, ftpChat()); } +void tst_NetworkSelfTest::ftpProxyServer() +{ + netChat(2121, ftpChat("@" + QtNetworkSettings::serverName().toLatin1())); +} + void tst_NetworkSelfTest::imapServer() { netChat(143, QList<Chat>() @@ -495,6 +576,14 @@ void tst_NetworkSelfTest::imapServer() void tst_NetworkSelfTest::httpServer() { + QString uniqueExtension; + qsrand(time(0)); +#ifndef Q_OS_WINCE + uniqueExtension = QString("%1%2%3").arg((qulonglong)this).arg(qrand()).arg((qulonglong)time(0)); +#else + uniqueExtension = QString("%1%2").arg((qulonglong)this).arg(qrand()); +#endif + netChat(80, QList<Chat>() // HTTP/0.9 chat: << Chat::send("GET /\r\n") @@ -523,9 +612,185 @@ void tst_NetworkSelfTest::httpServer() << Chat::discardUntil(" ") << Chat::expect("200 ") << Chat::DiscardUntilDisconnect + + // HTTP protected area + << Chat::Reconnect + << Chat::send("GET /qtest/protected/rfc3252.txt HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("401 ") + << Chat::DiscardUntilDisconnect + + << Chat::Reconnect + << Chat::send("HEAD /qtest/protected/rfc3252.txt HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "Authorization: Basic cXNvY2tzdGVzdDpwYXNzd29yZA==\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::DiscardUntilDisconnect + + // DAV area + << Chat::Reconnect + << Chat::send("HEAD /dav/ HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::DiscardUntilDisconnect + + // HTTP/1.0 PUT + << Chat::Reconnect + << Chat::send("PUT /dav/networkselftest-" + uniqueExtension.toLatin1() + ".txt HTTP/1.0\r\n" + "Content-Length: 5\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n" + "Hello") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("201 ") + << Chat::DiscardUntilDisconnect + + // check that the file did get uploaded + << Chat::Reconnect + << Chat::send("HEAD /dav/networkselftest-" + uniqueExtension.toLatin1() + ".txt HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::discardUntil("\r\nContent-Length: 5\r\n") + << Chat::DiscardUntilDisconnect + + // HTTP/1.0 DELETE + << Chat::Reconnect + << Chat::send("DELETE /dav/networkselftest-" + uniqueExtension.toLatin1() + ".txt HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("204 ") + << Chat::DiscardUntilDisconnect ); } +void tst_NetworkSelfTest::httpServerFiles_data() +{ + QTest::addColumn<QString>("uri"); + QTest::addColumn<int>("size"); + + QTest::newRow("fluke.gif") << "/qtest/fluke.gif" << -1; + QTest::newRow("bigfile") << "/qtest/bigfile" << 519240; + QTest::newRow("rfc3252.txt") << "/qtest/rfc3252.txt" << 25962; + QTest::newRow("protected/rfc3252.txt") << "/qtest/protected/rfc3252.txt" << 25962; + QTest::newRow("completelyEmptyQuery.xq") << "/qtest/qxmlquery/completelyEmptyQuery.xq" << -1; + QTest::newRow("notWellformedViaHttps.xml") << "/qtest/qxmlquery/notWellformedViaHttps.xml" << -1; + QTest::newRow("notWellformed.xml") << "/qtest/qxmlquery/notWellformed.xml" << -1; + QTest::newRow("viaHttp.xq") << "/qtest/qxmlquery/viaHttp.xq" << -1; + QTest::newRow("wellFormedViaHttps.xml") << "/qtest/qxmlquery/wellFormedViaHttps.xml" << -1; + QTest::newRow("wellFormed.xml") << "/qtest/qxmlquery/wellFormed.xml" << -1; +} + +void tst_NetworkSelfTest::httpServerFiles() +{ + QFETCH(QString, uri); + QFETCH(int, size); + + QList<Chat> chat; + chat << Chat::send("HEAD " + QUrl::toPercentEncoding(uri, "/") + " HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "Authorization: Basic cXNvY2tzdGVzdDpwYXNzd29yZA==\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::skipBytes(1) // HTTP/1.0 or 1.1 reply + << Chat::expect(" 200 "); + if (size != -1) + chat << Chat::discardUntil("\r\nContent-Length: " + QByteArray::number(size) + "\r\n"); + chat << Chat::DiscardUntilDisconnect; + netChat(80, chat); +} + +void tst_NetworkSelfTest::httpServerCGI_data() +{ + QTest::addColumn<QByteArray>("request"); + QTest::addColumn<QByteArray>("result"); + QTest::addColumn<QByteArray>("additionalHeader"); + + QTest::newRow("echo.cgi") + << QByteArray("GET /qtest/cgi-bin/echo.cgi?Hello+World HTTP/1.0\r\n" + "Connection: close\r\n" + "\r\n") + << QByteArray("Hello+World") + << QByteArray(); + + QTest::newRow("echo.cgi(POST)") + << QByteArray("POST /qtest/cgi-bin/echo.cgi?Hello+World HTTP/1.0\r\n" + "Connection: close\r\n" + "Content-Length: 15\r\n" + "\r\n" + "Hello, World!\r\n") + << QByteArray("Hello, World!\r\n") + << QByteArray(); + + QTest::newRow("md5sum.cgi") + << QByteArray("POST /qtest/cgi-bin/md5sum.cgi HTTP/1.0\r\n" + "Connection: close\r\n" + "Content-Length: 15\r\n" + "\r\n" + "Hello, World!\r\n") + << QByteArray("29b933a8d9a0fcef0af75f1713f4940e\n") + << QByteArray(); + + QTest::newRow("protected/md5sum.cgi") + << QByteArray("POST /qtest/protected/cgi-bin/md5sum.cgi HTTP/1.0\r\n" + "Connection: close\r\n" + "Authorization: Basic cXNvY2tzdGVzdDpwYXNzd29yZA==\r\n" + "Content-Length: 15\r\n" + "\r\n" + "Hello, World!\r\n") + << QByteArray("29b933a8d9a0fcef0af75f1713f4940e\n") + << QByteArray(); + + QTest::newRow("set-cookie.cgi") + << QByteArray("POST /qtest/cgi-bin/set-cookie.cgi HTTP/1.0\r\n" + "Connection: close\r\n" + "Content-Length: 8\r\n" + "\r\n" + "foo=bar\n") + << QByteArray("Success\n") + << QByteArray("\r\nSet-Cookie: foo=bar\r\n"); +} + +void tst_NetworkSelfTest::httpServerCGI() +{ + QFETCH(QByteArray, request); + QFETCH(QByteArray, result); + QFETCH(QByteArray, additionalHeader); + QList<Chat> chat; + chat << Chat::send(request) + << Chat::expect("HTTP/1.") << Chat::skipBytes(1) + << Chat::expect(" 200 "); + + if (!additionalHeader.isEmpty()) + chat << Chat::discardUntil(additionalHeader); + + chat << Chat::discardUntil("\r\n\r\n") + << Chat::expect(result) + << Chat::RemoteDisconnect; + netChat(80, chat); +} + void tst_NetworkSelfTest::httpsServer() { #ifndef QT_NO_OPENSSL @@ -727,7 +992,63 @@ void tst_NetworkSelfTest::supportsSsl() #ifdef QT_NO_OPENSSL QFAIL("SSL not compiled in"); #else - QVERIFY(QSslSocket::supportsSsl()); + QVERIFY2(QSslSocket::supportsSsl(), "Could not load SSL libraries"); +#endif +} + +void tst_NetworkSelfTest::smbServer() +{ + static const char contents[] = "This is 34 bytes. Do not change..."; +#ifdef Q_OS_WIN + // use Windows's native UNC support to try and open a file on the server + QString filepath = QString("\\\\%1\\testshare\\test.pri").arg(QtNetworkSettings::winServerName()); + FILE *f = fopen(filepath.toLatin1(), "rb"); + QVERIFY2(f, qt_error_string().toLocal8Bit()); + + char buf[128]; + size_t ret = fread(buf, 1, sizeof buf, f); + fclose(f); + + QCOMPARE(ret, strlen(contents)); + QVERIFY(memcmp(buf, contents, strlen(contents)) == 0); +#else + // try to use Samba + QString progname = "smbclient"; + QProcess smbclient; + smbclient.start(progname, QIODevice::ReadOnly); + if (!smbclient.waitForStarted(2000)) + QSKIP("Could not find smbclient (from Samba), cannot continue testing", SkipAll); + if (!smbclient.waitForFinished(2000) || smbclient.exitStatus() != QProcess::NormalExit) + QSKIP("smbclient isn't working, cannot continue testing", SkipAll); + smbclient.close(); + + // try listing the server + smbclient.start(progname, QStringList() << "-g" << "-N" << "-L" << QtNetworkSettings::winServerName(), QIODevice::ReadOnly); + QVERIFY(smbclient.waitForFinished(5000)); + if (smbclient.exitStatus() != QProcess::NormalExit) + QSKIP("smbclient crashed", SkipAll); + QVERIFY2(smbclient.exitCode() == 0, "Test server not found"); + + QByteArray output = smbclient.readAll(); + QVERIFY(output.contains("Disk|testshare|")); + QVERIFY(output.contains("Disk|testsharewritable|")); + QVERIFY(output.contains("Disk|testsharelargefile|")); + qDebug() << "Test server found and shares are correct"; + + // try getting a file + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.insert("PAGER", "/bin/cat"); // just in case + smbclient.setProcessEnvironment(env); + smbclient.start(progname, QStringList() << "-N" << "-c" << "more test.pri" + << QString("\\\\%1\\testshare").arg(QtNetworkSettings::winServerName()), QIODevice::ReadOnly); + QVERIFY(smbclient.waitForFinished(5000)); + if (smbclient.exitStatus() != QProcess::NormalExit) + QSKIP("smbclient crashed", SkipAll); + QVERIFY2(smbclient.exitCode() == 0, "File //qt-test-server/testshare/test.pri not found"); + + output = smbclient.readAll(); + QCOMPARE(output.constData(), contents); + qDebug() << "Test file is correct"; #endif } diff --git a/tests/auto/opengl.pro b/tests/auto/opengl.pro index 9b59cd1..6c8e4ca 100644 --- a/tests/auto/opengl.pro +++ b/tests/auto/opengl.pro @@ -3,4 +3,5 @@ SUBDIRS=\ qgl \ qglthreads \ qglbuffer \ + qglfunctions \ diff --git a/tests/auto/other.pro b/tests/auto/other.pro index 40fa4a9..655d666 100644 --- a/tests/auto/other.pro +++ b/tests/auto/other.pro @@ -3,8 +3,8 @@ TEMPLATE=subdirs SUBDIRS=\ -# exceptionsafety_objects \ shouldn't enable it - qaccessibility \ +# baselineexample \ Just an example demonstrating qbaselinetest usage + lancelot \ qalgorithms \ qcombobox \ qcssparser \ @@ -35,6 +35,8 @@ SUBDIRS=\ windowsmobile \ nativeimagehandleprovider +contains(QT_CONFIG, accessibility):SUBDIRS += qaccessibility + contains(QT_CONFIG, OdfWriter):SUBDIRS += qzip qtextodfwriter mac: { SUBDIRS += macgui \ @@ -54,6 +56,8 @@ symbian { qs60mainapplication } +!win32-msvc*:!wince*:SUBDIRS += exceptionsafety_objects + # Following tests depends on private API !contains(QT_CONFIG, private_tests): SUBDIRS -= \ qcssparser \ diff --git a/tests/auto/patternistexamples/patternistexamples.pro b/tests/auto/patternistexamples/patternistexamples.pro index f83e0aa..098b0fe 100644 --- a/tests/auto/patternistexamples/patternistexamples.pro +++ b/tests/auto/patternistexamples/patternistexamples.pro @@ -2,17 +2,17 @@ load(qttest_p4) SOURCES += tst_patternistexamples.cpp CONFIG += qtestlib wince*|symbian: { - snippets.sources = $$QT_SOURCE_TREE/doc/src/snippets/patternist/* + snippets.files = $$QT_SOURCE_TREE/doc/src/snippets/patternist/* snippets.path = patternist - widgetRen.sources = $$QT_SOURCE_TREE/examples/xmlpatterns/xquery/widgetRenderer/* + widgetRen.files = $$QT_SOURCE_TREE/examples/xmlpatterns/xquery/widgetRenderer/* widgetRen.path = widgetRenderer - globVar.sources = $$QT_SOURCE_TREE/examples/xmlpatterns/xquery/globalVariables/* + globVar.files = $$QT_SOURCE_TREE/examples/xmlpatterns/xquery/globalVariables/* globVar.path = globalVariables - filetree.sources = $$QT_SOURCE_TREE/examples/xmlpatterns/filetree/* + filetree.files = $$QT_SOURCE_TREE/examples/xmlpatterns/filetree/* filetree.path = filetree - recipes.sources = $$QT_SOURCE_TREE/examples/xmlpatterns/recipes/* + recipes.files = $$QT_SOURCE_TREE/examples/xmlpatterns/recipes/* recipes.path = recipes - files.sources = $$QT_SOURCE_TREE/examples/xmlpatterns/recipes/files/* + files.files = $$QT_SOURCE_TREE/examples/xmlpatterns/recipes/files/* files.path = recipes\\files DEPLOYMENT += snippets widgetRen globVar filetree recipes files diff --git a/tests/auto/platformsocketengine/.gitignore b/tests/auto/platformsocketengine/.gitignore new file mode 100644 index 0000000..afe9389 --- /dev/null +++ b/tests/auto/platformsocketengine/.gitignore @@ -0,0 +1 @@ +tst_platformsocketengine diff --git a/tests/auto/qnativesocketengine/qsocketengine.pri b/tests/auto/platformsocketengine/platformsocketengine.pri index 15f31fd..15f31fd 100644 --- a/tests/auto/qnativesocketengine/qsocketengine.pri +++ b/tests/auto/platformsocketengine/platformsocketengine.pri diff --git a/tests/auto/platformsocketengine/platformsocketengine.pro b/tests/auto/platformsocketengine/platformsocketengine.pro new file mode 100644 index 0000000..faf745c --- /dev/null +++ b/tests/auto/platformsocketengine/platformsocketengine.pro @@ -0,0 +1,16 @@ +load(qttest_p4) +SOURCES += tst_platformsocketengine.cpp + +include(../platformsocketengine/platformsocketengine.pri) + +requires(contains(QT_CONFIG,private_tests)) + +MOC_DIR=tmp + +QT = core network + +symbian { + TARGET.CAPABILITY = NetworkServices + INCLUDEPATH += $$OS_LAYER_SYSTEMINCLUDE + LIBS += -lesock +} diff --git a/tests/auto/qnativesocketengine/tst_qnativesocketengine.cpp b/tests/auto/platformsocketengine/tst_platformsocketengine.cpp index 92b8b34..257d412 100644 --- a/tests/auto/qnativesocketengine/tst_qnativesocketengine.cpp +++ b/tests/auto/platformsocketengine/tst_platformsocketengine.cpp @@ -50,7 +50,6 @@ #include <qdatastream.h> -#include <private/qnativesocketengine_p.h> #include <qhostaddress.h> #include <qdatetime.h> @@ -63,6 +62,20 @@ #include <stddef.h> +#ifdef Q_OS_SYMBIAN +#include <QNetworkConfigurationManager> +#include <QNetworkConfiguration> +#include <QNetworkSession> +#include <QScopedPointer> +#define PLATFORMSOCKETENGINE QSymbianSocketEngine +#define PLATFORMSOCKETENGINESTRING "QSymbianSocketEngine" +#include <private/qsymbiansocketengine_p.h> +#include <private/qcore_symbian_p.h> +#else +#define PLATFORMSOCKETENGINE QNativeSocketEngine +#define PLATFORMSOCKETENGINESTRING "QNativeSocketEngine" +#include <private/qnativesocketengine_p.h> +#endif #include <qstringlist.h> @@ -70,13 +83,13 @@ //TESTED_FILES=network/qnativesocketengine.cpp network/qnativesocketengine_p.h network/qnativesocketengine_unix.cpp -class tst_QNativeSocketEngine : public QObject +class tst_PlatformSocketEngine : public QObject { Q_OBJECT public: - tst_QNativeSocketEngine(); - virtual ~tst_QNativeSocketEngine(); + tst_PlatformSocketEngine(); + virtual ~tst_PlatformSocketEngine(); public slots: @@ -92,35 +105,35 @@ private slots: void udpLoopbackPerformance(); void tcpLoopbackPerformance(); void readWriteBufferSize(); - void tooManySockets(); void bind(); void networkError(); void setSocketDescriptor(); void invalidSend(); void receiveUrgentData(); + void tooManySockets(); }; -tst_QNativeSocketEngine::tst_QNativeSocketEngine() +tst_PlatformSocketEngine::tst_PlatformSocketEngine() { Q_SET_DEFAULT_IAP } -tst_QNativeSocketEngine::~tst_QNativeSocketEngine() +tst_PlatformSocketEngine::~tst_PlatformSocketEngine() { } -void tst_QNativeSocketEngine::init() +void tst_PlatformSocketEngine::init() { } -void tst_QNativeSocketEngine::cleanup() +void tst_PlatformSocketEngine::cleanup() { } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::construction() +void tst_PlatformSocketEngine::construction() { - QNativeSocketEngine socketDevice; + PLATFORMSOCKETENGINE socketDevice; QVERIFY(!socketDevice.isValid()); @@ -137,17 +150,17 @@ void tst_QNativeSocketEngine::construction() QVERIFY(socketDevice.peerPort() == 0); QVERIFY(socketDevice.error() == QAbstractSocket::UnknownSocketError); - QTest::ignoreMessage(QtWarningMsg, "QNativeSocketEngine::bytesAvailable() was called in QAbstractSocket::UnconnectedState"); + QTest::ignoreMessage(QtWarningMsg, PLATFORMSOCKETENGINESTRING "::bytesAvailable() was called in QAbstractSocket::UnconnectedState"); QVERIFY(socketDevice.bytesAvailable() == 0); - QTest::ignoreMessage(QtWarningMsg, "QNativeSocketEngine::hasPendingDatagrams() was called in QAbstractSocket::UnconnectedState"); + QTest::ignoreMessage(QtWarningMsg, PLATFORMSOCKETENGINESTRING "::hasPendingDatagrams() was called in QAbstractSocket::UnconnectedState"); QVERIFY(!socketDevice.hasPendingDatagrams()); } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::simpleConnectToIMAP() +void tst_PlatformSocketEngine::simpleConnectToIMAP() { - QNativeSocketEngine socketDevice; + PLATFORMSOCKETENGINE socketDevice; // Initialize device QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); @@ -202,12 +215,9 @@ void tst_QNativeSocketEngine::simpleConnectToIMAP() } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::udpLoopbackTest() +void tst_PlatformSocketEngine::udpLoopbackTest() { -#ifdef SYMBIAN_WINSOCK_CONNECTIVITY - QSKIP("Not working on Emulator without WinPCAP", SkipAll); -#endif - QNativeSocketEngine udpSocket; + PLATFORMSOCKETENGINE udpSocket; // Initialize device #1 QVERIFY(udpSocket.initialize(QAbstractSocket::UdpSocket)); @@ -224,7 +234,7 @@ void tst_QNativeSocketEngine::udpLoopbackTest() QVERIFY(port != 0); // Initialize device #2 - QNativeSocketEngine udpSocket2; + PLATFORMSOCKETENGINE udpSocket2; QVERIFY(udpSocket2.initialize(QAbstractSocket::UdpSocket)); // Connect device #2 to #1 @@ -253,12 +263,9 @@ void tst_QNativeSocketEngine::udpLoopbackTest() } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::udpIPv6LoopbackTest() +void tst_PlatformSocketEngine::udpIPv6LoopbackTest() { -#if defined(Q_OS_SYMBIAN) - QSKIP("Symbian: IPv6 is not yet supported", SkipAll); -#endif - QNativeSocketEngine udpSocket; + PLATFORMSOCKETENGINE udpSocket; // Initialize device #1 bool init = udpSocket.initialize(QAbstractSocket::UdpSocket, QAbstractSocket::IPv6Protocol); @@ -275,7 +282,7 @@ void tst_QNativeSocketEngine::udpIPv6LoopbackTest() QVERIFY(port != 0); // Initialize device #2 - QNativeSocketEngine udpSocket2; + PLATFORMSOCKETENGINE udpSocket2; QVERIFY(udpSocket2.initialize(QAbstractSocket::UdpSocket, QAbstractSocket::IPv6Protocol)); // Connect device #2 to #1 @@ -305,12 +312,26 @@ void tst_QNativeSocketEngine::udpIPv6LoopbackTest() } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::broadcastTest() +void tst_PlatformSocketEngine::broadcastTest() { +#ifdef Q_OS_SYMBIAN + //broadcast isn't supported on loopback connections, but is on WLAN +#ifndef QT_NO_BEARERMANAGEMENT + QScopedPointer<QNetworkConfigurationManager> netConfMan(new QNetworkConfigurationManager()); + QNetworkConfiguration networkConfiguration(netConfMan->defaultConfiguration()); + QScopedPointer<QNetworkSession> networkSession(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + bool ok = networkSession->waitForOpened(30000); + qDebug() << networkSession->isOpen() << networkSession->error() << networkSession->errorString(); + QVERIFY(ok); + } +#endif +#endif #ifdef Q_OS_AIX QSKIP("Broadcast does not work on darko", SkipAll); #endif - QNativeSocketEngine broadcastSocket; + PLATFORMSOCKETENGINE broadcastSocket; // Initialize a regular Udp socket QVERIFY(broadcastSocket.initialize(QAbstractSocket::UdpSocket)); @@ -324,10 +345,18 @@ void tst_QNativeSocketEngine::broadcastTest() // Broadcast an inappropriate troll message QByteArray trollMessage = "MOOT wtf is a MOOT? talk english not your sutpiD ENGLISH."; - QVERIFY(broadcastSocket.writeDatagram(trollMessage.data(), + qint64 written = broadcastSocket.writeDatagram(trollMessage.data(), trollMessage.size(), QHostAddress::Broadcast, - port) == trollMessage.size()); + port); + +#ifdef Q_OS_SYMBIAN + //On symbian, broadcasts return 0 bytes written if none of the interfaces support it. + //Notably the loopback interfaces do not. (though they do support multicast!?) + if (written == 0) + QEXPECT_FAIL("", "No active interface supports broadcast", Abort); +#endif + QCOMPARE((int)written, trollMessage.size()); // Wait until we receive it ourselves #if defined(Q_OS_FREEBSD) @@ -346,9 +375,9 @@ void tst_QNativeSocketEngine::broadcastTest() } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::serverTest() +void tst_PlatformSocketEngine::serverTest() { - QNativeSocketEngine server; + PLATFORMSOCKETENGINE server; // Initialize a Tcp socket QVERIFY(server.initialize(QAbstractSocket::TcpSocket)); @@ -363,7 +392,7 @@ void tst_QNativeSocketEngine::serverTest() QVERIFY(server.state() == QAbstractSocket::ListeningState); // Initialize a Tcp socket - QNativeSocketEngine client; + PLATFORMSOCKETENGINE client; QVERIFY(client.initialize(QAbstractSocket::TcpSocket)); if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) { QVERIFY(client.state() == QAbstractSocket::ConnectingState); @@ -377,7 +406,7 @@ void tst_QNativeSocketEngine::serverTest() // A socket device is initialized on the server side, passing the // socket descriptor from accept(). It's pre-connected. - QNativeSocketEngine serverSocket; + PLATFORMSOCKETENGINE serverSocket; QVERIFY(serverSocket.initialize(socketDescriptor)); QVERIFY(serverSocket.state() == QAbstractSocket::ConnectedState); @@ -400,12 +429,12 @@ void tst_QNativeSocketEngine::serverTest() } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::udpLoopbackPerformance() +void tst_PlatformSocketEngine::udpLoopbackPerformance() { #ifdef SYMBIAN_WINSOCK_CONNECTIVITY QSKIP("Not working on Emulator without WinPCAP", SkipAll); #endif - QNativeSocketEngine udpSocket; + PLATFORMSOCKETENGINE udpSocket; // Initialize device #1 QVERIFY(udpSocket.initialize(QAbstractSocket::UdpSocket)); @@ -422,7 +451,7 @@ void tst_QNativeSocketEngine::udpLoopbackPerformance() QVERIFY(port != 0); // Initialize device #2 - QNativeSocketEngine udpSocket2; + PLATFORMSOCKETENGINE udpSocket2; QVERIFY(udpSocket2.initialize(QAbstractSocket::UdpSocket)); // Connect device #2 to #1 @@ -454,9 +483,9 @@ void tst_QNativeSocketEngine::udpLoopbackPerformance() } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::tcpLoopbackPerformance() +void tst_PlatformSocketEngine::tcpLoopbackPerformance() { - QNativeSocketEngine server; + PLATFORMSOCKETENGINE server; // Initialize a Tcp socket QVERIFY(server.initialize(QAbstractSocket::TcpSocket)); @@ -471,7 +500,7 @@ void tst_QNativeSocketEngine::tcpLoopbackPerformance() QVERIFY(server.state() == QAbstractSocket::ListeningState); // Initialize a Tcp socket - QNativeSocketEngine client; + PLATFORMSOCKETENGINE client; QVERIFY(client.initialize(QAbstractSocket::TcpSocket)); // Connect to our server @@ -481,17 +510,21 @@ void tst_QNativeSocketEngine::tcpLoopbackPerformance() QVERIFY(client.state() == QAbstractSocket::ConnectedState); } - // The server accepts the connectio + // The server accepts the connection int socketDescriptor = server.accept(); QVERIFY(socketDescriptor > 0); // A socket device is initialized on the server side, passing the // socket descriptor from accept(). It's pre-connected. - QNativeSocketEngine serverSocket; + PLATFORMSOCKETENGINE serverSocket; QVERIFY(serverSocket.initialize(socketDescriptor)); QVERIFY(serverSocket.state() == QAbstractSocket::ConnectedState); +#if defined (Q_OS_SYMBIAN) && defined (__WINS__) + const int messageSize = 1024 * 16; +#else const int messageSize = 1024 * 256; +#endif QByteArray message1(messageSize, '@'); QByteArray answer(messageSize, '@'); @@ -517,9 +550,9 @@ void tst_QNativeSocketEngine::tcpLoopbackPerformance() } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::readWriteBufferSize() +void tst_PlatformSocketEngine::readWriteBufferSize() { - QNativeSocketEngine device; + PLATFORMSOCKETENGINE device; QVERIFY(device.initialize(QAbstractSocket::TcpSocket)); @@ -539,15 +572,15 @@ void tst_QNativeSocketEngine::readWriteBufferSize() } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::tooManySockets() +void tst_PlatformSocketEngine::tooManySockets() { #if defined Q_OS_WIN QSKIP("Certain windows machines suffocate and spend too much time in this test.", SkipAll); #endif - QList<QNativeSocketEngine *> sockets; - QNativeSocketEngine *socketLayer = 0; + QList<PLATFORMSOCKETENGINE *> sockets; + PLATFORMSOCKETENGINE *socketLayer = 0; for (;;) { - socketLayer = new QNativeSocketEngine; + socketLayer = new PLATFORMSOCKETENGINE; sockets.append(socketLayer); if (!socketLayer->initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)) @@ -560,20 +593,20 @@ void tst_QNativeSocketEngine::tooManySockets() } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::bind() +void tst_PlatformSocketEngine::bind() { #if !defined Q_OS_WIN && !defined Q_OS_SYMBIAN - QNativeSocketEngine binder; + PLATFORMSOCKETENGINE binder; QVERIFY(binder.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QVERIFY(!binder.bind(QHostAddress::Any, 82)); QVERIFY(binder.error() == QAbstractSocket::SocketAccessError); #endif - QNativeSocketEngine binder2; + PLATFORMSOCKETENGINE binder2; QVERIFY(binder2.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QVERIFY(binder2.bind(QHostAddress::Any, 31180)); - QNativeSocketEngine binder3; + PLATFORMSOCKETENGINE binder3; QVERIFY(binder3.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QVERIFY(!binder3.bind(QHostAddress::Any, 31180)); @@ -586,9 +619,9 @@ void tst_QNativeSocketEngine::bind() } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::networkError() +void tst_PlatformSocketEngine::networkError() { - QNativeSocketEngine client; + PLATFORMSOCKETENGINE client; QVERIFY(client.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); @@ -604,6 +637,12 @@ void tst_QNativeSocketEngine::networkError() #ifdef Q_OS_WIN // could use shutdown to produce different errors ::closesocket(client.socketDescriptor()); +#elif defined(Q_OS_SYMBIAN) + RSocket sock; + QVERIFY(QSymbianSocketManager::instance().lookupSocket(client.socketDescriptor(), sock)); + TRequestStatus stat; + sock.Shutdown(RSocket::EImmediate, stat); + User::WaitForRequest(stat); #else ::close(client.socketDescriptor()); #endif @@ -612,31 +651,31 @@ void tst_QNativeSocketEngine::networkError() } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::setSocketDescriptor() +void tst_PlatformSocketEngine::setSocketDescriptor() { - QNativeSocketEngine socket1; + PLATFORMSOCKETENGINE socket1; QVERIFY(socket1.initialize(QAbstractSocket::TcpSocket)); - QNativeSocketEngine socket2; + PLATFORMSOCKETENGINE socket2; QVERIFY(socket2.initialize(socket1.socketDescriptor())); } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::invalidSend() +void tst_PlatformSocketEngine::invalidSend() { - QNativeSocketEngine socket; + PLATFORMSOCKETENGINE socket; QVERIFY(socket.initialize(QAbstractSocket::TcpSocket)); - QTest::ignoreMessage(QtWarningMsg, "QNativeSocketEngine::writeDatagram() was" + QTest::ignoreMessage(QtWarningMsg, PLATFORMSOCKETENGINESTRING "::writeDatagram() was" " called by a socket other than QAbstractSocket::UdpSocket"); QCOMPARE(socket.writeDatagram("hei", 3, QHostAddress::LocalHost, 143), (qlonglong) -1); } //--------------------------------------------------------------------------- -void tst_QNativeSocketEngine::receiveUrgentData() +void tst_PlatformSocketEngine::receiveUrgentData() { - QNativeSocketEngine server; + PLATFORMSOCKETENGINE server; QVERIFY(server.initialize(QAbstractSocket::TcpSocket)); @@ -648,7 +687,7 @@ void tst_QNativeSocketEngine::receiveUrgentData() QVERIFY(server.listen()); QVERIFY(server.state() == QAbstractSocket::ListeningState); - QNativeSocketEngine client; + PLATFORMSOCKETENGINE client; QVERIFY(client.initialize(QAbstractSocket::TcpSocket)); if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) { @@ -660,7 +699,7 @@ void tst_QNativeSocketEngine::receiveUrgentData() int socketDescriptor = server.accept(); QVERIFY(socketDescriptor > 0); - QNativeSocketEngine serverSocket; + PLATFORMSOCKETENGINE serverSocket; QVERIFY(serverSocket.initialize(socketDescriptor)); QVERIFY(serverSocket.state() == QAbstractSocket::ConnectedState); @@ -676,7 +715,18 @@ void tst_QNativeSocketEngine::receiveUrgentData() // The server sends an urgent message msg = 'Q'; +#if defined(Q_OS_SYMBIAN) + RSocket sock; + QVERIFY(QSymbianSocketManager::instance().lookupSocket(socketDescriptor, sock)); + TRequestStatus stat; + TSockXfrLength len; + sock.Send(TPtrC8((TUint8*)&msg,1), KSockWriteUrgent, stat, len); + User::WaitForRequest(stat); + QVERIFY(stat == KErrNone); + QCOMPARE(len(), 1); +#else QCOMPARE(int(::send(socketDescriptor, &msg, sizeof(msg), MSG_OOB)), 1); +#endif // The client receives the urgent message QVERIFY(client.waitForRead()); @@ -689,7 +739,15 @@ void tst_QNativeSocketEngine::receiveUrgentData() // The client sends an urgent message msg = 'T'; int clientDescriptor = client.socketDescriptor(); +#if defined(Q_OS_SYMBIAN) + QVERIFY(QSymbianSocketManager::instance().lookupSocket(clientDescriptor, sock)); + sock.Send(TPtrC8((TUint8*)&msg,1), KSockWriteUrgent, stat, len); + User::WaitForRequest(stat); + QVERIFY(stat == KErrNone); + QCOMPARE(len(), 1); +#else QCOMPARE(int(::send(clientDescriptor, &msg, sizeof(msg), MSG_OOB)), 1); +#endif // The server receives the urgent message QVERIFY(serverSocket.waitForRead()); @@ -701,5 +759,5 @@ void tst_QNativeSocketEngine::receiveUrgentData() } -QTEST_MAIN(tst_QNativeSocketEngine) -#include "tst_qnativesocketengine.moc" +QTEST_MAIN(tst_PlatformSocketEngine) +#include "tst_platformsocketengine.moc" diff --git a/tests/auto/q3dns/tst_q3dns.cpp b/tests/auto/q3dns/tst_q3dns.cpp index 7b64806..7cfdfdc 100644 --- a/tests/auto/q3dns/tst_q3dns.cpp +++ b/tests/auto/q3dns/tst_q3dns.cpp @@ -144,7 +144,7 @@ void tst_Q3Dns::literals() QCOMPARE((int) ip6literal1.addresses().count(), 0); Q3Dns ip6literal2("::1", Q3Dns::Aaaa); - QCOMPARE(ip6literal2.addresses().first().toString(), QString("0:0:0:0:0:0:0:1")); + QCOMPARE(ip6literal2.addresses().first().toString(), QString("::1")); QCOMPARE((int) ip6literal2.addresses().count(), 1); } diff --git a/tests/auto/q3listview/tst_q3listview.cpp b/tests/auto/q3listview/tst_q3listview.cpp index f0d7937..091e02d 100644 --- a/tests/auto/q3listview/tst_q3listview.cpp +++ b/tests/auto/q3listview/tst_q3listview.cpp @@ -678,7 +678,7 @@ void tst_Q3ListView::selections_mouseClick() for (i = 0; i < items.count(); ++i) { Q3ListViewItem *item = items.at(i); - Q_ASSERT(item); + QVERIFY(item); if ( item->isSelected() ) { QVERIFY( selectedItems.contains( i ) ); } else { diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index 58b014b..66bd6bb 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -251,7 +251,7 @@ void tst_Q3SqlCursor::copyConstructor() } QSqlRecord* rec = cur2.primeUpdate(); - Q_ASSERT( rec ); + QVERIFY( rec ); QCOMPARE( (int)rec->count(), 4 ); int i = 0; @@ -398,7 +398,7 @@ void tst_Q3SqlCursor::batchInsert() int i = 0; for ( ; i < 100; ++i ) { QSqlRecord* irec = cur.primeInsert(); - Q_ASSERT( irec ); + QVERIFY( irec ); irec->setValue( "id", i ); irec->setValue( "t_varchar", "blah" ); irec->setValue( "t_char", "blah" ); @@ -412,7 +412,7 @@ void tst_Q3SqlCursor::batchInsert() for ( ; i < 200; ++i ) { QSqlRecord* irec = cur.primeInsert(); - Q_ASSERT( irec ); + QVERIFY( irec ); irec->setValue( "id", i ); irec->setValue( "t_varchar", "blah" ); irec->setValue( "t_char", "blah" ); @@ -699,7 +699,7 @@ void tst_Q3SqlCursor::updateNoPK() Q3SqlCursor cur(qTableName("qtestPK", __FILE__), true, db); QSqlRecord* rec = cur.primeInsert(); - Q_ASSERT(rec); + QVERIFY(rec); rec->setNull(0); rec->setNull(1); rec->setNull(2); @@ -724,7 +724,7 @@ void tst_Q3SqlCursor::updateNoPK() } rec = cur.primeUpdate(); - Q_ASSERT(rec); + QVERIFY(rec); rec->setValue(0, 1); rec->setNull(1); rec->setNull(2); diff --git a/tests/auto/q_func_info/q_func_info.pro b/tests/auto/q_func_info/q_func_info.pro index b30e3fb..64f08d4 100644 --- a/tests/auto/q_func_info/q_func_info.pro +++ b/tests/auto/q_func_info/q_func_info.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_q_func_info.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qabstractfileengine/qabstractfileengine.pro b/tests/auto/qabstractfileengine/qabstractfileengine.pro new file mode 100644 index 0000000..870473a --- /dev/null +++ b/tests/auto/qabstractfileengine/qabstractfileengine.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +QT = core + +SOURCES = tst_qabstractfileengine.cpp +RESOURCES += qabstractfileengine.qrc + diff --git a/tests/auto/qabstractfileengine/qabstractfileengine.qrc b/tests/auto/qabstractfileengine/qabstractfileengine.qrc new file mode 100644 index 0000000..5401b08 --- /dev/null +++ b/tests/auto/qabstractfileengine/qabstractfileengine.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/tst_qabstractfileengine/"> + <file>resources/</file> +</qresource> +</RCC> diff --git a/tests/auto/qabstractfileengine/resources/file.txt b/tests/auto/qabstractfileengine/resources/file.txt new file mode 100644 index 0000000..8a03e0e --- /dev/null +++ b/tests/auto/qabstractfileengine/resources/file.txt @@ -0,0 +1 @@ +This is a simple text file. diff --git a/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp b/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp new file mode 100644 index 0000000..a816333 --- /dev/null +++ b/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp @@ -0,0 +1,794 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the FOO module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QAbstractFileEngine> +#include <QtCore/QFSFileEngine> + +#include <QtCore/QMutex> +#include <QtCore/QMutexLocker> +#include <QtCore/QSharedPointer> +#include <QtCore/QScopedPointer> +#include <QtCore/QHash> + +#include <QtTest/QTest> + +#include <QtCore/QDebug> + +class tst_QAbstractFileEngine + : public QObject +{ + Q_OBJECT +public slots: + void cleanupTestCase(); + +private slots: + void customHandler(); + + void fileIO_data(); + void fileIO(); + +private: + QStringList filesForRemoval; +}; + +class ReferenceFileEngine + : public QAbstractFileEngine +{ +public: + ReferenceFileEngine(const QString &fileName) + : fileName_(fileName) + , position_(-1) + , openForRead_(false) + , openForWrite_(false) + { + } + + bool open(QIODevice::OpenMode openMode) + { + if (openForRead_ || openForWrite_) { + qWarning("%s: file is already open for %s", + Q_FUNC_INFO, + (openForRead_ ? "reading" : "writing")); + return false; + } + + openFile_ = resolveFile(openMode & QIODevice::WriteOnly); + if (!openFile_) + return false; + + position_ = 0; + if (openMode & QIODevice::ReadOnly) + openForRead_ = true; + + if (openMode & QIODevice::WriteOnly) { + openForWrite_ = true; + + QMutexLocker lock(&openFile_->mutex); + if (openMode & QIODevice::Truncate + || !(openForRead_ || openMode & QIODevice::Append)) + openFile_->content.clear(); + + if (openMode & QIODevice::Append) + position_ = openFile_->content.size(); + } + + return true; + } + + bool close() + { + openFile_.clear(); + + openForRead_ = false; + openForWrite_ = false; + position_ = -1; + + return true; + } + + qint64 size() const + { + QSharedPointer<File> file = resolveFile(false); + if (!file) + return 0; + + QMutexLocker lock(&file->mutex); + return file->content.size(); + } + + qint64 pos() const + { + if (!openForRead_ && !openForWrite_) { + qWarning("%s: file is not open", Q_FUNC_INFO); + return -1; + } + return position_; + } + + bool seek(qint64 pos) + { + if (!openForRead_ && !openForWrite_) { + qWarning("%s: file is not open", Q_FUNC_INFO); + return false; + } + + if (pos >= 0) { + position_ = pos; + return true; + } + + return false; + } + + bool flush() + { + if (!openForRead_ && !openForWrite_) { + qWarning("%s: file is not open", Q_FUNC_INFO); + return false; + } + + return true; + } + + bool remove() + { + QMutexLocker lock(&fileSystemMutex); + int count = fileSystem.remove(fileName_); + + return (count == 1); + } + + bool copy(const QString &newName) + { + QMutexLocker lock(&fileSystemMutex); + if (!fileSystem.contains(fileName_) + || fileSystem.contains(newName)) + return false; + + fileSystem.insert(newName, fileSystem.value(fileName_)); + return true; + } + + bool rename(const QString &newName) + { + QMutexLocker lock(&fileSystemMutex); + if (!fileSystem.contains(fileName_) + || fileSystem.contains(newName)) + return false; + + fileSystem.insert(newName, fileSystem.take(fileName_)); + return true; + } + + // bool link(const QString &newName) + // { + // Q_UNUSED(newName) + // return false; + // } + + // bool mkdir(const QString &dirName, bool createParentDirectories) const + // { + // Q_UNUSED(dirName) + // Q_UNUSED(createParentDirectories) + + // return false; + // } + + // bool rmdir(const QString &dirName, bool recurseParentDirectories) const + // { + // Q_UNUSED(dirName) + // Q_UNUSED(recurseParentDirectories) + + // return false; + // } + + bool setSize(qint64 size) + { + if (size < 0) + return false; + + QSharedPointer<File> file = resolveFile(false); + if (!file) + return false; + + QMutexLocker lock(&file->mutex); + file->content.resize(size); + + if (openForRead_ || openForWrite_) + if (position_ > size) + position_ = size; + + return (file->content.size() == size); + } + + FileFlags fileFlags(FileFlags type) const + { + QSharedPointer<File> file = resolveFile(false); + if (file) { + QMutexLocker lock(&file->mutex); + return (file->fileFlags & type); + } + + return FileFlags(); + } + + // bool setPermissions(uint perms) + // { + // Q_UNUSED(perms) + + // return false; + // } + + QString fileName(FileName file) const + { + switch (file) { + case DefaultName: + return QLatin1String("DefaultName"); + case BaseName: + return QLatin1String("BaseName"); + case PathName: + return QLatin1String("PathName"); + case AbsoluteName: + return QLatin1String("AbsoluteName"); + case AbsolutePathName: + return QLatin1String("AbsolutePathName"); + case LinkName: + return QLatin1String("LinkName"); + case CanonicalName: + return QLatin1String("CanonicalName"); + case CanonicalPathName: + return QLatin1String("CanonicalPathName"); + case BundleName: + return QLatin1String("BundleName"); + + default: + break; + } + + return QString(); + } + + uint ownerId(FileOwner owner) const + { + QSharedPointer<File> file = resolveFile(false); + if (file) { + switch (owner) { + case OwnerUser: + { + QMutexLocker lock(&file->mutex); + return file->userId; + } + case OwnerGroup: + { + QMutexLocker lock(&file->mutex); + return file->groupId; + } + } + } + + return -2; + } + + QString owner(FileOwner owner) const + { + QSharedPointer<File> file = resolveFile(false); + if (file) { + uint ownerId; + switch (owner) { + case OwnerUser: + { + QMutexLocker lock(&file->mutex); + ownerId = file->userId; + } + + { + QMutexLocker lock(&fileSystemMutex); + return fileSystemUsers.value(ownerId); + } + + case OwnerGroup: + { + QMutexLocker lock(&file->mutex); + ownerId = file->groupId; + } + + { + QMutexLocker lock(&fileSystemMutex); + return fileSystemGroups.value(ownerId); + } + } + } + + return QString(); + } + + QDateTime fileTime(FileTime time) const + { + QSharedPointer<File> file = resolveFile(false); + if (file) { + QMutexLocker lock(&file->mutex); + switch (time) { + case CreationTime: + return file->creation; + case ModificationTime: + return file->modification; + case AccessTime: + return file->access; + } + } + + return QDateTime(); + } + + void setFileName(const QString &file) + { + if (openForRead_ || openForWrite_) + qWarning("%s: Can't set file name while file is open", Q_FUNC_INFO); + else + fileName_ = file; + } + + // typedef QAbstractFileEngineIterator Iterator; + // Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) + // { + // Q_UNUSED(filters) + // Q_UNUSED(filterNames) + + // return 0; + // } + + // Iterator *endEntryList() + // { + // return 0; + // } + + qint64 read(char *data, qint64 maxLen) + { + if (!openForRead_) { + qWarning("%s: file must be open for reading", Q_FUNC_INFO); + return -1; + } + + if (openFile_.isNull()) { + qWarning("%s: file must not be null", Q_FUNC_INFO); + return -1; + } + + QMutexLocker lock(&openFile_->mutex); + qint64 readSize = qMin(openFile_->content.size() - position_, maxLen); + if (readSize < 0) + return -1; + + qMemCopy(data, openFile_->content.constData() + position_, readSize); + position_ += readSize; + + return readSize; + } + + qint64 write(const char *data, qint64 length) + { + if (!openForWrite_) { + qWarning("%s: file must be open for writing", Q_FUNC_INFO); + return -1; + } + + if (openFile_.isNull()) { + qWarning("%s: file must not be null", Q_FUNC_INFO); + return -1; + } + + if (length < 0) + return -1; + + QMutexLocker lock(&openFile_->mutex); + if (openFile_->content.size() == position_) + openFile_->content.append(data, length); + else { + if (position_ + length > openFile_->content.size()) + openFile_->content.resize(position_ + length); + openFile_->content.replace(position_, length, data, length); + } + + qint64 writeSize = qMin(length, openFile_->content.size() - position_); + position_ += writeSize; + + return writeSize; + } + +protected: + // void setError(QFile::FileError error, const QString &str); + + struct File + { + File() + : userId(0) + , groupId(0) + , fileFlags( + ReadOwnerPerm | WriteOwnerPerm | ExeOwnerPerm + | ReadUserPerm | WriteUserPerm | ExeUserPerm + | ReadGroupPerm | WriteGroupPerm | ExeGroupPerm + | ReadOtherPerm | WriteOtherPerm | ExeOtherPerm + | FileType | ExistsFlag) + { + } + + QMutex mutex; + + uint userId, groupId; + QAbstractFileEngine::FileFlags fileFlags; + QDateTime creation, modification, access; + + QByteArray content; + }; + + QSharedPointer<File> resolveFile(bool create) const + { + if (openForRead_ || openForWrite_) { + if (!openFile_) + qWarning("%s: file should not be null", Q_FUNC_INFO); + return openFile_; + } + + QMutexLocker lock(&fileSystemMutex); + if (create) { + QSharedPointer<File> &p = fileSystem[fileName_]; + if (p.isNull()) + p = QSharedPointer<File>(new File); + return p; + } + + return fileSystem.value(fileName_); + } + + static QMutex fileSystemMutex; + static QHash<uint, QString> fileSystemUsers, fileSystemGroups; + static QHash<QString, QSharedPointer<File> > fileSystem; + +private: + QString fileName_; + qint64 position_; + bool openForRead_; + bool openForWrite_; + + mutable QSharedPointer<File> openFile_; +}; + +QMutex ReferenceFileEngine::fileSystemMutex; +QHash<uint, QString> ReferenceFileEngine::fileSystemUsers, ReferenceFileEngine::fileSystemGroups; +QHash<QString, QSharedPointer<ReferenceFileEngine::File> > ReferenceFileEngine::fileSystem; + +class FileEngineHandler + : QAbstractFileEngineHandler +{ + QAbstractFileEngine *create(const QString &fileName) const + { + if (fileName.startsWith("QFSFileEngine:")) + return new QFSFileEngine(fileName.mid(14)); + if (fileName.startsWith("reference-file-engine:")) + return new ReferenceFileEngine(fileName.mid(22)); + if (fileName.startsWith("resource:")) + return QAbstractFileEngine::create(QLatin1String(":/tst_qabstractfileengine/resources/") + fileName.mid(9)); + return 0; + } +}; + +void tst_QAbstractFileEngine::cleanupTestCase() +{ + bool failed = false; + + FileEngineHandler handler; + Q_FOREACH(QString file, filesForRemoval) + if (!QFile::remove(file) + || QFile::exists(file)) { + failed = true; + qDebug() << "Couldn't remove file:" << file; + } + + QVERIFY(!failed); +} + +void tst_QAbstractFileEngine::customHandler() +{ + QScopedPointer<QAbstractFileEngine> file; + { + file.reset(QAbstractFileEngine::create("resource:file.txt")); + + QVERIFY(file); + } + + { + FileEngineHandler handler; + + QFile file("resource:file.txt"); + QVERIFY(file.exists()); + } + + { + QFile file("resource:file.txt"); + QVERIFY(!file.exists()); + } +} + +void tst_QAbstractFileEngine::fileIO_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::addColumn<QByteArray>("readContent"); + QTest::addColumn<QByteArray>("writeContent"); + QTest::addColumn<bool>("fileExists"); + + QString resourceTxtFile(":/tst_qabstractfileengine/resources/file.txt"); + QByteArray readContent("This is a simple text file.\n"); + QByteArray writeContent("This contains two lines of text.\n"); + + QTest::newRow("resource") << resourceTxtFile << readContent << QByteArray() << true; + QTest::newRow("native") << "native-file.txt" << readContent << writeContent << false; + QTest::newRow("Forced QFSFileEngine") << "QFSFileEngine:QFSFileEngine-file.txt" << readContent << writeContent << false; + QTest::newRow("Custom FE") << "reference-file-engine:file.txt" << readContent << writeContent << false; + + QTest::newRow("Forced QFSFileEngine (native)") << "QFSFileEngine:native-file.txt" << readContent << writeContent << true; + QTest::newRow("native (Forced QFSFileEngine)") << "QFSFileEngine-file.txt" << readContent << writeContent << true; + QTest::newRow("Custom FE (2)") << "reference-file-engine:file.txt" << readContent << writeContent << true; +} + +void tst_QAbstractFileEngine::fileIO() +{ + QFETCH(QString, fileName); + QFETCH(QByteArray, readContent); + QFETCH(QByteArray, writeContent); + QFETCH(bool, fileExists); + + FileEngineHandler handler; + + + { + QFile file(fileName); + QCOMPARE(file.exists(), fileExists); + + if (!fileExists) { + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Unbuffered)); + filesForRemoval.append(fileName); + + QCOMPARE(file.write(readContent), qint64(readContent.size())); + } + } + + // + // File content is: readContent + // + + qint64 fileSize = readContent.size(); + { + // Reading + QFile file(fileName); + + QVERIFY(!file.isOpen()); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered)); + + QVERIFY(file.isOpen()); + QCOMPARE(file.size(), fileSize); + QCOMPARE(file.pos(), qint64(0)); + + QCOMPARE(file.size(), fileSize); + QCOMPARE(file.readAll(), readContent); + QCOMPARE(file.pos(), fileSize); + + file.close(); + QVERIFY(!file.isOpen()); + QCOMPARE(file.size(), fileSize); + } + + if (writeContent.isEmpty()) + return; + + { + // Writing / appending + QFile file(fileName); + + QVERIFY(!file.isOpen()); + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered)); + + QVERIFY(file.isOpen()); + QCOMPARE(file.size(), fileSize); + QCOMPARE(file.pos(), fileSize); + + QCOMPARE(file.write(writeContent), qint64(writeContent.size())); + + fileSize += writeContent.size(); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + file.close(); + QVERIFY(!file.isOpen()); + QCOMPARE(file.size(), fileSize); + } + + // + // File content is: readContent + writeContent + // + + { + // Reading and Writing + QFile file(fileName); + + QVERIFY(!file.isOpen()); + QVERIFY(file.open(QIODevice::ReadWrite | QIODevice::Unbuffered)); + + QVERIFY(file.isOpen()); + QCOMPARE(file.size(), fileSize); + QCOMPARE(file.pos(), qint64(0)); + + QCOMPARE(file.readAll(), readContent + writeContent); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + QVERIFY(file.seek(writeContent.size())); + QCOMPARE(file.pos(), qint64(writeContent.size())); + QCOMPARE(file.size(), fileSize); + + QCOMPARE(file.write(readContent), qint64(readContent.size())); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + QVERIFY(file.seek(0)); + QCOMPARE(file.pos(), qint64(0)); + QCOMPARE(file.size(), fileSize); + + QCOMPARE(file.write(writeContent), qint64(writeContent.size())); + QCOMPARE(file.pos(), qint64(writeContent.size())); + QCOMPARE(file.size(), fileSize); + + QVERIFY(file.seek(0)); + QCOMPARE(file.read(writeContent.size()), writeContent); + QCOMPARE(file.pos(), qint64(writeContent.size())); + QCOMPARE(file.size(), fileSize); + + QCOMPARE(file.readAll(), readContent); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + file.close(); + QVERIFY(!file.isOpen()); + QCOMPARE(file.size(), fileSize); + } + + // + // File content is: writeContent + readContent + // + + { + // Writing + QFile file(fileName); + + QVERIFY(!file.isOpen()); + QVERIFY(file.open(QIODevice::ReadWrite | QIODevice::Unbuffered)); + + QVERIFY(file.isOpen()); + QCOMPARE(file.size(), fileSize); + QCOMPARE(file.pos(), qint64(0)); + + QCOMPARE(file.write(writeContent), qint64(writeContent.size())); + QCOMPARE(file.pos(), qint64(writeContent.size())); + QCOMPARE(file.size(), fileSize); + + QVERIFY(file.resize(writeContent.size())); + QCOMPARE(file.size(), qint64(writeContent.size())); + + file.close(); + QVERIFY(!file.isOpen()); + QCOMPARE(file.size(), qint64(writeContent.size())); + + QVERIFY(file.resize(fileSize)); + QCOMPARE(file.size(), fileSize); + } + + // + // File content is: writeContent + <undefined> + // File size is : (readContent + writeContent).size() + // + + { + // Writing / extending + QFile file(fileName); + + QVERIFY(!file.isOpen()); + QVERIFY(file.open(QIODevice::ReadWrite | QIODevice::Unbuffered)); + + QVERIFY(file.isOpen()); + QCOMPARE(file.size(), fileSize); + QCOMPARE(file.pos(), qint64(0)); + + QVERIFY(file.seek(1024)); + QCOMPARE(file.pos(), qint64(1024)); + QCOMPARE(file.size(), fileSize); + + fileSize = 1024 + writeContent.size(); + QCOMPARE(file.write(writeContent), qint64(writeContent.size())); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + QVERIFY(file.seek(1028)); + QCOMPARE(file.pos(), qint64(1028)); + QCOMPARE(file.size(), fileSize); + + fileSize = 1028 + writeContent.size(); + QCOMPARE(file.write(writeContent), qint64(writeContent.size())); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + file.close(); + QVERIFY(!file.isOpen()); + QCOMPARE(file.size(), fileSize); + } + + // + // File content is: writeContent + <undefined> + writeContent + // File size is : 1024 + writeContent.size() + // + + { + // Writing / truncating + QFile file(fileName); + + QVERIFY(!file.isOpen()); + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Unbuffered)); + + QVERIFY(file.isOpen()); + QCOMPARE(file.size(), qint64(0)); + QCOMPARE(file.pos(), qint64(0)); + + fileSize = readContent.size(); + QCOMPARE(file.write(readContent), fileSize); + QCOMPARE(file.pos(), fileSize); + QCOMPARE(file.size(), fileSize); + + file.close(); + QVERIFY(!file.isOpen()); + QCOMPARE(file.size(), fileSize); + } + + // + // File content is: readContent + // +} + +QTEST_APPLESS_MAIN(tst_QAbstractFileEngine) +#include "tst_qabstractfileengine.moc" + diff --git a/tests/auto/qabstractnetworkcache/qabstractnetworkcache.pro b/tests/auto/qabstractnetworkcache/qabstractnetworkcache.pro index 2e2577d..6f5044f 100644 --- a/tests/auto/qabstractnetworkcache/qabstractnetworkcache.pro +++ b/tests/auto/qabstractnetworkcache/qabstractnetworkcache.pro @@ -4,7 +4,7 @@ QT -= gui SOURCES += tst_qabstractnetworkcache.cpp wince*|symbian: { - testFiles.sources = tests + testFiles.files = tests testFiles.path = . DEPLOYMENT += testFiles } diff --git a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp index a243fba..aefe0b9 100644 --- a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp +++ b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp @@ -45,6 +45,12 @@ #include "../../shared/util.h" #include "../network-settings.h" +#ifndef QT_NO_BEARERMANAGEMENT +#include <QtNetwork/qnetworkconfigmanager.h> +#include <QtNetwork/qnetworkconfiguration.h> +#include <QtNetwork/qnetworksession.h> +#endif + #define TESTFILE QString("http://%1/qtest/cgi-bin/").arg(QtNetworkSettings::serverName()) class tst_QAbstractNetworkCache : public QObject @@ -56,6 +62,7 @@ public: virtual ~tst_QAbstractNetworkCache(); private slots: + void initTestCase(); void expires_data(); void expires(); void expiresSynchronous_data(); @@ -81,6 +88,12 @@ private slots: private: void check(); void checkSynchronous(); + +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkConfigurationManager *netConfMan; + QNetworkConfiguration networkConfiguration; + QScopedPointer<QNetworkSession> networkSession; +#endif }; class NetworkDiskCache : public QNetworkDiskCache @@ -124,6 +137,26 @@ static bool AlwaysFalse = false; Q_DECLARE_METATYPE(QNetworkRequest::CacheLoadControl) +void tst_QAbstractNetworkCache::initTestCase() +{ +#ifndef QT_NO_BEARERMANAGEMENT + netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + networkConfiguration = netConfMan->defaultConfiguration(); + if (networkConfiguration.isValid()) { + networkSession.reset(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); + } +#endif +} + void tst_QAbstractNetworkCache::expires_data() { QTest::addColumn<QNetworkRequest::CacheLoadControl>("cacheLoadControl"); @@ -235,14 +268,14 @@ void tst_QAbstractNetworkCache::cacheControl_data() QTest::newRow("200-2") << QNetworkRequest::AlwaysNetwork << "httpcachetest_cachecontrol.cgi?no-cache" << AlwaysFalse; QTest::newRow("200-3") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?no-cache" << false; - QTest::newRow("200-4") << QNetworkRequest::AlwaysCache << "httpcachetest_cachecontrol.cgi?no-cache" << false;//AlwaysTrue; + QTest::newRow("200-4") << QNetworkRequest::AlwaysCache << "httpcachetest_cachecontrol.cgi?no-cache" << false; QTest::newRow("200-5") << QNetworkRequest::PreferCache << "httpcachetest_cachecontrol.cgi?no-cache" << false; QTest::newRow("304-0") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?max-age=1000" << true; QTest::newRow("304-1") << QNetworkRequest::AlwaysNetwork << "httpcachetest_cachecontrol.cgi?max-age=1000, must-revalidate" << AlwaysFalse; QTest::newRow("304-2") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?max-age=1000, must-revalidate" << true; - QTest::newRow("304-3") << QNetworkRequest::AlwaysCache << "httpcachetest_cachecontrol.cgi?max-age=1000, must-revalidate" << AlwaysTrue; + QTest::newRow("304-3") << QNetworkRequest::AlwaysCache << "httpcachetest_cachecontrol.cgi?max-age=1000, must-revalidate" << false; QTest::newRow("304-4") << QNetworkRequest::PreferCache << "httpcachetest_cachecontrol.cgi?max-age=1000, must-revalidate" << true; // see QTBUG-7060 @@ -331,7 +364,7 @@ void tst_QAbstractNetworkCache::checkSynchronous() QNetworkRequest request(realUrl); request.setAttribute( - static_cast<QNetworkRequest::Attribute>(QNetworkRequest::DownloadBufferAttribute + 1), + QNetworkRequest::SynchronousRequestAttribute, true); // prime the cache diff --git a/tests/auto/qabstractxmlnodemodel/LoadingModel.cpp b/tests/auto/qabstractxmlnodemodel/LoadingModel.cpp index 2d17e29..794eb4f 100644 --- a/tests/auto/qabstractxmlnodemodel/LoadingModel.cpp +++ b/tests/auto/qabstractxmlnodemodel/LoadingModel.cpp @@ -39,7 +39,6 @@ ** ****************************************************************************/ - #include <QFile> #include <QStack> @@ -54,7 +53,6 @@ LoadingModel::LoadingModel(const Node::Vector &content, const QXmlNamePool &np) : QSimpleXmlNodeModel(np) , m_nodes(content) { - Q_ASSERT(!content.isEmpty()); /* foreach(const Node *n, content) qDebug() << "this:" << n @@ -79,20 +77,21 @@ const LoadingModel::Node *LoadingModel::toInternal(const QXmlNodeModelIndex &ni) QXmlNodeModelIndex LoadingModel::createIndex(const Node *const internal) const { - Q_ASSERT_X(internal, Q_FUNC_INFO, - "We shouldn't construct from null pointers."); + if (!internal) + qFatal("%s: cannot construct a model index from a null pointer", Q_FUNC_INFO); return QAbstractXmlNodeModel::createIndex(const_cast<Node *>(internal)); } QUrl LoadingModel::documentUri(const QXmlNodeModelIndex &) const { - Q_ASSERT(false); + qFatal("%s: This method should not be called during the test", Q_FUNC_INFO); return QUrl(); } QXmlNodeModelIndex::NodeKind LoadingModel::kind(const QXmlNodeModelIndex &ni) const { - Q_ASSERT(!ni.isNull()); + if (ni.isNull()) + qFatal("%s: node model index should not be null", Q_FUNC_INFO); return toInternal(ni)->kind; } @@ -100,8 +99,10 @@ QXmlNodeModelIndex::DocumentOrder LoadingModel::compareOrder(const QXmlNodeModel { const Node *const in1 = toInternal(n1); const Node *const in2 = toInternal(n2); - Q_ASSERT(m_nodes.indexOf(in1) != -1); - Q_ASSERT(m_nodes.indexOf(in2) != -1); + if (m_nodes.indexOf(in1) == -1) + qFatal("%s: node n1 is not in internal node list", Q_FUNC_INFO); + if (m_nodes.indexOf(in2) == -1) + qFatal("%s: node n2 is not in internal node list", Q_FUNC_INFO); if(in1 == in2) return QXmlNodeModelIndex::Is; @@ -113,7 +114,10 @@ QXmlNodeModelIndex::DocumentOrder LoadingModel::compareOrder(const QXmlNodeModel QXmlNodeModelIndex LoadingModel::root(const QXmlNodeModelIndex &) const { - Q_ASSERT(kind(createIndex(m_nodes.first())) == QXmlNodeModelIndex::Document); + if (kind(createIndex(m_nodes.first())) != QXmlNodeModelIndex::Document) { + qWarning("%s: first node must be a Document node", Q_FUNC_INFO); + return QXmlNodeModelIndex(); + } return createIndex(m_nodes.first()); } @@ -126,8 +130,11 @@ QVariant LoadingModel::typedValue(const QXmlNodeModelIndex &ni) const { const Node *const internal = toInternal(ni); - Q_ASSERT(internal->kind == QXmlNodeModelIndex::Attribute - || internal->kind == QXmlNodeModelIndex::Element); + if (internal->kind != QXmlNodeModelIndex::Attribute + && internal->kind != QXmlNodeModelIndex::Element) { + qWarning("%s: node must be an attribute or element", Q_FUNC_INFO); + return QVariant(); + } return internal->value; } @@ -167,10 +174,10 @@ QXmlNodeModelIndex LoadingModel::nextFromSimpleAxis(QAbstractXmlNodeModel::Simpl return internal->precedingSibling ? createIndex(internal->precedingSibling) : QXmlNodeModelIndex(); case NextSibling: return internal->followingSibling ? createIndex(internal->followingSibling) : QXmlNodeModelIndex(); + default: + qWarning("%s: unknown axis enum value %d", Q_FUNC_INFO, static_cast<int>(axis)); + return QXmlNodeModelIndex(); } - - Q_ASSERT(false); - return QXmlNodeModelIndex(); } QVector<QXmlNodeModelIndex> LoadingModel::attributes(const QXmlNodeModelIndex &ni) const @@ -326,18 +333,16 @@ void Loader::load() break; } case QXmlStreamReader::DTD: - /* Fallthrough. */ + qFatal("%s: QXmlStreamReader::DTD token is not supported", Q_FUNC_INFO); + break; case QXmlStreamReader::EntityReference: - { - Q_ASSERT_X(false, Q_FUNC_INFO, - "We don't support this."); - /* Fallthrough. */ - } + qFatal("%s: QXmlStreamReader::EntityReference token is not supported", Q_FUNC_INFO); + break; case QXmlStreamReader::NoToken: /* Fallthrough. */ case QXmlStreamReader::Invalid: { - qWarning(qPrintable(reader.errorString())); + qWarning("%s", qPrintable(reader.errorString())); m_result.clear(); return; } @@ -346,7 +351,7 @@ void Loader::load() if(reader.hasError()) { - qWarning(qPrintable(reader.errorString())); + qWarning("%s", qPrintable(reader.errorString())); m_result.clear(); } } @@ -355,6 +360,11 @@ QAbstractXmlNodeModel::Ptr LoadingModel::create(const QXmlNamePool &np) { Loader loader(np); loader.load(); + if (loader.m_result.isEmpty()) { + qWarning("%s: attempt to create model with no content", Q_FUNC_INFO); + return Ptr(0); + } + return Ptr(new LoadingModel(loader.m_result, np)); } #endif //QTEST_XMLPATTERNS diff --git a/tests/auto/qabstractxmlnodemodel/qabstractxmlnodemodel.pro b/tests/auto/qabstractxmlnodemodel/qabstractxmlnodemodel.pro index a18f4ca..b8f509d 100644 --- a/tests/auto/qabstractxmlnodemodel/qabstractxmlnodemodel.pro +++ b/tests/auto/qabstractxmlnodemodel/qabstractxmlnodemodel.pro @@ -7,7 +7,7 @@ HEADERS += TestNodeModel.h LoadingModel.h include (../xmlpatterns.pri) wince*: { - addFiles.sources = tree.xml + addFiles.files = tree.xml addFiles.path = . DEPLOYMENT += addFiles diff --git a/tests/auto/qaccessibility/qaccessibility.pro b/tests/auto/qaccessibility/qaccessibility.pro index 1b30beb..71d6f95 100644 --- a/tests/auto/qaccessibility/qaccessibility.pro +++ b/tests/auto/qaccessibility/qaccessibility.pro @@ -1,11 +1,12 @@ load(qttest_p4) +requires(contains(QT_CONFIG,accessibility)) SOURCES += tst_qaccessibility.cpp unix:!mac:LIBS+=-lm contains(QT_CONFIG, qt3support): QT += qt3support wince*: { - accessneeded.sources = $$QT_BUILD_TREE\\plugins\\accessible\\*.dll + accessneeded.files = $$QT_BUILD_TREE\\plugins\\accessible\\*.dll accessneeded.path = accessible DEPLOYMENT += accessneeded -}
\ No newline at end of file +} diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index 01029ba..92e3a8b 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -245,10 +245,13 @@ private slots: void actionText(); void doAction(); + void applicationTest(); + void mainWindowTest(); void buttonTest(); void sliderTest(); void scrollBarTest(); void tabTest(); + void tabWidgetTest(); void menuTest(); void spinBoxTest(); void doubleSpinBoxTest(); @@ -323,69 +326,16 @@ QString eventName(const int ev) } } -static QString stateNames(int state) -{ - QString stateString; - if (state == 0x00000000) stateString += " Normal"; - if (state & 0x00000001) stateString += " Unavailable"; - if (state & 0x00000002) stateString += " Selected"; - if (state & 0x00000004) stateString += " Focused"; - if (state & 0x00000008) stateString += " Pressed"; - if (state & 0x00000010) stateString += " Checked"; - if (state & 0x00000020) stateString += " Mixed"; - if (state & 0x00000040) stateString += " ReadOnly"; - if (state & 0x00000080) stateString += " HotTracked"; - if (state & 0x00000100) stateString += " DefaultButton"; - if (state & 0x00000200) stateString += " Expanded"; - if (state & 0x00000400) stateString += " Collapsed"; - if (state & 0x00000800) stateString += " Busy"; - if (state & 0x00001000) stateString += " Floating"; - if (state & 0x00002000) stateString += " Marqueed"; - if (state & 0x00004000) stateString += " Animated"; - if (state & 0x00008000) stateString += " Invisible"; - if (state & 0x00010000) stateString += " Offscreen"; - if (state & 0x00020000) stateString += " Sizeable"; - if (state & 0x00040000) stateString += " Moveable"; - if (state & 0x00080000) stateString += " SelfVoicing"; - if (state & 0x00100000) stateString += " Focusable"; - if (state & 0x00200000) stateString += " Selectable"; - if (state & 0x00400000) stateString += " Linked"; - if (state & 0x00800000) stateString += " Traversed"; - if (state & 0x01000000) stateString += " MultiSelectable"; - if (state & 0x02000000) stateString += " ExtSelectable"; - if (state & 0x04000000) stateString += " AlertLow"; - if (state & 0x08000000) stateString += " AlertMedium"; - if (state & 0x10000000) stateString += " AlertHigh"; - if (state & 0x20000000) stateString += " Protected"; - if (state & 0x3fffffff) stateString += " Valid"; - - if (stateString.isEmpty()) - stateString = "Unknown state " + QString::number(state); - - return stateString; -} - QAccessible::State state(QWidget * const widget) { QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); - Q_ASSERT(iface); - QAccessible::State state = iface->state(0); + if (!iface) + qWarning() << "Cannot get QAccessibleInterface for widget"; + QAccessible::State state = (iface ? iface->state(0) : static_cast<QAccessible::State>(0)); delete iface; return state; } -void printState(QWidget * const widget) -{ - qDebug() << "State for" << widget->metaObject()->className() << stateNames(state(widget)); -} - -void printState(QAccessibleInterface * const iface, const int child = 0) -{ - qDebug() << "State for" << iface->object()->metaObject()->className() << "child" << child - << iface->text(QAccessible::Name, child) << stateNames(iface->state(child)); -} - - class QtTestAccessibleWidget: public QWidget { Q_OBJECT @@ -400,7 +350,6 @@ public: } }; -#ifdef QTEST_ACCESSIBILITY class QtTestAccessibleWidgetIface: public QAccessibleWidget { public: @@ -418,7 +367,6 @@ public: return 0; } }; -#endif tst_QAccessibility::tst_QAccessibility() { @@ -430,17 +378,13 @@ tst_QAccessibility::~tst_QAccessibility() void tst_QAccessibility::initTestCase() { -#ifdef QTEST_ACCESSIBILITY QTestAccessibility::initialize(); QAccessible::installFactory(QtTestAccessibleWidgetIface::ifaceFactory); -#endif } void tst_QAccessibility::cleanupTestCase() { -#ifdef QTEST_ACCESSIBILITY QTestAccessibility::cleanup(); -#endif } void tst_QAccessibility::init() @@ -450,7 +394,6 @@ void tst_QAccessibility::init() void tst_QAccessibility::cleanup() { -#ifdef QTEST_ACCESSIBILITY const EventList list = QTestAccessibility::events(); if (!list.isEmpty()) { qWarning("%d accessibility event(s) were not handled in testfunction '%s':", list.count(), @@ -460,14 +403,10 @@ void tst_QAccessibility::cleanup() eventName(list.at(i).event).toAscii().constData(), list.at(i).event, list.at(i).child); } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::eventTest() { -#ifdef QTEST_ACCESSIBILITY QPushButton* button = new QPushButton(0); button->setObjectName(QString("Olaf")); @@ -479,18 +418,19 @@ void tst_QAccessibility::eventTest() QVERIFY_EVENT(button, 0, QAccessible::StateChanged); QVERIFY_EVENT(button, 0, QAccessible::StateChanged); + button->setAccessibleName("Olaf the second"); + QVERIFY_EVENT(button, 0, QAccessible::NameChanged); + button->setAccessibleDescription("This is a button labeled Olaf"); + QVERIFY_EVENT(button, 0, QAccessible::DescriptionChanged); + button->hide(); QVERIFY_EVENT(button, 0, QAccessible::ObjectHide); delete button; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::customWidget() { -#ifdef QTEST_ACCESSIBILITY QtTestAccessibleWidget* widget = new QtTestAccessibleWidget(0, "Heinz"); QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); @@ -502,14 +442,10 @@ void tst_QAccessibility::customWidget() delete iface; delete widget; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::deletedWidget() { -#ifdef QTEST_ACCESSIBILITY QtTestAccessibleWidget *widget = new QtTestAccessibleWidget(0, "Ralf"); QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); QVERIFY(iface != 0); @@ -520,9 +456,6 @@ void tst_QAccessibility::deletedWidget() widget = 0; QVERIFY(!iface->isValid()); delete iface; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } QWidget *tst_QAccessibility::createGUI() @@ -531,7 +464,6 @@ QWidget *tst_QAccessibility::createGUI() qWarning( "Should never get here without Qt3Support"); return 0; #else -# ifdef QTEST_ACCESSIBILITY QWidget *toplevel = new QWidget(0, Qt::X11BypassWindowManagerHint); QGridLayout *grid = new QGridLayout(toplevel, 2, 2); @@ -603,10 +535,6 @@ QWidget *tst_QAccessibility::createGUI() radioAM->setFocus(); QTestAccessibility::clearEvents(); return toplevel; -# else - Q_ASSERT(0); // this function cannot be called without accessibility support - return 0; -# endif #endif // !QT3_SUPPORT } @@ -615,7 +543,6 @@ void tst_QAccessibility::childAt() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); QAccessibleInterface *acc_toplevel = QAccessible::queryAccessibleInterface(toplevel); QVERIFY(acc_toplevel); @@ -647,9 +574,6 @@ void tst_QAccessibility::childAt() delete acc_toplevel; delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -658,7 +582,6 @@ void tst_QAccessibility::childCount() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); QObject *topLeft = toplevel->child("topLeft"); QObject *topRight = toplevel->child("topRight"); @@ -691,9 +614,6 @@ void tst_QAccessibility::childCount() delete acc_bottomRight; delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -702,7 +622,6 @@ void tst_QAccessibility::relationTo() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); toplevel->resize(400,300); QObject *topLeft = toplevel->child("topLeft"); @@ -908,15 +827,11 @@ void tst_QAccessibility::relationTo() delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } void tst_QAccessibility::navigateGeometric() { -#ifdef QTEST_ACCESSIBILITY { static const int skip = 20; //speed the test up significantly static const double step = Q_PI / 180; @@ -1012,14 +927,10 @@ void tst_QAccessibility::navigateGeometric() delete w; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::navigateSlider() { -#ifdef QTEST_ACCESSIBILITY { QSlider *slider = new QSlider(0); slider->setObjectName(QString("Slidy")); @@ -1046,14 +957,10 @@ void tst_QAccessibility::navigateSlider() delete slider; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::navigateCovered() { -#ifdef QTEST_ACCESSIBILITY { QWidget *w = new QWidget(0); w->setObjectName(QString("Harry")); @@ -1156,14 +1063,10 @@ void tst_QAccessibility::navigateCovered() delete w; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::navigateHierarchy() { -#ifdef QTEST_ACCESSIBILITY { QWidget *w = new QWidget(0); w->setObjectName(QString("Hans")); @@ -1259,9 +1162,6 @@ void tst_QAccessibility::navigateHierarchy() delete w; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } #define QSETCOMPARE(thetypename, elements, otherelements) \ @@ -1272,7 +1172,6 @@ void tst_QAccessibility::navigateControllers() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY { Q3VBox vbox; QSlider slider(&vbox); @@ -1355,9 +1254,6 @@ void tst_QAccessibility::navigateControllers() delete acc_slider; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -1366,7 +1262,6 @@ void tst_QAccessibility::navigateLabels() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY { Q3VBox vbox; Q3HBox hbox(&vbox); @@ -1488,9 +1383,6 @@ void tst_QAccessibility::navigateLabels() delete acc_lineedit3; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -1542,7 +1434,6 @@ static QWidget *createWidgets() void tst_QAccessibility::accessibleName() { -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createWidgets(); toplevel->show(); #if defined(Q_WS_X11) @@ -1567,9 +1458,6 @@ void tst_QAccessibility::accessibleName() delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::text() @@ -1577,7 +1465,6 @@ void tst_QAccessibility::text() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); toplevel->show(); #if defined(Q_WS_X11) @@ -1673,10 +1560,6 @@ void tst_QAccessibility::text() delete toplevel; QTestAccessibility::clearEvents(); - -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -1685,7 +1568,6 @@ void tst_QAccessibility::setText() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); toplevel->show(); QObject *bottomLeft = toplevel->findChild<QObject *>("bottomLeft"); @@ -1709,16 +1591,11 @@ void tst_QAccessibility::setText() delete acc_lineedit; delete toplevel; QTestAccessibility::clearEvents(); - -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif //QT3_SUPPORT } void tst_QAccessibility::hideShowTest() { -#ifdef QTEST_ACCESSIBILITY QWidget * const window = new QWidget(); QWidget * const child = new QWidget(window); @@ -1745,14 +1622,10 @@ void tst_QAccessibility::hideShowTest() delete window; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::userActionCount() { -#ifdef QTEST_ACCESSIBILITY QWidget widget; QAccessibleInterface *test = QAccessible::queryAccessibleInterface(&widget); @@ -1782,18 +1655,14 @@ void tst_QAccessibility::userActionCount() QCOMPARE(test->userActionCount(1), 0); QCOMPARE(test->userActionCount(-1), 0); delete test; test = 0; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::actionText() { -#ifdef QTEST_ACCESSIBILITY - QWidget widget; - widget.show(); + QWidget *widget = new QWidget; + widget->show(); - QAccessibleInterface *test = QAccessible::queryAccessibleInterface(&widget); + QAccessibleInterface *test = QAccessible::queryAccessibleInterface(widget); QVERIFY(test); QVERIFY(test->isValid()); @@ -1805,65 +1674,101 @@ void tst_QAccessibility::actionText() QCOMPARE(test->actionText(QAccessible::DefaultAction, QAccessible::Name, 0), QString("SetFocus")); QCOMPARE(test->actionText(QAccessible::SetFocus, QAccessible::Name, 0), QString("SetFocus")); - delete test; test = 0; + delete test; + delete widget; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif + QTestAccessibility::clearEvents(); } void tst_QAccessibility::doAction() { -#ifdef QTEST_ACCESSIBILITY QSKIP("TODO: Implement me", SkipAll); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } +void tst_QAccessibility::applicationTest() +{ + QLatin1String name = QLatin1String("My Name"); + qApp->setApplicationName(name); + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(qApp); + QCOMPARE(interface->text(QAccessible::Name, 0), name); + QCOMPARE(interface->role(0), QAccessible::Application); + delete interface; +} + +void tst_QAccessibility::mainWindowTest() +{ + QMainWindow mw; + mw.resize(300, 200); + mw.show(); // triggers layout + + QLatin1String name = QLatin1String("I am the main window"); + mw.setWindowTitle(name); + QTest::qWaitForWindowShown(&mw); + + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&mw); + QCOMPARE(interface->text(QAccessible::Name, 0), name); + QCOMPARE(interface->role(0), QAccessible::Window); + delete interface; +} + +class CounterButton : public QPushButton { + Q_OBJECT +public: + CounterButton(const QString& name, QWidget* parent) + : QPushButton(name, parent), clickCount(0) + { + connect(this, SIGNAL(clicked(bool)), SLOT(incClickCount())); + } + int clickCount; +public Q_SLOTS: + void incClickCount() { + ++clickCount; + } +}; + void tst_QAccessibility::buttonTest() { -//#ifdef QTEST_ACCESSIBILITY -#if 0 - QAccessibleInterface *test = 0; - Q3VBox vbox; + QWidget window; + window.setLayout(new QVBoxLayout); // Standard push button - QPushButton pushButton("Ok", &vbox); - - // toggle push button - QPushButton togglepush("Toggle", &vbox); - togglepush.setToggleButton(TRUE); + CounterButton pushButton("Ok", &window); - // push button with a menu - QPushButton menuButton("Menu", &vbox); - Q3PopupMenu buttonMenu(&menuButton); - buttonMenu.insertItem("Some item"); - menuButton.setPopup(&buttonMenu); + // toggle button + QPushButton toggleButton("Toggle", &window); + toggleButton.setCheckable(true); // standard checkbox - QCheckBox checkBox("Check me!", &vbox); + QCheckBox checkBox("Check me!", &window); // tristate checkbox - QCheckBox tristate("Tristate!", &vbox); + QCheckBox tristate("Tristate!", &window); tristate.setTristate(TRUE); // radiobutton - QRadioButton radio("Radio me!", &vbox); + QRadioButton radio("Radio me!", &window); // standard toolbutton - QToolButton toolbutton(&vbox); + QToolButton toolbutton(&window); toolbutton.setText("Tool"); toolbutton.setMinimumSize(20,20); // standard toolbutton - QToolButton toggletool(&vbox); - toggletool.setToggleButton(TRUE); + QToolButton toggletool(&window); + toggletool.setCheckable(true); toggletool.setText("Toggle"); toggletool.setMinimumSize(20,20); +#if 0 + // QT3_SUPPORT + // push button with a menu + QPushButton menuButton("Menu", &window); + Q3PopupMenu buttonMenu(&menuButton); + buttonMenu.insertItem("Some item"); + menuButton.setPopup(&buttonMenu); + // menu toolbutton - QToolButton menuToolButton(&vbox); + QToolButton menuToolButton(&window); menuToolButton.setText("Menu Tool"); Q3PopupMenu toolMenu(&menuToolButton); toolMenu.insertItem("Some item"); @@ -1871,142 +1776,146 @@ void tst_QAccessibility::buttonTest() menuToolButton.setMinimumSize(20,20); // splitted menu toolbutton - QToolButton splitToolButton(&vbox); + QToolButton splitToolButton(&window); splitToolButton.setTextLabel("Split Tool"); Q3PopupMenu splitMenu(&splitToolButton); splitMenu.insertItem("Some item"); splitToolButton.setPopup(&splitMenu); splitToolButton.setPopupDelay(0); splitToolButton.setMinimumSize(20,20); +#endif // test push button - QVERIFY(QAccessible::queryAccessibleInterface(&pushButton, &test)); - QCOMPARE(test->role(0), QAccessible::PushButton); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - pushButton.setDown(TRUE); - QCOMPARE(test->state(0), (int)QAccessible::Pressed); - QVERIFY(test->doAction(QAccessible::Press, 0)); + QAccessibleInterface* interface = QAccessible::queryAccessibleInterface(&pushButton); + QAccessibleActionInterface* actionInterface = interface->actionInterface(); + QVERIFY(actionInterface != 0); + + QCOMPARE(interface->role(0), QAccessible::PushButton); + + // currently our buttons only have click as action, press and release are missing + QCOMPARE(actionInterface->actionCount(), 1); + QCOMPARE(actionInterface->name(0), QString("Press")); + QCOMPARE(pushButton.clickCount, 0); + actionInterface->doAction(0); QTest::qWait(500); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - test->release(); - - // test toggle push button - QVERIFY(QAccessible::queryAccessibleInterface(&togglepush, &test)); - QCOMPARE(test->role(0), QAccessible::CheckBox); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - QVERIFY(test->doAction(QAccessible::Press, 0)); + QCOMPARE(pushButton.clickCount, 1); + delete interface; + + // test toggle button + interface = QAccessible::queryAccessibleInterface(&toggleButton); + actionInterface = interface->actionInterface(); + QCOMPARE(interface->role(0), QAccessible::CheckBox); + QCOMPARE(actionInterface->description(0), QString("Toggles the button.")); + QCOMPARE(actionInterface->name(0), QString("Check")); + QVERIFY(!toggleButton.isChecked()); + QVERIFY((interface->state(0) & QAccessible::Checked) == 0); + actionInterface->doAction(0); QTest::qWait(500); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); - QCOMPARE(test->state(0), (int)QAccessible::Checked); - test->release(); - - // test menu push button - QVERIFY(QAccessible::queryAccessibleInterface(&menuButton, &test)); - QCOMPARE(test->role(0), QAccessible::ButtonMenu); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Open")); - QCOMPARE(test->state(0), (int)QAccessible::HasPopup); - test->release(); + QCOMPARE(actionInterface->name(0), QString("Uncheck")); + QVERIFY(toggleButton.isChecked()); + QVERIFY((interface->state(0) & QAccessible::Checked)); + delete interface; + +// // test menu push button +// QVERIFY(QAccessible::queryAccessibleInterface(&menuButton, &test)); +// QCOMPARE(test->role(0), QAccessible::ButtonMenu); +// QCOMPARE(test->defaultAction(0), QAccessible::Press); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Open")); +// QCOMPARE(test->state(0), (int)QAccessible::HasPopup); +// test->release(); // test check box - QVERIFY(QAccessible::queryAccessibleInterface(&checkBox, &test)); - QCOMPARE(test->role(0), QAccessible::CheckBox); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - QVERIFY(test->doAction(QAccessible::Press, 0)); - QTest::qWait(500); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); - QCOMPARE(test->state(0), (int)QAccessible::Checked); - test->release(); - - // test tristate check box - QVERIFY(QAccessible::queryAccessibleInterface(&tristate, &test)); - QCOMPARE(test->role(0), QAccessible::CheckBox); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Toggle")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - QVERIFY(test->doAction(QAccessible::Press, 0)); - QTest::qWait(500); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); - QCOMPARE(test->state(0), (int)QAccessible::Mixed); - QVERIFY(test->doAction(QAccessible::Press, 0)); + interface = QAccessible::queryAccessibleInterface(&checkBox); + actionInterface = interface->actionInterface(); + QCOMPARE(interface->role(0), QAccessible::CheckBox); + QCOMPARE(actionInterface->name(0), QString("Check")); + QVERIFY((interface->state(0) & QAccessible::Checked) == 0); + actionInterface->doAction(0); QTest::qWait(500); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); - QCOMPARE(test->state(0), (int)QAccessible::Checked); - test->release(); + QCOMPARE(actionInterface->name(0), QString("Uncheck")); + QVERIFY(interface->state(0) & QAccessible::Checked); + QVERIFY(checkBox.isChecked()); + delete interface; + +// // test tristate check box +// QVERIFY(QAccessible::queryAccessibleInterface(&tristate, &test)); +// QCOMPARE(test->role(0), QAccessible::CheckBox); +// QCOMPARE(test->defaultAction(0), QAccessible::Press); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Toggle")); +// QCOMPARE(test->state(0), (int)QAccessible::Normal); +// QVERIFY(test->doAction(QAccessible::Press, 0)); +// QTest::qWait(500); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); +// QCOMPARE(test->state(0), (int)QAccessible::Mixed); +// QVERIFY(test->doAction(QAccessible::Press, 0)); +// QTest::qWait(500); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); +// QCOMPARE(test->state(0), (int)QAccessible::Checked); +// test->release(); // test radiobutton - QVERIFY(QAccessible::queryAccessibleInterface(&radio, &test)); - QCOMPARE(test->role(0), QAccessible::RadioButton); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - QVERIFY(test->doAction(QAccessible::Press, 0)); - QTest::qWait(500); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); - QCOMPARE(test->state(0), (int)QAccessible::Checked); - test->release(); - - // test standard toolbutton - QVERIFY(QAccessible::queryAccessibleInterface(&toolbutton, &test)); - QCOMPARE(test->role(0), QAccessible::PushButton); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - test->release(); - - // toggle tool button - QVERIFY(QAccessible::queryAccessibleInterface(&toggletool, &test)); - QCOMPARE(test->role(0), QAccessible::CheckBox); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - QVERIFY(test->doAction(QAccessible::Press, 0)); + interface = QAccessible::queryAccessibleInterface(&radio); + actionInterface = interface->actionInterface(); + QCOMPARE(interface->role(0), QAccessible::RadioButton); + QCOMPARE(actionInterface->name(0), QString("Check")); + QVERIFY((interface->state(0) & QAccessible::Checked) == 0); + actionInterface->doAction(0); QTest::qWait(500); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); - QCOMPARE(test->state(0), (int)QAccessible::Checked); - test->release(); - - // test menu toolbutton - QVERIFY(QAccessible::queryAccessibleInterface(&menuToolButton, &test)); - QCOMPARE(test->role(0), QAccessible::ButtonMenu); - QCOMPARE(test->defaultAction(0), 1); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Open")); - QCOMPARE(test->state(0), (int)QAccessible::HasPopup); - QCOMPARE(test->actionCount(0), 1); - QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 0), QString("Press")); - test->release(); - - // test splitted menu toolbutton - QVERIFY(QAccessible::queryAccessibleInterface(&splitToolButton, &test)); - QCOMPARE(test->childCount(), 2); - QCOMPARE(test->role(0), QAccessible::ButtonDropDown); - QCOMPARE(test->role(1), QAccessible::PushButton); - QCOMPARE(test->role(2), QAccessible::ButtonMenu); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->defaultAction(1), QAccessible::Press); - QCOMPARE(test->defaultAction(2), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); - QCOMPARE(test->state(0), (int)QAccessible::HasPopup); - QCOMPARE(test->actionCount(0), 1); - QCOMPARE(test->actionText(1, QAccessible::Name, 0), QString("Open")); - QCOMPARE(test->actionText(test->defaultAction(1), QAccessible::Name, 1), QString("Press")); - QCOMPARE(test->state(1), (int)QAccessible::Normal); - QCOMPARE(test->actionText(test->defaultAction(2), QAccessible::Name, 2), QString("Open")); - QCOMPARE(test->state(2), (int)QAccessible::HasPopup); - test->release(); + QCOMPARE(actionInterface->name(0), QString("Uncheck")); + QVERIFY(interface->state(0) & QAccessible::Checked); + QVERIFY(checkBox.isChecked()); + delete interface; - QTestAccessibility::clearEvents(); +// // test standard toolbutton +// QVERIFY(QAccessible::queryAccessibleInterface(&toolbutton, &test)); +// QCOMPARE(test->role(0), QAccessible::PushButton); +// QCOMPARE(test->defaultAction(0), QAccessible::Press); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); +// QCOMPARE(test->state(0), (int)QAccessible::Normal); +// test->release(); + +// // toggle tool button +// QVERIFY(QAccessible::queryAccessibleInterface(&toggletool, &test)); +// QCOMPARE(test->role(0), QAccessible::CheckBox); +// QCOMPARE(test->defaultAction(0), QAccessible::Press); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); +// QCOMPARE(test->state(0), (int)QAccessible::Normal); +// QVERIFY(test->doAction(QAccessible::Press, 0)); +// QTest::qWait(500); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); +// QCOMPARE(test->state(0), (int)QAccessible::Checked); +// test->release(); + +// // test menu toolbutton +// QVERIFY(QAccessible::queryAccessibleInterface(&menuToolButton, &test)); +// QCOMPARE(test->role(0), QAccessible::ButtonMenu); +// QCOMPARE(test->defaultAction(0), 1); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Open")); +// QCOMPARE(test->state(0), (int)QAccessible::HasPopup); +// QCOMPARE(test->actionCount(0), 1); +// QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 0), QString("Press")); +// test->release(); + +// // test splitted menu toolbutton +// QVERIFY(QAccessible::queryAccessibleInterface(&splitToolButton, &test)); +// QCOMPARE(test->childCount(), 2); +// QCOMPARE(test->role(0), QAccessible::ButtonDropDown); +// QCOMPARE(test->role(1), QAccessible::PushButton); +// QCOMPARE(test->role(2), QAccessible::ButtonMenu); +// QCOMPARE(test->defaultAction(0), QAccessible::Press); +// QCOMPARE(test->defaultAction(1), QAccessible::Press); +// QCOMPARE(test->defaultAction(2), QAccessible::Press); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); +// QCOMPARE(test->state(0), (int)QAccessible::HasPopup); +// QCOMPARE(test->actionCount(0), 1); +// QCOMPARE(test->actionText(1, QAccessible::Name, 0), QString("Open")); +// QCOMPARE(test->actionText(test->defaultAction(1), QAccessible::Name, 1), QString("Press")); +// QCOMPARE(test->state(1), (int)QAccessible::Normal); +// QCOMPARE(test->actionText(test->defaultAction(2), QAccessible::Name, 2), QString("Open")); +// QCOMPARE(test->state(2), (int)QAccessible::HasPopup); +// test->release(); -#else -// QSKIP("Test needs accessibility support.", SkipAll); - QSKIP("No action interface in Qt 4 yet.", SkipAll); -#endif + QTestAccessibility::clearEvents(); } void tst_QAccessibility::sliderTest() @@ -2014,20 +1923,19 @@ void tst_QAccessibility::sliderTest() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QAccessibleInterface *test = 0; - Q3VBox vbox; - QLabel labelHorizontal("Horizontal", &vbox); - QSlider sliderHorizontal(Qt::Horizontal, &vbox); - labelHorizontal.setBuddy(&sliderHorizontal); + Q3VBox *vbox = new Q3VBox; + QLabel *labelHorizontal = new QLabel("Horizontal", vbox); + QSlider *sliderHorizontal = new QSlider(Qt::Horizontal, vbox); + labelHorizontal->setBuddy(sliderHorizontal); - QLabel labelVertical("Vertical", &vbox); - QSlider sliderVertical(Qt::Vertical, &vbox); - labelVertical.setBuddy(&sliderVertical); - vbox.show(); + QLabel *labelVertical = new QLabel("Vertical", vbox); + QSlider *sliderVertical = new QSlider(Qt::Vertical, vbox); + labelVertical->setBuddy(sliderVertical); + vbox->show(); // test horizontal slider - test = QAccessible::queryAccessibleInterface(&sliderHorizontal); + test = QAccessible::queryAccessibleInterface(sliderHorizontal); QVERIFY(test); QCOMPARE(test->childCount(), 3); QCOMPARE(test->role(0), QAccessible::Slider); @@ -2035,15 +1943,15 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->role(2), QAccessible::Indicator); QCOMPARE(test->role(3), QAccessible::PushButton); - QCOMPARE(test->text(QAccessible::Name, 0), labelHorizontal.text()); + QCOMPARE(test->text(QAccessible::Name, 0), labelHorizontal->text()); QCOMPARE(test->text(QAccessible::Name, 1), QSlider::tr("Page left")); QCOMPARE(test->text(QAccessible::Name, 2), QSlider::tr("Position")); QCOMPARE(test->text(QAccessible::Name, 3), QSlider::tr("Page right")); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.value())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->value())); QCOMPARE(test->text(QAccessible::Value, 1), QString()); - QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderHorizontal.value())); + QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderHorizontal->value())); QCOMPARE(test->text(QAccessible::Value, 3), QString()); -// Skip acton tests. +// Skip action tests. #if 0 QCOMPARE(test->defaultAction(0), QAccessible::SetFocus); QCOMPARE(test->defaultAction(1), QAccessible::Press); @@ -2055,26 +1963,26 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->actionText(QAccessible::Decrease, QAccessible::Name, 2), QSlider::tr("Decrease")); QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 3), QSlider::tr("Press")); QVERIFY(test->doAction(QAccessible::Press, 3)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 3)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 1)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 1)); QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); QVERIFY(test->doAction(QAccessible::Increase, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->lineStep())); QVERIFY(test->doAction(QAccessible::Increase, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal->lineStep())); QVERIFY(test->doAction(QAccessible::Decrease, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->lineStep())); QVERIFY(test->doAction(QAccessible::Decrease, 2)); QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); #endif delete test; // test vertical slider - test = QAccessible::queryAccessibleInterface(&sliderVertical); + test = QAccessible::queryAccessibleInterface(sliderVertical); QVERIFY(test); QCOMPARE(test->childCount(), 3); QCOMPARE(test->role(0), QAccessible::Slider); @@ -2082,15 +1990,15 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->role(2), QAccessible::Indicator); QCOMPARE(test->role(3), QAccessible::PushButton); - QCOMPARE(test->text(QAccessible::Name, 0), labelVertical.text()); + QCOMPARE(test->text(QAccessible::Name, 0), labelVertical->text()); QCOMPARE(test->text(QAccessible::Name, 1), QSlider::tr("Page up")); QCOMPARE(test->text(QAccessible::Name, 2), QSlider::tr("Position")); QCOMPARE(test->text(QAccessible::Name, 3), QSlider::tr("Page down")); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.value())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->value())); QCOMPARE(test->text(QAccessible::Value, 1), QString()); - QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderVertical.value())); + QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderVertical->value())); QCOMPARE(test->text(QAccessible::Value, 3), QString()); -// Skip acton tests. +// Skip action tests. #if 0 QCOMPARE(test->defaultAction(0), QAccessible::SetFocus); QCOMPARE(test->defaultAction(1), QAccessible::Press); @@ -2102,23 +2010,28 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->actionText(QAccessible::Decrease, QAccessible::Name, 2), QSlider::tr("Decrease")); QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 3), QSlider::tr("Press")); QVERIFY(test->doAction(QAccessible::Press, 3)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 3)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 1)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 1)); QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); QVERIFY(test->doAction(QAccessible::Increase, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->lineStep())); QVERIFY(test->doAction(QAccessible::Increase, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical->lineStep())); QVERIFY(test->doAction(QAccessible::Decrease, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->lineStep())); QVERIFY(test->doAction(QAccessible::Decrease, 2)); QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); #endif delete test; + delete sliderHorizontal; + delete sliderVertical; + delete labelHorizontal; + delete labelVertical; + delete vbox; // Test that when we hide() a slider, the PageLeft, Indicator, and PageRight also gets the // Invisible state bit set. @@ -2201,17 +2114,12 @@ void tst_QAccessibility::sliderTest() delete sliderInterface; } - QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif //!QT3_SUPPORT } void tst_QAccessibility::scrollBarTest() { -#ifdef QTEST_ACCESSIBILITY // Test that when we hide() a slider, the PageLeft, Indicator, and PageRight also gets the // Invisible state bit set. enum SubControls { LineUp = 1, @@ -2219,7 +2127,7 @@ void tst_QAccessibility::scrollBarTest() Position = 3, PageDown = 4, LineDown = 5 - }; + }; QScrollBar *scrollBar = new QScrollBar(); QAccessibleInterface * const scrollBarInterface = QAccessible::queryAccessibleInterface(scrollBar); @@ -2301,15 +2209,10 @@ void tst_QAccessibility::scrollBarTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif - } void tst_QAccessibility::tabTest() { -#ifdef QTEST_ACCESSIBILITY QTabBar *tabBar = new QTabBar(); tabBar->show(); @@ -2345,14 +2248,99 @@ void tst_QAccessibility::tabTest() delete tabBar; delete interface; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif +} + +void tst_QAccessibility::tabWidgetTest() +{ + QTabWidget *tabWidget = new QTabWidget(); + tabWidget->show(); + + // the interface for the tab is just a container for tabbar and stacked widget + QAccessibleInterface * const interface = QAccessible::queryAccessibleInterface(tabWidget); + QVERIFY(interface); + QCOMPARE(interface->childCount(), 2); + QCOMPARE(interface->role(0), QAccessible::Client); + + // Create pages, check navigation + QLabel *label1 = new QLabel("Page 1", tabWidget); + tabWidget->addTab(label1, "Tab 1"); + QLabel *label2 = new QLabel("Page 2", tabWidget); + tabWidget->addTab(label2, "Tab 2"); + + QCOMPARE(interface->childCount(), 2); + + QAccessibleInterface* tabBarInterface = 0; + // there is no special logic to sort the children, so the contents will be 1, the tab bar 2 + QCOMPARE(interface->navigate(QAccessible::Child, 2 , &tabBarInterface), 0); + QVERIFY(tabBarInterface); + QCOMPARE(tabBarInterface->childCount(), 4); + QCOMPARE(tabBarInterface->role(0), QAccessible::PageTabList); + + QAccessibleInterface* tabButton1Interface = 0; + QCOMPARE(tabBarInterface->navigate(QAccessible::Child, 1 , &tabButton1Interface), 1); + QVERIFY(tabButton1Interface == 0); + + QCOMPARE(tabBarInterface->role(1), QAccessible::PageTab); + QCOMPARE(tabBarInterface->text(QAccessible::Name, 1), QLatin1String("Tab 1")); + QCOMPARE(tabBarInterface->role(2), QAccessible::PageTab); + QCOMPARE(tabBarInterface->text(QAccessible::Name, 2), QLatin1String("Tab 2")); + QCOMPARE(tabBarInterface->role(3), QAccessible::PushButton); + QCOMPARE(tabBarInterface->text(QAccessible::Name, 3), QLatin1String("Scroll Left")); + QCOMPARE(tabBarInterface->role(4), QAccessible::PushButton); + QCOMPARE(tabBarInterface->text(QAccessible::Name, 4), QLatin1String("Scroll Right")); + + QAccessibleInterface* stackWidgetInterface = 0; + QCOMPARE(interface->navigate(QAccessible::Child, 1, &stackWidgetInterface), 0); + QVERIFY(stackWidgetInterface); + QCOMPARE(stackWidgetInterface->childCount(), 2); + QCOMPARE(stackWidgetInterface->role(0), QAccessible::LayeredPane); + + QAccessibleInterface* stackChild1Interface = 0; + QCOMPARE(stackWidgetInterface->navigate(QAccessible::Child, 1, &stackChild1Interface), 0); + QVERIFY(stackChild1Interface); +#ifndef Q_CC_INTEL + QCOMPARE(stackChild1Interface->childCount(), 0); +#endif + QCOMPARE(stackChild1Interface->role(0), QAccessible::StaticText); + QCOMPARE(stackChild1Interface->text(QAccessible::Name, 0), QLatin1String("Page 1")); + QCOMPARE(label1, stackChild1Interface->object()); + + // Navigation in stack widgets should be consistent + QAccessibleInterface* parent = 0; + QCOMPARE(stackChild1Interface->navigate(QAccessible::Ancestor, 1, &parent), 0); + QVERIFY(parent); +#ifndef Q_CC_INTEL + QCOMPARE(parent->childCount(), 2); +#endif + QCOMPARE(parent->role(0), QAccessible::LayeredPane); + delete parent; + + QAccessibleInterface* stackChild2Interface = 0; + QCOMPARE(stackWidgetInterface->navigate(QAccessible::Child, 2, &stackChild2Interface), 0); + QVERIFY(stackChild2Interface); + QCOMPARE(stackChild2Interface->childCount(), 0); + QCOMPARE(stackChild2Interface->role(0), QAccessible::StaticText); + QCOMPARE(label2, stackChild2Interface->object()); // the text will be empty since it is not visible + + QCOMPARE(stackChild2Interface->navigate(QAccessible::Ancestor, 1, &parent), 0); + QVERIFY(parent); +#ifndef Q_CC_INTEL + QCOMPARE(parent->childCount(), 2); +#endif + QCOMPARE(parent->role(0), QAccessible::LayeredPane); + delete parent; + + delete tabBarInterface; + delete stackChild1Interface; + delete stackChild2Interface; + delete stackWidgetInterface; + delete interface; + delete tabWidget; + QTestAccessibility::clearEvents(); } void tst_QAccessibility::menuTest() { -#ifdef QTEST_ACCESSIBILITY { QMainWindow mw; mw.resize(300, 200); @@ -2598,14 +2586,10 @@ void tst_QAccessibility::menuTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); -#endif } void tst_QAccessibility::spinBoxTest() { -#ifdef QTEST_ACCESSIBILITY QSpinBox * const spinBox = new QSpinBox(); spinBox->show(); @@ -2632,14 +2616,10 @@ void tst_QAccessibility::spinBoxTest() QVERIFY(events.contains(expectedEvent)); delete spinBox; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::doubleSpinBoxTest() { -#ifdef QTEST_ACCESSIBILITY QDoubleSpinBox *doubleSpinBox = new QDoubleSpinBox; doubleSpinBox->show(); @@ -2659,14 +2639,10 @@ void tst_QAccessibility::doubleSpinBoxTest() delete doubleSpinBox; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::textEditTest() { -#ifdef QTEST_ACCESSIBILITY { QTextEdit edit; QString text = "hello world\nhow are you today?\n"; @@ -2679,16 +2655,17 @@ void tst_QAccessibility::textEditTest() QCOMPARE(iface->text(QAccessible::Value, 4), QString("hello world")); QCOMPARE(iface->text(QAccessible::Value, 5), QString("how are you today?")); QCOMPARE(iface->text(QAccessible::Value, 6), QString()); + QCOMPARE(iface->textInterface()->characterCount(), 31); + QFontMetrics fm(edit.font()); + QCOMPARE(iface->textInterface()->characterRect(0, QAccessible2::RelativeToParent).size(), QSize(fm.width("h"), fm.height())); + QCOMPARE(iface->textInterface()->characterRect(5, QAccessible2::RelativeToParent).size(), QSize(fm.width(" "), fm.height())); + QCOMPARE(iface->textInterface()->characterRect(6, QAccessible2::RelativeToParent).size(), QSize(fm.width("w"), fm.height())); } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::textBrowserTest() { -#ifdef QTEST_ACCESSIBILITY { QTextBrowser textBrowser; QString text = QLatin1String("Hello world\nhow are you today?\n"); @@ -2705,14 +2682,10 @@ void tst_QAccessibility::textBrowserTest() QCOMPARE(interface->text(QAccessible::Value, 6), QString()); } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::listViewTest() { -#if 1 //def QTEST_ACCESSIBILITY { QListView listView; QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&listView); @@ -2778,15 +2751,11 @@ void tst_QAccessibility::listViewTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::mdiAreaTest() { -#ifdef QTEST_ACCESSIBILITY { QMdiArea mdiArea; mdiArea.resize(400,300); @@ -2835,14 +2804,10 @@ void tst_QAccessibility::mdiAreaTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::mdiSubWindowTest() { -#ifdef QTEST_ACCESSIBILITY { QMdiArea mdiArea; mdiArea.show(); @@ -2965,14 +2930,10 @@ void tst_QAccessibility::mdiSubWindowTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::lineEditTest() { -#ifdef QTEST_ACCESSIBILITY QLineEdit *le = new QLineEdit; QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(le); QVERIFY(iface); @@ -3030,14 +2991,10 @@ void tst_QAccessibility::lineEditTest() delete le2; delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::workspaceTest() { -#ifdef QTEST_ACCESSIBILITY { QWorkspace workspace; workspace.resize(400,300); @@ -3091,14 +3048,10 @@ void tst_QAccessibility::workspaceTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::dialogButtonBoxTest() { -#ifdef QTEST_ACCESSIBILITY { QDialogButtonBox box(QDialogButtonBox::Reset | QDialogButtonBox::Help | @@ -3211,14 +3164,10 @@ void tst_QAccessibility::dialogButtonBoxTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::dialTest() { -#ifdef QTEST_ACCESSIBILITY { QDial dial; dial.setValue(20); @@ -3260,28 +3209,20 @@ void tst_QAccessibility::dialTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::rubberBandTest() { -#ifdef QTEST_ACCESSIBILITY QRubberBand rubberBand(QRubberBand::Rectangle); QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&rubberBand); QVERIFY(interface); QCOMPARE(interface->role(0), QAccessible::Border); delete interface; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::abstractScrollAreaTest() { -#ifdef QTEST_ACCESSIBILITY { QAbstractScrollArea abstractScrollArea; @@ -3439,14 +3380,10 @@ void tst_QAccessibility::abstractScrollAreaTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::scrollAreaTest() { -#ifdef QTEST_ACCESSIBILITY { QScrollArea scrollArea; scrollArea.show(); @@ -3460,14 +3397,10 @@ void tst_QAccessibility::scrollAreaTest() delete interface; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::tableWidgetTest() { -#ifdef QTEST_ACCESSIBILITY { QWidget *topLevel = new QWidget; QTableWidget *w = new QTableWidget(8,4,topLevel); @@ -3507,10 +3440,6 @@ void tst_QAccessibility::tableWidgetTest() delete topLevel; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif - } class QtTestTableModel: public QAbstractTableModel @@ -3593,7 +3522,6 @@ public: void tst_QAccessibility::tableViewTest() { -#ifdef QTEST_ACCESSIBILITY { QtTestTableModel *model = new QtTestTableModel(3, 4); QTableView *w = new QTableView(); @@ -3673,15 +3601,11 @@ void tst_QAccessibility::tableViewTest() delete model; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::calendarWidgetTest() { #ifndef QT_NO_CALENDARWIDGET -#ifdef QTEST_ACCESSIBILITY { QCalendarWidget calendarWidget; @@ -3774,17 +3698,12 @@ void tst_QAccessibility::calendarWidgetTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // QT_NO_CALENDARWIDGET } void tst_QAccessibility::dockWidgetTest() { #ifndef QT_NO_DOCKWIDGET - -#ifdef QTEST_ACCESSIBILITY // Set up a proper main window with two dock widgets QMainWindow *mw = new QMainWindow(); QFrame *central = new QFrame(mw); @@ -3852,19 +3771,14 @@ void tst_QAccessibility::dockWidgetTest() delete dock2; delete mw; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // QT_NO_DOCKWIDGET } void tst_QAccessibility::pushButtonTest() { #if !defined(QT3_SUPPORT) - qWarning( "Should never get here without Qt3Support"); - return ; + QSKIP( "Should never get here without Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY // Set up a proper main window with two dock widgets QWidget *toplevel = createGUI(); QObject *topRight = toplevel->findChild<QObject *>("topRight"); @@ -3883,10 +3797,10 @@ void tst_QAccessibility::pushButtonTest() QAccessibleInterface *acc; QAccessibleInterface *acc2; int entry = accToplevel->childAt(pt.x(), pt.y()); - int child = accToplevel->navigate(QAccessible::Child, entry, &acc); + accToplevel->navigate(QAccessible::Child, entry, &acc); if (acc) { entry = acc->childAt(pt.x(), pt.y()); - child = acc->navigate(QAccessible::Child, entry, &acc2); + acc->navigate(QAccessible::Child, entry, &acc2); delete acc; acc = acc2; } @@ -3898,15 +3812,11 @@ void tst_QAccessibility::pushButtonTest() delete accToplevel; delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif //QT3_SUPPORT } void tst_QAccessibility::comboBoxTest() { -#ifdef QTEST_ACCESSIBILITY #if defined(Q_OS_WINCE) if (!IsValidCEPlatform()) { QSKIP("Test skipped on Windows Mobile test hardware", SkipAll); @@ -3944,15 +3854,10 @@ void tst_QAccessibility::comboBoxTest() delete w; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif - } void tst_QAccessibility::treeWidgetTest() { -#ifdef QTEST_ACCESSIBILITY QWidget *w = new QWidget; QTreeWidget *tree = new QTreeWidget(w); QHBoxLayout *l = new QHBoxLayout(w); @@ -4010,14 +3915,10 @@ void tst_QAccessibility::treeWidgetTest() delete w; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::labelTest() { -#ifdef QTEST_ACCESSIBILITY QString text = "Hello World"; QLabel *label = new QLabel(text); label->show(); @@ -4056,14 +3957,10 @@ void tst_QAccessibility::labelTest() delete acc_label; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::accelerators() { -#ifdef QTEST_ACCESSIBILITY QWidget *window = new QWidget; QHBoxLayout *lay = new QHBoxLayout(window); QLabel *label = new QLabel(tr("&Line edit"), window); @@ -4075,7 +3972,8 @@ void tst_QAccessibility::accelerators() window->show(); QAccessibleInterface *accLineEdit = QAccessible::queryAccessibleInterface(le); - QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString() + QLatin1String("L")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("L")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("L")); label->setText(tr("Q &")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); label->setText(tr("Q &&")); @@ -4083,11 +3981,15 @@ void tst_QAccessibility::accelerators() label->setText(tr("Q && A")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); label->setText(tr("Q &&&A")); - QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString() + QLatin1String("A")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("A")); label->setText(tr("Q &&A")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); + +#if !defined(QT_NO_DEBUG) && !defined(Q_WS_MAC) + QTest::ignoreMessage(QtWarningMsg, "QKeySequence::mnemonic: \"Q &A&B\" contains multiple occurrences of '&'"); +#endif label->setText(tr("Q &A&B")); - QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString() + QLatin1String("A")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("A")); #if defined(Q_WS_X11) qt_x11_wait_for_window_manager(window); @@ -4095,9 +3997,6 @@ void tst_QAccessibility::accelerators() QTest::qWait(100); delete window; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); -#endif } diff --git a/tests/auto/qaction/tst_qaction.cpp b/tests/auto/qaction/tst_qaction.cpp index 43843ac..903c31d 100644 --- a/tests/auto/qaction/tst_qaction.cpp +++ b/tests/auto/qaction/tst_qaction.cpp @@ -242,7 +242,7 @@ void tst_QAction::setStandardKeys() QList<QKeySequence> expected; #if defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN) expected << QKeySequence("CTRL+C"); -#elif defined(Q_WS_WIN) || defined(Q_WS_QWS) +#elif defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_QPA) expected << QKeySequence("CTRL+C") << QKeySequence("CTRL+INSERT"); #else expected << QKeySequence("CTRL+C") << QKeySequence("F16") << QKeySequence("CTRL+INSERT"); diff --git a/tests/auto/qalgorithms/tst_qalgorithms.cpp b/tests/auto/qalgorithms/tst_qalgorithms.cpp index 9c0f5af..1513c98 100644 --- a/tests/auto/qalgorithms/tst_qalgorithms.cpp +++ b/tests/auto/qalgorithms/tst_qalgorithms.cpp @@ -81,6 +81,7 @@ private slots: void test_qBinaryFind(); void qBinaryFindOneEntry(); void swap(); + void swap2(); void sortEmptyList(); void sortedList(); void sortAPItest(); @@ -240,7 +241,8 @@ QList<ResultSet> testAlgorithm(Algorithm &algorithm, QStringList dataSetTypes, foreach(QString dataSetType, dataSetTypes) { QVector<DataType> container = generateData<DataType>(dataSetType, size); results.append(testRun(container, algorithm, time)); - Q_ASSERT(isSorted(container)); + if (!isSorted(container)) + qWarning("%s: container is not sorted after test", Q_FUNC_INFO); } return results; } @@ -521,6 +523,28 @@ void tst_QAlgorithms::swap() } } +namespace SwapTest { + struct ST { int i; int j; }; + void swap(ST &a, ST &b) { + a.i = b.j; + b.i = a.j; + } +} + +void tst_QAlgorithms::swap2() +{ + { +#ifndef QT_NO_SQL + //check the namespace lookup works correctly + SwapTest::ST a = { 45, 65 }; + SwapTest::ST b = { 48, 68 }; + qSwap(a, b); + QCOMPARE(a.i, 68); + QCOMPARE(b.i, 65); +#endif + } +} + void tst_QAlgorithms::sortEmptyList() { // Only test if it crashes diff --git a/tests/auto/qanimationgroup/qanimationgroup.pro b/tests/auto/qanimationgroup/qanimationgroup.pro index 31667a8..5e1be0c 100644 --- a/tests/auto/qanimationgroup/qanimationgroup.pro +++ b/tests/auto/qanimationgroup/qanimationgroup.pro @@ -3,3 +3,4 @@ QT = core SOURCES += tst_qanimationgroup.cpp +CONFIG += parallel_test diff --git a/tests/auto/qapplication/test/test.pro b/tests/auto/qapplication/test/test.pro index d946e7e..73799f4 100644 --- a/tests/auto/qapplication/test/test.pro +++ b/tests/auto/qapplication/test/test.pro @@ -4,19 +4,19 @@ SOURCES += ../tst_qapplication.cpp TARGET = ../tst_qapplication wince* { - additional.sources = ../desktopsettingsaware/desktopsettingsaware.exe + additional.files = ../desktopsettingsaware/desktopsettingsaware.exe additional.path = desktopsettingsaware - someTest.sources = test.pro + someTest.files = test.pro someTest.path = test - DEPLOYMENT = additional deploy someTest + DEPLOYMENT += additional deploy someTest } symbian: { - additional.sources = $$OUT_PWD/../desktopsettingsaware/desktopsettingsaware.exe + additional.files = $$OUT_PWD/../desktopsettingsaware/desktopsettingsaware.exe additional.path = desktopsettingsaware - someTest.sources = test.pro + someTest.files = test.pro someTest.path = test - windowIcon.sources = ../heart.svg + windowIcon.files = ../heart.svg DEPLOYMENT += additional deploy someTest windowIcon LIBS += -lcone -lavkon } diff --git a/tests/auto/qatomicint/qatomicint.pro b/tests/auto/qatomicint/qatomicint.pro index 4a09d5f..7850d93 100644 --- a/tests/auto/qatomicint/qatomicint.pro +++ b/tests/auto/qatomicint/qatomicint.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qatomicint.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qatomicint/tst_qatomicint.cpp b/tests/auto/qatomicint/tst_qatomicint.cpp index a683322..27a2cc2 100644 --- a/tests/auto/qatomicint/tst_qatomicint.cpp +++ b/tests/auto/qatomicint/tst_qatomicint.cpp @@ -116,8 +116,7 @@ tst_QAtomicInt::~tst_QAtomicInt() void tst_QAtomicInt::warningFreeHelper() { - Q_ASSERT(false); - // The code below is bogus, and shouldn't be run. We're looking for warnings, only. + qFatal("This code is bogus, and shouldn't be run. We're looking for compiler warnings only."); QBasicAtomicInt i = Q_BASIC_ATOMIC_INITIALIZER(0); diff --git a/tests/auto/qatomicpointer/qatomicpointer.pro b/tests/auto/qatomicpointer/qatomicpointer.pro index d192bad..89ff137 100644 --- a/tests/auto/qatomicpointer/qatomicpointer.pro +++ b/tests/auto/qatomicpointer/qatomicpointer.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qatomicpointer.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qatomicpointer/tst_qatomicpointer.cpp b/tests/auto/qatomicpointer/tst_qatomicpointer.cpp index 0e8aa6b..42e744a 100644 --- a/tests/auto/qatomicpointer/tst_qatomicpointer.cpp +++ b/tests/auto/qatomicpointer/tst_qatomicpointer.cpp @@ -98,8 +98,7 @@ struct WFHC void tst_QAtomicPointer::warningFreeHelper() { - Q_ASSERT(false); - // The code below is bogus, and shouldn't be run. We're looking for warnings, only. + qFatal("This code is bogus, and shouldn't be run. We're looking for compiler warnings only."); QBasicAtomicPointer<WFHC> p = Q_BASIC_ATOMIC_INITIALIZER(0); diff --git a/tests/auto/qaudioinput/qaudioinput.pro b/tests/auto/qaudioinput/qaudioinput.pro index 5eb1613..aac7fb4 100644 --- a/tests/auto/qaudioinput/qaudioinput.pro +++ b/tests/auto/qaudioinput/qaudioinput.pro @@ -5,8 +5,8 @@ SOURCES += tst_qaudioinput.cpp QT = core multimedia wince* { - deploy.sources += 4.wav - DEPLOYMENT = deploy + deploy.files += 4.wav + DEPLOYMENT += deploy DEFINES += SRCDIR=\\\"\\\" QT += gui } else { diff --git a/tests/auto/qaudiooutput/qaudiooutput.pro b/tests/auto/qaudiooutput/qaudiooutput.pro index e1734e0..f4d840a 100644 --- a/tests/auto/qaudiooutput/qaudiooutput.pro +++ b/tests/auto/qaudiooutput/qaudiooutput.pro @@ -5,8 +5,8 @@ SOURCES += tst_qaudiooutput.cpp QT = core multimedia wince*|symbian: { - deploy.sources += 4.wav - DEPLOYMENT = deploy + deploy.files += 4.wav + DEPLOYMENT += deploy !symbian { DEFINES += SRCDIR=\\\"\\\" QT += gui diff --git a/tests/auto/qbitarray/qbitarray.pro b/tests/auto/qbitarray/qbitarray.pro index ec110c6..358d81b 100644 --- a/tests/auto/qbitarray/qbitarray.pro +++ b/tests/auto/qbitarray/qbitarray.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qbitarray.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qbitarray/tst_qbitarray.cpp b/tests/auto/qbitarray/tst_qbitarray.cpp index 337a86f..83fcfcc 100644 --- a/tests/auto/qbitarray/tst_qbitarray.cpp +++ b/tests/auto/qbitarray/tst_qbitarray.cpp @@ -88,6 +88,7 @@ private slots: void countBits(); void countBits2(); void isEmpty(); + void swap(); void fill(); void toggleBit_data(); void toggleBit(); @@ -269,6 +270,14 @@ void tst_QBitArray::isEmpty() QVERIFY(a1.size() == 2); } +void tst_QBitArray::swap() +{ + QBitArray b1 = QStringToQBitArray("1"), b2 = QStringToQBitArray("10"); + b1.swap(b2); + QCOMPARE(b1,QStringToQBitArray("10")); + QCOMPARE(b2,QStringToQBitArray("1")); +} + void tst_QBitArray::fill() { int N = 64; diff --git a/tests/auto/qbrush/tst_qbrush.cpp b/tests/auto/qbrush/tst_qbrush.cpp index eb2897c..9ee679e 100644 --- a/tests/auto/qbrush/tst_qbrush.cpp +++ b/tests/auto/qbrush/tst_qbrush.cpp @@ -76,6 +76,7 @@ private slots: void textures(); + void swap(); void nullBrush(); void isOpaque(); void debug(); @@ -385,6 +386,14 @@ void tst_QBrush::textures() QCOMPARE(image_brush.textureImage(), image_source); } +void tst_QBrush::swap() +{ + QBrush b1(Qt::black), b2(Qt::white); + b1.swap(b2); + QCOMPARE(b1.color(), QColor(Qt::white)); + QCOMPARE(b2.color(), QColor(Qt::black)); +} + void tst_QBrush::nullBrush() { QBrush brush(QColor(100,0,0), Qt::NoBrush); diff --git a/tests/auto/qbuffer/qbuffer.pro b/tests/auto/qbuffer/qbuffer.pro index ea83657..b768eb8 100644 --- a/tests/auto/qbuffer/qbuffer.pro +++ b/tests/auto/qbuffer/qbuffer.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qbuffer.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qbuffer/tst_qbuffer.cpp b/tests/auto/qbuffer/tst_qbuffer.cpp index aee3b81..776935d 100644 --- a/tests/auto/qbuffer/tst_qbuffer.cpp +++ b/tests/auto/qbuffer/tst_qbuffer.cpp @@ -309,8 +309,7 @@ void tst_QBuffer::seekTest() // (see Task 184730) { char c; - const int offset = 1; - Q_ASSERT(offset > 0); // any positive integer will do + const int offset = 1; // any positive integer will do const qint64 pos = buf.size() + offset; QVERIFY(buf.seek(pos)); QCOMPARE(buf.pos(), pos); diff --git a/tests/auto/qbuttongroup/tst_qbuttongroup.cpp b/tests/auto/qbuttongroup/tst_qbuttongroup.cpp index f945941..87173ae 100644 --- a/tests/auto/qbuttongroup/tst_qbuttongroup.cpp +++ b/tests/auto/qbuttongroup/tst_qbuttongroup.cpp @@ -98,10 +98,7 @@ private slots: void task106609(); - // fixed for Qt 4.6.0 -#if QT_VERSION >= 0x040600 void autoIncrementId(); -#endif void task209485_removeFromGroupInEventHandler_data(); void task209485_removeFromGroupInEventHandler(); @@ -338,10 +335,7 @@ void tst_QButtonGroup::testSignals() QCOMPARE(clickedSpy.count(), 1); QCOMPARE(clickedIdSpy.count(), 1); - int expectedId = -1; -#if QT_VERSION >= 0x040600 - expectedId = -2; -#endif + int expectedId = -2; QVERIFY(clickedIdSpy.takeFirst().at(0).toInt() == expectedId); QCOMPARE(pressedSpy.count(), 1); @@ -500,7 +494,6 @@ void tst_QButtonGroup::task209485_removeFromGroupInEventHandler() QCOMPARE(spy1.count() + spy2.count(), signalCount); } -#if QT_VERSION >= 0x040600 void tst_QButtonGroup::autoIncrementId() { QDialog dlg(0); @@ -529,7 +522,6 @@ void tst_QButtonGroup::autoIncrementId() dlg.show(); } -#endif QTEST_MAIN(tst_QButtonGroup) #include "tst_qbuttongroup.moc" diff --git a/tests/auto/qbytearray/qbytearray.pro b/tests/auto/qbytearray/qbytearray.pro index a0c143e..f195dc8 100644 --- a/tests/auto/qbytearray/qbytearray.pro +++ b/tests/auto/qbytearray/qbytearray.pro @@ -5,7 +5,7 @@ SOURCES += tst_qbytearray.cpp QT = core wince*|symbian { - addFile.sources = rfc3252.txt + addFile.files = rfc3252.txt addFile.path = . DEPLOYMENT += addFile } @@ -18,3 +18,4 @@ wince* { DEFINES += SRCDIR=\\\"$$PWD/\\\" } +CONFIG += parallel_test diff --git a/tests/auto/qbytearray/tst_qbytearray.cpp b/tests/auto/qbytearray/tst_qbytearray.cpp index 6536365..9889aae 100644 --- a/tests/auto/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/qbytearray/tst_qbytearray.cpp @@ -71,6 +71,7 @@ public slots: void init(); void cleanup(); private slots: + void swap(); void qCompress_data(); #ifndef QT_NO_COMPRESS void qCompress(); @@ -142,6 +143,8 @@ private slots: void repeated_data() const; void byteRefDetaching() const; + + void reserve(); }; tst_QByteArray::tst_QByteArray() @@ -221,18 +224,18 @@ void tst_QByteArray::qUncompress_data() QTest::addColumn<QByteArray>("in"); QTest::addColumn<QByteArray>("out"); - QTest::newRow("0x00000000") << QByteArray("\x00\x00\x00\x00") << QByteArray(); - QTest::newRow("0x000000ff") << QByteArray("\x00\x00\x00\xff") << QByteArray(); - QTest::newRow("0x3f000000") << QByteArray("\x3f\x00\x00\x00") << QByteArray(); - QTest::newRow("0x3fffffff") << QByteArray("\x3f\xff\xff\xff") << QByteArray(); - QTest::newRow("0x7fffff00") << QByteArray("\x7f\xff\xff\x00") << QByteArray(); - QTest::newRow("0x7fffffff") << QByteArray("\x7f\xff\xff\xff") << QByteArray(); - QTest::newRow("0x80000000") << QByteArray("\x80\x00\x00\x00") << QByteArray(); - QTest::newRow("0x800000ff") << QByteArray("\x80\x00\x00\xff") << QByteArray(); - QTest::newRow("0xcf000000") << QByteArray("\xcf\x00\x00\x00") << QByteArray(); - QTest::newRow("0xcfffffff") << QByteArray("\xcf\xff\xff\xff") << QByteArray(); - QTest::newRow("0xffffff00") << QByteArray("\xff\xff\xff\x00") << QByteArray(); - QTest::newRow("0xffffffff") << QByteArray("\xff\xff\xff\xff") << QByteArray(); + QTest::newRow("0x00000000") << QByteArray("\x00\x00\x00\x00", 4) << QByteArray(); + QTest::newRow("0x000000ff") << QByteArray("\x00\x00\x00\xff", 4) << QByteArray(); + QTest::newRow("0x3f000000") << QByteArray("\x3f\x00\x00\x00", 4) << QByteArray(); + QTest::newRow("0x3fffffff") << QByteArray("\x3f\xff\xff\xff", 4) << QByteArray(); + QTest::newRow("0x7fffff00") << QByteArray("\x7f\xff\xff\x00", 4) << QByteArray(); + QTest::newRow("0x7fffffff") << QByteArray("\x7f\xff\xff\xff", 4) << QByteArray(); + QTest::newRow("0x80000000") << QByteArray("\x80\x00\x00\x00", 4) << QByteArray(); + QTest::newRow("0x800000ff") << QByteArray("\x80\x00\x00\xff", 4) << QByteArray(); + QTest::newRow("0xcf000000") << QByteArray("\xcf\x00\x00\x00", 4) << QByteArray(); + QTest::newRow("0xcfffffff") << QByteArray("\xcf\xff\xff\xff", 4) << QByteArray(); + QTest::newRow("0xffffff00") << QByteArray("\xff\xff\xff\x00", 4) << QByteArray(); + QTest::newRow("0xffffffff") << QByteArray("\xff\xff\xff\xff", 4) << QByteArray(); } void tst_QByteArray::qUncompress() @@ -249,18 +252,10 @@ void tst_QByteArray::qUncompress() #endif QByteArray res; - QT_TRY { - res = ::qUncompress(in); - } QT_CATCH(const std::bad_alloc &) { - res = QByteArray(); - } + res = ::qUncompress(in); QCOMPARE(res, out); - QT_TRY { - res = ::qUncompress(in + "blah"); - } QT_CATCH(const std::bad_alloc &) { - res = QByteArray(); - } + res = ::qUncompress(in + "blah"); QCOMPARE(res, out); } @@ -459,6 +454,14 @@ void tst_QByteArray::split() QCOMPARE(list.count(), size); } +void tst_QByteArray::swap() +{ + QByteArray b1 = "b1", b2 = "b2"; + b1.swap(b2); + QCOMPARE(b1, QByteArray("b2")); + QCOMPARE(b2, QByteArray("b1")); +} + void tst_QByteArray::base64_data() { QTest::addColumn<QByteArray>("rawdata"); @@ -895,12 +898,12 @@ void tst_QByteArray::indexOf_data() QByteArray veryBigHaystack(500, 'a'); veryBigHaystack += 'B'; QTest::newRow("BoyerMooreStressTest") << veryBigHaystack << veryBigHaystack << 0 << 0; - QTest::newRow("BoyerMooreStressTest2") << veryBigHaystack + 'c' << veryBigHaystack << 0 << 0; - QTest::newRow("BoyerMooreStressTest3") << 'c' + veryBigHaystack << veryBigHaystack << 0 << 1; - QTest::newRow("BoyerMooreStressTest4") << veryBigHaystack << veryBigHaystack + 'c' << 0 << -1; - QTest::newRow("BoyerMooreStressTest5") << veryBigHaystack << 'c' + veryBigHaystack << 0 << -1; - QTest::newRow("BoyerMooreStressTest6") << 'd' + veryBigHaystack << 'c' + veryBigHaystack << 0 << -1; - QTest::newRow("BoyerMooreStressTest6") << veryBigHaystack + 'c' << 'c' + veryBigHaystack << 0 << -1; + QTest::newRow("BoyerMooreStressTest2") << QByteArray(veryBigHaystack + 'c') << QByteArray(veryBigHaystack) << 0 << 0; + QTest::newRow("BoyerMooreStressTest3") << QByteArray('c' + veryBigHaystack) << QByteArray(veryBigHaystack) << 0 << 1; + QTest::newRow("BoyerMooreStressTest4") << QByteArray(veryBigHaystack) << QByteArray(veryBigHaystack + 'c') << 0 << -1; + QTest::newRow("BoyerMooreStressTest5") << QByteArray(veryBigHaystack) << QByteArray('c' + veryBigHaystack) << 0 << -1; + QTest::newRow("BoyerMooreStressTest6") << QByteArray('d' + veryBigHaystack) << QByteArray('c' + veryBigHaystack) << 0 << -1; + QTest::newRow("BoyerMooreStressTest6") << QByteArray(veryBigHaystack + 'c') << QByteArray('c' + veryBigHaystack) << 0 << -1; } void tst_QByteArray::indexOf() @@ -1516,6 +1519,22 @@ void tst_QByteArray::byteRefDetaching() const } } +void tst_QByteArray::reserve() +{ + int capacity = 100; + QByteArray qba; + qba.reserve(capacity); + QVERIFY(qba.capacity() == capacity); + char *data = qba.data(); + + // FIXME count from 0 to make it fail + for (int i = 1; i < capacity; i++) { + qba.resize(i); + QVERIFY(capacity == qba.capacity()); + QVERIFY(data == qba.data()); + } +} + const char globalChar = '1'; QTEST_APPLESS_MAIN(tst_QByteArray) diff --git a/tests/auto/qbytearraymatcher/qbytearraymatcher.pro b/tests/auto/qbytearraymatcher/qbytearraymatcher.pro index 1618c3e..a2458e6 100644 --- a/tests/auto/qbytearraymatcher/qbytearraymatcher.pro +++ b/tests/auto/qbytearraymatcher/qbytearraymatcher.pro @@ -2,3 +2,4 @@ load(qttest_p4) SOURCES += tst_qbytearraymatcher.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qcache/qcache.pro b/tests/auto/qcache/qcache.pro index 728b0b6..0da4e14 100644 --- a/tests/auto/qcache/qcache.pro +++ b/tests/auto/qcache/qcache.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qcache.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qchar/qchar.pro b/tests/auto/qchar/qchar.pro index 3813e4e..1681220 100644 --- a/tests/auto/qchar/qchar.pro +++ b/tests/auto/qchar/qchar.pro @@ -4,8 +4,8 @@ SOURCES += tst_qchar.cpp QT = core wince*|symbian: { -deploy.sources += NormalizationTest.txt -DEPLOYMENT = deploy +deploy.files += NormalizationTest.txt +DEPLOYMENT += deploy } symbian: { @@ -13,3 +13,4 @@ symbian: { } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" } +CONFIG += parallel_test diff --git a/tests/auto/qchar/tst_qchar.cpp b/tests/auto/qchar/tst_qchar.cpp index 54c3b90..1fdbc34 100644 --- a/tests/auto/qchar/tst_qchar.cpp +++ b/tests/auto/qchar/tst_qchar.cpp @@ -548,14 +548,14 @@ void tst_QChar::normalization_data() QList<QByteArray> l = line.split(';'); - Q_ASSERT(l.size() == 5); + QCOMPARE(l.size(), 5); QStringList columns; for (int i = 0; i < 5; ++i) { columns.append(QString()); QList<QByteArray> c = l.at(i).split(' '); - Q_ASSERT(!c.isEmpty()); + QVERIFY(!c.isEmpty()); for (int j = 0; j < c.size(); ++j) { bool ok; diff --git a/tests/auto/qcheckbox/tst_qcheckbox.cpp b/tests/auto/qcheckbox/tst_qcheckbox.cpp index 8409b34..a11dfe0 100644 --- a/tests/auto/qcheckbox/tst_qcheckbox.cpp +++ b/tests/auto/qcheckbox/tst_qcheckbox.cpp @@ -92,6 +92,7 @@ private slots: void setAccel(); void group(); void foregroundRole(); + void minimumSizeHint(); protected slots: void onClicked(); @@ -425,5 +426,11 @@ void tst_QCheckBox::foregroundRole() QVERIFY(testWidget->foregroundRole() == QPalette::WindowText); } +void tst_QCheckBox::minimumSizeHint() +{ + QCheckBox box(tr("CheckBox's sizeHint is the same as it's minimumSizeHint")); + QCOMPARE(box.sizeHint(), box.minimumSizeHint()); +} + QTEST_MAIN(tst_QCheckBox) #include "tst_qcheckbox.moc" diff --git a/tests/auto/qclipboard/test/test.pro b/tests/auto/qclipboard/test/test.pro index 97b0c9c..12c6b6c 100644 --- a/tests/auto/qclipboard/test/test.pro +++ b/tests/auto/qclipboard/test/test.pro @@ -11,22 +11,22 @@ win32 { } wince*|symbian: { - copier.sources = ../copier/copier.exe + copier.files = ../copier/copier.exe copier.path = copier - paster.sources = ../paster/paster.exe + paster.files = ../paster/paster.exe paster.path = paster symbian: { LIBS += -lbafl -lestor -letext load(data_caging_paths) - rsc.sources = $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/copier.rsc - rsc.sources += $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/paster.rsc + rsc.files = $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/copier.rsc + rsc.files += $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/paster.rsc rsc.path = $$APP_RESOURCE_DIR - reg_resource.sources = $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/copier_reg.rsc - reg_resource.sources += $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/paster_reg.rsc + reg_resource.files = $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/copier_reg.rsc + reg_resource.files += $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/paster_reg.rsc reg_resource.path = $$REG_RESOURCE_IMPORT_DIR } - DEPLOYMENT = copier paster rsc reg_resource + DEPLOYMENT += copier paster rsc reg_resource }
\ No newline at end of file diff --git a/tests/auto/qclipboard/tst_qclipboard.cpp b/tests/auto/qclipboard/tst_qclipboard.cpp index c7497ec..7e47c27 100644 --- a/tests/auto/qclipboard/tst_qclipboard.cpp +++ b/tests/auto/qclipboard/tst_qclipboard.cpp @@ -205,7 +205,7 @@ void tst_QClipboard::testSignals() void tst_QClipboard::copy_exit_paste() { #ifndef QT_NO_PROCESS -#if defined Q_WS_X11 || defined Q_WS_QWS +#if defined Q_WS_X11 || defined Q_WS_QWS || defined (Q_WS_QPA) QSKIP("This test does not make sense on X11 and embedded, copied data disappears from the clipboard when the application exits ", SkipAll); // ### It's still possible to test copy/paste - just keep the apps running #elif defined (Q_OS_SYMBIAN) && defined (Q_CC_NOKIAX86) diff --git a/tests/auto/qcolor/tst_qcolor.cpp b/tests/auto/qcolor/tst_qcolor.cpp index f0568c74..2b6896a 100644 --- a/tests/auto/qcolor/tst_qcolor.cpp +++ b/tests/auto/qcolor/tst_qcolor.cpp @@ -148,6 +148,8 @@ private slots: void specConstructor_data(); void specConstructor(); + void achromaticHslHue(); + #ifdef Q_WS_X11 void allowX11ColorNames(); void setallowX11ColorNames(); @@ -1459,6 +1461,14 @@ void tst_QColor::specConstructor() QCOMPARE(color.spec(), spec); } +void tst_QColor::achromaticHslHue() +{ + QColor color = Qt::black; + + QColor hsl = color.toHsl(); + QCOMPARE(hsl.hslHue(), -1); +} + #ifdef Q_WS_X11 void tst_QColor::allowX11ColorNames() { @@ -1496,7 +1506,6 @@ void tst_QColor::setallowX11ColorNames() for (int i = 0; i < x11RgbTblSize; ++i) { QString colorName = QLatin1String(x11RgbTbl[i].name); QColor color; - QTest::ignoreMessage(QtWarningMsg, QString("QColor::setNamedColor: Unknown color name '%1'").arg(colorName).toLatin1()); color.setNamedColor(colorName); QVERIFY(!color.isValid()); } @@ -1518,7 +1527,6 @@ void tst_QColor::setallowX11ColorNames() for (int i = 0; i < x11RgbTblSize; ++i) { QString colorName = QLatin1String(x11RgbTbl[i].name); QColor color; - QTest::ignoreMessage(QtWarningMsg, QString("QColor::setNamedColor: Unknown color name '%1'").arg(colorName).toLatin1()); color.setNamedColor(colorName); QVERIFY(!color.isValid()); } diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index e27dcaa..855e94d 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -157,6 +157,7 @@ private slots: void keyBoardNavigationWithMouse(); void task_QTBUG_1071_changingFocusEmitsActivated(); void maxVisibleItems(); + void task_QTBUG_10491_currentIndexAndModelColumn(); protected slots: void onEditTextChanged( const QString &newString ); @@ -474,6 +475,18 @@ void tst_QComboBox::setPalette() QVERIFY(((QWidget*)o)->palette() == pal); } } + + testWidget->setEditable(true); + pal.setColor(QPalette::Base, Qt::red); + //Setting it on the lineedit should be separate form the combo + testWidget->lineEdit()->setPalette(pal); + QVERIFY(testWidget->palette() != pal); + QVERIFY(testWidget->lineEdit()->palette() == pal); + pal.setColor(QPalette::Base, Qt::green); + //Setting it on the combo directly should override lineedit + testWidget->setPalette(pal); + QVERIFY(testWidget->palette() == pal); + QVERIFY(testWidget->lineEdit()->palette() == pal); } void tst_QComboBox::sizeAdjustPolicy() @@ -2555,11 +2568,33 @@ void tst_QComboBox::maxVisibleItems() QAbstractItemView *v = comboBox.view(); int itemHeight = v->visualRect(v->model()->index(0,0)).height(); - if (v->style()->styleHint(QStyle::SH_ComboBox_Popup)) + QListView *lv = qobject_cast<QListView*>(v); + if (lv) + itemHeight += lv->spacing(); + QStyleOptionComboBox opt; + opt.initFrom(&comboBox); + if (!comboBox.style()->styleHint(QStyle::SH_ComboBox_Popup, &opt)) QCOMPARE(v->viewport()->height(), itemHeight * comboBox.maxVisibleItems()); - // QCombobox without a popup does not work, see QTBUG-760 } +void tst_QComboBox::task_QTBUG_10491_currentIndexAndModelColumn() +{ + QComboBox comboBox; + + QStandardItemModel model(4, 4, &comboBox); + for (int i = 0; i < 4; i++){ + model.setItem(i, 0, new QStandardItem(QString("Employee Nr %1").arg(i))); + model.setItem(i, 1, new QStandardItem(QString("Street Nr %1").arg(i))); + model.setItem(i, 2, new QStandardItem(QString("Town Nr %1").arg(i))); + model.setItem(i, 3, new QStandardItem(QString("Phone Nr %1").arg(i))); + } + comboBox.setModel(&model); + comboBox.setModelColumn(0); + + QComboBoxPrivate *d = static_cast<QComboBoxPrivate *>(QComboBoxPrivate::get(&comboBox)); + d->setCurrentIndex(model.index(2, 2)); + QCOMPARE(QModelIndex(d->currentIndex), model.index(2, comboBox.modelColumn())); +} QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc" diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index e900c4f..c1467c6 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -49,6 +49,7 @@ #include <QPointer> #include "../../shared/util.h" +#include "../../shared/filesystem.h" //TESTED_CLASS= //TESTED_FILES= @@ -276,7 +277,9 @@ retry: case 'L': row = completer->completionCount() - 1; break; case 'F': row = 0; break; default: - Q_ASSERT(false); + QFAIL(qPrintable(QString( + "Problem with 'step' value in test data: %1 (only P, N, L and F are allowed)." + ).arg(step[i]))); } completer->setCurrentRow(row); } @@ -1247,9 +1250,7 @@ public: void tst_QCompleter::task189564_omitNonSelectableItems() { const QString prefix("a"); - Q_ASSERT(!prefix.isEmpty()); const int n = 5; - Q_ASSERT(n > 0); QStringList strings; for (int i = 0; i < n; ++i) @@ -1277,10 +1278,11 @@ public: { setEditable(true); setInsertPolicy(NoInsert); - Q_ASSERT(completer()); - completer()->setCompletionMode(QCompleter::PopupCompletion); - completer()->setCompletionRole(Qt::DisplayRole); - connect(lineEdit(), SIGNAL(editingFinished()), SLOT(setCompletionPrefix())); + if (completer()) { + completer()->setCompletionMode(QCompleter::PopupCompletion); + completer()->setCompletionRole(Qt::DisplayRole); + connect(lineEdit(), SIGNAL(editingFinished()), SLOT(setCompletionPrefix())); + } } private slots: void setCompletionPrefix() { completer()->setCompletionPrefix(lineEdit()->text()); } @@ -1289,6 +1291,7 @@ private slots: void tst_QCompleter::task246056_setCompletionPrefix() { task246056_ComboBox *comboBox = new task246056_ComboBox; + QVERIFY(comboBox->completer()); comboBox->addItem(""); comboBox->addItem("a1"); comboBox->addItem("a2"); @@ -1455,24 +1458,16 @@ void tst_QCompleter::task247560_keyboardNavigation() void tst_QCompleter::QTBUG_14292_filesystem() { - QDir tmpDir = QDir::temp(); + FileSystem fs; + QDir tmpDir = QDir::currentPath(); + qsrand(QTime::currentTime().msec()); QString d = "tst_QCompleter_" + QString::number(qrand()); - QVERIFY(tmpDir.mkdir(d)); - -#if 0 - struct Cleanup { - QString dir; - ~Cleanup() { - qDebug() << dir << - QFile::remove(dir); } - } cleanup; - cleanup.dir = tmpDir.absolutePath()+"/" +d; -#endif + QVERIFY(fs.createDirectory(tmpDir.filePath(d))); QVERIFY(tmpDir.cd(d)); - QVERIFY(tmpDir.mkdir("hello")); - QVERIFY(tmpDir.mkdir("holla")); + QVERIFY(fs.createDirectory(tmpDir.filePath("hello"))); + QVERIFY(fs.createDirectory(tmpDir.filePath("holla"))); QLineEdit edit; QCompleter comp; @@ -1500,12 +1495,12 @@ void tst_QCompleter::QTBUG_14292_filesystem() QCOMPARE(comp.popup()->model()->rowCount(), 1); QTest::keyClick(&edit, 'r'); QTRY_VERIFY(!comp.popup()->isVisible()); - QVERIFY(tmpDir.mkdir("hero")); + QVERIFY(fs.createDirectory(tmpDir.filePath("hero"))); QTRY_VERIFY(comp.popup()->isVisible()); QCOMPARE(comp.popup()->model()->rowCount(), 1); QTest::keyClick(comp.popup(), Qt::Key_Escape); QTRY_VERIFY(!comp.popup()->isVisible()); - QVERIFY(tmpDir.mkdir("nothingThere")); + QVERIFY(fs.createDirectory(tmpDir.filePath("nothingThere"))); //there is no reason creating a file should open a popup, it did in Qt 4.7.0 QTest::qWait(60); QVERIFY(!comp.popup()->isVisible()); @@ -1522,7 +1517,7 @@ void tst_QCompleter::QTBUG_14292_filesystem() QTest::qWaitForWindowShown(&w); QTRY_VERIFY(!edit.hasFocus() && !comp.popup()->hasFocus()); - QVERIFY(tmpDir.mkdir("hemo")); + QVERIFY(fs.createDirectory(tmpDir.filePath("hemo"))); //there is no reason creating a file should open a popup, it did in Qt 4.7.0 QTest::qWait(60); QVERIFY(!comp.popup()->isVisible()); diff --git a/tests/auto/qcomplextext/tst_qcomplextext.cpp b/tests/auto/qcomplextext/tst_qcomplextext.cpp index 1fccdb0..c72393c 100644 --- a/tests/auto/qcomplextext/tst_qcomplextext.cpp +++ b/tests/auto/qcomplextext/tst_qcomplextext.cpp @@ -45,6 +45,7 @@ #if !defined(Q_WS_MAC) #include <QtTest/QtTest> +#include <QtGui/QtGui> #include <private/qtextengine_p.h> #include "bidireorderstring.h" @@ -68,6 +69,12 @@ public slots: private slots: void bidiReorderString_data(); void bidiReorderString(); + void bidiCursor_qtbug2795(); + void bidiCursor_PDF(); + void bidiCursorMovement_data(); + void bidiCursorMovement(); + void bidiCursorLogicalMovement_data(); + void bidiCursorLogicalMovement(); }; tst_QComplexText::tst_QComplexText() @@ -159,6 +166,126 @@ void tst_QComplexText::bidiReorderString() QTEST(visual, "VISUAL"); } +void tst_QComplexText::bidiCursor_qtbug2795() +{ + QString str = QString::fromUtf8("الجزيرة نت"); + QTextLayout l1(str); + + l1.beginLayout(); + QTextLine line1 = l1.createLine(); + l1.endLayout(); + + qreal x1 = line1.cursorToX(0) - line1.cursorToX(str.size()); + + str.append("1"); + QTextLayout l2(str); + l2.beginLayout(); + QTextLine line2 = l2.createLine(); + l2.endLayout(); + + qreal x2 = line2.cursorToX(0) - line2.cursorToX(str.size()); + + // The cursor should remain at the same position after a digit is appended + QVERIFY(x1 == x2); +} + +void tst_QComplexText::bidiCursorMovement_data() +{ + QTest::addColumn<QString>("logical"); + QTest::addColumn<int>("basicDir"); + + const LV *data = logical_visual; + while ( data->name ) { + //next we fill it with data + QTest::newRow( data->name ) + << QString::fromUtf8( data->logical ) + << (int) data->basicDir; + data++; + } +} + +void tst_QComplexText::bidiCursorMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + QTextLayout layout(logical); + + QTextOption option = layout.textOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + layout.setTextOption(option); + layout.setCursorMoveStyle(Qt::VisualMoveStyle); + bool moved; + int oldPos, newPos = 0; + qreal x, newX; + + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + + newX = line.cursorToX(0); + do { + oldPos = newPos; + x = newX; + newX = line.cursorToX(oldPos); + if (basicDir == QChar::DirL) { + QVERIFY(newX >= x); + newPos = layout.rightCursorPosition(oldPos); + } else + { + QVERIFY(newX <= x); + newPos = layout.leftCursorPosition(oldPos); + } + moved = (oldPos != newPos); + } while (moved); +} + +void tst_QComplexText::bidiCursorLogicalMovement_data() +{ + bidiCursorMovement_data(); +} + +void tst_QComplexText::bidiCursorLogicalMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + QTextLayout layout(logical); + + QTextOption option = layout.textOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + layout.setTextOption(option); + bool moved; + int oldPos, newPos = 0; + + do { + oldPos = newPos; + newPos = layout.nextCursorPosition(oldPos); + QVERIFY(newPos >= oldPos); + moved = (oldPos != newPos); + } while (moved); + + do { + oldPos = newPos; + newPos = layout.previousCursorPosition(oldPos); + QVERIFY(newPos <= oldPos); + moved = (oldPos != newPos); + } while (moved); +} + +void tst_QComplexText::bidiCursor_PDF() +{ + QString str = QString::fromUtf8("\342\200\252hello\342\200\254"); + QTextLayout layout(str); + + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + + int size = str.size(); + + QVERIFY(line.cursorToX(size) == line.cursorToX(size - 1)); +} QTEST_MAIN(tst_QComplexText) #include "tst_qcomplextext.moc" diff --git a/tests/auto/qcontiguouscache/qcontiguouscache.pro b/tests/auto/qcontiguouscache/qcontiguouscache.pro index 618efed..5951f87 100644 --- a/tests/auto/qcontiguouscache/qcontiguouscache.pro +++ b/tests/auto/qcontiguouscache/qcontiguouscache.pro @@ -6,3 +6,4 @@ SOURCES += tst_qcontiguouscache.cpp +CONFIG += parallel_test diff --git a/tests/auto/qcontiguouscache/tst_qcontiguouscache.cpp b/tests/auto/qcontiguouscache/tst_qcontiguouscache.cpp index 47b5a23..0a0c999 100644 --- a/tests/auto/qcontiguouscache/tst_qcontiguouscache.cpp +++ b/tests/auto/qcontiguouscache/tst_qcontiguouscache.cpp @@ -55,6 +55,8 @@ public: virtual ~tst_QContiguousCache() {} private slots: void empty(); + void swap(); + void append_data(); void append(); @@ -99,6 +101,17 @@ void tst_QContiguousCache::empty() QCOMPARE(c.capacity(), 10); } +void tst_QContiguousCache::swap() +{ + QContiguousCache<int> c1(10), c2(100); + c1.append(1); + c1.swap(c2); + QCOMPARE(c1.capacity(), 100); + QCOMPARE(c1.count(), 0 ); + QCOMPARE(c2.capacity(), 10 ); + QCOMPARE(c2.count(), 1 ); +} + void tst_QContiguousCache::append_data() { QTest::addColumn<int>("start"); diff --git a/tests/auto/qcopchannel/testSend/main.cpp b/tests/auto/qcopchannel/testSend/main.cpp index 5a80cfa..ab5a421 100644 --- a/tests/auto/qcopchannel/testSend/main.cpp +++ b/tests/auto/qcopchannel/testSend/main.cpp @@ -49,7 +49,11 @@ int main(int argc, char** argv) #ifdef Q_WS_QWS QApplication app(argc, argv); QStringList args = app.arguments(); - Q_ASSERT(args.count() == 3 || args.count() == 4); + if (args.count() != 3 && args.count() != 4) { + fprintf(stdout,qPrintable(QString("Usage: %1 channel message [data]").arg(args.at(0)))); + fflush(stdout); + return 1; + } QString channelName = args.at(1); QString msg = args.at(2); QByteArray data; diff --git a/tests/auto/qcoreapplication/qcoreapplication.pro b/tests/auto/qcoreapplication/qcoreapplication.pro index 27f5e58..031af39 100644 --- a/tests/auto/qcoreapplication/qcoreapplication.pro +++ b/tests/auto/qcoreapplication/qcoreapplication.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qcoreapplication.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qcryptographichash/qcryptographichash.pro b/tests/auto/qcryptographichash/qcryptographichash.pro index 7e1a866..65e31dc 100644 --- a/tests/auto/qcryptographichash/qcryptographichash.pro +++ b/tests/auto/qcryptographichash/qcryptographichash.pro @@ -6,3 +6,4 @@ symbian: { TARGET.EPOCSTACKSIZE =0x5000 TARGET.EPOCHEAPSIZE="0x100000 0x1000000" # // Min 1Mb, max 16Mb } +CONFIG += parallel_test diff --git a/tests/auto/qcssparser/qcssparser.pro b/tests/auto/qcssparser/qcssparser.pro index 4953490..fc3daa3 100644 --- a/tests/auto/qcssparser/qcssparser.pro +++ b/tests/auto/qcssparser/qcssparser.pro @@ -8,9 +8,9 @@ requires(contains(QT_CONFIG,private_tests)) } wince*|symbian: { - addFiles.sources = testdata + addFiles.files = testdata addFiles.path = . - timesFont.sources = c:/windows/fonts/times.ttf + timesFont.files = c:/windows/fonts/times.ttf timesFont.path = . DEPLOYMENT += addFiles timesFont } diff --git a/tests/auto/qdatastream/qdatastream.pro b/tests/auto/qdatastream/qdatastream.pro index c132073..eba7c00 100644 --- a/tests/auto/qdatastream/qdatastream.pro +++ b/tests/auto/qdatastream/qdatastream.pro @@ -12,13 +12,13 @@ QT += svg wince*: { - addFiles.sources = datastream.q42 tests2.svg + addFiles.files = datastream.q42 tests2.svg addFiles.path = . DEPLOYMENT += addFiles DEFINES += SRCDIR=\\\"\\\" } else:symbian { # SRCDIR and SVGFILE defined in code in symbian - addFiles.sources = datastream.q42 tests2.svg + addFiles.files = datastream.q42 tests2.svg addFiles.path = . DEPLOYMENT += addFiles TARGET.EPOCHEAPSIZE = 1000000 10000000 diff --git a/tests/auto/qdatastream/tst_qdatastream.cpp b/tests/auto/qdatastream/tst_qdatastream.cpp index d4d6156..7efbfab 100644 --- a/tests/auto/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/qdatastream/tst_qdatastream.cpp @@ -168,6 +168,8 @@ private slots: void stream_atEnd_data(); void stream_atEnd(); + void stream_writeError(); + void stream_QByteArray2(); void setVersion_data(); @@ -2345,6 +2347,55 @@ void tst_QDataStream::stream_atEnd() } } +class FakeBuffer : public QBuffer +{ +protected: + qint64 writeData(const char *c, qint64 i) { return m_lock ? 0 : QBuffer::writeData(c, i); } +public: + FakeBuffer(bool locked = false) : m_lock(locked) {} + void setLocked(bool locked) { m_lock = locked; } +private: + bool m_lock; +}; + +#define TEST_WRITE_ERROR(op) \ + { \ + FakeBuffer fb(false); \ + QVERIFY(fb.open(QBuffer::ReadWrite)); \ + QDataStream fs(&fb); \ + fs.writeRawData("hello", 5); \ + /* first write some initial content */ \ + QCOMPARE(fs.status(), QDataStream::Ok); \ + QCOMPARE(fb.data(), QByteArray("hello")); \ + /* then test that writing can cause an error */ \ + fb.setLocked(true); \ + fs op; \ + QCOMPARE(fs.status(), QDataStream::WriteFailed); \ + QCOMPARE(fb.data(), QByteArray("hello")); \ + /* finally test that writing after an error doesn't change the stream any more */ \ + fb.setLocked(false); \ + fs op; \ + QCOMPARE(fs.status(), QDataStream::WriteFailed); \ + QCOMPARE(fb.data(), QByteArray("hello")); \ + } + +void tst_QDataStream::stream_writeError() +{ + TEST_WRITE_ERROR(<< true) + TEST_WRITE_ERROR(<< (qint8)1) + TEST_WRITE_ERROR(<< (quint8)1) + TEST_WRITE_ERROR(<< (qint16)1) + TEST_WRITE_ERROR(<< (quint16)1) + TEST_WRITE_ERROR(<< (qint32)1) + TEST_WRITE_ERROR(<< (quint32)1) + TEST_WRITE_ERROR(<< (qint64)1) + TEST_WRITE_ERROR(<< (quint64)1) + TEST_WRITE_ERROR(<< "hello") + TEST_WRITE_ERROR(<< (float)1.0) + TEST_WRITE_ERROR(<< (double)1.0) + TEST_WRITE_ERROR(.writeRawData("test", 4)) +} + void tst_QDataStream::stream_QByteArray2() { QByteArray ba; diff --git a/tests/auto/qdate/qdate.pro b/tests/auto/qdate/qdate.pro index 6e2781b3..1c04100 100644 --- a/tests/auto/qdate/qdate.pro +++ b/tests/auto/qdate/qdate.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qdate.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qdatetime/qdatetime.pro b/tests/auto/qdatetime/qdatetime.pro index 02d3989..08a321e 100644 --- a/tests/auto/qdatetime/qdatetime.pro +++ b/tests/auto/qdatetime/qdatetime.pro @@ -12,3 +12,4 @@ win32-msvc|win32-msvc9x { } +CONFIG += parallel_test diff --git a/tests/auto/qdatetime/tst_qdatetime.cpp b/tests/auto/qdatetime/tst_qdatetime.cpp index a48c22c..95995e8 100644 --- a/tests/auto/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/qdatetime/tst_qdatetime.cpp @@ -85,6 +85,8 @@ private slots: void setTime_t(); void setMSecsSinceEpoch_data(); void setMSecsSinceEpoch(); + void toString_isoDate_data(); + void toString_isoDate(); void toString_enumformat(); void toString_strformat_data(); void toString_strformat(); @@ -198,8 +200,8 @@ void tst_QDateTime::ctor() QDateTime dt3(QDate(2004, 1, 2), QTime(1, 2, 3), Qt::UTC); QVERIFY(dt1 == dt2); - QVERIFY(dt1 != dt3); if (europeanTimeZone) { + QVERIFY(dt1 != dt3); QVERIFY(dt1 < dt3); QVERIFY(dt1.addSecs(3600).toUTC() == dt3); } @@ -506,6 +508,36 @@ void tst_QDateTime::setMSecsSinceEpoch() QCOMPARE(dt, reference.addMSecs(msecs)); } +void tst_QDateTime::toString_isoDate_data() +{ + QTest::addColumn<QDateTime>("dt"); + QTest::addColumn<QString>("formatted"); + + QTest::newRow("localtime") + << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34)) + << QString("1978-11-09T13:28:34"); + QTest::newRow("UTC") + << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), Qt::UTC) + << QString("1978-11-09T13:28:34Z"); + QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34)); + dt.setUtcOffset(19800); + QTest::newRow("positive OffsetFromUTC") + << dt + << QString("1978-11-09T13:28:34+05:30"); + dt.setUtcOffset(-7200); + QTest::newRow("negative OffsetFromUTC") + << dt + << QString("1978-11-09T13:28:34-02:00"); +} + +void tst_QDateTime::toString_isoDate() +{ + QFETCH(QDateTime, dt); + QFETCH(QString, formatted); + + QCOMPARE(dt.toString(Qt::ISODate), formatted); +} + void tst_QDateTime::toString_enumformat() { QDateTime dt1(QDate(1995, 5, 20), QTime(12, 34, 56)); @@ -705,12 +737,12 @@ void tst_QDateTime::addSecs_data() } // Year sign change - QTest::newRow("toNegative") << QDateTime(QDate(1, 1, 1), QTime(0, 0, 0)) + QTest::newRow("toNegative") << QDateTime(QDate(1, 1, 1), QTime(0, 0, 0), Qt::UTC) << -1 - << QDateTime(QDate(-1, 12, 31), QTime(23, 59, 59)); - QTest::newRow("toPositive") << QDateTime(QDate(-1, 12, 31), QTime(23, 59, 59)) + << QDateTime(QDate(-1, 12, 31), QTime(23, 59, 59), Qt::UTC); + QTest::newRow("toPositive") << QDateTime(QDate(-1, 12, 31), QTime(23, 59, 59), Qt::UTC) << 1 - << QDateTime(QDate(1, 1, 1), QTime(0, 0, 0)); + << QDateTime(QDate(1, 1, 1), QTime(0, 0, 0), Qt::UTC); // Gregorian/Julian switchover QTest::newRow("toGregorian") << QDateTime(QDate(1582, 10, 4), QTime(23, 59, 59)) diff --git a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp index ff2cdca..c64c9e7 100644 --- a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp +++ b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp @@ -273,6 +273,11 @@ private slots: void task196924(); void focusNextPrevChild(); + + void taskQTBUG_12384_timeSpecShowTimeOnly(); + + void deleteCalendarWidget(); + private: EditorDateEdit* testWidget; QWidget *testFocusWidget; @@ -2696,17 +2701,10 @@ void tst_QDateTimeEdit::task98554() QCOMPARE(testWidget->time(), QTime(0, 0, 10, 0)); } -static QList<int> makeList(int val1, int val2 = -1, int val3 = -1, int val4 = -1, int val5 = -1, int val6 = -1, int val7 = -1) +static QList<int> makeList(int val1, int val2, int val3) { QList<int> ret; - Q_ASSERT(val1 >= 0); - ret << val1; - if (val2 < 0) {return ret;} else {ret << val2;} - if (val3 < 0) {return ret;} else {ret << val3;} - if (val4 < 0) {return ret;} else {ret << val4;} - if (val5 < 0) {return ret;} else {ret << val5;} - if (val6 < 0) {return ret;} else {ret << val6;} - if (val7 >= 0) {ret << val2;} + ret << val1 << val2 << val3; return ret; } @@ -2748,7 +2746,7 @@ void tst_QDateTimeEdit::setCurrentSection() QFETCH(QList<int>, setCurrentSections); QFETCH(QList<int>, expectedCursorPositions); - Q_ASSERT(setCurrentSections.size() == expectedCursorPositions.size()); + QCOMPARE(setCurrentSections.size(), expectedCursorPositions.size()); testWidget->setDisplayFormat(format); testWidget->setDateTime(dateTime); #ifdef Q_WS_MAC @@ -3420,7 +3418,41 @@ void tst_QDateTimeEdit::focusNextPrevChild() QCOMPARE(edit.currentSection(), QDateTimeEdit::MonthSection); } +void tst_QDateTimeEdit::taskQTBUG_12384_timeSpecShowTimeOnly() +{ + QDateTime time = QDateTime::fromString("20100723 04:02:40", "yyyyMMdd hh:mm:ss"); + time.setTimeSpec(Qt::UTC); + + EditorDateEdit edit; + edit.setDisplayFormat("hh:mm:ss"); + edit.setTimeSpec(Qt::UTC); + edit.setDateTime(time); + + QCOMPARE(edit.minimumTime(), QTime(0, 0, 0, 0)); + QCOMPARE(edit.maximumTime(), QTime(23, 59, 59, 999)); + QCOMPARE(edit.time(), time.time()); +} +void tst_QDateTimeEdit::deleteCalendarWidget() +{ + { + // setup + QCalendarWidget *cw = 0; + QDateEdit edit; + QVERIFY(!edit.calendarWidget()); + edit.setCalendarPopup(true); + QVERIFY(edit.calendarWidget()); + edit.calendarWidget()->setObjectName("cw1");; + + // delete + cw = edit.calendarWidget(); + delete cw; + + // it should create a new widget + QVERIFY(edit.calendarWidget()); + QVERIFY(edit.calendarWidget()->objectName() != "cw1"); + } +} QTEST_MAIN(tst_QDateTimeEdit) #include "tst_qdatetimeedit.moc" diff --git a/tests/auto/qdbusabstractadaptor/myobject.h b/tests/auto/qdbusabstractadaptor/myobject.h new file mode 100644 index 0000000..2aaaa7e --- /dev/null +++ b/tests/auto/qdbusabstractadaptor/myobject.h @@ -0,0 +1,286 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MYOBJECT_H +#define MYOBJECT_H + +#include <QtCore/QObject> +#include <QtDBus/QtDBus> + +extern const char *slotSpy; +extern QString valueSpy; + +class QDBusSignalSpy: public QObject +{ + Q_OBJECT + +public slots: + void slot(const QDBusMessage &msg) + { + ++count; + interface = msg.interface(); + name = msg.member(); + signature = msg.signature(); + path = msg.path(); + value.clear(); + if (msg.arguments().count()) + value = msg.arguments().at(0); + } + +public: + QDBusSignalSpy() : count(0) { } + + int count; + QString interface; + QString name; + QString signature; + QString path; + QVariant value; +}; + +class Interface1: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "local.Interface1") +public: + Interface1(QObject *parent) : QDBusAbstractAdaptor(parent) + { } +}; + +class Interface2: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "local.Interface2") + Q_PROPERTY(QString prop1 READ prop1) + Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2 SCRIPTABLE true) + Q_PROPERTY(QUrl nonDBusProperty READ nonDBusProperty) +public: + Interface2(QObject *parent) : QDBusAbstractAdaptor(parent) + { setAutoRelaySignals(true); } + + QString prop1() const + { return QLatin1String("QString Interface2::prop1() const"); } + + QString prop2() const + { return QLatin1String("QString Interface2::prop2() const"); } + + void setProp2(const QString &value) + { + slotSpy = "void Interface2::setProp2(const QString &)"; + valueSpy = value; + } + + QUrl nonDBusProperty() const + { return QUrl(); } + + void emitSignal(const QString &, const QVariant &) + { emit signal(); } + +public slots: + void method() + { + slotSpy = "void Interface2::method()"; + } + + Q_SCRIPTABLE void scriptableMethod() + { + slotSpy = "void Interface2::scriptableMethod()"; + } + +signals: + void signal(); +}; + +class Interface3: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "local.Interface3") + Q_PROPERTY(QString prop1 READ prop1) + Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2) + Q_PROPERTY(QString interface3prop READ interface3prop) +public: + Interface3(QObject *parent) : QDBusAbstractAdaptor(parent) + { setAutoRelaySignals(true); } + + QString prop1() const + { return QLatin1String("QString Interface3::prop1() const"); } + + QString prop2() const + { return QLatin1String("QString Interface3::prop2() const"); } + + void setProp2(const QString &value) + { + slotSpy = "void Interface3::setProp2(const QString &)"; + valueSpy = value; + } + + QString interface3prop() const + { return QLatin1String("QString Interface3::interface3prop() const"); } + + void emitSignal(const QString &name, const QVariant &value) + { + if (name == "signalVoid") + emit signalVoid(); + else if (name == "signalInt") + emit signalInt(value.toInt()); + else if (name == "signalString") + emit signalString(value.toString()); + } + +public slots: + void methodVoid() { slotSpy = "void Interface3::methodVoid()"; } + void methodInt(int) { slotSpy = "void Interface3::methodInt(int)"; } + void methodString(QString) { slotSpy = "void Interface3::methodString(QString)"; } + + int methodStringString(const QString &s, QString &out) + { + slotSpy = "int Interface3::methodStringString(const QString &, QString &)"; + out = s; + return 42; + } + +signals: + void signalVoid(); + void signalInt(int); + void signalString(const QString &); +}; + +class Interface4: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "local.Interface4") + Q_PROPERTY(QString prop1 READ prop1) + Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2) + Q_PROPERTY(QString interface4prop READ interface4prop) +public: + Interface4(QObject *parent) : QDBusAbstractAdaptor(parent) + { setAutoRelaySignals(true); } + + QString prop1() const + { return QLatin1String("QString Interface4::prop1() const"); } + + QString prop2() const + { return QLatin1String("QString Interface4::prop2() const"); } + + QString interface4prop() const + { return QLatin1String("QString Interface4::interface4prop() const"); } + + void setProp2(const QString &value) + { + slotSpy = "void Interface4::setProp2(const QString &)"; + valueSpy = value; + } + + void emitSignal(const QString &, const QVariant &value) + { + switch (value.type()) + { + case QVariant::Invalid: + emit signal(); + break; + case QVariant::Int: + emit signal(value.toInt()); + break; + case QVariant::String: + emit signal(value.toString()); + break; + default: + break; + } + } + +public slots: + void method() { slotSpy = "void Interface4::method()"; } + void method(int) { slotSpy = "void Interface4::method(int)"; } + void method(QString) { slotSpy = "void Interface4::method(QString)"; } + +signals: + void signal(); + void signal(int); + void signal(const QString &); +}; + +class MyObject: public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "local.MyObject") +public: + Interface1 *if1; + Interface2 *if2; + Interface3 *if3; + Interface4 *if4; + + MyObject(int n = 4) + : if1(0), if2(0), if3(0), if4(0) + { + switch (n) + { + case 4: + if4 = new Interface4(this); + case 3: + if3 = new Interface3(this); + case 2: + if2 = new Interface2(this); + case 1: + if1 = new Interface1(this); + } + } + + void emitSignal(const QString &name, const QVariant &value) + { + if (name == "scriptableSignalVoid") + emit scriptableSignalVoid(); + else if (name == "scriptableSignalInt") + emit scriptableSignalInt(value.toInt()); + else if (name == "scriptableSignalString") + emit scriptableSignalString(value.toString()); + else if (name == "nonScriptableSignalVoid") + emit nonScriptableSignalVoid(); + } + +signals: + Q_SCRIPTABLE void scriptableSignalVoid(); + Q_SCRIPTABLE void scriptableSignalInt(int); + Q_SCRIPTABLE void scriptableSignalString(QString); + void nonScriptableSignalVoid(); +}; + +#endif // MYOBJECT_H
\ No newline at end of file diff --git a/tests/auto/qdbusabstractadaptor/qdbusabstractadaptor.pro b/tests/auto/qdbusabstractadaptor/qdbusabstractadaptor.pro index 16358c5..c3e3f7f 100644 --- a/tests/auto/qdbusabstractadaptor/qdbusabstractadaptor.pro +++ b/tests/auto/qdbusabstractadaptor/qdbusabstractadaptor.pro @@ -1,10 +1,9 @@ load(qttest_p4) QT = core contains(QT_CONFIG,dbus): { - SOURCES += tst_qdbusabstractadaptor.cpp - QT += dbus + TEMPLATE = subdirs + CONFIG += ordered + SUBDIRS = qmyserver test } else { - SOURCES += ../qdbusmarshall/dummy.cpp + SOURCES += ../qdbusmarshall/dummy.cpp } - - diff --git a/tests/auto/qdbusabstractadaptor/qmyserver/qmyserver.cpp b/tests/auto/qdbusabstractadaptor/qmyserver/qmyserver.cpp new file mode 100644 index 0000000..a06232c --- /dev/null +++ b/tests/auto/qdbusabstractadaptor/qmyserver/qmyserver.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtCore/QtCore> +#include <QtDBus/QtDBus> + +#include "../myobject.h" + +static const char serviceName[] = "com.trolltech.autotests.qmyserver"; +static const char objectPath[] = "/com/trolltech/qmyserver"; +//static const char *interfaceName = serviceName; + +const char *slotSpy; +QString valueSpy; + +Q_DECLARE_METATYPE(QDBusConnection::RegisterOptions) + +class MyServer : public QDBusServer +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.trolltech.autotests.qmyserver") + +public: + MyServer(QString addr = "unix:tmpdir=/tmp", QObject* parent = 0) + : QDBusServer(addr, parent), + m_conn("none"), + obj(NULL) + { + connect(this, SIGNAL(newConnection(const QDBusConnection&)), SLOT(handleConnection(const QDBusConnection&))); + } + + ~MyServer() + { + if (obj) + obj->deleteLater(); + } + +public slots: + QString address() const + { + return QDBusServer::address(); + } + + bool isConnected() const + { + return m_conn.isConnected(); + } + + void emitSignal(const QString& interface, const QString& name, const QDBusVariant& parameter) + { + if (interface.endsWith('2')) + obj->if2->emitSignal(name, parameter.variant()); + else if (interface.endsWith('3')) + obj->if3->emitSignal(name, parameter.variant()); + else if (interface.endsWith('4')) + obj->if4->emitSignal(name, parameter.variant()); + else + obj->emitSignal(name, parameter.variant()); + } + + void emitSignal2(const QString& interface, const QString& name) + { + if (interface.endsWith('2')) + obj->if2->emitSignal(name, QVariant()); + else if (interface.endsWith('3')) + obj->if3->emitSignal(name, QVariant()); + else if (interface.endsWith('4')) + obj->if4->emitSignal(name, QVariant()); + else + obj->emitSignal(name, QVariant()); + } + + void newMyObject(int nInterfaces = 4) + { + if (obj) + obj->deleteLater(); + obj = new MyObject(nInterfaces); + } + + void registerMyObject(const QString & path, int options) + { + m_conn.registerObject(path, obj, (QDBusConnection::RegisterOptions)options); + } + + QString slotSpyServer() + { + return QLatin1String(slotSpy); + } + + QString valueSpyServer() + { + return valueSpy; + } + + void clearValueSpy() + { + valueSpy.clear(); + } + +private slots: + void handleConnection(const QDBusConnection& con) + { + m_conn = con; + } + +private: + QDBusConnection m_conn; + MyObject* obj; +}; + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + QDBusConnection con = QDBusConnection::sessionBus(); + if (!con.isConnected()) + exit(1); + + if (!con.registerService(serviceName)) + exit(2); + + MyServer server; + con.registerObject(objectPath, &server, QDBusConnection::ExportAllSlots); + + printf("ready.\n"); + + return app.exec(); +} + +#include "qmyserver.moc"
\ No newline at end of file diff --git a/tests/auto/qdbusabstractadaptor/qmyserver/qmyserver.pro b/tests/auto/qdbusabstractadaptor/qmyserver/qmyserver.pro new file mode 100644 index 0000000..f4fe02c --- /dev/null +++ b/tests/auto/qdbusabstractadaptor/qmyserver/qmyserver.pro @@ -0,0 +1,5 @@ +SOURCES = qmyserver.cpp +HEADERS = ../myobject.h +TARGET = qmyserver +QT += dbus +QT -= gui diff --git a/tests/auto/qdbusabstractadaptor/test/test.pro b/tests/auto/qdbusabstractadaptor/test/test.pro new file mode 100644 index 0000000..014a9e8 --- /dev/null +++ b/tests/auto/qdbusabstractadaptor/test/test.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +SOURCES += ../tst_qdbusabstractadaptor.cpp +HEADERS += ../myobject.h +TARGET = ../tst_qdbusabstractadaptor + +QT = core +QT += dbus diff --git a/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp b/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp index 5cf21e6..ff684ff 100644 --- a/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp +++ b/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp @@ -46,6 +46,11 @@ #include <QtDBus> #include "../qdbusmarshall/common.h" +#include "myobject.h" + +static const char serviceName[] = "com.trolltech.autotests.qmyserver"; +static const char objectPath[] = "/com/trolltech/qmyserver"; +static const char *interfaceName = serviceName; const char *slotSpy; QString valueSpy; @@ -73,273 +78,6 @@ namespace QTest { } QT_END_NAMESPACE -class tst_QDBusAbstractAdaptor: public QObject -{ - Q_OBJECT - -private slots: - void initTestCase() { commonInit(); } - void methodCalls_data(); - void methodCalls(); - void methodCallScriptable(); - void signalEmissions_data(); - void signalEmissions(); - void sameSignalDifferentPaths(); - void sameObjectDifferentPaths(); - void scriptableSignalOrNot(); - void overloadedSignalEmission_data(); - void overloadedSignalEmission(); - void readProperties(); - void readPropertiesInvalidInterface(); - void readPropertiesEmptyInterface_data(); - void readPropertiesEmptyInterface(); - void readAllProperties(); - void readAllPropertiesInvalidInterface(); - void readAllPropertiesEmptyInterface_data(); - void readAllPropertiesEmptyInterface(); - void writeProperties(); - - void typeMatching_data(); - void typeMatching(); - - void methodWithMoreThanOneReturnValue(); -}; - -class QDBusSignalSpy: public QObject -{ - Q_OBJECT - -public slots: - void slot(const QDBusMessage &msg) - { - ++count; - interface = msg.interface(); - name = msg.member(); - signature = msg.signature(); - path = msg.path(); - value.clear(); - if (msg.arguments().count()) - value = msg.arguments().at(0); - } - -public: - QDBusSignalSpy() : count(0) { } - - int count; - QString interface; - QString name; - QString signature; - QString path; - QVariant value; -}; - -class Interface1: public QDBusAbstractAdaptor -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "local.Interface1") -public: - Interface1(QObject *parent) : QDBusAbstractAdaptor(parent) - { } -}; - -class Interface2: public QDBusAbstractAdaptor -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "local.Interface2") - Q_PROPERTY(QString prop1 READ prop1) - Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2 SCRIPTABLE true) - Q_PROPERTY(QUrl nonDBusProperty READ nonDBusProperty) -public: - Interface2(QObject *parent) : QDBusAbstractAdaptor(parent) - { setAutoRelaySignals(true); } - - QString prop1() const - { return QLatin1String("QString Interface2::prop1() const"); } - - QString prop2() const - { return QLatin1String("QString Interface2::prop2() const"); } - - void setProp2(const QString &value) - { - slotSpy = "void Interface2::setProp2(const QString &)"; - valueSpy = value; - } - - QUrl nonDBusProperty() const - { return QUrl(); } - - void emitSignal(const QString &, const QVariant &) - { emit signal(); } - -public slots: - void method() - { - slotSpy = "void Interface2::method()"; - } - - Q_SCRIPTABLE void scriptableMethod() - { - slotSpy = "void Interface2::scriptableMethod()"; - } - -signals: - void signal(); -}; - -class Interface3: public QDBusAbstractAdaptor -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "local.Interface3") - Q_PROPERTY(QString prop1 READ prop1) - Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2) - Q_PROPERTY(QString interface3prop READ interface3prop) -public: - Interface3(QObject *parent) : QDBusAbstractAdaptor(parent) - { setAutoRelaySignals(true); } - - QString prop1() const - { return QLatin1String("QString Interface3::prop1() const"); } - - QString prop2() const - { return QLatin1String("QString Interface3::prop2() const"); } - - void setProp2(const QString &value) - { - slotSpy = "void Interface3::setProp2(const QString &)"; - valueSpy = value; - } - - QString interface3prop() const - { return QLatin1String("QString Interface3::interface3prop() const"); } - - void emitSignal(const QString &name, const QVariant &value) - { - if (name == "signalVoid") - emit signalVoid(); - else if (name == "signalInt") - emit signalInt(value.toInt()); - else if (name == "signalString") - emit signalString(value.toString()); - } - -public slots: - void methodVoid() { slotSpy = "void Interface3::methodVoid()"; } - void methodInt(int) { slotSpy = "void Interface3::methodInt(int)"; } - void methodString(QString) { slotSpy = "void Interface3::methodString(QString)"; } - - int methodStringString(const QString &s, QString &out) - { - slotSpy = "int Interface3::methodStringString(const QString &, QString &)"; - out = s; - return 42; - } - -signals: - void signalVoid(); - void signalInt(int); - void signalString(const QString &); -}; - -class Interface4: public QDBusAbstractAdaptor -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "local.Interface4") - Q_PROPERTY(QString prop1 READ prop1) - Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2) - Q_PROPERTY(QString interface4prop READ interface4prop) -public: - Interface4(QObject *parent) : QDBusAbstractAdaptor(parent) - { setAutoRelaySignals(true); } - - QString prop1() const - { return QLatin1String("QString Interface4::prop1() const"); } - - QString prop2() const - { return QLatin1String("QString Interface4::prop2() const"); } - - QString interface4prop() const - { return QLatin1String("QString Interface4::interface4prop() const"); } - - void setProp2(const QString &value) - { - slotSpy = "void Interface4::setProp2(const QString &)"; - valueSpy = value; - } - - void emitSignal(const QString &, const QVariant &value) - { - switch (value.type()) - { - case QVariant::Invalid: - emit signal(); - break; - case QVariant::Int: - emit signal(value.toInt()); - break; - case QVariant::String: - emit signal(value.toString()); - break; - default: - break; - } - } - -public slots: - void method() { slotSpy = "void Interface4::method()"; } - void method(int) { slotSpy = "void Interface4::method(int)"; } - void method(QString) { slotSpy = "void Interface4::method(QString)"; } - -signals: - void signal(); - void signal(int); - void signal(const QString &); -}; - -class MyObject: public QObject -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "local.MyObject") -public: - Interface1 *if1; - Interface2 *if2; - Interface3 *if3; - Interface4 *if4; - - MyObject(int n = 4) - : if1(0), if2(0), if3(0), if4(0) - { - switch (n) - { - case 4: - if4 = new Interface4(this); - case 3: - if3 = new Interface3(this); - case 2: - if2 = new Interface2(this); - case 1: - if1 = new Interface1(this); - } - } - - void emitSignal(const QString &name, const QVariant &value) - { - if (name == "scriptableSignalVoid") - emit scriptableSignalVoid(); - else if (name == "scriptableSignalInt") - emit scriptableSignalInt(value.toInt()); - else if (name == "scriptableSignalString") - emit scriptableSignalString(value.toString()); - else if (name == "nonScriptableSignalVoid") - emit nonScriptableSignalVoid(); - } - -signals: - Q_SCRIPTABLE void scriptableSignalVoid(); - Q_SCRIPTABLE void scriptableSignalInt(int); - Q_SCRIPTABLE void scriptableSignalString(QString); - void nonScriptableSignalVoid(); -}; - class TypesInterface: public QDBusAbstractAdaptor { Q_OBJECT @@ -593,6 +331,191 @@ public slots: } }; +void newMyObjectPeer(int nInterfaces = 4) +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "newMyObject"); + req << nInterfaces; + QDBusMessage reply = QDBusConnection::sessionBus().call(req); +} + +void registerMyObjectPeer(const QString & path, QDBusConnection::RegisterOptions options = QDBusConnection::ExportAdaptors) +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "registerMyObject"); + req << path; + req << (int)options; + QDBusMessage reply = QDBusConnection::sessionBus().call(req); +} + +void emitSignalPeer(const QString &interface, const QString &name, const QVariant ¶meter) +{ + if (parameter.isValid()) + { + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "emitSignal"); + req << interface; + req << name; + req << QVariant::fromValue(QDBusVariant(parameter)); + QDBusConnection::sessionBus().send(req); + } + else + { + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "emitSignal2"); + req << interface; + req << name; + QDBusConnection::sessionBus().send(req); + } + + QTest::qWait(1000); +} + +const char* slotSpyPeer() +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "slotSpyServer"); + QDBusMessage reply = QDBusConnection::sessionBus().call(req); + return reply.arguments().at(0).toString().toLatin1().data(); +} + +QString valueSpyPeer() +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "valueSpyServer"); + QDBusMessage reply = QDBusConnection::sessionBus().call(req); + return reply.arguments().at(0).toString(); +} + +void clearValueSpyPeer() +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "clearValueSpy"); + QDBusMessage reply = QDBusConnection::sessionBus().call(req); +} + +class tst_QDBusAbstractAdaptor: public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void methodCalls_data(); + void methodCalls(); + void methodCallScriptable(); + void signalEmissions_data(); + void signalEmissions(); + void sameSignalDifferentPaths(); + void sameObjectDifferentPaths(); + void scriptableSignalOrNot(); + void overloadedSignalEmission_data(); + void overloadedSignalEmission(); + void readProperties(); + void readPropertiesInvalidInterface(); + void readPropertiesEmptyInterface_data(); + void readPropertiesEmptyInterface(); + void readAllProperties(); + void readAllPropertiesInvalidInterface(); + void readAllPropertiesEmptyInterface_data(); + void readAllPropertiesEmptyInterface(); + void writeProperties(); + + void methodCallsPeer_data(); + void methodCallsPeer(); + void methodCallScriptablePeer(); + void signalEmissionsPeer_data(); + void signalEmissionsPeer(); + void sameSignalDifferentPathsPeer(); + void sameObjectDifferentPathsPeer(); + void scriptableSignalOrNotPeer(); + void overloadedSignalEmissionPeer_data(); + void overloadedSignalEmissionPeer(); + void readPropertiesPeer(); + void readPropertiesInvalidInterfacePeer(); + void readPropertiesEmptyInterfacePeer_data(); + void readPropertiesEmptyInterfacePeer(); + void readAllPropertiesPeer(); + void readAllPropertiesInvalidInterfacePeer(); + void readAllPropertiesEmptyInterfacePeer_data(); + void readAllPropertiesEmptyInterfacePeer(); + void writePropertiesPeer(); + + void typeMatching_data(); + void typeMatching(); + + void methodWithMoreThanOneReturnValue(); + void methodWithMoreThanOneReturnValuePeer(); +private: + QProcess proc; +}; + +class WaitForQMyServer: public QObject +{ + Q_OBJECT +public: + WaitForQMyServer(); + bool ok(); +public Q_SLOTS: + void ownerChange(const QString &name) + { + if (name == serviceName) + loop.quit(); + } + +private: + QEventLoop loop; +}; + +WaitForQMyServer::WaitForQMyServer() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + if (!ok()) { + connect(con.interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), + SLOT(ownerChange(QString))); + QTimer::singleShot(2000, &loop, SLOT(quit())); + loop.exec(); + } +} + +bool WaitForQMyServer::ok() +{ + return QDBusConnection::sessionBus().isConnected() && + QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName); +} + +void tst_QDBusAbstractAdaptor::initTestCase() +{ + commonInit(); + + // start peer server + #ifdef Q_OS_WIN + proc.start("qmyserver"); + #else + proc.start("./qmyserver/qmyserver"); + #endif + QVERIFY(proc.waitForStarted()); + + WaitForQMyServer w; + QVERIFY(w.ok()); + //QTest::qWait(2000); + + // get peer server address + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "address"); + QDBusMessage rpl = QDBusConnection::sessionBus().call(req); + QVERIFY(rpl.type() == QDBusMessage::ReplyMessage); + QString address = rpl.arguments().at(0).toString(); + + // connect to peer server + QDBusConnection peercon = QDBusConnection::connectToPeer(address, "peer"); + QVERIFY(peercon.isConnected()); + + QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "isConnected"); + QDBusMessage rpl2 = QDBusConnection::sessionBus().call(req2); + QVERIFY(rpl2.type() == QDBusMessage::ReplyMessage); + QVERIFY(rpl2.arguments().at(0).toBool()); +} + +void tst_QDBusAbstractAdaptor::cleanupTestCase() +{ + proc.close(); + proc.kill(); +} + void tst_QDBusAbstractAdaptor::methodCalls_data() { QTest::addColumn<int>("nInterfaces"); @@ -1151,6 +1074,512 @@ void tst_QDBusAbstractAdaptor::writeProperties() } } +void tst_QDBusAbstractAdaptor::methodCallsPeer_data() +{ + methodCalls_data(); +} + +void tst_QDBusAbstractAdaptor::methodCallsPeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + { + // must fail: no object + QDBusInterface if1(QString(), "/", "local.Interface1", con); + QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage); + } + + QFETCH(int, nInterfaces); + newMyObjectPeer(nInterfaces); + registerMyObjectPeer("/"); + + QDBusInterface if1(QString(), "/", "local.Interface1", con); + QDBusInterface if2(QString(), "/", "local.Interface2", con); + QDBusInterface if3(QString(), "/", "local.Interface3", con); + QDBusInterface if4(QString(), "/", "local.Interface4", con); + + // must fail: no such method + QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage); + if (!nInterfaces--) + return; + if (!nInterfaces--) + return; + + // simple call: one such method exists + QCOMPARE(if2.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpyPeer(), "void Interface2::method()"); + if (!nInterfaces--) + return; + + // multiple methods in multiple interfaces, no name overlap + QCOMPARE(if1.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ErrorMessage); + QCOMPARE(if1.call(QDBus::BlockWithGui, "methodInt").type(), QDBusMessage::ErrorMessage); + QCOMPARE(if1.call(QDBus::BlockWithGui, "methodString").type(), QDBusMessage::ErrorMessage); + QCOMPARE(if2.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ErrorMessage); + QCOMPARE(if2.call(QDBus::BlockWithGui, "methodInt").type(), QDBusMessage::ErrorMessage); + QCOMPARE(if2.call(QDBus::BlockWithGui, "methodString").type(), QDBusMessage::ErrorMessage); + + QCOMPARE(if3.call(QDBus::BlockWithGui, "methodVoid").type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpyPeer(), "void Interface3::methodVoid()"); + QCOMPARE(if3.call(QDBus::BlockWithGui, "methodInt", 42).type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpyPeer(), "void Interface3::methodInt(int)"); + QCOMPARE(if3.call(QDBus::BlockWithGui, "methodString", QString("")).type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpyPeer(), "void Interface3::methodString(QString)"); + + if (!nInterfaces--) + return; + + // method overloading: different interfaces + QCOMPARE(if4.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpyPeer(), "void Interface4::method()"); + + // method overloading: different parameters + QCOMPARE(if4.call(QDBus::BlockWithGui, "method.i", 42).type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpyPeer(), "void Interface4::method(int)"); + QCOMPARE(if4.call(QDBus::BlockWithGui, "method.s", QString()).type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpyPeer(), "void Interface4::method(QString)"); +} + +void tst_QDBusAbstractAdaptor::methodCallScriptablePeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(2); + registerMyObjectPeer("/"); + + QDBusInterface if2(QString(), "/", "local.Interface2", con); + + QCOMPARE(if2.call(QDBus::BlockWithGui,"scriptableMethod").type(), QDBusMessage::ReplyMessage); + QCOMPARE(slotSpyPeer(), "void Interface2::scriptableMethod()"); +} + +void tst_QDBusAbstractAdaptor::signalEmissionsPeer_data() +{ + signalEmissions_data(); +} + +void tst_QDBusAbstractAdaptor::signalEmissionsPeer() +{ + QFETCH(QString, interface); + QFETCH(QString, name); + QFETCH(QVariant, parameter); + + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(3); + registerMyObjectPeer("/", QDBusConnection::ExportAdaptors + | QDBusConnection::ExportScriptableSignals); + + // connect all signals and emit only one + { + QDBusSignalSpy spy; + con.connect(QString(), "/", "local.Interface2", "signal", + &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/", "local.Interface3", "signalVoid", + &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/", "local.Interface3", "signalInt", + &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/", "local.Interface3", "signalString", + &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/", "local.MyObject", "scriptableSignalVoid", + &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/", "local.MyObject", "scriptableSignalInt", + &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/", "local.MyObject", "scriptableSignalString", + &spy, SLOT(slot(QDBusMessage))); + + emitSignalPeer(interface, name, parameter); + + QCOMPARE(spy.count, 1); + QCOMPARE(spy.interface, interface); + QCOMPARE(spy.name, name); + QTEST(spy.signature, "signature"); + QCOMPARE(spy.value, parameter); + } + + // connect one signal and emit them all + { + QDBusSignalSpy spy; + con.connect(QString(), "/", interface, name, &spy, SLOT(slot(QDBusMessage))); + emitSignalPeer("local.Interface2", "signal", QVariant()); + emitSignalPeer("local.Interface3", "signalVoid", QVariant()); + emitSignalPeer("local.Interface3", "signalInt", QVariant(1)); + emitSignalPeer("local.Interface3", "signalString", QVariant("foo")); + emitSignalPeer("local.MyObject", "scriptableSignalVoid", QVariant()); + emitSignalPeer("local.MyObject", "scriptableSignalInt", QVariant(1)); + emitSignalPeer("local.MyObject", "scriptableSignalString", QVariant("foo")); + + QCOMPARE(spy.count, 1); + QCOMPARE(spy.interface, interface); + QCOMPARE(spy.name, name); + QTEST(spy.signature, "signature"); + QCOMPARE(spy.value, parameter); + } +} + +void tst_QDBusAbstractAdaptor::sameSignalDifferentPathsPeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(2); + + registerMyObjectPeer("/p1"); + registerMyObjectPeer("/p2"); + + QDBusSignalSpy spy; + con.connect(QString(), "/p1", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage))); + emitSignalPeer("local.Interface2", QString(), QVariant()); + QTest::qWait(200); + + QCOMPARE(spy.count, 1); + QCOMPARE(spy.interface, QString("local.Interface2")); + QCOMPARE(spy.name, QString("signal")); + QVERIFY(spy.signature.isEmpty()); + + // now connect the other one + spy.count = 0; + con.connect(QString(), "/p2", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage))); + emitSignalPeer("local.Interface2", QString(), QVariant()); + QTest::qWait(200); + + QCOMPARE(spy.count, 2); +} + +void tst_QDBusAbstractAdaptor::sameObjectDifferentPathsPeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(2); + + registerMyObjectPeer("/p1"); + registerMyObjectPeer("/p2", 0); // don't export anything + + QDBusSignalSpy spy; + con.connect(QString(), "/p1", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/p2", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage))); + emitSignalPeer("local.Interface2", QString(), QVariant()); + QTest::qWait(200); + + QCOMPARE(spy.count, 1); + QCOMPARE(spy.interface, QString("local.Interface2")); + QCOMPARE(spy.name, QString("signal")); + QVERIFY(spy.signature.isEmpty()); +} + +void tst_QDBusAbstractAdaptor::scriptableSignalOrNotPeer() +{ + QDBusConnection con("peer");; + QVERIFY(con.isConnected()); + + { + newMyObjectPeer(0); + + registerMyObjectPeer("/p1", QDBusConnection::ExportScriptableSignals); + registerMyObjectPeer("/p2", 0); // don't export anything + + QDBusSignalSpy spy; + con.connect(QString(), "/p1", "local.MyObject", "scriptableSignalVoid", &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/p2", "local.MyObject", "scriptableSignalVoid", &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/p1", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage))); + emitSignalPeer("local.MyObject", "scriptableSignalVoid", QVariant()); + emitSignalPeer("local.MyObject", "nonScriptableSignalVoid", QVariant()); + QTest::qWait(200); + + QCOMPARE(spy.count, 1); // only /p1 must have emitted + QCOMPARE(spy.interface, QString("local.MyObject")); + QCOMPARE(spy.name, QString("scriptableSignalVoid")); + QCOMPARE(spy.path, QString("/p1")); + QVERIFY(spy.signature.isEmpty()); + } + + { + newMyObjectPeer(0); + + registerMyObjectPeer("/p1", QDBusConnection::ExportScriptableSignals); + registerMyObjectPeer("/p2", QDBusConnection::ExportScriptableSignals + | QDBusConnection::ExportNonScriptableSignals); + + QDBusSignalSpy spy; + con.connect(QString(), "/p1", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage))); + emitSignalPeer("local.MyObject", "nonScriptableSignalVoid", QVariant()); + QTest::qWait(200); + + QCOMPARE(spy.count, 1); // only /p2 must have emitted now + QCOMPARE(spy.interface, QString("local.MyObject")); + QCOMPARE(spy.name, QString("nonScriptableSignalVoid")); + QCOMPARE(spy.path, QString("/p2")); + QVERIFY(spy.signature.isEmpty()); + } + + { + QDBusSignalSpy spy; + con.connect(QString(), "/p1", "local.MyObject", "destroyed", &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/p2", "local.MyObject", "destroyed", &spy, SLOT(slot(QDBusMessage))); + + { + newMyObjectPeer(0); + + registerMyObjectPeer("/p1", QDBusConnection::ExportScriptableSignals); + registerMyObjectPeer("/p2", QDBusConnection::ExportScriptableSignals + | QDBusConnection::ExportNonScriptableSignals); + } // <--- QObject emits the destroyed(QObject*) signal at this point + + QTest::qWait(200); + + QCOMPARE(spy.count, 0); + } +} + +void tst_QDBusAbstractAdaptor::overloadedSignalEmissionPeer_data() +{ + overloadedSignalEmission_data(); +} + +void tst_QDBusAbstractAdaptor::overloadedSignalEmissionPeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(); + registerMyObjectPeer("/"); + + QString interface = "local.Interface4"; + QString name = "signal"; + QFETCH(QVariant, parameter); + //QDBusInterface *if4 = new QDBusInterface(QString(), "/", interface, con); + + // connect all signals and emit only one + { + QDBusSignalSpy spy; + con.connect(QString(), "/", "local.Interface4", "signal", "", + &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/", "local.Interface4", "signal", "i", + &spy, SLOT(slot(QDBusMessage))); + con.connect(QString(), "/", "local.Interface4", "signal", "s", + &spy, SLOT(slot(QDBusMessage))); + + emitSignalPeer(interface, name, parameter); + + QCOMPARE(spy.count, 1); + QCOMPARE(spy.interface, interface); + QCOMPARE(spy.name, name); + QTEST(spy.signature, "signature"); + QCOMPARE(spy.value, parameter); + } + + QFETCH(QString, signature); + // connect one signal and emit them all + { + QDBusSignalSpy spy; + con.connect(QString(), "/", interface, name, signature, &spy, SLOT(slot(QDBusMessage))); + emitSignalPeer("local.Interface4", "signal", QVariant()); + emitSignalPeer("local.Interface4", "signal", QVariant(1)); + emitSignalPeer("local.Interface4", "signal", QVariant("foo")); + + QCOMPARE(spy.count, 1); + QCOMPARE(spy.interface, interface); + QCOMPARE(spy.name, name); + QTEST(spy.signature, "signature"); + QCOMPARE(spy.value, parameter); + } +} + +void tst_QDBusAbstractAdaptor::readPropertiesPeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(); + registerMyObjectPeer("/"); + + QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con); + for (int i = 2; i <= 4; ++i) { + QString name = QString("Interface%1").arg(i); + + for (int j = 1; j <= 2; ++j) { + QString propname = QString("prop%1").arg(j); + QDBusReply<QVariant> reply = + properties.call(QDBus::BlockWithGui, "Get", "local." + name, propname); + QVariant value = reply; + + QCOMPARE(value.userType(), int(QVariant::String)); + QCOMPARE(value.toString(), QString("QString %1::%2() const").arg(name, propname)); + } + } +} + +void tst_QDBusAbstractAdaptor::readPropertiesInvalidInterfacePeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(); + registerMyObjectPeer("/"); + + QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con); + + // test an invalid interface: + QDBusReply<QVariant> reply = properties.call(QDBus::BlockWithGui, "Get", "local.DoesntExist", "prop1"); + QVERIFY(!reply.isValid()); +} + +void tst_QDBusAbstractAdaptor::readPropertiesEmptyInterfacePeer_data() +{ + readPropertiesEmptyInterface_data(); +} + +void tst_QDBusAbstractAdaptor::readPropertiesEmptyInterfacePeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(); + registerMyObjectPeer("/"); + + QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con); + + QFETCH(QVariantMap, expectedProperties); + QFETCH(bool, existing); + + QVariantMap::ConstIterator it = expectedProperties.constBegin(); + for ( ; it != expectedProperties.constEnd(); ++it) { + QDBusReply<QVariant> reply = properties.call(QDBus::BlockWithGui, "Get", "", it.key()); + + if (existing) { + QVERIFY2(reply.isValid(), qPrintable(it.key())); + } else { + QVERIFY2(!reply.isValid(), qPrintable(it.key())); + continue; + } + + QCOMPARE(int(reply.value().type()), int(QVariant::String)); + if (it.value().isValid()) + QCOMPARE(reply.value().toString(), it.value().toString()); + } +} + +void tst_QDBusAbstractAdaptor::readAllPropertiesPeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(); + registerMyObjectPeer("/"); + + QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con); + for (int i = 2; i <= 4; ++i) { + QString name = QString("Interface%1").arg(i); + QDBusReply<QVariantMap> reply = + properties.call(QDBus::BlockWithGui, "GetAll", "local." + name); + + for (int j = 1; j <= 2; ++j) { + QString propname = QString("prop%1").arg(j); + QVERIFY2(reply.value().contains(propname), + qPrintable(propname + " on " + name)); + QVariant value = reply.value().value(propname); + + QCOMPARE(value.userType(), int(QVariant::String)); + QCOMPARE(value.toString(), QString("QString %1::%2() const").arg(name, propname)); + } + } +} + +void tst_QDBusAbstractAdaptor::readAllPropertiesInvalidInterfacePeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(); + registerMyObjectPeer("/"); + + QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con); + + // test an invalid interface: + QDBusReply<QVariantMap> reply = properties.call(QDBus::BlockWithGui, "GetAll", "local.DoesntExist"); + QVERIFY(!reply.isValid()); +} + +void tst_QDBusAbstractAdaptor::readAllPropertiesEmptyInterfacePeer_data() +{ + readAllPropertiesEmptyInterface_data(); +} + +void tst_QDBusAbstractAdaptor::readAllPropertiesEmptyInterfacePeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(); + registerMyObjectPeer("/"); + + QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con); + + QDBusReply<QVariantMap> reply = properties.call(QDBus::BlockWithGui, "GetAll", ""); + QVERIFY(reply.isValid()); + + QVariantMap allprops = reply; + + QFETCH(QVariantMap, expectedProperties); + QFETCH(bool, existing); + + QVariantMap::ConstIterator it = expectedProperties.constBegin(); + if (existing) { + for ( ; it != expectedProperties.constEnd(); ++it) { + QVERIFY2(allprops.contains(it.key()), qPrintable(it.key())); + + QVariant propvalue = allprops.value(it.key()); + QVERIFY2(!propvalue.isNull(), qPrintable(it.key())); + QVERIFY2(propvalue.isValid(), qPrintable(it.key())); + + QString stringvalue = propvalue.toString(); + QVERIFY2(!stringvalue.isEmpty(), qPrintable(it.key())); + + if (it.value().isValid()) + QCOMPARE(stringvalue, it.value().toString()); + + // remove this property from the map + allprops.remove(it.key()); + } + + QVERIFY2(allprops.isEmpty(), + qPrintable(QStringList(allprops.keys()).join(" "))); + } else { + for ( ; it != expectedProperties.constEnd(); ++it) + QVERIFY2(!allprops.contains(it.key()), qPrintable(it.key())); + } +} + +void tst_QDBusAbstractAdaptor::writePropertiesPeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(); + registerMyObjectPeer("/"); + + QDBusInterface properties(QString(), "/", "org.freedesktop.DBus.Properties", con); + for (int i = 2; i <= 4; ++i) { + QString name = QString("Interface%1").arg(i); + + clearValueSpyPeer(); + properties.call(QDBus::BlockWithGui, "Set", "local." + name, QString("prop1"), + qVariantFromValue(QDBusVariant(name))); + QVERIFY(valueSpyPeer().isEmpty()); // call mustn't have succeeded + + properties.call(QDBus::BlockWithGui, "Set", "local." + name, QString("prop2"), + qVariantFromValue(QDBusVariant(name))); + QCOMPARE(valueSpyPeer(), name); + QCOMPARE(QString(slotSpyPeer()), QString("void %1::setProp2(const QString &)").arg(name)); + } +} + #if 0 void tst_QDBusAbstractAdaptor::adaptorIntrospection_data() { @@ -1438,6 +1867,28 @@ void tst_QDBusAbstractAdaptor::methodWithMoreThanOneReturnValue() QCOMPARE(qdbus_cast<QString>(reply.arguments().at(1)), testString); } +void tst_QDBusAbstractAdaptor::methodWithMoreThanOneReturnValuePeer() +{ + QDBusConnection con("peer"); + QVERIFY(con.isConnected()); + + newMyObjectPeer(); + registerMyObjectPeer("/"); + + QString testString = "This is a test string."; + + QDBusInterface remote(QString(), "/", "local.Interface3", con); + QDBusMessage reply = remote.call(QDBus::BlockWithGui, "methodStringString", testString); + QVERIFY(reply.arguments().count() == 2); + + QDBusReply<int> intreply = reply; + QVERIFY(intreply.isValid()); + QCOMPARE(intreply.value(), 42); + + QCOMPARE(reply.arguments().at(1).userType(), int(QVariant::String)); + QCOMPARE(qdbus_cast<QString>(reply.arguments().at(1)), testString); +} + QTEST_MAIN(tst_QDBusAbstractAdaptor) #include "tst_qdbusabstractadaptor.moc" diff --git a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml index fb2aab8..1667591 100644 --- a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml +++ b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml @@ -24,7 +24,7 @@ </method> <method name="multiOutMethod"> <arg type="s" direction="out"/> - <arg type="i" direction="out"/ + <arg type="i" direction="out"/> </method> </interface> </node> diff --git a/tests/auto/qdbusabstractinterface/interface.h b/tests/auto/qdbusabstractinterface/interface.h index d3aac18..b840a38 100644 --- a/tests/auto/qdbusabstractinterface/interface.h +++ b/tests/auto/qdbusabstractinterface/interface.h @@ -84,6 +84,7 @@ class Interface: public QObject Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp SCRIPTABLE true) friend class tst_QDBusAbstractInterface; + friend class PingerServer; QString m_stringProp; QDBusVariant m_variantProp; RegisteredType m_complexProp; diff --git a/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro b/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro index a4853b8..f9077b9 100644 --- a/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro +++ b/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro @@ -1,15 +1,10 @@ load(qttest_p4) -QT = core -contains(QT_CONFIG,dbus): { - SOURCES += tst_qdbusabstractinterface.cpp interface.cpp - HEADERS += interface.h - QT += dbus - - # These are generated sources - # To regenerate, see the command-line at the top of the files - SOURCES += pinger.cpp - HEADERS += pinger.h +contains(QT_CONFIG,dbus): { + TEMPLATE = subdirs + CONFIG += ordered + SUBDIRS = qpinger test +} else { + SOURCES += ../qdbusmarshall/dummy.cpp } -else:SOURCES += ../qdbusmarshall/dummy.cpp OTHER_FILES += com.trolltech.QtDBus.Pinger.xml diff --git a/tests/auto/qdbusabstractinterface/qpinger/qpinger.cpp b/tests/auto/qdbusabstractinterface/qpinger/qpinger.cpp new file mode 100644 index 0000000..393d647 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/qpinger/qpinger.cpp @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtCore/QtCore> +#include <QtDBus/QtDBus> +#include "../interface.h" + +static const char serviceName[] = "com.trolltech.autotests.qpinger"; +static const char objectPath[] = "/com/trolltech/qpinger"; +//static const char *interfaceName = serviceName; + +class PingerServer : public QDBusServer +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.trolltech.autotests.qpinger") +public: + PingerServer(QString addr = "unix:tmpdir=/tmp", QObject* parent = 0) + : QDBusServer(addr, parent), + m_conn("none") + { + connect(this, SIGNAL(newConnection(const QDBusConnection&)), SLOT(handleConnection(const QDBusConnection&))); + reset(); + } + +public slots: + QString address() const + { + return QDBusServer::address(); + } + + bool isConnected() const + { + return m_conn.isConnected(); + } + + void reset() + { + targetObj.m_stringProp = "This is a test"; + targetObj.m_variantProp = QDBusVariant(QVariant(42)); + targetObj.m_complexProp = RegisteredType("This is a test"); + } + + void voidSignal() + { + emit targetObj.voidSignal(); + } + + void stringSignal(const QString& value) + { + emit targetObj.stringSignal(value); + } + + void complexSignal(const QString& value) + { + RegisteredType reg(value); + emit targetObj.complexSignal(reg); + } + +private slots: + void handleConnection(const QDBusConnection& con) + { + m_conn = con; + m_conn.registerObject("/", &targetObj, QDBusConnection::ExportScriptableContents); + } + +private: + Interface targetObj; + QDBusConnection m_conn; +}; + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + // register the meta types + qDBusRegisterMetaType<RegisteredType>(); + qRegisterMetaType<UnregisteredType>(); + + QDBusConnection con = QDBusConnection::sessionBus(); + if (!con.isConnected()) + exit(1); + + if (!con.registerService(serviceName)) + exit(2); + + PingerServer server; + con.registerObject(objectPath, &server, QDBusConnection::ExportAllSlots); + + printf("ready.\n"); + + return app.exec(); +} + +#include "qpinger.moc" diff --git a/tests/auto/qdbusabstractinterface/qpinger/qpinger.pro b/tests/auto/qdbusabstractinterface/qpinger/qpinger.pro new file mode 100644 index 0000000..27545bb --- /dev/null +++ b/tests/auto/qdbusabstractinterface/qpinger/qpinger.pro @@ -0,0 +1,5 @@ +SOURCES = qpinger.cpp ../interface.cpp +HEADERS = ../interface.h +TARGET = qpinger +QT += dbus +QT -= gui diff --git a/tests/auto/qdbusabstractinterface/test/test.pro b/tests/auto/qdbusabstractinterface/test/test.pro new file mode 100644 index 0000000..98bcaa7 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/test/test.pro @@ -0,0 +1,13 @@ +load(qttest_p4) +SOURCES += ../tst_qdbusabstractinterface.cpp ../interface.cpp +HEADERS += ../interface.h + +# These are generated sources +# To regenerate, see the command-line at the top of the files +SOURCES += ../pinger.cpp +HEADERS += ../pinger.h + +TARGET = ../tst_qdbusabstractinterface + +QT = core +QT += dbus diff --git a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp index 78c9902..00e3a76 100644 --- a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp +++ b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -49,6 +49,10 @@ #include "interface.h" #include "pinger.h" +static const char serviceName[] = "com.trolltech.autotests.qpinger"; +static const char objectPath[] = "/com/trolltech/qpinger"; +static const char *interfaceName = serviceName; + typedef QSharedPointer<com::trolltech::QtDBus::Pinger> Pinger; class tst_QDBusAbstractInterface: public QObject @@ -66,22 +70,47 @@ class tst_QDBusAbstractInterface: public QObject return Pinger(new com::trolltech::QtDBus::Pinger(service, path, con)); } + Pinger getPingerPeer(const QString &path = "/") + { + QDBusConnection con = QDBusConnection("peer"); + if (!con.isConnected()) + return Pinger(); + return Pinger(new com::trolltech::QtDBus::Pinger("", path, con)); + } + + void resetServer() + { + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "reset"); + QDBusConnection::sessionBus().send(req); + } + public: tst_QDBusAbstractInterface(); private slots: void initTestCase(); + void cleanupTestCase(); void makeVoidCall(); void makeStringCall(); void makeComplexCall(); void makeMultiOutCall(); + void makeVoidCallPeer(); + void makeStringCallPeer(); + void makeComplexCallPeer(); + void makeMultiOutCallPeer(); + void makeAsyncVoidCall(); void makeAsyncStringCall(); void makeAsyncComplexCall(); void makeAsyncMultiOutCall(); + void makeAsyncVoidCallPeer(); + void makeAsyncStringCallPeer(); + void makeAsyncComplexCallPeer(); + void makeAsyncMultiOutCallPeer(); + void stringPropRead(); void stringPropWrite(); void variantPropRead(); @@ -89,6 +118,13 @@ private slots: void complexPropRead(); void complexPropWrite(); + void stringPropReadPeer(); + void stringPropWritePeer(); + void variantPropReadPeer(); + void variantPropWritePeer(); + void complexPropReadPeer(); + void complexPropWritePeer(); + void stringPropDirectRead(); void stringPropDirectWrite(); void variantPropDirectRead(); @@ -96,6 +132,13 @@ private slots: void complexPropDirectRead(); void complexPropDirectWrite(); + void stringPropDirectReadPeer(); + void stringPropDirectWritePeer(); + void variantPropDirectReadPeer(); + void variantPropDirectWritePeer(); + void complexPropDirectReadPeer(); + void complexPropDirectWritePeer(); + void getVoidSignal_data(); void getVoidSignal(); void getStringSignal_data(); @@ -103,16 +146,31 @@ private slots: void getComplexSignal_data(); void getComplexSignal(); + void getVoidSignalPeer_data(); + void getVoidSignalPeer(); + void getStringSignalPeer_data(); + void getStringSignalPeer(); + void getComplexSignalPeer_data(); + void getComplexSignalPeer(); + void followSignal(); void createErrors_data(); void createErrors(); + void createErrorsPeer_data(); + void createErrorsPeer(); + void callErrors_data(); void callErrors(); void asyncCallErrors_data(); void asyncCallErrors(); + void callErrorsPeer_data(); + void callErrorsPeer(); + void asyncCallErrorsPeer_data(); + void asyncCallErrorsPeer(); + void propertyReadErrors_data(); void propertyReadErrors(); void propertyWriteErrors_data(); @@ -121,8 +179,53 @@ private slots: void directPropertyReadErrors(); void directPropertyWriteErrors_data(); void directPropertyWriteErrors(); + + void propertyReadErrorsPeer_data(); + void propertyReadErrorsPeer(); + void propertyWriteErrorsPeer_data(); + void propertyWriteErrorsPeer(); + void directPropertyReadErrorsPeer_data(); + void directPropertyReadErrorsPeer(); + void directPropertyWriteErrorsPeer_data(); + void directPropertyWriteErrorsPeer(); +private: + QProcess proc; +}; + +class WaitForQPinger: public QObject +{ + Q_OBJECT +public: + WaitForQPinger(); + bool ok(); +public Q_SLOTS: + void ownerChange(const QString &name) + { + if (name == serviceName) + loop.quit(); + } + +private: + QEventLoop loop; }; +WaitForQPinger::WaitForQPinger() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + if (!ok()) { + connect(con.interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), + SLOT(ownerChange(QString))); + QTimer::singleShot(2000, &loop, SLOT(quit())); + loop.exec(); + } +} + +bool WaitForQPinger::ok() +{ + return QDBusConnection::sessionBus().isConnected() && + QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName); +} + tst_QDBusAbstractInterface::tst_QDBusAbstractInterface() { // register the meta types @@ -139,6 +242,39 @@ void tst_QDBusAbstractInterface::initTestCase() QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); con.registerObject("/", &targetObj, QDBusConnection::ExportScriptableContents); + + // start peer server + #ifdef Q_OS_WIN + proc.start("qpinger"); + #else + proc.start("./qpinger/qpinger"); + #endif + QVERIFY(proc.waitForStarted()); + + WaitForQPinger w; + QVERIFY(w.ok()); + //QTest::qWait(2000); + + // get peer server address + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "address"); + QDBusMessage rpl = con.call(req); + QVERIFY(rpl.type() == QDBusMessage::ReplyMessage); + QString address = rpl.arguments().at(0).toString(); + + // connect to peer server + QDBusConnection peercon = QDBusConnection::connectToPeer(address, "peer"); + QVERIFY(peercon.isConnected()); + + QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "isConnected"); + QDBusMessage rpl2 = con.call(req2); + QVERIFY(rpl2.type() == QDBusMessage::ReplyMessage); + QVERIFY(rpl2.arguments().at(0).toBool()); +} + +void tst_QDBusAbstractInterface::cleanupTestCase() +{ + proc.close(); + proc.kill(); } void tst_QDBusAbstractInterface::makeVoidCall() @@ -184,6 +320,49 @@ void tst_QDBusAbstractInterface::makeMultiOutCall() QCOMPARE(value, expectedValue); } +void tst_QDBusAbstractInterface::makeVoidCallPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusReply<void> r = p->voidMethod(); + QVERIFY(r.isValid()); +} + +void tst_QDBusAbstractInterface::makeStringCallPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusReply<QString> r = p->stringMethod(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.stringMethod()); +} + +void tst_QDBusAbstractInterface::makeComplexCallPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusReply<RegisteredType> r = p->complexMethod(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.complexMethod()); +} + +void tst_QDBusAbstractInterface::makeMultiOutCallPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + + int value; + QDBusReply<QString> r = p->multiOutMethod(value); + QVERIFY(r.isValid()); + + int expectedValue; + QCOMPARE(r.value(), targetObj.multiOutMethod(expectedValue)); + QCOMPARE(value, expectedValue); +} + void tst_QDBusAbstractInterface::makeAsyncVoidCall() { Pinger p = getPinger(); @@ -230,6 +409,55 @@ void tst_QDBusAbstractInterface::makeAsyncMultiOutCall() QCOMPARE(r.argumentAt<1>(), expectedValue); } +void tst_QDBusAbstractInterface::makeAsyncVoidCallPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply<void> r = p->voidMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); +} +void tst_QDBusAbstractInterface::makeAsyncStringCallPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusMessage reply = p->call(QDBus::BlockWithGui, QLatin1String("voidMethod")); + QVERIFY(reply.type() == QDBusMessage::ReplyMessage); + + QDBusPendingReply<QString> r = p->stringMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.stringMethod()); +} + +void tst_QDBusAbstractInterface::makeAsyncComplexCallPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply<RegisteredType> r = p->complexMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.complexMethod()); +} + +void tst_QDBusAbstractInterface::makeAsyncMultiOutCallPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply<QString, int> r = p->multiOutMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); + + int expectedValue; + QCOMPARE(r.value(), targetObj.multiOutMethod(expectedValue)); + QCOMPARE(r.argumentAt<1>(), expectedValue); + QCoreApplication::instance()->processEvents(); +} + void tst_QDBusAbstractInterface::stringPropRead() { Pinger p = getPinger(); @@ -295,6 +523,77 @@ void tst_QDBusAbstractInterface::complexPropWrite() QCOMPARE(targetObj.m_complexProp, expectedValue); } +void tst_QDBusAbstractInterface::stringPropReadPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + resetServer(); + + QString expectedValue = "This is a test"; + QVariant v = p->property("stringProp"); + QVERIFY(v.isValid()); + QCOMPARE(v.toString(), expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropWritePeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + resetServer(); + + QString expectedValue = "This is a value"; + QVERIFY(p->setProperty("stringProp", expectedValue)); + QCOMPARE(targetObj.m_stringProp, expectedValue); +} + +void tst_QDBusAbstractInterface::variantPropReadPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + resetServer(); + + QDBusVariant expectedValue = QDBusVariant(QVariant(42)); + QVariant v = p->property("variantProp"); + QVERIFY(v.isValid()); + QDBusVariant value = v.value<QDBusVariant>(); + QCOMPARE(value.variant().userType(), expectedValue.variant().userType()); + QCOMPARE(value.variant(), expectedValue.variant()); +} + +void tst_QDBusAbstractInterface::variantPropWritePeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + resetServer(); + + QDBusVariant expectedValue = QDBusVariant(Q_INT64_C(-47)); + QVERIFY(p->setProperty("variantProp", qVariantFromValue(expectedValue))); + QCOMPARE(targetObj.m_variantProp.variant(), expectedValue.variant()); +} + +void tst_QDBusAbstractInterface::complexPropReadPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + resetServer(); + + RegisteredType expectedValue = RegisteredType("This is a test"); + QVariant v = p->property("complexProp"); + QVERIFY(v.userType() == qMetaTypeId<RegisteredType>()); + QCOMPARE(v.value<RegisteredType>(), expectedValue); +} + +void tst_QDBusAbstractInterface::complexPropWritePeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + resetServer(); + + RegisteredType expectedValue = RegisteredType("This is a value"); + QVERIFY(p->setProperty("complexProp", qVariantFromValue(expectedValue))); + QCOMPARE(targetObj.m_complexProp, expectedValue); +} + void tst_QDBusAbstractInterface::stringPropDirectRead() { Pinger p = getPinger(); @@ -353,6 +652,70 @@ void tst_QDBusAbstractInterface::complexPropDirectWrite() QCOMPARE(targetObj.m_complexProp, expectedValue); } +void tst_QDBusAbstractInterface::stringPropDirectReadPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + resetServer(); + + QString expectedValue = "This is a test"; + QCOMPARE(p->stringProp(), expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropDirectWritePeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + resetServer(); + + QString expectedValue = "This is a value"; + p->setStringProp(expectedValue); + QCOMPARE(targetObj.m_stringProp, expectedValue); +} + +void tst_QDBusAbstractInterface::variantPropDirectReadPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + resetServer(); + + QDBusVariant expectedValue = QDBusVariant(42); + QCOMPARE(p->variantProp().variant(), expectedValue.variant()); +} + +void tst_QDBusAbstractInterface::variantPropDirectWritePeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + resetServer(); + + QDBusVariant expectedValue = QDBusVariant(Q_INT64_C(-47)); + p->setVariantProp(expectedValue); + QCOMPARE(targetObj.m_variantProp.variant().userType(), expectedValue.variant().userType()); + QCOMPARE(targetObj.m_variantProp.variant(), expectedValue.variant()); +} + +void tst_QDBusAbstractInterface::complexPropDirectReadPeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + resetServer(); + + RegisteredType expectedValue = RegisteredType("This is a test"); + QCOMPARE(p->complexProp(), expectedValue); +} + +void tst_QDBusAbstractInterface::complexPropDirectWritePeer() +{ + Pinger p = getPingerPeer(); + QVERIFY2(p, "Not connected to D-Bus"); + resetServer(); + + RegisteredType expectedValue = RegisteredType("This is a value"); + p->setComplexProp(expectedValue); + QCOMPARE(targetObj.m_complexProp, expectedValue); +} + void tst_QDBusAbstractInterface::getVoidSignal_data() { QTest::addColumn<QString>("service"); @@ -437,6 +800,89 @@ void tst_QDBusAbstractInterface::getComplexSignal() QCOMPARE(s[0][0].value<RegisteredType>(), expectedValue); } +void tst_QDBusAbstractInterface::getVoidSignalPeer_data() +{ + QTest::addColumn<QString>("path"); + + QTest::newRow("specific") << "/"; + QTest::newRow("wildcard") << QString(); +} + +void tst_QDBusAbstractInterface::getVoidSignalPeer() +{ + QFETCH(QString, path); + Pinger p = getPingerPeer(path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(voidSignal()), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(voidSignal())); + + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "voidSignal"); + QVERIFY(QDBusConnection::sessionBus().send(req)); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(s.size() == 1); + QVERIFY(s.at(0).size() == 0); +} + +void tst_QDBusAbstractInterface::getStringSignalPeer_data() +{ + getVoidSignalPeer_data(); +} + +void tst_QDBusAbstractInterface::getStringSignalPeer() +{ + QFETCH(QString, path); + Pinger p = getPingerPeer(path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(stringSignal(QString)), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(stringSignal(QString))); + + QString expectedValue = "Good morning"; + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "stringSignal"); + req << expectedValue; + QVERIFY(QDBusConnection::sessionBus().send(req)); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(s.size() == 1); + QVERIFY(s[0].size() == 1); + QCOMPARE(s[0][0].userType(), int(QVariant::String)); + QCOMPARE(s[0][0].toString(), expectedValue); +} + +void tst_QDBusAbstractInterface::getComplexSignalPeer_data() +{ + getVoidSignalPeer_data(); +} + +void tst_QDBusAbstractInterface::getComplexSignalPeer() +{ + QFETCH(QString, path); + Pinger p = getPingerPeer(path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(complexSignal(RegisteredType)), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(complexSignal(RegisteredType))); + + RegisteredType expectedValue("Good evening"); + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "complexSignal"); + req << "Good evening"; + QVERIFY(QDBusConnection::sessionBus().send(req)); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(s.size() == 1); + QVERIFY(s[0].size() == 1); + QCOMPARE(s[0][0].userType(), qMetaTypeId<RegisteredType>()); + QCOMPARE(s[0][0].value<RegisteredType>(), expectedValue); +} + void tst_QDBusAbstractInterface::followSignal() { const QString serviceToFollow = "com.trolltech.tst_qdbusabstractinterface.FollowMe"; @@ -514,6 +960,24 @@ void tst_QDBusAbstractInterface::createErrors() QTEST(p->lastError().name(), "errorName"); } +void tst_QDBusAbstractInterface::createErrorsPeer_data() +{ + QTest::addColumn<QString>("path"); + QTest::addColumn<QString>("errorName"); + + QTest::newRow("invalid-path") << "this isn't valid" << "com.trolltech.QtDBus.Error.InvalidObjectPath"; +} + +void tst_QDBusAbstractInterface::createErrorsPeer() +{ + QFETCH(QString, path); + Pinger p = getPingerPeer(path); + QVERIFY2(p, "Not connected to D-Bus"); + + QVERIFY(!p->isValid()); + QTEST(p->lastError().name(), "errorName"); +} + void tst_QDBusAbstractInterface::callErrors_data() { createErrors_data(); @@ -556,6 +1020,43 @@ void tst_QDBusAbstractInterface::asyncCallErrors() QCOMPARE(p->lastError().name(), r.error().name()); } +void tst_QDBusAbstractInterface::callErrorsPeer_data() +{ + createErrorsPeer_data(); + QTest::newRow("path-wildcard") << QString() << "com.trolltech.QtDBus.Error.InvalidObjectPath"; +} + +void tst_QDBusAbstractInterface::callErrorsPeer() +{ + QFETCH(QString, path); + Pinger p = getPingerPeer(path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to make this call: + QDBusReply<QString> r = p->stringMethod(); + QVERIFY(!r.isValid()); + QTEST(r.error().name(), "errorName"); + QCOMPARE(p->lastError().name(), r.error().name()); +} + +void tst_QDBusAbstractInterface::asyncCallErrorsPeer_data() +{ + callErrorsPeer_data(); +} + +void tst_QDBusAbstractInterface::asyncCallErrorsPeer() +{ + QFETCH(QString, path); + Pinger p = getPingerPeer(path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to make this call: + QDBusPendingReply<QString> r = p->stringMethod(); + QVERIFY(r.isError()); + QTEST(r.error().name(), "errorName"); + QCOMPARE(p->lastError().name(), r.error().name()); +} + void tst_QDBusAbstractInterface::propertyReadErrors_data() { callErrors_data(); @@ -632,5 +1133,77 @@ void tst_QDBusAbstractInterface::directPropertyWriteErrors() QTEST(p->lastError().name(), "errorName"); } +void tst_QDBusAbstractInterface::propertyReadErrorsPeer_data() +{ + callErrorsPeer_data(); +} + +void tst_QDBusAbstractInterface::propertyReadErrorsPeer() +{ + QFETCH(QString, path); + Pinger p = getPingerPeer(path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + QVariant v = p->property("stringProp"); + QVERIFY(v.isNull()); + QVERIFY(!v.isValid()); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::propertyWriteErrorsPeer_data() +{ + callErrorsPeer_data(); +} + +void tst_QDBusAbstractInterface::propertyWriteErrorsPeer() +{ + QFETCH(QString, path); + Pinger p = getPingerPeer(path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + if (p->isValid()) + QCOMPARE(int(p->lastError().type()), int(QDBusError::NoError)); + QVERIFY(!p->setProperty("stringProp", "")); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::directPropertyReadErrorsPeer_data() +{ + callErrorsPeer_data(); +} + +void tst_QDBusAbstractInterface::directPropertyReadErrorsPeer() +{ + QFETCH(QString, path); + Pinger p = getPingerPeer(path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + QString v = p->stringProp(); + QVERIFY(v.isNull()); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::directPropertyWriteErrorsPeer_data() +{ + callErrorsPeer_data(); +} + +void tst_QDBusAbstractInterface::directPropertyWriteErrorsPeer() +{ + QFETCH(QString, path); + Pinger p = getPingerPeer(path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + // but there's no direct way of verifying that the setting failed + if (p->isValid()) + QCOMPARE(int(p->lastError().type()), int(QDBusError::NoError)); + p->setStringProp(""); + QTEST(p->lastError().name(), "errorName"); +} + QTEST_MAIN(tst_QDBusAbstractInterface) #include "tst_qdbusabstractinterface.moc" diff --git a/tests/auto/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/qdbusconnection/tst_qdbusconnection.cpp index 73afcde..e06e3a8 100644 --- a/tests/auto/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/qdbusconnection/tst_qdbusconnection.cpp @@ -86,6 +86,7 @@ public slots: private slots: void noConnection(); void connectToBus(); + void connectToPeer(); void connect(); void send(); void sendWithGui(); @@ -94,9 +95,13 @@ private slots: void registerObject_data(); void registerObject(); + void registerObjectPeer_data(); + void registerObjectPeer(); void registerObject2(); + void registerObjectPeer2(); void registerQObjectChildren(); + void registerQObjectChildrenPeer(); void callSelf(); void callSelfByAnotherName_data(); @@ -111,6 +116,7 @@ private slots: public: QString serviceName() const { return "com.trolltech.Qt.Autotests.QDBusConnection"; } bool callMethod(const QDBusConnection &conn, const QString &path); + bool callMethodPeer(const QDBusConnection &conn, const QString &path); }; class QDBusSpy: public QObject @@ -259,6 +265,14 @@ void tst_QDBusConnection::connectToBus() QVERIFY(!con.lastError().isValid()); } + QDBusConnection::disconnectFromPeer("bubu"); + + { + QDBusConnection con("bubu"); + QVERIFY(con.isConnected()); + QVERIFY(!con.lastError().isValid()); + } + QDBusConnection::disconnectFromBus("bubu"); { @@ -277,6 +291,65 @@ void tst_QDBusConnection::connectToBus() } } +void tst_QDBusConnection::connectToPeer() +{ + { + QDBusConnection con = QDBusConnection::connectToPeer( + "", "newconn"); + QVERIFY(!con.isConnected()); + QVERIFY(con.lastError().isValid()); + } + + QDBusServer server("unix:tmpdir=/tmp", 0); + + { + QDBusConnection con = QDBusConnection::connectToPeer( + "unix:abstract=/tmp/dbus-XXXXXXXXXX,guid=00000000000000000000000000000000", "newconn2"); + QVERIFY(!con.isConnected()); + QVERIFY(con.lastError().isValid()); + } + + { + QDBusConnection con = QDBusConnection::connectToPeer( + server.address(), "bubu"); + + QVERIFY(con.isConnected()); + QVERIFY(!con.lastError().isValid()); + + QDBusConnection con2("foo"); + QVERIFY(!con2.isConnected()); + QVERIFY(!con2.lastError().isValid()); + + con2 = con; + QVERIFY(con.isConnected()); + QVERIFY(con2.isConnected()); + QVERIFY(!con.lastError().isValid()); + QVERIFY(!con2.lastError().isValid()); + } + + { + QDBusConnection con("bubu"); + QVERIFY(con.isConnected()); + QVERIFY(!con.lastError().isValid()); + } + + QDBusConnection::disconnectFromBus("bubu"); + + { + QDBusConnection con("bubu"); + QVERIFY(con.isConnected()); + QVERIFY(!con.lastError().isValid()); + } + + QDBusConnection::disconnectFromPeer("bubu"); + + { + QDBusConnection con("bubu"); + QVERIFY(!con.isConnected()); + QVERIFY(!con.lastError().isValid()); + } +} + void tst_QDBusConnection::registerObject_data() { QTest::addColumn<QString>("path"); @@ -308,6 +381,106 @@ void tst_QDBusConnection::registerObject() QVERIFY(!callMethod(con, path)); } +class MyServer : public QDBusServer +{ + Q_OBJECT +public: + MyServer(QString path, QString addr, QObject* parent) : QDBusServer(addr, parent), + m_path(path), + m_conn("none") + { + connect(this, SIGNAL(newConnection(const QDBusConnection&)), SLOT(handleConnection(const QDBusConnection&))); + } + + bool registerObject() + { + if( !m_conn.registerObject(m_path, &m_obj, QDBusConnection::ExportAllSlots) ) + return false; + if(! (m_conn.objectRegisteredAt(m_path) == &m_obj)) + return false; + return true; + } + + void unregisterObject() + { + m_conn.unregisterObject(m_path); + } + +public slots: + void handleConnection(const QDBusConnection& c) + { + m_conn = c; + QVERIFY(isConnected()); + QVERIFY(m_conn.isConnected()); + QVERIFY(registerObject()); + } + +private: + MyObject m_obj; + QString m_path; + QDBusConnection m_conn; +}; + + +void tst_QDBusConnection::registerObjectPeer_data() +{ + QTest::addColumn<QString>("path"); + + QTest::newRow("/") << "/"; + QTest::newRow("/p1") << "/p1"; + QTest::newRow("/p2") << "/p2"; + QTest::newRow("/p1/q") << "/p1/q"; + QTest::newRow("/p1/q/r") << "/p1/q/r"; +} + +void tst_QDBusConnection::registerObjectPeer() +{ + QFETCH(QString, path); + + MyServer server(path, "unix:tmpdir=/tmp", 0); + + { + QDBusConnection con = QDBusConnection::connectToPeer(server.address(), "foo"); + + QCoreApplication::processEvents(); + QVERIFY(con.isConnected()); + + MyObject obj; + QVERIFY(callMethodPeer(con, path)); + QCOMPARE(obj.path, path); + } + + { + QDBusConnection con("foo"); + QVERIFY(con.isConnected()); + QVERIFY(callMethodPeer(con, path)); + } + + server.unregisterObject(); + + { + QDBusConnection con("foo"); + QVERIFY(con.isConnected()); + QVERIFY(!callMethodPeer(con, path)); + } + + server.registerObject(); + + { + QDBusConnection con("foo"); + QVERIFY(con.isConnected()); + QVERIFY(callMethodPeer(con, path)); + } + + QDBusConnection::disconnectFromPeer("foo"); + + { + QDBusConnection con("foo"); + QVERIFY(!con.isConnected()); + QVERIFY(!callMethodPeer(con, path)); + } +} + void tst_QDBusConnection::registerObject2() { QDBusConnection con = QDBusConnection::sessionBus(); @@ -401,6 +574,134 @@ void tst_QDBusConnection::registerObject2() } } +class MyServer2 : public QDBusServer +{ + Q_OBJECT +public: + MyServer2(QString addr, QObject* parent) : QDBusServer(addr, parent), + m_conn("none") + { + connect(this, SIGNAL(newConnection(const QDBusConnection&)), SLOT(handleConnection(const QDBusConnection&))); + } + + QDBusConnection connection() + { + return m_conn; + } + +public slots: + void handleConnection(const QDBusConnection& c) + { + m_conn = c; + QVERIFY(isConnected()); + QVERIFY(m_conn.isConnected()); + } + +private: + MyObject m_obj; + QDBusConnection m_conn; +}; + +void tst_QDBusConnection::registerObjectPeer2() +{ + MyServer2 server("unix:tmpdir=/tmp", 0); + QDBusConnection con = QDBusConnection::connectToPeer(server.address(), "foo"); + QCoreApplication::processEvents(); + QVERIFY(con.isConnected()); + + QDBusConnection srv_con = server.connection(); + + // make sure nothing is using our paths: + QVERIFY(!callMethodPeer(srv_con, "/")); + QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY(!callMethodPeer(srv_con, "/p2")); + QVERIFY(!callMethodPeer(srv_con, "/p1/q")); + QVERIFY(!callMethodPeer(srv_con, "/p1/q/r")); + + { + // register one object at root: + MyObject obj; + QVERIFY(con.registerObject("/", &obj, QDBusConnection::ExportAllSlots)); + QVERIFY(callMethodPeer(srv_con, "/")); + qDebug() << obj.path; + QCOMPARE(obj.path, QString("/")); + } + // make sure it's gone + QVERIFY(!callMethodPeer(srv_con, "/")); + + { + // register one at an element: + MyObject obj; + QVERIFY(con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots)); + QVERIFY(!callMethodPeer(srv_con, "/")); + QVERIFY(callMethodPeer(srv_con, "/p1")); + qDebug() << obj.path; + QCOMPARE(obj.path, QString("/p1")); + + // re-register it somewhere else + QVERIFY(con.registerObject("/p2", &obj, QDBusConnection::ExportAllSlots)); + QVERIFY(callMethodPeer(srv_con, "/p1")); + QCOMPARE(obj.path, QString("/p1")); + QVERIFY(callMethodPeer(srv_con, "/p2")); + QCOMPARE(obj.path, QString("/p2")); + } + // make sure it's gone + QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY(!callMethodPeer(srv_con, "/p2")); + + { + // register at a deep path + MyObject obj; + QVERIFY(con.registerObject("/p1/q/r", &obj, QDBusConnection::ExportAllSlots)); + QVERIFY(!callMethodPeer(srv_con, "/")); + QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY(!callMethodPeer(srv_con, "/p1/q")); + QVERIFY(callMethodPeer(srv_con, "/p1/q/r")); + QCOMPARE(obj.path, QString("/p1/q/r")); + } + // make sure it's gone + QVERIFY(!callMethodPeer(srv_con, "/p1/q/r")); + + { + MyObject obj; + QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots)); + QVERIFY(callMethodPeer(srv_con, "/p1/q2")); + QCOMPARE(obj.path, QString("/p1/q2")); + + // try unregistering + con.unregisterObject("/p1/q2"); + QVERIFY(!callMethodPeer(srv_con, "/p1/q2")); + + // register it again + QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots)); + QVERIFY(callMethodPeer(srv_con, "/p1/q2")); + QCOMPARE(obj.path, QString("/p1/q2")); + + // now try removing things around it: + con.unregisterObject("/p2"); + QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unrelated object shouldn't affect + + con.unregisterObject("/p1"); + QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering just the parent shouldn't affect it + + con.unregisterObject("/p1/q2/r"); + QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering non-existing child shouldn't affect it either + + con.unregisterObject("/p1/q"); + QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering sibling (before) shouldn't affect + + con.unregisterObject("/p1/r"); + QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering sibling (after) shouldn't affect + + // now remove it: + con.unregisterObject("/p1", QDBusConnection::UnregisterTree); + QVERIFY(!callMethodPeer(srv_con, "/p1/q2")); // we removed the full tree + } + + QDBusConnection::disconnectFromPeer("foo"); +} + + void tst_QDBusConnection::registerQObjectChildren() { // make sure no one is there @@ -456,6 +757,68 @@ void tst_QDBusConnection::registerQObjectChildren() QVERIFY(!callMethod(con, "/p1/c/cc")); } +void tst_QDBusConnection::registerQObjectChildrenPeer() +{ + MyServer2 server("unix:tmpdir=/tmp", 0); + QDBusConnection con = QDBusConnection::connectToPeer(server.address(), "foo"); + QCoreApplication::processEvents(); + QVERIFY(con.isConnected()); + + QDBusConnection srv_con = server.connection(); + + QVERIFY(!callMethodPeer(srv_con, "/p1")); + + { + MyObject obj, *a, *b, *c, *cc; + + a = new MyObject(&obj); + a->setObjectName("a"); + + b = new MyObject(&obj); + b->setObjectName("b"); + + c = new MyObject(&obj); + c->setObjectName("c"); + + cc = new MyObject(c); + cc->setObjectName("cc"); + + con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots | + QDBusConnection::ExportChildObjects); + + // make calls + QVERIFY(callMethodPeer(srv_con, "/p1")); + QCOMPARE(obj.callCount, 1); + QVERIFY(callMethodPeer(srv_con, "/p1/a")); + QCOMPARE(a->callCount, 1); + QVERIFY(callMethodPeer(srv_con, "/p1/b")); + QCOMPARE(b->callCount, 1); + QVERIFY(callMethodPeer(srv_con, "/p1/c")); + QCOMPARE(c->callCount, 1); + QVERIFY(callMethodPeer(srv_con, "/p1/c/cc")); + QCOMPARE(cc->callCount, 1); + + QVERIFY(!callMethodPeer(srv_con, "/p1/d")); + QVERIFY(!callMethodPeer(srv_con, "/p1/c/abc")); + + // pull an object, see if it goes away: + delete b; + QVERIFY(!callMethodPeer(srv_con, "/p1/b")); + + delete c; + QVERIFY(!callMethodPeer(srv_con, "/p1/c")); + QVERIFY(!callMethodPeer(srv_con, "/p1/c/cc")); + } + + QVERIFY(!callMethodPeer(srv_con, "/p1")); + QVERIFY(!callMethodPeer(srv_con, "/p1/a")); + QVERIFY(!callMethodPeer(srv_con, "/p1/b")); + QVERIFY(!callMethodPeer(srv_con, "/p1/c")); + QVERIFY(!callMethodPeer(srv_con, "/p1/c/cc")); + + QDBusConnection::disconnectFromPeer("foo"); +} + bool tst_QDBusConnection::callMethod(const QDBusConnection &conn, const QString &path) { QDBusMessage msg = QDBusMessage::createMethodCall(conn.baseService(), path, "", "method"); @@ -475,6 +838,25 @@ bool tst_QDBusConnection::callMethod(const QDBusConnection &conn, const QString return true; } +bool tst_QDBusConnection::callMethodPeer(const QDBusConnection &conn, const QString &path) +{ + QDBusMessage msg = QDBusMessage::createMethodCall("", path, "", "method"); + QDBusMessage reply = conn.call(msg, QDBus::BlockWithGui); + + if (reply.type() != QDBusMessage::ReplyMessage) + return false; + if (MyObject::path == path) { + QTest::compare_helper(true, "COMPARE()", __FILE__, __LINE__); + } else { + QTest::compare_helper(false, "Compared values are not the same", + QTest::toString(MyObject::path), QTest::toString(path), + "MyObject::path", "path", __FILE__, __LINE__); + return false; + } + + return true; +} + class TestObject : public QObject { Q_OBJECT diff --git a/tests/auto/qdbusinterface/myobject.h b/tests/auto/qdbusinterface/myobject.h new file mode 100644 index 0000000..3959823 --- /dev/null +++ b/tests/auto/qdbusinterface/myobject.h @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MYOBJECT_H +#define MYOBJECT_H + +#include <QtCore/QObject> +#include <QtDBus/QtDBus> + +Q_DECLARE_METATYPE(QVariantList) + +class MyObject: public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.MyObject") + Q_CLASSINFO("D-Bus Introspection", "" +" <interface name=\"com.trolltech.QtDBus.MyObject\" >\n" +" <property access=\"readwrite\" type=\"i\" name=\"prop1\" />\n" +" <property name=\"complexProp\" type=\"ai\" access=\"readwrite\">\n" +" <annotation name=\"com.trolltech.QtDBus.QtTypeName\" value=\"QList<int>\"/>\n" +" </property>\n" +" <signal name=\"somethingHappened\" >\n" +" <arg direction=\"out\" type=\"s\" />\n" +" </signal>\n" +" <method name=\"ping\" >\n" +" <arg direction=\"in\" type=\"v\" name=\"ping\" />\n" +" <arg direction=\"out\" type=\"v\" name=\"ping\" />\n" +" </method>\n" +" <method name=\"ping_invokable\" >\n" +" <arg direction=\"in\" type=\"v\" name=\"ping_invokable\" />\n" +" <arg direction=\"out\" type=\"v\" name=\"ping_invokable\" />\n" +" </method>\n" +" <method name=\"ping\" >\n" +" <arg direction=\"in\" type=\"v\" name=\"ping1\" />\n" +" <arg direction=\"in\" type=\"v\" name=\"ping2\" />\n" +" <arg direction=\"out\" type=\"v\" name=\"pong1\" />\n" +" <arg direction=\"out\" type=\"v\" name=\"pong2\" />\n" +" </method>\n" +" <method name=\"ping_invokable\" >\n" +" <arg direction=\"in\" type=\"v\" name=\"ping1_invokable\" />\n" +" <arg direction=\"in\" type=\"v\" name=\"ping2_invokable\" />\n" +" <arg direction=\"out\" type=\"v\" name=\"pong1_invokable\" />\n" +" <arg direction=\"out\" type=\"v\" name=\"pong2_invokable\" />\n" +" </method>\n" +" <method name=\"ping\" >\n" +" <arg direction=\"in\" type=\"ai\" name=\"ping\" />\n" +" <arg direction=\"out\" type=\"ai\" name=\"ping\" />\n" +" <annotation name=\"com.trolltech.QtDBus.QtTypeName.In0\" value=\"QList<int>\"/>\n" +" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QList<int>\"/>\n" +" </method>\n" +" <method name=\"ping_invokable\" >\n" +" <arg direction=\"in\" type=\"ai\" name=\"ping_invokable\" />\n" +" <arg direction=\"out\" type=\"ai\" name=\"ping_invokable\" />\n" +" <annotation name=\"com.trolltech.QtDBus.QtTypeName.In0\" value=\"QList<int>\"/>\n" +" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QList<int>\"/>\n" +" </method>\n" +" </interface>\n" + "") + Q_PROPERTY(int prop1 READ prop1 WRITE setProp1) + Q_PROPERTY(QList<int> complexProp READ complexProp WRITE setComplexProp) + +public: + static int callCount; + static QVariantList callArgs; + MyObject() + { + QObject *subObject = new QObject(this); + subObject->setObjectName("subObject"); + } + + int m_prop1; + int prop1() const + { + ++callCount; + return m_prop1; + } + void setProp1(int value) + { + ++callCount; + m_prop1 = value; + } + + QList<int> m_complexProp; + QList<int> complexProp() const + { + ++callCount; + return m_complexProp; + } + void setComplexProp(const QList<int> &value) + { + ++callCount; + m_complexProp = value; + } + + Q_INVOKABLE void ping_invokable(QDBusMessage msg) + { + QDBusConnection sender = QDBusConnection::sender(); + if (!sender.isConnected()) + exit(1); + + ++callCount; + callArgs = msg.arguments(); + + msg.setDelayedReply(true); + if (!sender.send(msg.createReply(callArgs))) + exit(1); + } + +public slots: + + void ping(QDBusMessage msg) + { + QDBusConnection sender = QDBusConnection::sender(); + if (!sender.isConnected()) + exit(1); + + ++callCount; + callArgs = msg.arguments(); + + msg.setDelayedReply(true); + if (!sender.send(msg.createReply(callArgs))) + exit(1); + } +}; + +#endif // INTERFACE_H diff --git a/tests/auto/qdbusinterface/qdbusinterface.pro b/tests/auto/qdbusinterface/qdbusinterface.pro index ac14ab7..0aca06c 100644 --- a/tests/auto/qdbusinterface/qdbusinterface.pro +++ b/tests/auto/qdbusinterface/qdbusinterface.pro @@ -1,10 +1,11 @@ load(qttest_p4) QT = core contains(QT_CONFIG,dbus): { - SOURCES += tst_qdbusinterface.cpp - QT += dbus + TEMPLATE = subdirs + CONFIG += ordered + SUBDIRS = qmyserver test } else { - SOURCES += ../qdbusmarshall/dummy.cpp + SOURCES += ../qdbusmarshall/dummy.cpp } diff --git a/tests/auto/qdbusinterface/qmyserver/qmyserver.cpp b/tests/auto/qdbusinterface/qmyserver/qmyserver.cpp new file mode 100644 index 0000000..dd15012 --- /dev/null +++ b/tests/auto/qdbusinterface/qmyserver/qmyserver.cpp @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtCore/QtCore> +#include <QtDBus/QtDBus> + +#include "../myobject.h" + +static const char serviceName[] = "com.trolltech.autotests.qmyserver"; +static const char objectPath[] = "/com/trolltech/qmyserver"; +//static const char *interfaceName = serviceName; + +int MyObject::callCount = 0; +QVariantList MyObject::callArgs; + +class MyServer : public QDBusServer +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.trolltech.autotests.qmyserver") + +public: + MyServer(QString addr = "unix:tmpdir=/tmp", QObject* parent = 0) + : QDBusServer(addr, parent), + m_conn("none") + { + connect(this, SIGNAL(newConnection(const QDBusConnection&)), SLOT(handleConnection(const QDBusConnection&))); + } + +public slots: + QString address() const + { + return QDBusServer::address(); + } + + bool isConnected() const + { + return m_conn.isConnected(); + } + + void emitSignal(const QString &interface, const QString &name, const QString &arg) + { + QDBusMessage msg = QDBusMessage::createSignal("/", interface, name); + msg << arg; + m_conn.send(msg); + } + + void reset() + { + MyObject::callCount = 0; + obj.m_complexProp.clear(); + } + + int callCount() + { + return MyObject::callCount; + } + + QVariantList callArgs() + { + qDebug() << "callArgs" << MyObject::callArgs.count(); + return MyObject::callArgs; + } + + void setProp1(int val) + { + obj.m_prop1 = val; + } + + int prop1() + { + return obj.m_prop1; + } + + void setComplexProp(QList<int> val) + { + obj.m_complexProp = val; + } + + QList<int> complexProp() + { + return obj.m_complexProp; + } + + +private slots: + void handleConnection(const QDBusConnection& con) + { + m_conn = con; + m_conn.registerObject("/", &obj, QDBusConnection::ExportAllProperties + | QDBusConnection::ExportAllSlots + | QDBusConnection::ExportAllInvokables); + } + +private: + QDBusConnection m_conn; + MyObject obj; +}; + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + QDBusConnection con = QDBusConnection::sessionBus(); + if (!con.isConnected()) + exit(1); + + if (!con.registerService(serviceName)) + exit(2); + + MyServer server; + con.registerObject(objectPath, &server, QDBusConnection::ExportAllSlots); + + printf("ready.\n"); + + return app.exec(); +} + +#include "qmyserver.moc"
\ No newline at end of file diff --git a/tests/auto/qdbusinterface/qmyserver/qmyserver.pro b/tests/auto/qdbusinterface/qmyserver/qmyserver.pro new file mode 100644 index 0000000..f4fe02c --- /dev/null +++ b/tests/auto/qdbusinterface/qmyserver/qmyserver.pro @@ -0,0 +1,5 @@ +SOURCES = qmyserver.cpp +HEADERS = ../myobject.h +TARGET = qmyserver +QT += dbus +QT -= gui diff --git a/tests/auto/qdbusinterface/test/test.pro b/tests/auto/qdbusinterface/test/test.pro new file mode 100644 index 0000000..3252188 --- /dev/null +++ b/tests/auto/qdbusinterface/test/test.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +SOURCES += ../tst_qdbusinterface.cpp +HEADERS += ../myobject.h +TARGET = ../tst_qdbusinterface + +QT = core +QT += dbus diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp index f0009f3..96ab311 100644 --- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ /* -*- C++ -*- */ + #include <qcoreapplication.h> #include <qmetatype.h> #include <QtTest/QtTest> @@ -47,125 +48,15 @@ #include <QtDBus/QtDBus> #include "../qdbusmarshall/common.h" - -Q_DECLARE_METATYPE(QVariantList) +#include "myobject.h" #define TEST_INTERFACE_NAME "com.trolltech.QtDBus.MyObject" #define TEST_SIGNAL_NAME "somethingHappened" -class MyObject: public QObject -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.MyObject") - Q_CLASSINFO("D-Bus Introspection", "" -" <interface name=\"com.trolltech.QtDBus.MyObject\" >\n" -" <property access=\"readwrite\" type=\"i\" name=\"prop1\" />\n" -" <property name=\"complexProp\" type=\"ai\" access=\"readwrite\">\n" -" <annotation name=\"com.trolltech.QtDBus.QtTypeName\" value=\"QList<int>\"/>\n" -" </property>\n" -" <signal name=\"somethingHappened\" >\n" -" <arg direction=\"out\" type=\"s\" />\n" -" </signal>\n" -" <method name=\"ping\" >\n" -" <arg direction=\"in\" type=\"v\" name=\"ping\" />\n" -" <arg direction=\"out\" type=\"v\" name=\"ping\" />\n" -" </method>\n" -" <method name=\"ping_invokable\" >\n" -" <arg direction=\"in\" type=\"v\" name=\"ping_invokable\" />\n" -" <arg direction=\"out\" type=\"v\" name=\"ping_invokable\" />\n" -" </method>\n" -" <method name=\"ping\" >\n" -" <arg direction=\"in\" type=\"v\" name=\"ping1\" />\n" -" <arg direction=\"in\" type=\"v\" name=\"ping2\" />\n" -" <arg direction=\"out\" type=\"v\" name=\"pong1\" />\n" -" <arg direction=\"out\" type=\"v\" name=\"pong2\" />\n" -" </method>\n" -" <method name=\"ping_invokable\" >\n" -" <arg direction=\"in\" type=\"v\" name=\"ping1_invokable\" />\n" -" <arg direction=\"in\" type=\"v\" name=\"ping2_invokable\" />\n" -" <arg direction=\"out\" type=\"v\" name=\"pong1_invokable\" />\n" -" <arg direction=\"out\" type=\"v\" name=\"pong2_invokable\" />\n" -" </method>\n" -" <method name=\"ping\" >\n" -" <arg direction=\"in\" type=\"ai\" name=\"ping\" />\n" -" <arg direction=\"out\" type=\"ai\" name=\"ping\" />\n" -" <annotation name=\"com.trolltech.QtDBus.QtTypeName.In0\" value=\"QList<int>\"/>\n" -" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QList<int>\"/>\n" -" </method>\n" -" <method name=\"ping_invokable\" >\n" -" <arg direction=\"in\" type=\"ai\" name=\"ping_invokable\" />\n" -" <arg direction=\"out\" type=\"ai\" name=\"ping_invokable\" />\n" -" <annotation name=\"com.trolltech.QtDBus.QtTypeName.In0\" value=\"QList<int>\"/>\n" -" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QList<int>\"/>\n" -" </method>\n" -" </interface>\n" - "") - Q_PROPERTY(int prop1 READ prop1 WRITE setProp1) - Q_PROPERTY(QList<int> complexProp READ complexProp WRITE setComplexProp) - -public: - static int callCount; - static QVariantList callArgs; - MyObject() - { - QObject *subObject = new QObject(this); - subObject->setObjectName("subObject"); - } +static const char serviceName[] = "com.trolltech.autotests.qmyserver"; +static const char objectPath[] = "/com/trolltech/qmyserver"; +static const char *interfaceName = serviceName; - int m_prop1; - int prop1() const - { - ++callCount; - return m_prop1; - } - void setProp1(int value) - { - ++callCount; - m_prop1 = value; - } - - QList<int> m_complexProp; - QList<int> complexProp() const - { - ++callCount; - return m_complexProp; - } - void setComplexProp(const QList<int> &value) - { - ++callCount; - m_complexProp = value; - } - - Q_INVOKABLE void ping_invokable(QDBusMessage msg) - { - QDBusConnection sender = QDBusConnection::sender(); - if (!sender.isConnected()) - exit(1); - - ++callCount; - callArgs = msg.arguments(); - - msg.setDelayedReply(true); - if (!sender.send(msg.createReply(callArgs))) - exit(1); - } - -public slots: - - void ping(QDBusMessage msg) - { - QDBusConnection sender = QDBusConnection::sender(); - if (!sender.isConnected()) - exit(1); - - ++callCount; - callArgs = msg.arguments(); - - msg.setDelayedReply(true); - if (!sender.send(msg.createReply(callArgs))) - exit(1); - } -}; int MyObject::callCount = 0; QVariantList MyObject::callArgs; @@ -228,10 +119,70 @@ void emitSignal(const QString &interface, const QString &name, const QString &ar QTest::qWait(1000); } +void emitSignalPeer(const QString &interface, const QString &name, const QString &arg) +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "emitSignal"); + req << interface; + req << name; + req << arg; + QDBusConnection::sessionBus().send(req); + + QTest::qWait(1000); +} + +int callCountPeer() +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "callCount"); + QDBusMessage reply = QDBusConnection::sessionBus().call(req); + return reply.arguments().at(0).toInt(); +} + +QVariantList callArgsPeer() +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "callArgs"); + QDBusMessage reply = QDBusConnection::sessionBus().call(req); + return qdbus_cast<QVariantList>(reply.arguments().at(0)); +} + +void setProp1Peer(int val) +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "setProp1"); + req << val; + QDBusMessage reply = QDBusConnection::sessionBus().call(req); +} + +int prop1Peer() +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "prop1"); + QDBusMessage reply = QDBusConnection::sessionBus().call(req); + return reply.arguments().at(0).toInt(); +} + +void setComplexPropPeer(QList<int> val) +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "setComplexProp"); + req << qVariantFromValue(val); + QDBusMessage reply = QDBusConnection::sessionBus().call(req); +} + +QList<int> complexPropPeer() +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "complexProp"); + QDBusMessage reply = QDBusConnection::sessionBus().call(req); + return qdbus_cast<QList<int> >(reply.arguments().at(0)); +} + +void resetPeer() +{ + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "reset"); + QDBusConnection::sessionBus().call(req); +} + class tst_QDBusInterface: public QObject { Q_OBJECT MyObject obj; + public slots: void testServiceOwnerChanged(const QString &service) { @@ -241,6 +192,7 @@ public slots: private slots: void initTestCase(); + void cleanupTestCase(); void notConnected(); void notValid(); @@ -254,14 +206,63 @@ private slots: void invokeMethodWithMultiReturn(); void invokeMethodWithComplexReturn(); + void introspectPeer(); + void callMethodPeer(); + void invokeMethodPeer(); + void invokeMethodWithReturnPeer(); + void invokeMethodWithMultiReturnPeer(); + void invokeMethodWithComplexReturnPeer(); + void signal(); + void signalPeer(); void propertyRead(); void propertyWrite(); void complexPropertyRead(); void complexPropertyWrite(); + + void propertyReadPeer(); + void propertyWritePeer(); + void complexPropertyReadPeer(); + void complexPropertyWritePeer(); +private: + QProcess proc; }; +class WaitForQMyServer: public QObject +{ + Q_OBJECT +public: + WaitForQMyServer(); + bool ok(); +public Q_SLOTS: + void ownerChange(const QString &name) + { + if (name == serviceName) + loop.quit(); + } + +private: + QEventLoop loop; +}; + +WaitForQMyServer::WaitForQMyServer() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + if (!ok()) { + connect(con.interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), + SLOT(ownerChange(QString))); + QTimer::singleShot(2000, &loop, SLOT(quit())); + loop.exec(); + } +} + +bool WaitForQMyServer::ok() +{ + return QDBusConnection::sessionBus().isConnected() && + QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName); +} + void tst_QDBusInterface::initTestCase() { QDBusConnection con = QDBusConnection::sessionBus(); @@ -271,6 +272,39 @@ void tst_QDBusInterface::initTestCase() con.registerObject("/", &obj, QDBusConnection::ExportAllProperties | QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllInvokables); + + // start peer server + #ifdef Q_OS_WIN + proc.start("qmyserver"); + #else + proc.start("./qmyserver/qmyserver"); + #endif + QVERIFY(proc.waitForStarted()); + + WaitForQMyServer w; + QVERIFY(w.ok()); + //QTest::qWait(2000); + + // get peer server address + QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "address"); + QDBusMessage rpl = con.call(req); + QVERIFY(rpl.type() == QDBusMessage::ReplyMessage); + QString address = rpl.arguments().at(0).toString(); + + // connect to peer server + QDBusConnection peercon = QDBusConnection::connectToPeer(address, "peer"); + QVERIFY(peercon.isConnected()); + + QDBusMessage req2 = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "isConnected"); + QDBusMessage rpl2 = con.call(req2); + QVERIFY(rpl2.type() == QDBusMessage::ReplyMessage); + QVERIFY(rpl2.arguments().at(0).toBool()); +} + +void tst_QDBusInterface::cleanupTestCase() +{ + proc.close(); + proc.kill(); } void tst_QDBusInterface::notConnected() @@ -369,7 +403,7 @@ void tst_QDBusInterface::callMethod() TEST_INTERFACE_NAME); MyObject::callCount = 0; - + // call a SLOT method QDBusMessage reply = iface.call("ping", qVariantFromValue(QDBusVariant("foo"))); QCOMPARE(MyObject::callCount, 1); @@ -388,7 +422,7 @@ void tst_QDBusInterface::callMethod() dv = qdbus_cast<QDBusVariant>(v); QCOMPARE(dv.variant().type(), QVariant::String); QCOMPARE(dv.variant().toString(), QString("foo")); - + // call an INVOKABLE method reply = iface.call("ping_invokable", qVariantFromValue(QDBusVariant("bar"))); QCOMPARE(MyObject::callCount, 2); @@ -416,7 +450,7 @@ void tst_QDBusInterface::invokeMethod() TEST_INTERFACE_NAME); MyObject::callCount = 0; - + // make the SLOT call without a return type QDBusVariant arg("foo"); QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_ARG(QDBusVariant, arg))); @@ -428,7 +462,7 @@ void tst_QDBusInterface::invokeMethod() QDBusVariant dv = qdbus_cast<QDBusVariant>(v); QCOMPARE(dv.variant().type(), QVariant::String); QCOMPARE(dv.variant().toString(), QString("foo")); - + // make the INVOKABLE call without a return type QDBusVariant arg2("bar"); QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_ARG(QDBusVariant, arg2))); @@ -465,7 +499,7 @@ void tst_QDBusInterface::invokeMethodWithReturn() // verify that we got the reply as expected QCOMPARE(retArg.variant(), arg.variant()); - + // make the INVOKABLE call without a return type QDBusVariant arg2("bar"); QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg2))); @@ -490,7 +524,7 @@ void tst_QDBusInterface::invokeMethodWithMultiReturn() MyObject::callCount = 0; QDBusVariant retArg, retArg2; - + // make the SLOT call without a return type QDBusVariant arg("foo"), arg2("bar"); QVERIFY(QMetaObject::invokeMethod(&iface, "ping", @@ -515,7 +549,7 @@ void tst_QDBusInterface::invokeMethodWithMultiReturn() // verify that we got the replies as expected QCOMPARE(retArg.variant(), arg.variant()); QCOMPARE(retArg2.variant(), arg2.variant()); - + // make the INVOKABLE call without a return type QDBusVariant arg3("hello"), arg4("world"); QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", @@ -550,7 +584,7 @@ void tst_QDBusInterface::invokeMethodWithComplexReturn() MyObject::callCount = 0; QList<int> retArg; - + // make the SLOT call without a return type QList<int> arg = QList<int>() << 42 << -47; QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg))); @@ -564,7 +598,7 @@ void tst_QDBusInterface::invokeMethodWithComplexReturn() // verify that we got the reply as expected QCOMPARE(retArg, arg); - + // make the INVOKABLE call without a return type QList<int> arg2 = QList<int>() << 24 << -74; QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg2))); @@ -580,6 +614,250 @@ void tst_QDBusInterface::invokeMethodWithComplexReturn() QCOMPARE(retArg, arg2); } +void tst_QDBusInterface::introspectPeer() +{ + QDBusConnection con("peer"); + QDBusInterface iface(QString(), QLatin1String("/"), + TEST_INTERFACE_NAME, con); + + const QMetaObject *mo = iface.metaObject(); + + QCOMPARE(mo->methodCount() - mo->methodOffset(), 7); + QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1); + + QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2); + QVERIFY(mo->indexOfProperty("prop1") != -1); + QVERIFY(mo->indexOfProperty("complexProp") != -1); +} + +void tst_QDBusInterface::callMethodPeer() +{ + QDBusConnection con("peer"); + QDBusInterface iface(QString(), QLatin1String("/"), + TEST_INTERFACE_NAME, con); + + resetPeer(); + + // call a SLOT method + QDBusMessage reply = iface.call("ping", qVariantFromValue(QDBusVariant("foo"))); + QCOMPARE(callCountPeer(), 1); + QCOMPARE(reply.type(), QDBusMessage::ReplyMessage); + + // verify what the callee received + QVariantList callArgs = callArgsPeer(); + QCOMPARE(callArgs.count(), 1); + QVariant v = callArgs.at(0); + QDBusVariant dv = qdbus_cast<QDBusVariant>(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), QString("foo")); + + // verify reply + QCOMPARE(reply.arguments().count(), 1); + v = reply.arguments().at(0); + dv = qdbus_cast<QDBusVariant>(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), QString("foo")); + + // call an INVOKABLE method + reply = iface.call("ping_invokable", qVariantFromValue(QDBusVariant("bar"))); + QCOMPARE(callCountPeer(), 2); + QCOMPARE(reply.type(), QDBusMessage::ReplyMessage); + + // verify what the callee received + callArgs = callArgsPeer(); + QCOMPARE(callArgs.count(), 1); + v = callArgs.at(0); + dv = qdbus_cast<QDBusVariant>(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), QString("bar")); + + // verify reply + QCOMPARE(reply.arguments().count(), 1); + v = reply.arguments().at(0); + dv = qdbus_cast<QDBusVariant>(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), QString("bar")); +} + +void tst_QDBusInterface::invokeMethodPeer() +{ + QDBusConnection con("peer"); + QDBusInterface iface(QString(), QLatin1String("/"), + TEST_INTERFACE_NAME, con); + + resetPeer(); + + // make the SLOT call without a return type + QDBusVariant arg("foo"); + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_ARG(QDBusVariant, arg))); + QCOMPARE(callCountPeer(), 1); + + // verify what the callee received + QVariantList callArgs = callArgsPeer(); + QCOMPARE(callArgs.count(), 1); + QVariant v = callArgs.at(0); + QDBusVariant dv = qdbus_cast<QDBusVariant>(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), QString("foo")); + + // make the INVOKABLE call without a return type + QDBusVariant arg2("bar"); + QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_ARG(QDBusVariant, arg2))); + QCOMPARE(callCountPeer(), 2); + + // verify what the callee received + callArgs = callArgsPeer(); + QCOMPARE(callArgs.count(), 1); + v = callArgs.at(0); + dv = qdbus_cast<QDBusVariant>(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), QString("bar")); +} + +void tst_QDBusInterface::invokeMethodWithReturnPeer() +{ + QDBusConnection con("peer"); + QDBusInterface iface(QString(), QLatin1String("/"), + TEST_INTERFACE_NAME, con); + + resetPeer(); + QDBusVariant retArg; + + // make the SLOT call without a return type + QDBusVariant arg("foo"); + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg))); + QCOMPARE(callCountPeer(), 1); + + // verify what the callee received + QVariantList callArgs = callArgsPeer(); + QCOMPARE(callArgs.count(), 1); + QVariant v = callArgs.at(0); + QDBusVariant dv = qdbus_cast<QDBusVariant>(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg.variant().toString()); + + // verify that we got the reply as expected + QCOMPARE(retArg.variant(), arg.variant()); + + // make the INVOKABLE call without a return type + QDBusVariant arg2("bar"); + QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg2))); + QCOMPARE(callCountPeer(), 2); + + // verify what the callee received + callArgs = callArgsPeer(); + QCOMPARE(callArgs.count(), 1); + v = callArgs.at(0); + dv = qdbus_cast<QDBusVariant>(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg2.variant().toString()); + + // verify that we got the reply as expected + QCOMPARE(retArg.variant(), arg2.variant()); +} + +void tst_QDBusInterface::invokeMethodWithMultiReturnPeer() +{ + QDBusConnection con("peer"); + QDBusInterface iface(QString(), QLatin1String("/"), + TEST_INTERFACE_NAME, con); + + resetPeer(); + QDBusVariant retArg, retArg2; + + // make the SLOT call without a return type + QDBusVariant arg("foo"), arg2("bar"); + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", + Q_RETURN_ARG(QDBusVariant, retArg), + Q_ARG(QDBusVariant, arg), + Q_ARG(QDBusVariant, arg2), + Q_ARG(QDBusVariant&, retArg2))); + QCOMPARE(callCountPeer(), 1); + + // verify what the callee received + QVariantList callArgs = callArgsPeer(); + QCOMPARE(callArgs.count(), 2); + QVariant v = callArgs.at(0); + QDBusVariant dv = qdbus_cast<QDBusVariant>(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg.variant().toString()); + + v = callArgs.at(1); + dv = qdbus_cast<QDBusVariant>(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg2.variant().toString()); + + // verify that we got the replies as expected + QCOMPARE(retArg.variant(), arg.variant()); + QCOMPARE(retArg2.variant(), arg2.variant()); + + // make the INVOKABLE call without a return type + QDBusVariant arg3("hello"), arg4("world"); + QVERIFY(QMetaObject::invokeMethod(&iface, "ping_invokable", + Q_RETURN_ARG(QDBusVariant, retArg), + Q_ARG(QDBusVariant, arg3), + Q_ARG(QDBusVariant, arg4), + Q_ARG(QDBusVariant&, retArg2))); + QCOMPARE(callCountPeer(), 2); + + // verify what the callee received + callArgs = callArgsPeer(); + QCOMPARE(callArgs.count(), 2); + v = callArgs.at(0); + dv = qdbus_cast<QDBusVariant>(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg3.variant().toString()); + + v = callArgs.at(1); + dv = qdbus_cast<QDBusVariant>(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg4.variant().toString()); + + // verify that we got the replies as expected + QCOMPARE(retArg.variant(), arg3.variant()); + QCOMPARE(retArg2.variant(), arg4.variant()); +} + +void tst_QDBusInterface::invokeMethodWithComplexReturnPeer() +{ + QDBusConnection con("peer"); + QDBusInterface iface(QString(), QLatin1String("/"), + TEST_INTERFACE_NAME, con); + + resetPeer(); + QList<int> retArg; + + // make the SLOT call without a return type + QList<int> arg = QList<int>() << 42 << -47; + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg))); + QCOMPARE(callCountPeer(), 1); + + // verify what the callee received + QVariantList callArgs = callArgsPeer(); + QCOMPARE(callArgs.count(), 1); + QVariant v = callArgs.at(0); + QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>()); + QCOMPARE(qdbus_cast<QList<int> >(v), arg); + + // verify that we got the reply as expected + QCOMPARE(retArg, arg); + + // make the INVOKABLE call without a return type + QList<int> arg2 = QList<int>() << 24 << -74; + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList<int>, retArg), Q_ARG(QList<int>, arg2))); + QCOMPARE(callCountPeer(), 2); + + // verify what the callee received + callArgs = callArgsPeer(); + QCOMPARE(callArgs.count(), 1); + v = callArgs.at(0); + QCOMPARE(v.userType(), qMetaTypeId<QDBusArgument>()); + QCOMPARE(qdbus_cast<QList<int> >(v), arg2); + + // verify that we got the reply as expected + QCOMPARE(retArg, arg2); +} + void tst_QDBusInterface::signal() { QDBusConnection con = QDBusConnection::sessionBus(); @@ -621,6 +899,47 @@ void tst_QDBusInterface::signal() } } +void tst_QDBusInterface::signalPeer() +{ + QDBusConnection con("peer"); + QDBusInterface iface(QString(), QLatin1String("/"), + TEST_INTERFACE_NAME, con); + + QString arg = "So long and thanks for all the fish"; + { + Spy spy; + spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString))); + + emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg); + QCOMPARE(spy.count, 1); + QCOMPARE(spy.received, arg); + } + + QDBusInterface iface2(QString(), QLatin1String("/"), + TEST_INTERFACE_NAME, con); + { + Spy spy; + spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString))); + spy.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString))); + + emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg); + QCOMPARE(spy.count, 2); + QCOMPARE(spy.received, arg); + } + + { + Spy spy, spy2; + spy.connect(&iface, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString))); + spy2.connect(&iface2, SIGNAL(somethingHappened(QString)), SLOT(spySlot(QString))); + + emitSignalPeer(TEST_INTERFACE_NAME, TEST_SIGNAL_NAME, arg); + QCOMPARE(spy.count, 1); + QCOMPARE(spy.received, arg); + QCOMPARE(spy2.count, 1); + QCOMPARE(spy2.received, arg); + } +} + void tst_QDBusInterface::propertyRead() { QDBusConnection con = QDBusConnection::sessionBus(); @@ -683,7 +1002,69 @@ void tst_QDBusInterface::complexPropertyWrite() QCOMPARE(obj.m_complexProp, arg); } +void tst_QDBusInterface::propertyReadPeer() +{ + QDBusConnection con("peer"); + QDBusInterface iface(QString(), QLatin1String("/"), + TEST_INTERFACE_NAME, con); + + resetPeer(); + int arg = 42; + setProp1Peer(42); + + QVariant v = iface.property("prop1"); + QVERIFY(v.isValid()); + QCOMPARE(v.userType(), int(QVariant::Int)); + QCOMPARE(v.toInt(), arg); + QCOMPARE(callCountPeer(), 1); +} + +void tst_QDBusInterface::propertyWritePeer() +{ + QDBusConnection con("peer"); + QDBusInterface iface(QString(), QLatin1String("/"), + TEST_INTERFACE_NAME, con); + + resetPeer(); + int arg = 42; + setProp1Peer(0); + + QVERIFY(iface.setProperty("prop1", arg)); + QCOMPARE(callCountPeer(), 1); + QCOMPARE(prop1Peer(), arg); +} + +void tst_QDBusInterface::complexPropertyReadPeer() +{ + QDBusConnection con("peer"); + QDBusInterface iface(QString(), QLatin1String("/"), + TEST_INTERFACE_NAME, con); + + resetPeer(); + QList<int> arg = QList<int>() << 42 << -47; + setComplexPropPeer(arg); + + QVariant v = iface.property("complexProp"); + QVERIFY(v.isValid()); + QCOMPARE(v.userType(), qMetaTypeId<QList<int> >()); + QCOMPARE(v.value<QList<int> >(), arg); + QCOMPARE(callCountPeer(), 1); +} + +void tst_QDBusInterface::complexPropertyWritePeer() +{ + QDBusConnection con("peer"); + QDBusInterface iface(QString(), QLatin1String("/"), + TEST_INTERFACE_NAME, con); + + resetPeer(); + QList<int> arg = QList<int>() << -47 << 42; + + QVERIFY(iface.setProperty("complexProp", qVariantFromValue(arg))); + QCOMPARE(callCountPeer(), 1); + QCOMPARE(complexPropPeer(), arg); +} + QTEST_MAIN(tst_QDBusInterface) #include "tst_qdbusinterface.moc" - diff --git a/tests/auto/qdbusmarshall/common.h b/tests/auto/qdbusmarshall/common.h index 941f988..35fe5f1 100644 --- a/tests/auto/qdbusmarshall/common.h +++ b/tests/auto/qdbusmarshall/common.h @@ -39,6 +39,22 @@ ** ****************************************************************************/ #include <math.h> // isnan +#include <qvariant.h> + +#ifdef Q_OS_UNIX +# include <private/qcore_unix_p.h> + +static bool compareFileDescriptors(int fd1, int fd2) +{ + QT_STATBUF st1, st2; + if (QT_FSTAT(fd1, &st1) == -1 || QT_FSTAT(fd2, &st2) == -1) { + perror("fstat"); + return false; + } + + return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino); +} +#endif Q_DECLARE_METATYPE(QVariant) Q_DECLARE_METATYPE(QList<bool>) @@ -77,6 +93,22 @@ Q_DECLARE_METATYPE(ObjectPathStringMap) Q_DECLARE_METATYPE(LLDateTimeMap) Q_DECLARE_METATYPE(SignatureStringMap) +static bool compare(const QDBusUnixFileDescriptor &t1, const QDBusUnixFileDescriptor &t2) +{ + int fd1 = t1.fileDescriptor(); + int fd2 = t2.fileDescriptor(); + if ((fd1 == -1 || fd2 == -1) && fd1 != fd2) { + // one is valid, the other isn't + return false; + } + +#ifdef Q_OS_UNIX + return compareFileDescriptors(fd1, fd2); +#else + return true; +#endif +} + struct MyStruct { int i; @@ -130,6 +162,32 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, MyVariantMapStruct &ms return arg; } +struct MyFileDescriptorStruct +{ + QDBusUnixFileDescriptor fd; + + inline bool operator==(const MyFileDescriptorStruct &other) const + { return compare(fd, other.fd); } +}; +Q_DECLARE_METATYPE(MyFileDescriptorStruct) +Q_DECLARE_METATYPE(QList<MyFileDescriptorStruct>) + +QDBusArgument &operator<<(QDBusArgument &arg, const MyFileDescriptorStruct &ms) +{ + arg.beginStructure(); + arg << ms.fd; + arg.endStructure(); + return arg; +} + +const QDBusArgument &operator>>(const QDBusArgument &arg, MyFileDescriptorStruct &ms) +{ + arg.beginStructure(); + arg >> ms.fd; + arg.endStructure(); + return arg; +} + void commonInit() { @@ -157,6 +215,8 @@ void commonInit() qDBusRegisterMetaType<MyStruct>(); qDBusRegisterMetaType<MyVariantMapStruct>(); qDBusRegisterMetaType<QList<MyVariantMapStruct> >(); + qDBusRegisterMetaType<MyFileDescriptorStruct>(); + qDBusRegisterMetaType<QList<MyFileDescriptorStruct> >(); } #ifdef USE_PRIVATE_CODE #include "private/qdbusintrospection_p.h" @@ -467,6 +527,8 @@ bool compareToArgument(const QDBusArgument &arg, const QVariant &v2) return compare<QList<QDBusObjectPath> >(arg, v2); else if (id == qMetaTypeId<QList<QDBusSignature> >()) return compare<QList<QDBusSignature> >(arg, v2); + else if (id == qMetaTypeId<QList<QDBusUnixFileDescriptor> >()) + return compare<QList<QDBusUnixFileDescriptor> >(arg, v2); else if (id == qMetaTypeId<QList<QDateTime> >()) return compare<QList<QDateTime> >(arg, v2); @@ -511,6 +573,10 @@ bool compareToArgument(const QDBusArgument &arg, const QVariant &v2) return compare<MyVariantMapStruct>(arg, v2); else if (id == qMetaTypeId<QList<MyVariantMapStruct> >()) return compare<QList<MyVariantMapStruct> >(arg, v2); + else if (id == qMetaTypeId<MyFileDescriptorStruct>()) + return compare<MyFileDescriptorStruct>(arg, v2); + else if (id == qMetaTypeId<QList<MyFileDescriptorStruct> >()) + return compare<QList<MyFileDescriptorStruct> >(arg, v2); } qWarning() << "Unexpected QVariant type" << v2.userType() @@ -563,6 +629,9 @@ template<> bool compare(const QVariant &v1, const QVariant &v2) else if (id == qMetaTypeId<QDBusSignature>()) return qvariant_cast<QDBusSignature>(v1).signature() == qvariant_cast<QDBusSignature>(v2).signature(); + else if (id == qMetaTypeId<QDBusUnixFileDescriptor>()) + return compare(qvariant_cast<QDBusUnixFileDescriptor>(v1), qvariant_cast<QDBusUnixFileDescriptor>(v2)); + else if (id == qMetaTypeId<QDBusVariant>()) return compare(qvariant_cast<QDBusVariant>(v1).variant(), qvariant_cast<QDBusVariant>(v2).variant()); diff --git a/tests/auto/qdbusmarshall/qdbusmarshall.pro b/tests/auto/qdbusmarshall/qdbusmarshall.pro index f8e0875..ad40c0d 100644 --- a/tests/auto/qdbusmarshall/qdbusmarshall.pro +++ b/tests/auto/qdbusmarshall/qdbusmarshall.pro @@ -3,6 +3,8 @@ contains(QT_CONFIG,dbus): { TEMPLATE = subdirs CONFIG += ordered SUBDIRS = qpong test + + requires(contains(QT_CONFIG,private_tests)) } else { SOURCES += dummy.cpp } diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index 3b07417..cca212e 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -42,6 +42,7 @@ #include <QtTest/QtTest> #include <QtDBus/QtDBus> #include <QtDBus/private/qdbusutil_p.h> +#include <QtDBus/private/qdbusconnection_p.h> #include "common.h" #include <limits> @@ -93,7 +94,11 @@ private slots: void receiveUnknownType(); private: + int fileDescriptorForTest(); + QProcess proc; + QTemporaryFile tempFile; + bool fileDescriptorPassing; }; class QDBusMessageSpy: public QObject @@ -116,6 +121,7 @@ void tst_QDBusMarshall::initTestCase() { commonInit(); QDBusConnection con = QDBusConnection::sessionBus(); + fileDescriptorPassing = con.connectionCapabilities() & QDBusConnection::UnixFileDescriptorPassing; #ifdef Q_OS_WIN proc.start("qpong"); #else @@ -144,6 +150,15 @@ void tst_QDBusMarshall::cleanupTestCase() proc.waitForFinished(200); } +int tst_QDBusMarshall::fileDescriptorForTest() +{ + if (!tempFile.isOpen()) { + tempFile.setFileTemplate(QDir::tempPath() + "/qdbusmarshalltestXXXXXX.tmp"); + tempFile.open(); + } + return tempFile.handle(); +} + void tst_QDBusMarshall::sendBasic_data() { QTest::addColumn<QVariant>("value"); @@ -167,6 +182,9 @@ void tst_QDBusMarshall::sendBasic_data() QTest::newRow("signature") << qVariantFromValue(QDBusSignature("g")) << "g" << "[Signature: g]"; QTest::newRow("emptystring") << QVariant("") << "s" << "\"\""; QTest::newRow("nullstring") << QVariant(QString()) << "s" << "\"\""; + + if (fileDescriptorPassing) + QTest::newRow("file-descriptor") << qVariantFromValue(QDBusUnixFileDescriptor(fileDescriptorForTest())) << "h" << "[Unix FD: valid]"; #endif } @@ -255,6 +273,18 @@ void tst_QDBusMarshall::sendArrays_data() << std::numeric_limits<double>::quiet_NaN(); QTest::newRow("doublelist") << qVariantFromValue(doubles) << "ad" << "[Argument: ad {1.2, 2.2, 4.4, -inf, inf, nan}]"; + QList<QDBusObjectPath> objectPaths; + QTest::newRow("emptyobjectpathlist") << qVariantFromValue(objectPaths) << "ao" << "[Argument: ao {}]"; + objectPaths << QDBusObjectPath("/") << QDBusObjectPath("/foo"); + QTest::newRow("objectpathlist") << qVariantFromValue(objectPaths) << "ao" << "[Argument: ao {[ObjectPath: /], [ObjectPath: /foo]}]"; + + if (fileDescriptorPassing) { + QList<QDBusUnixFileDescriptor> fileDescriptors; + QTest::newRow("emptyfiledescriptorlist") << qVariantFromValue(fileDescriptors) << "ah" << "[Argument: ah {}]"; + fileDescriptors << QDBusUnixFileDescriptor(fileDescriptorForTest()) << QDBusUnixFileDescriptor(1); + QTest::newRow("filedescriptorlist") << qVariantFromValue(fileDescriptors) << "ah" << "[Argument: ah {[Unix FD: valid], [Unix FD: valid]}]"; + } + QVariantList variants; QTest::newRow("emptyvariantlist") << QVariant(variants) << "av" << "[Argument: av {}]"; variants << QString("Hello") << QByteArray("World") << 42 << -43.0 << 44U << Q_INT64_C(-45) @@ -456,6 +486,12 @@ void tst_QDBusMarshall::sendMaps_data() QTest::newRow("gs-map") << qVariantFromValue(gsmap) << "a{gs}" << "[Argument: a{gs} {[Signature: a{gs}] = \"array of dict_entry of (signature, string)\", [Signature: i] = \"int32\", [Signature: s] = \"string\"}]"; + if (fileDescriptorPassing) { + svmap["zzfiledescriptor"] = qVariantFromValue(QDBusUnixFileDescriptor(fileDescriptorForTest())); + QTest::newRow("sv-map1-fd") << qVariantFromValue(svmap) << "a{sv}" + << "[Argument: a{sv} {\"a\" = [Variant(int): 1], \"b\" = [Variant(QByteArray): {99}], \"c\" = [Variant(QString): \"b\"], \"d\" = [Variant(uint): 42], \"e\" = [Variant(short): -47], \"f\" = [Variant: [Variant(int): 0]], \"zzfiledescriptor\" = [Variant(QDBusUnixFileDescriptor): [Unix FD: valid]]}]"; + } + svmap.clear(); svmap["ismap"] = qVariantFromValue(ismap); svmap["ssmap"] = qVariantFromValue(ssmap); @@ -509,6 +545,18 @@ void tst_QDBusMarshall::sendStructs_data() QTest::newRow("empty-list-of-string-variantmap") << qVariantFromValue(list) << "a(sa{sv})" << "[Argument: a(sa{sv}) {}]"; list << mvms; QTest::newRow("list-of-string-variantmap") << qVariantFromValue(list) << "a(sa{sv})" << "[Argument: a(sa{sv}) {[Argument: (sa{sv}) \"Hello, World\", [Argument: a{sv} {\"bytearray\" = [Variant(QByteArray): {72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100}], \"int\" = [Variant(int): 42], \"short\" = [Variant(short): -47], \"uint\" = [Variant(uint): 42]}]]}]"; + + if (fileDescriptorPassing) { + MyFileDescriptorStruct fds; + fds.fd = QDBusUnixFileDescriptor(fileDescriptorForTest()); + QTest::newRow("fdstruct") << qVariantFromValue(fds) << "(h)" << "[Argument: (h) [Unix FD: valid]]"; + + QList<MyFileDescriptorStruct> fdlist; + QTest::newRow("empty-list-of-fdstruct") << qVariantFromValue(fdlist) << "a(h)" << "[Argument: a(h) {}]"; + + fdlist << fds; + QTest::newRow("list-of-fdstruct") << qVariantFromValue(fdlist) << "a(h)" << "[Argument: a(h) {[Argument: (h) [Unix FD: valid]]}]"; + } } void tst_QDBusMarshall::sendComplex_data() @@ -642,6 +690,12 @@ void tst_QDBusMarshall::sendArgument_data() arg << QString(); QTest::newRow("nullstring") << qVariantFromValue(arg) << "s" << int(QDBusArgument::BasicType); + if (fileDescriptorPassing) { + arg = QDBusArgument(); + arg << QDBusUnixFileDescriptor(fileDescriptorForTest()); + QTest::newRow("filedescriptor") << qVariantFromValue(arg) << "h" << int(QDBusArgument::BasicType); + } + arg = QDBusArgument(); arg << QDBusVariant(1); QTest::newRow("variant") << qVariantFromValue(arg) << "v" << int(QDBusArgument::VariantType); @@ -902,6 +956,27 @@ void tst_QDBusMarshall::sendCallErrors_data() << "Marshalling failed: Unregistered type UnregisteredType passed in arguments" << QString("QDBusMarshaller: type `UnregisteredType' (%1) is not registered with D-BUS. Use qDBusRegisterMetaType to register it") .arg(qMetaTypeId<UnregisteredType>()); + + QTest::newRow("invalid-object-path-arg") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << qVariantFromValue(QDBusObjectPath())) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Invalid object path passed in arguments" + << ""; + + QTest::newRow("invalid-signature-arg") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << qVariantFromValue(QDBusSignature())) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Invalid signature passed in arguments" + << ""; + + // invalid file descriptor + if (fileDescriptorPassing) { + QTest::newRow("invalid-file-descriptor") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << qVariantFromValue(QDBusUnixFileDescriptor(-1))) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Invalid file descriptor passed in arguments" + << ""; + } } void tst_QDBusMarshall::sendCallErrors() @@ -967,6 +1042,21 @@ typedef QScopedPointer<DBusConnection, DisconnectRawDBus> ScopedDBusConnection; typedef QScopedPointer<DBusMessage, GenericUnref<DBusMessage, dbus_message_unref> > ScopedDBusMessage; typedef QScopedPointer<DBusPendingCall, GenericUnref<DBusPendingCall, dbus_pending_call_unref> > ScopedDBusPendingCall; +template <typename T> struct SetResetValue +{ + const T oldValue; + T &value; +public: + SetResetValue(T &v, T newValue) : oldValue(v), value(v) + { + value = newValue; + } + ~SetResetValue() + { + value = oldValue; + } +}; + void tst_QDBusMarshall::receiveUnknownType() { #ifndef DBUS_TYPE_UNIX_FD @@ -986,6 +1076,10 @@ void tst_QDBusMarshall::receiveUnknownType() if (!dbus_connection_can_send_type(rawcon.data(), DBUS_TYPE_UNIX_FD)) QSKIP("Your session bus does not allow sending Unix file descriptors", SkipAll); + // make sure this QDBusConnection won't handle Unix file descriptors + QDBusConnection::ConnectionCapabilities &capabRef = QDBusConnectionPrivate::d(con)->capabilities; + SetResetValue<QDBusConnection::ConnectionCapabilities> resetter(capabRef, capabRef & ~QDBusConnection::UnixFileDescriptorPassing); + if (qstrcmp(QTest::currentDataTag(), "in-call") == 0) { // create a call back to us containing a file descriptor QDBusMessageSpy spy; diff --git a/tests/auto/qdbusperformance/.gitignore b/tests/auto/qdbusperformance/.gitignore deleted file mode 100644 index 4cd8399..0000000 --- a/tests/auto/qdbusperformance/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -tst_qdbusperformance -server/server diff --git a/tests/auto/qdbusperformance/qdbusperformance.pro b/tests/auto/qdbusperformance/qdbusperformance.pro deleted file mode 100644 index 6880518..0000000 --- a/tests/auto/qdbusperformance/qdbusperformance.pro +++ /dev/null @@ -1,8 +0,0 @@ -load(qttest_p4) -contains(QT_CONFIG,dbus): { - TEMPLATE = subdirs - CONFIG += ordered - SUBDIRS = server test -} else { - SOURCES += ../qdbusmarshall/dummy.cpp -} diff --git a/tests/auto/qdbusperformance/server/server.pro b/tests/auto/qdbusperformance/server/server.pro deleted file mode 100644 index 30f81dd..0000000 --- a/tests/auto/qdbusperformance/server/server.pro +++ /dev/null @@ -1,5 +0,0 @@ -SOURCES = server.cpp -HEADERS = ../serverobject.h -TARGET = server -CONFIG += qdbus -QT -= gui diff --git a/tests/auto/qdbusperformance/test/test.pro b/tests/auto/qdbusperformance/test/test.pro deleted file mode 100644 index 9f5712e..0000000 --- a/tests/auto/qdbusperformance/test/test.pro +++ /dev/null @@ -1,7 +0,0 @@ -load(qttest_p4) -SOURCES += ../tst_qdbusperformance.cpp -HEADERS += ../serverobject.h -TARGET = ../tst_qdbusperformance - -QT = core -CONFIG += qdbus diff --git a/tests/auto/qdbusperformance/tst_qdbusperformance.cpp b/tests/auto/qdbusperformance/tst_qdbusperformance.cpp deleted file mode 100644 index 216d181..0000000 --- a/tests/auto/qdbusperformance/tst_qdbusperformance.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include <QtCore/QtCore> -#include <QtTest/QtTest> -#include <QtDBus/QtDBus> - -#include "./serverobject.h" - -static const char serviceName[] = "com.trolltech.autotests.performance"; -static const int runTime = 500; - -class tst_QDBusPerformance: public QObject -{ - Q_OBJECT - QProcess proc; - QDBusInterface *target; - - QDBusInterface *remote; - QDBusInterface *local; - - bool executeTest(const char *funcname, int size, const QVariant &data); - -public slots: - void initTestCase_data(); - void initTestCase(); - void init(); - -private slots: - void callSpeed(); - - void oneWay_data(); - void oneWay(); - void oneWayVariant_data(); - void oneWayVariant(); - - void roundTrip_data(); - void roundTrip(); - void roundTripVariant_data(); - void roundTripVariant(); -}; -Q_DECLARE_METATYPE(QVariant) - -void tst_QDBusPerformance::initTestCase() -{ - QDBusConnection con = QDBusConnection::sessionBus(); - QVERIFY(con.isConnected()); - - QDBusServiceWatcher watcher(serviceName, con, - QDBusServiceWatcher::WatchForRegistration); - connect(&watcher, SIGNAL(serviceRegistered(QString)), - &QTestEventLoop::instance(), SLOT(exitLoop())); - -#ifdef Q_OS_WIN - proc.start("server"); -#else - proc.start("./server/server"); -#endif - QVERIFY(proc.waitForStarted()); - - QTestEventLoop::instance().enterLoop(5); - QVERIFY(con.interface()->isServiceRegistered(serviceName)); - - remote = new QDBusInterface(serviceName, "/", "com.trolltech.autotests.Performance", con, this); - QVERIFY(remote->isValid()); - - new ServerObject("/", con, this); - local = new QDBusInterface(con.baseService(), "/", "com.trolltech.autotests.Performance", con, this); - QVERIFY(local->isValid()); -} - -void tst_QDBusPerformance::initTestCase_data() -{ - QTest::addColumn<bool>("loopback"); - - QTest::newRow("normal") << false; - QTest::newRow("loopback") << true; -} - -void tst_QDBusPerformance::init() -{ - QFETCH_GLOBAL(bool, loopback); - if (loopback) - target = local; - else - target = remote; -} - -void tst_QDBusPerformance::callSpeed() -{ - QElapsedTimer timer; - - int callCount = 0; - timer.start(); - while (timer.elapsed() < runTime) { - QDBusReply<void> reply = target->call("nothing"); - QVERIFY(reply.isValid()); - - ++callCount; - } - qDebug() << callCount << "calls in" << timer.elapsed() << "ms:" - << (callCount * 1000.0 / timer.elapsed()) << "calls/sec"; -} - -bool tst_QDBusPerformance::executeTest(const char *funcname, int size, const QVariant &data) -{ - QElapsedTimer timer; - - int callCount = 0; - qint64 transferred = 0; - timer.start(); - while (timer.elapsed() < runTime) { - QDBusMessage reply = target->call(funcname, data); - if (reply.type() != QDBusMessage::ReplyMessage) - return false; - - transferred += size; - ++callCount; - } - qDebug() << transferred << "bytes in" << timer.elapsed() << "ms" - << "(in" << callCount << "calls):" - << (transferred * 1000.0 / timer.elapsed() / 1024 / 1024) << "MB/s"; - - return true; -} - -void tst_QDBusPerformance::oneWay_data() -{ - QTest::addColumn<QVariant>("data"); - QTest::addColumn<int>("size"); - - QByteArray ba(256, 'a'); - while (ba.size() < 8193) { - QTest::newRow(QString("%1-byteArray").arg(ba.size()).toAscii()) << qVariantFromValue(ba) << ba.size(); - ba += ba; - } - - QString s(256, QLatin1Char('a')); - while (s.size() < 8193) { - QTest::newRow(QString("%1-string").arg(s.size()).toAscii()) << qVariantFromValue(s) << s.size(); - s += s; - } -} - -void tst_QDBusPerformance::oneWay() -{ - QFETCH(QVariant, data); - QFETCH(int, size); - - QVERIFY(executeTest("size", size, data)); -} - -void tst_QDBusPerformance::oneWayVariant_data() -{ - oneWay_data(); -} - -void tst_QDBusPerformance::oneWayVariant() -{ - QFETCH(QVariant, data); - QFETCH(int, size); - - QVERIFY(executeTest("size", size, qVariantFromValue(QDBusVariant(data)))); -} - -void tst_QDBusPerformance::roundTrip_data() -{ - oneWay_data(); -} - -void tst_QDBusPerformance::roundTrip() -{ - QFETCH(QVariant, data); - QFETCH(int, size); - - QVERIFY(executeTest("echo", size, data)); -} - -void tst_QDBusPerformance::roundTripVariant_data() -{ - oneWay_data(); -} - -void tst_QDBusPerformance::roundTripVariant() -{ - QFETCH(QVariant, data); - QFETCH(int, size); - - QVERIFY(executeTest("echo", size, qVariantFromValue(QDBusVariant(data)))); -} - -QTEST_MAIN(tst_QDBusPerformance) -#include "tst_qdbusperformance.moc" diff --git a/tests/auto/qdbusthreading/tst_qdbusthreading.cpp b/tests/auto/qdbusthreading/tst_qdbusthreading.cpp index f93d126..e37e4c3 100644 --- a/tests/auto/qdbusthreading/tst_qdbusthreading.cpp +++ b/tests/auto/qdbusthreading/tst_qdbusthreading.cpp @@ -592,7 +592,7 @@ void tst_QDBusThreading::callbackInAnotherAuxThread() // wait for the event loop sem1.release(); sem2.acquire(); - Q_ASSERT(loop); + QVERIFY(loop); // create the second thread new Thread; diff --git a/tests/auto/qdbustype/qdbustype.pro b/tests/auto/qdbustype/qdbustype.pro new file mode 100644 index 0000000..e2f0c90 --- /dev/null +++ b/tests/auto/qdbustype/qdbustype.pro @@ -0,0 +1,10 @@ +load(qttest_p4) +QT = core +contains(QT_CONFIG,dbus): { + SOURCES += tst_qdbustype.cpp + QT += dbus + QMAKE_CXXFLAGS += $$QT_CFLAGS_DBUS + LIBS_PRIVATE += $$QT_LIBS_DBUS +} else { + SOURCES += ../qdbusmarshall/dummy.cpp +} diff --git a/tests/auto/qdbustype/tst_qdbustype.cpp b/tests/auto/qdbustype/tst_qdbustype.cpp new file mode 100644 index 0000000..be4c19c --- /dev/null +++ b/tests/auto/qdbustype/tst_qdbustype.cpp @@ -0,0 +1,273 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the FOO module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtCore/QCoreApplication> + +#include <QtDBus/private/qdbusutil_p.h> + +#include <dbus/dbus.h> + +class tst_QDBusType : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void isValidFixedType_data(); + void isValidFixedType(); + void isValidBasicType_data(); + void isValidBasicType(); + void isValidSingleSignature_data(); + void isValidSingleSignature(); + void isValidArray_data(); + void isValidArray(); + void isValidSignature_data(); + void isValidSignature(); +}; + +enum { Invalid = false, Valid = true }; + +static void addColumns() +{ + // All tests use these two columns only + QTest::addColumn<QString>("data"); + QTest::addColumn<bool>("result"); + QTest::addColumn<bool>("isValid"); +} + +// ---- type adds --- +static void addFixedTypes() +{ + QTest::newRow("bool") << DBUS_TYPE_BOOLEAN_AS_STRING << true << true; + QTest::newRow("byte") << DBUS_TYPE_BYTE_AS_STRING << true << true; + QTest::newRow("int16") << DBUS_TYPE_INT16_AS_STRING << true << true; + QTest::newRow("uint16") << DBUS_TYPE_UINT16_AS_STRING << true << true; + QTest::newRow("int32") << DBUS_TYPE_INT32_AS_STRING << true << true; + QTest::newRow("uint32") << DBUS_TYPE_UINT32_AS_STRING << true << true; + QTest::newRow("int64") << DBUS_TYPE_INT64_AS_STRING << true << true; + QTest::newRow("uint64") << DBUS_TYPE_UINT64_AS_STRING << true << true; + QTest::newRow("double") << DBUS_TYPE_DOUBLE_AS_STRING << true << true; +#ifdef DBUS_TYPE_UNIX_FD_AS_STRING + QTest::newRow("unixfd") << DBUS_TYPE_UNIX_FD_AS_STRING << true << true; +#endif +} + +static void addInvalidSingleLetterTypes() +{ + QChar nulString[] = { 0 }; + QTest::newRow("nul") << QString(nulString, 1) << false << false; + QTest::newRow("tilde") << "~" << false << false; + QTest::newRow("struct-begin") << "(" << false << false; + QTest::newRow("struct-end") << ")" << false << false; + QTest::newRow("dict-entry-begin") << "{" << false << false; + QTest::newRow("dict-entry-end") << "}" << false << false; + QTest::newRow("array-no-element") << "a" << false << false; +} + +static void addBasicTypes(bool basicsAreValid) +{ + addFixedTypes(); + QTest::newRow("string") << DBUS_TYPE_STRING_AS_STRING << basicsAreValid << true; + QTest::newRow("object-path") << DBUS_TYPE_OBJECT_PATH_AS_STRING << basicsAreValid << true; + QTest::newRow("signature") << DBUS_TYPE_SIGNATURE_AS_STRING << basicsAreValid << true; +} + +static void addVariant(bool variantIsValid) +{ + QTest::newRow("variant") << "v" << variantIsValid << true; +} + +static void addSingleSignatures() +{ + addBasicTypes(Valid); + addVariant(Valid); + QTest::newRow("struct-1") << "(y)" << true; + QTest::newRow("struct-2") << "(yy)" << true; + QTest::newRow("struct-3") << "(yyv)" << true; + + QTest::newRow("struct-nested-1") << "((y))" << true; + QTest::newRow("struct-nested-2") << "((yy))" << true; + QTest::newRow("struct-nested-3") << "(y(y))" << true; + QTest::newRow("struct-nested-4") << "((y)y)" << true; + QTest::newRow("struct-nested-5") << "(y(y)y)" << true; + QTest::newRow("struct-nested-6") << "((y)(y))" << true; + + QTest::newRow("array-1") << "as" << true; + QTest::newRow("struct-array-1") << "(as)" << true; + QTest::newRow("struct-array-2") << "(yas)" << true; + QTest::newRow("struct-array-3") << "(asy)" << true; + QTest::newRow("struct-array-4") << "(yasy)" << true; + + QTest::newRow("dict-1") << "a{sy}" << true; + QTest::newRow("dict-2") << "a{sv}" << true; + QTest::newRow("dict-struct-1") << "a{s(y)}" << true; + QTest::newRow("dict-struct-2") << "a{s(yyyy)}" << true; + QTest::newRow("dict-struct-array") << "a{s(ay)}" << true; + QTest::newRow("dict-array") << "a{sas}" << true; + QTest::newRow("dict-array-struct") << "a{sa(y)}" << true; + + addInvalidSingleLetterTypes(); + QTest::newRow("naked-dict-empty") << "{}" << false; + QTest::newRow("naked-dict-missing-value") << "{i}" << false; + + QTest::newRow("dict-empty") << "a{}" << false; + QTest::newRow("dict-missing-value") << "a{i}" << false; + QTest::newRow("dict-non-basic-key") << "a{vi}" << false; + QTest::newRow("dict-struct-key") << "a{(y)y}" << false; + QTest::newRow("dict-missing-close") << "a{sv" << false; + QTest::newRow("dict-mismatched-close") << "a{sv)" << false; + QTest::newRow("dict-missing-value-close") << "a{s" << false; + + QTest::newRow("empty-struct") << "()" << false; + QTest::newRow("struct-missing-close") << "(s" << false; + QTest::newRow("struct-nested-missing-close-1") << "((s)" << false; + QTest::newRow("struct-nested-missing-close-2") << "((s" << false; + + QTest::newRow("struct-ending-array-no-element") << "(a)" << false; +} + +static void addNakedDictEntry() +{ + QTest::newRow("naked-dict-entry") << "{sv}" << false; +} + +// ---- tests ---- + +void tst_QDBusType::isValidFixedType_data() +{ + addColumns(); + addFixedTypes(); + addBasicTypes(Invalid); + addVariant(Invalid); + addInvalidSingleLetterTypes(); +} + +void tst_QDBusType::isValidFixedType() +{ + QFETCH(QString, data); + QFETCH(bool, result); + QFETCH(bool, isValid); + Q_ASSERT_X(data.length() == 1, "tst_QDBusType", "Test is malformed, this function must test only one-letter types"); + Q_ASSERT(isValid || (!isValid && !result)); + + int type = data.at(0).unicode(); + if (isValid) + QCOMPARE(bool(dbus_type_is_fixed(type)), result); + QCOMPARE(QDBusUtil::isValidFixedType(type), result); +} + +void tst_QDBusType::isValidBasicType_data() +{ + addColumns(); + addBasicTypes(Valid); + addVariant(Invalid); + addInvalidSingleLetterTypes(); +} + +void tst_QDBusType::isValidBasicType() +{ + QFETCH(QString, data); + QFETCH(bool, result); + QFETCH(bool, isValid); + Q_ASSERT_X(data.length() == 1, "tst_QDBusType", "Test is malformed, this function must test only one-letter types"); + Q_ASSERT(isValid || (!isValid && !result)); + + int type = data.at(0).unicode(); + if (isValid) + QCOMPARE(bool(dbus_type_is_basic(type)), result); + QCOMPARE(QDBusUtil::isValidBasicType(type), result); +} + +void tst_QDBusType::isValidSingleSignature_data() +{ + addColumns(); + addSingleSignatures(); + addNakedDictEntry(); +} + +void tst_QDBusType::isValidSingleSignature() +{ + QFETCH(QString, data); + QFETCH(bool, result); + + QCOMPARE(bool(dbus_signature_validate_single(data.toLatin1(), 0)), result); + QCOMPARE(QDBusUtil::isValidSingleSignature(data), result); +} + +void tst_QDBusType::isValidArray_data() +{ + addColumns(); + addSingleSignatures(); +} + +void tst_QDBusType::isValidArray() +{ + QFETCH(QString, data); + QFETCH(bool, result); + + data.prepend("a"); + QCOMPARE(bool(dbus_signature_validate_single(data.toLatin1(), 0)), result); + QCOMPARE(QDBusUtil::isValidSingleSignature(data), result); + + data.prepend("a"); + QCOMPARE(bool(dbus_signature_validate_single(data.toLatin1(), 0)), result); + QCOMPARE(QDBusUtil::isValidSingleSignature(data), result); +} + +void tst_QDBusType::isValidSignature_data() +{ + isValidSingleSignature_data(); +} + +void tst_QDBusType::isValidSignature() +{ + QFETCH(QString, data); + QFETCH(bool, result); + + data.append(data); + if (data.at(0).unicode()) + QCOMPARE(bool(dbus_signature_validate(data.toLatin1(), 0)), result); + QCOMPARE(QDBusUtil::isValidSignature(data), result); +} + +QTEST_MAIN(tst_QDBusType) + +#include "tst_qdbustype.moc" diff --git a/tests/auto/qdebug/qdebug.pro b/tests/auto/qdebug/qdebug.pro index 6e75a09..2b57168 100644 --- a/tests/auto/qdebug/qdebug.pro +++ b/tests/auto/qdebug/qdebug.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qdebug.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qdesktopservices/qdesktopservices.pro b/tests/auto/qdesktopservices/qdesktopservices.pro index d32ed4c..43f6cba 100644 --- a/tests/auto/qdesktopservices/qdesktopservices.pro +++ b/tests/auto/qdesktopservices/qdesktopservices.pro @@ -3,22 +3,22 @@ CONFIG += qttest_p4 SOURCES += tst_qdesktopservices.cpp TARGET = tst_qdesktopservices symbian: { - dummy.sources = text\\testfile.txt + dummy.files = text\\testfile.txt dummy.path = . - text.sources = text\\* + text.files = text\\* text.path = \\data\\others - image.sources = image\\* + image.files = image\\* image.path = \\data\\images - audio.sources = audio\\* + audio.files = audio\\* audio.path = \\data\\sounds - video.sources = video\\* + video.files = video\\* video.path = \\data\\videos - install.sources = install\\* + install.files = install\\* install.path = \\data\\installs DEPLOYMENT += image audio video install diff --git a/tests/auto/qdial/tst_qdial.cpp b/tests/auto/qdial/tst_qdial.cpp index d3c7cfc..568b82d 100644 --- a/tests/auto/qdial/tst_qdial.cpp +++ b/tests/auto/qdial/tst_qdial.cpp @@ -54,6 +54,7 @@ private slots: void getSetCheck(); void valueChanged(); void sliderMoved(); + void wrappingCheck(); }; // Testing get/set functions @@ -143,5 +144,68 @@ void tst_QDial::sliderMoved() } +void tst_QDial::wrappingCheck() +{ + //This tests if dial will wrap past the maximum value back to the minimum + //and vice versa when changing the value with a keypress + QDial dial; + dial.setMinimum(0); + dial.setMaximum(100); + dial.setSingleStep(1); + dial.setWrapping(true); + dial.setValue(99); + dial.show(); + + { //set value to maximum but do not wrap + QTest::keyPress(&dial, Qt::Key_Up); + QCOMPARE( dial.value(), 100); + } + + { //step up once more and wrap clockwise to minimum + 1 + QTest::keyPress(&dial, Qt::Key_Up); + QCOMPARE( dial.value(), 1); + } + + { //step down once, and wrap anti-clockwise to minimum, then again to maximum - 1 + QTest::keyPress(&dial, Qt::Key_Down); + QCOMPARE( dial.value(), 0); + + QTest::keyPress(&dial, Qt::Key_Down); + QCOMPARE( dial.value(), 99); + } + + { //when wrapping property is false no wrapping will occur + dial.setWrapping(false); + dial.setValue(100); + + QTest::keyPress(&dial, Qt::Key_Up); + QCOMPARE( dial.value(), 100); + + dial.setValue(0); + QTest::keyPress(&dial, Qt::Key_Down); + QCOMPARE( dial.value(), 0); + } + + { //When the step is really big or small, wrapping should still behave + dial.setWrapping(true); + dial.setValue(dial.minimum()); + dial.setSingleStep(305); + + QTest::keyPress(&dial, Qt::Key_Up); + QCOMPARE( dial.value(), 5); + + dial.setValue(dial.minimum()); + QTest::keyPress(&dial, Qt::Key_Down); + QCOMPARE( dial.value(), 95); + + dial.setMinimum(-30); + dial.setMaximum(-4); + dial.setSingleStep(200); + dial.setValue(dial.minimum()); + QTest::keyPress(&dial, Qt::Key_Down); + QCOMPARE( dial.value(), -22); + } +} + QTEST_MAIN(tst_QDial) #include "tst_qdial.moc" diff --git a/tests/auto/qdir/qdir.pro b/tests/auto/qdir/qdir.pro index d81e428..384c048 100644 --- a/tests/auto/qdir/qdir.pro +++ b/tests/auto/qdir/qdir.pro @@ -4,7 +4,7 @@ RESOURCES += qdir.qrc QT = core wince*|symbian { - DirFiles.sources = testdir testData searchdir resources entrylist types tst_qdir.cpp + DirFiles.files = testdir testData searchdir resources entrylist types tst_qdir.cpp DirFiles.path = . DEPLOYMENT += DirFiles } @@ -15,8 +15,11 @@ wince* { TARGET.CAPABILITY += AllFiles TARGET.UID3 = 0xE0340002 DEFINES += SYMBIAN_SRCDIR_UID=$$lower($$replace(TARGET.UID3,"0x","")) + LIBS += -lefsrv + INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE } else { contains(QT_CONFIG, qt3support):QT += qt3support DEFINES += SRCDIR=\\\"$$PWD/\\\" } +CONFIG += parallel_test diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 8eea43d..0a42a97 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -49,14 +49,21 @@ #include <qregexp.h> #include <qstringlist.h> #include "../network-settings.h" + +#if defined(Q_OS_WIN) +#define _WIN32_WINNT 0x500 +#endif + #include "../../shared/filesystem.h" #if defined(Q_OS_SYMBIAN) +# include <f32file.h> # define STRINGIFY(x) #x # define TOSTRING(x) STRINGIFY(x) # define SRCDIR "C:/Private/" TOSTRING(SYMBIAN_SRCDIR_UID) "/" #elif defined(Q_OS_UNIX) # include <unistd.h> +# include <sys/stat.h> #endif #if defined(Q_OS_VXWORKS) @@ -64,7 +71,7 @@ #endif #if defined(Q_OS_SYMBIAN) -// Open C in Symbian doesn't support symbolic links to directories +#define Q_NO_SYMLINKS #define Q_NO_SYMLINKS_TO_DIRS #endif @@ -98,6 +105,8 @@ private slots: void mkdir_data(); void mkdir(); + void makedirReturnCode(); + void rmdir_data(); void rmdir(); @@ -169,6 +178,32 @@ private slots: void updateFileLists(); void detachingOperations(); + + void testCaching(); + + void isRoot_data(); + void isRoot(); + +#ifndef QT_NO_REGEXP + void match_data(); + void match(); +#endif + + void drives(); + + void arrayOperator(); + +#ifdef QT3_SUPPORT + void setNameFilter(); +#endif + + void equalityOperator_data(); + void equalityOperator(); + + void isRelative_data(); + void isRelative(); + + void isReadable(); }; // Testing get/set functions @@ -283,6 +318,17 @@ void tst_QDir::mkdir() QVERIFY(fi.exists() && fi.isDir()); } +void tst_QDir::makedirReturnCode() +{ + QString dirName = QString::fromLatin1("makedirReturnCode"); + QDir::current().rmdir(dirName); // cleanup a previous run. + QDir dir(dirName); + QVERIFY(!dir.exists()); + QVERIFY(QDir::current().mkdir(dirName)); + QVERIFY(!QDir::current().mkdir(dirName)); // calling mkdir on an existing dir will fail. + QVERIFY(QDir::current().mkpath(dirName)); // calling mkpath on an existing dir will pass +} + void tst_QDir::rmdir_data() { QTest::addColumn<QString>("path"); @@ -374,6 +420,9 @@ void tst_QDir::isRelativePath_data() #endif QTest::newRow("data2") << "somedir" << true; QTest::newRow("data3") << "/somedir" << false; + + QTest::newRow("resource0") << ":/prefix" << false; + QTest::newRow("resource1") << ":/prefix/foo.bar" << false; } void tst_QDir::isRelativePath() @@ -525,6 +574,12 @@ void tst_QDir::entryList_data() << int(QDir::AllEntries | QDir::Writable) << int(QDir::Name) << filterLinks(QString(".,..,directory,linktodirectory.lnk,writable").split(',')); #endif + QTest::newRow("QDir::Files | QDir::Readable") << SRCDIR "entrylist/" << QStringList("*") + << int(QDir::Files | QDir::Readable) << int(QDir::Name) + << filterLinks(QString("file,linktofile.lnk,writable").split(',')); + QTest::newRow("QDir::Dirs | QDir::Readable") << SRCDIR "entrylist/" << QStringList("*") + << int(QDir::Dirs | QDir::Readable) << int(QDir::Name) + << filterLinks(QString(".,..,directory,linktodirectory.lnk").split(',')); QTest::newRow("Namefilters b*") << SRCDIR "entrylist/" << QStringList("d*") << int(QDir::NoFilter) << int(QDir::Name) << filterLinks(QString("directory").split(',')); @@ -587,6 +642,7 @@ void tst_QDir::entryList() expected.removeAll(".."); #endif +#ifndef Q_NO_SYMLINKS #if defined(Q_OS_WIN) // ### Sadly, this is a platform difference right now. QFile::link(SRCDIR "entryList/file", SRCDIR "entrylist/linktofile.lnk"); @@ -641,6 +697,7 @@ void tst_QDir::entryList() QFile::link("directory", SRCDIR "entrylist/linktodirectory.lnk"); QFile::link("nothing", SRCDIR "entrylist/brokenlink.lnk"); #endif +#endif //Q_NO_SYMLINKS #ifdef Q_WS_MAC if (qstrcmp(QTest::currentDataTag(), "unprintablenames") == 0) @@ -802,6 +859,26 @@ void tst_QDir::canonicalPath_data() QTest::newRow("absPath") << appPath + "\\testData\\..\\testData" << appPath + "/testData"; #endif QTest::newRow("nonexistant") << "testd" << QString(); + + QTest::newRow("rootPath") << QDir::rootPath() << QDir::rootPath(); + +#ifdef Q_OS_MAC + // On Mac OS X 10.5 and earlier, canonicalPath depends on cleanPath which + // is itself very broken and fundamentally wrong on "/./" which, this would + // exercise + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) +#endif + QTest::newRow("rootPath + ./") << QDir::rootPath().append("./") << QDir::rootPath(); + + QTest::newRow("rootPath + ../.. ") << QDir::rootPath().append("../..") << QDir::rootPath(); +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + QTest::newRow("drive:\\") << QDir::toNativeSeparators(QDir::rootPath()) << QDir::rootPath(); + QTest::newRow("drive:\\.\\") << QDir::toNativeSeparators(QDir::rootPath().append("./")) << QDir::rootPath(); + QTest::newRow("drive:\\..\\..") << QDir::toNativeSeparators(QDir::rootPath().append("../..")) << QDir::rootPath(); + QTest::newRow("drive:") << QDir().canonicalPath().left(2) << QDir().canonicalPath(); +#endif + + QTest::newRow("resource") << ":/tst_qdir/resources/entryList" << ":/tst_qdir/resources/entryList"; } void tst_QDir::canonicalPath() @@ -870,7 +947,7 @@ void tst_QDir::current() if (!path.isEmpty()) { bool b = QDir::setCurrent(path); - // If path is non existant, then setCurrent should be false (currentDir is empty in testData) + // If path is non existent, then setCurrent should be false (currentDir is empty in testData) QVERIFY(b == !currentDir.isEmpty()); } if (!currentDir.isEmpty()) { @@ -915,6 +992,7 @@ void tst_QDir::cd() QFETCH(QString, newDir); QDir d = startDir; + bool notUsed = d.exists(); // make sure we cache this before so we can see if 'cd' fails to flush this QCOMPARE(d.cd(cdDir), successExpected); if (successExpected) QCOMPARE(d.absolutePath(), newDir); @@ -994,6 +1072,9 @@ tst_QDir::cleanPath_data() QTest::newRow("data10") << "/:/" << "/:"; #endif #endif + + QTest::newRow("resource0") << ":/prefix/foo.bar" << ":/prefix/foo.bar"; + QTest::newRow("resource1") << "://prefix/..//prefix/foo.bar" << ":/prefix/foo.bar"; } @@ -1017,6 +1098,7 @@ void tst_QDir::absoluteFilePath_data() QTest::newRow("2") << "/" << "passwd" << "/passwd"; QTest::newRow("3") << "relative" << "path" << QDir::currentPath() + "/relative/path"; QTest::newRow("4") << "" << "" << QDir::currentPath(); + QTest::newRow("resource") << ":/prefix" << "foo.bar" << ":/prefix/foo.bar"; } void tst_QDir::absoluteFilePath() @@ -1045,6 +1127,7 @@ void tst_QDir::absolutePath_data() QTest::newRow("4") << "c:/machine/share/dir1" << "c:/machine/share/dir1"; QTest::newRow("5") << "c:\\machine\\share\\dir1" << "c:/machine/share/dir1"; #endif + QTest::newRow("resource") << ":/prefix/foo.bar" << ":/prefix/foo.bar"; } void tst_QDir::absolutePath() @@ -1084,26 +1167,29 @@ void tst_QDir::relativeFilePath_data() QTest::newRow("14") << "C:/foo/bar" << "/ding/dong" << "../../ding/dong"; QTest::newRow("15") << "C:/foo/bar" << "D:/ding/dong" << "D:/ding/dong"; QTest::newRow("16") << "C:" << "C:/ding/dong" << "ding/dong"; - QTest::newRow("16") << "C:/" << "C:/ding/dong" << "ding/dong"; - QTest::newRow("17") << "C:" << "C:" << ""; - QTest::newRow("18") << "C:/" << "C:" << ""; - QTest::newRow("19") << "C:" << "C:/" << ""; - QTest::newRow("20") << "C:/" << "C:/" << ""; - QTest::newRow("17") << "C:" << "C:file.txt" << "file.txt"; - QTest::newRow("18") << "C:/" << "C:file.txt" << "file.txt"; - QTest::newRow("19") << "C:" << "C:/file.txt" << "file.txt"; - QTest::newRow("20") << "C:/" << "C:/file.txt" << "file.txt"; - QTest::newRow("21") << "C:" << "D:" << "D:"; - QTest::newRow("22") << "C:" << "D:/" << "D:/"; - QTest::newRow("23") << "C:/" << "D:" << "D:"; - QTest::newRow("24") << "C:/" << "D:/" << "D:/"; + QTest::newRow("17") << "C:/" << "C:/ding/dong" << "ding/dong"; + QTest::newRow("18") << "C:" << "C:" << ""; + QTest::newRow("19") << "C:/" << "C:" << ""; + QTest::newRow("20") << "C:" << "C:/" << ""; + QTest::newRow("21") << "C:/" << "C:/" << ""; + QTest::newRow("22") << "C:" << "C:file.txt" << "file.txt"; + QTest::newRow("23") << "C:/" << "C:file.txt" << "file.txt"; + QTest::newRow("24") << "C:" << "C:/file.txt" << "file.txt"; + QTest::newRow("25") << "C:/" << "C:/file.txt" << "file.txt"; + QTest::newRow("26") << "C:" << "D:" << "D:"; + QTest::newRow("27") << "C:" << "D:/" << "D:/"; + QTest::newRow("28") << "C:/" << "D:" << "D:"; + QTest::newRow("29") << "C:/" << "D:/" << "D:/"; # if !defined(Q_OS_SYMBIAN) - QTest::newRow("25") << "C:/foo/bar" << "//anotherHost/foo/bar" << "//anotherHost/foo/bar"; - QTest::newRow("26") << "//anotherHost/foo" << "//anotherHost/foo/bar" << "bar"; - QTest::newRow("27") << "//anotherHost/foo" << "bar" << "bar"; - QTest::newRow("28") << "//anotherHost/foo" << "C:/foo/bar" << "C:/foo/bar"; + QTest::newRow("30") << "C:/foo/bar" << "//anotherHost/foo/bar" << "//anotherHost/foo/bar"; + QTest::newRow("31") << "//anotherHost/foo" << "//anotherHost/foo/bar" << "bar"; + QTest::newRow("32") << "//anotherHost/foo" << "bar" << "bar"; + QTest::newRow("33") << "//anotherHost/foo" << "C:/foo/bar" << "C:/foo/bar"; # endif #endif + + QTest::newRow("resource0") << ":/prefix" << "foo.bar" << "foo.bar"; + QTest::newRow("resource1") << ":/prefix" << ":/prefix/foo.bar" << "foo.bar"; } void tst_QDir::relativeFilePath() @@ -1126,6 +1212,7 @@ void tst_QDir::filePath_data() QTest::newRow("2") << "/" << "passwd" << "/passwd"; QTest::newRow("3") << "relative" << "path" << "relative/path"; QTest::newRow("4") << "" << "" << "."; + QTest::newRow("resource") << ":/prefix" << "foo.bar" << ":/prefix/foo.bar"; } void tst_QDir::filePath() @@ -1147,6 +1234,8 @@ void tst_QDir::remove() QDir dir; QVERIFY(dir.remove("remove-test")); QVERIFY(!dir.remove("/remove-test")); + QTest::ignoreMessage(QtWarningMsg, "QDir::remove: Empty or null file name"); + QVERIFY(!dir.remove("")); } void tst_QDir::rename() @@ -1159,10 +1248,18 @@ void tst_QDir::rename() QVERIFY(dir.rename("rename-test-renamed", "rename-test")); #if defined(Q_OS_MAC) QVERIFY(!dir.rename("rename-test", "/etc/rename-test-renamed")); -#elif !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN) - // on windows/symbian this is possible - maybe make the test a bit better +#elif defined(Q_OS_SYMBIAN) + QVERIFY(!dir.rename("rename-test", "/resource/rename-test-renamed")); +#elif !defined(Q_OS_WIN) + // on windows this is possible - maybe make the test a bit better QVERIFY(!dir.rename("rename-test", "/rename-test-renamed")); #endif + QTest::ignoreMessage(QtWarningMsg, "QDir::rename: Empty or null file name(s)"); + QVERIFY(!dir.rename("rename-test", "")); + QTest::ignoreMessage(QtWarningMsg, "QDir::rename: Empty or null file name(s)"); + QVERIFY(!dir.rename("", "rename-test-renamed")); + QVERIFY(!dir.rename("some-file-that-does-not-exist", "rename-test-renamed")); + QVERIFY(dir.remove("rename-test")); } @@ -1178,6 +1275,8 @@ void tst_QDir::exists2_data() QTest::newRow("4") << "/testData" << false; QTest::newRow("5") << "tst_qdir.cpp" << true; QTest::newRow("6") << "/resources.cpp" << false; + QTest::newRow("resource0") << ":/prefix/foo.bar" << false; + QTest::newRow("resource1") << ":/tst_qdir/resources/entryList/file1.data" << true; } void tst_QDir::exists2() @@ -1214,6 +1313,8 @@ void tst_QDir::dirName_data() QTest::newRow("bslash1") << "\\winnt\\system32" << "system32"; QTest::newRow("bslash2") << "c:\\winnt\\system32\\kernel32.dll" << "kernel32.dll"; #endif + + QTest::newRow("resource") << ":/prefix" << "prefix"; } void tst_QDir::dirName() @@ -1236,12 +1337,13 @@ void tst_QDir::dotAndDotDot() { #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) QSKIP("WinCE and Symbian do not have . nor ..", SkipAll); -#endif +#else QDir dir(QString(SRCDIR "testdir/")); QStringList entryList = dir.entryList(QDir::Dirs); QCOMPARE(entryList, QStringList() << QString(".") << QString("..") << QString("dir") << QString("spaces")); entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); QCOMPARE(entryList, QStringList() << QString("dir") << QString("spaces")); +#endif } #ifdef QT3_SUPPORT @@ -1396,6 +1498,29 @@ void tst_QDir::searchPaths() for (int i = 0; i < searchPathPrefixList.count(); ++i) { QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty()); } + + for (int i = 0; i < searchPathPrefixList.count(); ++i) { + foreach (QString path, searchPathsList.at(i).split(",")) { + QDir::addSearchPath(searchPathPrefixList.at(i), path); + } + } + for (int i = 0; i < searchPathPrefixList.count(); ++i) { + QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)) == searchPathsList.at(i).split(",")); + } + + QCOMPARE(QFile(filename).exists(), exists); + QCOMPARE(QFileInfo(filename).exists(), exists); + + if (exists) { + QCOMPARE(QFileInfo(filename).absoluteFilePath(), expectedAbsolutePath); + } + + for (int i = 0; i < searchPathPrefixList.count(); ++i) { + QDir::setSearchPaths(searchPathPrefixList.at(i), QStringList()); + } + for (int i = 0; i < searchPathPrefixList.count(); ++i) { + QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty()); + } } void tst_QDir::entryListWithSearchPaths() @@ -1640,6 +1765,252 @@ void tst_QDir::detachingOperations() QCOMPARE(dir1.sorting(), sorting); } +void tst_QDir::testCaching() +{ + QString dirName = QString::fromLatin1("testCaching"); + QDir::current().rmdir(dirName); // cleanup a previous run. + QDir dir(dirName); + QVERIFY(!dir.exists()); + QDir::current().mkdir(dirName); + QVERIFY(QDir(dirName).exists()); // dir exists + QVERIFY(dir.exists()); // QDir doesn't cache the 'exist' between calls. +} + +void tst_QDir::isRoot_data() +{ + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("isRoot"); + + QString test = QDir::rootPath(); + QTest::newRow(QString("rootPath " + test).toLatin1()) << test << true; + test = QDir::rootPath().append("./"); + QTest::newRow(QString("./ appended " + test).toLatin1()) << test << false; + + test = QDir(QDir::rootPath().append("./")).canonicalPath(); +#ifdef Q_OS_MAC + // On Mac OS X 10.5 and earlier, canonicalPath depends on cleanPath which + // is itself very broken and fundamentally wrong on "/./", which this would + // exercise + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) +#endif + QTest::newRow(QString("canonicalPath " + test).toLatin1()) << test << true; + +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + test = QDir::rootPath().left(2); + QTest::newRow(QString("drive relative " + test).toLatin1()) << test << false; +#endif + + QTest::newRow("resources root") << ":/" << true; + QTest::newRow("resources nonroot") << ":/entrylist" << false; +} + +void tst_QDir::isRoot() +{ + QFETCH(QString, path); + QFETCH(bool, isRoot); + + QDir dir(path); + QCOMPARE(dir.isRoot(),isRoot); +} + +#ifndef QT_NO_REGEXP +void tst_QDir::match_data() +{ + QTest::addColumn<QString>("filter"); + QTest::addColumn<QString>("filename"); + QTest::addColumn<bool>("match"); + + QTest::newRow("single, matching") << "*.cpp" << "tst_qdir.cpp" << true; + QTest::newRow("single, not matching") << "*.cpp" << "tst_qdir.h" << false; + QTest::newRow("multi, matching") << "*.cpp;*.h" << "tst_qdir.cpp" << true; + QTest::newRow("multi, matching2") << "*.cpp;*.h" << "tst_qdir.h" << true; + QTest::newRow("multi, not matching") << "*.cpp;*.h" << "readme.txt" << false; +} + +void tst_QDir::match() +{ + QFETCH(QString, filter); + QFETCH(QString, filename); + QFETCH(bool, match); + + QCOMPARE(QDir::match(filter, filename), match); + QCOMPARE(QDir::match(filter.split(QLatin1Char(';')), filename), match); +} +#endif + +void tst_QDir::drives() +{ + QFileInfoList list(QDir::drives()); +#if defined(Q_OS_WIN) + QVERIFY(list.count() >= 1); //system + QLatin1Char systemdrive('c'); +#elif defined(Q_OS_SYMBIAN) + QVERIFY(list.count() >= 2); //system, rom + QLatin1Char romdrive('z'); + QLatin1Char systemdrive('a' + int(RFs::GetSystemDrive())); +#endif +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + QVERIFY(list.count() <= 26); + bool foundsystem = false; +#ifdef Q_OS_SYMBIAN + bool foundrom = false; +#endif + foreach (QFileInfo fi, list) { + QCOMPARE(fi.absolutePath().size(), 3); //"x:/" + QCOMPARE(fi.absolutePath().at(1), QChar(QLatin1Char(':'))); + QCOMPARE(fi.absolutePath().at(2), QChar(QLatin1Char('/'))); + if (fi.absolutePath().at(0).toLower() == systemdrive) + foundsystem = true; +#ifdef Q_OS_SYMBIAN + if (fi.absolutePath().at(0).toLower() == romdrive) + foundrom = true; +#endif + } + QCOMPARE(foundsystem, true); +#ifdef Q_OS_SYMBIAN + QCOMPARE(foundrom, true); +#endif +#else + QCOMPARE(list.count(), 1); //root + QCOMPARE(list.at(0).absolutePath(), QLatin1String("/")); +#endif +} + +void tst_QDir::arrayOperator() +{ + QDir dir1(SRCDIR "entrylist/"); + QDir dir2(SRCDIR "entrylist/"); + + QStringList entries(dir1.entryList()); + int i = dir2.count(); + QCOMPARE(i, entries.count()); + --i; + for (;i>=0;--i) { + QCOMPARE(dir2[i], entries.at(i)); + } +} + +#ifdef QT3_SUPPORT +void tst_QDir::setNameFilter() +{ + QStringList filters; + filters << "*.jpg" << "*.png" << "*.gif"; + QStringList filters2; + filters2 << "*.cpp" << "*.h" << "*.c"; + + QDir dir(SRCDIR "entrylist/"); + + dir.setNameFilter(filters.join(";")); + QCOMPARE(filters, dir.nameFilters()); + QCOMPARE(filters, dir.nameFilter().split(';')); + + dir.setNameFilters(filters2); + QCOMPARE(filters2, dir.nameFilter().split(';')); + + dir.setNameFilter(filters.join(" ")); + QCOMPARE(filters, dir.nameFilters()); + QCOMPARE(filters, dir.nameFilter().split(' ')); + + dir.setNameFilters(filters2); + QCOMPARE(filters2, dir.nameFilter().split(' ')); +} +#endif + +void tst_QDir::equalityOperator_data() +{ + QTest::addColumn<QString>("leftPath"); + QTest::addColumn<QString>("leftNameFilters"); + QTest::addColumn<int>("leftSort"); + QTest::addColumn<int>("leftFilters"); + QTest::addColumn<QString>("rightPath"); + QTest::addColumn<QString>("rightNameFilters"); + QTest::addColumn<int>("rightSort"); + QTest::addColumn<int>("rightFilters"); + QTest::addColumn<bool>("expected"); + + QTest::newRow("same") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << true; + + QTest::newRow("relativepaths") << "entrylist/" << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << "./entrylist" << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << true; + + QTest::newRow("diff-filters") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Dirs) + << false; + + QTest::newRow("diff-sort") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << SRCDIR << "*.cpp" << int(QDir::Time) << int(QDir::Files) + << false; + + QTest::newRow("diff-namefilters") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << SRCDIR << "*.jpg" << int(QDir::Name) << int(QDir::Files) + << false; +} + +void tst_QDir::equalityOperator() +{ + QFETCH(QString, leftPath); + QFETCH(QString, leftNameFilters); + QFETCH(int, leftSort); + QFETCH(int, leftFilters); + QFETCH(QString, rightPath); + QFETCH(QString, rightNameFilters); + QFETCH(int, rightSort); + QFETCH(int, rightFilters); + QFETCH(bool, expected); + + QDir dir1(leftPath, leftNameFilters, QDir::SortFlags(leftSort), QDir::Filters(leftFilters)); + QDir dir2(rightPath, rightNameFilters, QDir::SortFlags(rightSort), QDir::Filters(rightFilters)); + + QCOMPARE((dir1 == dir2), expected); + QCOMPARE((dir2 == dir1), expected); + QCOMPARE((dir1 != dir2), !expected); + QCOMPARE((dir2 != dir1), !expected); +} + +void tst_QDir::isRelative_data() +{ + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("relative"); + + QTest::newRow(".") << "./" << true; + QTest::newRow("..") << "../" << true; + QTest::newRow("content") << "entrylist/" << true; + QTest::newRow("current") << QDir::currentPath() << false; + QTest::newRow("homepath") << QDir::homePath() << false; + QTest::newRow("temppath") << QDir::tempPath() << false; + QTest::newRow("rootpath") << QDir::rootPath() << false; + foreach (QFileInfo root, QDir::drives()) { + QTest::newRow(root.absolutePath().toLocal8Bit()) << root.absolutePath() << false; + } + + QTest::newRow("resource") << ":/prefix" << false; +} + +void tst_QDir::isRelative() +{ + QFETCH(QString, path); + QFETCH(bool, relative); + + QCOMPARE(QDir(path).isRelative(), relative); +} + +void tst_QDir::isReadable() +{ + QDir dir; + + QVERIFY(dir.isReadable()); +#if defined (Q_OS_UNIX) && !defined (Q_OS_SYMBIAN) + QVERIFY(dir.mkdir("nonreadabledir")); + QVERIFY(0 == ::chmod("nonreadabledir", 0)); + QVERIFY(!QDir("nonreadabledir").isReadable()); + QVERIFY(0 == ::chmod("nonreadabledir", S_IRUSR | S_IWUSR | S_IXUSR)); + QVERIFY(dir.rmdir("nonreadabledir")); +#endif +} + QTEST_MAIN(tst_QDir) #include "tst_qdir.moc" diff --git a/tests/auto/qdiriterator/qdiriterator.pro b/tests/auto/qdiriterator/qdiriterator.pro index d60b52d..0807a18 100644 --- a/tests/auto/qdiriterator/qdiriterator.pro +++ b/tests/auto/qdiriterator/qdiriterator.pro @@ -3,10 +3,6 @@ SOURCES += tst_qdiriterator.cpp RESOURCES += qdiriterator.qrc QT = core -wince*|symbian: { - addFiles.sources = entrylist recursiveDirs foo - addFiles.path = . - DEPLOYMENT += addFiles wince*mips*|wincewm50smart-msvc200*: DEFINES += WINCE_BROKEN_ITERATE=1 -} +CONFIG += parallel_test diff --git a/tests/auto/qdiriterator/tst_qdiriterator.cpp b/tests/auto/qdiriterator/tst_qdiriterator.cpp index ea1ea3d..42ac065 100644 --- a/tests/auto/qdiriterator/tst_qdiriterator.cpp +++ b/tests/auto/qdiriterator/tst_qdiriterator.cpp @@ -53,10 +53,14 @@ #endif #if defined(Q_OS_SYMBIAN) -// Open C in Symbian doesn't support symbolic links to directories +#define Q_NO_SYMLINKS #define Q_NO_SYMLINKS_TO_DIRS #endif +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#include "../network-settings.h" +#endif + Q_DECLARE_METATYPE(QDirIterator::IteratorFlags) Q_DECLARE_METATYPE(QDir::Filters) @@ -118,6 +122,10 @@ private slots: void longPath(); void task185502_dirorder(); void relativePaths(); +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + void uncPaths_data(); + void uncPaths(); +#endif void qtbug15421_hiddenDirs_hiddenFiles(); }; @@ -148,6 +156,8 @@ tst_QDirIterator::tst_QDirIterator() createDirectory("foo/bar"); createFile("foo/bar/readme.txt"); + createDirectory("empty"); + #ifndef Q_NO_SYMLINKS # if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) // ### Sadly, this is a platform difference right now. @@ -303,6 +313,20 @@ void tst_QDirIterator::iterateRelativeDirectory_data() #endif "entrylist/directory/dummy," "entrylist/writable").split(','); + + QTest::newRow("empty, default") + << QString("empty") << QDirIterator::IteratorFlags(0) + << QDir::Filters(QDir::NoFilter) << QStringList("*") +#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE) + << QStringList(); +#else + << QString("empty/.,empty/..").split(','); +#endif + + QTest::newRow("empty, QDir::NoDotAndDotDot") + << QString("empty") << QDirIterator::IteratorFlags(0) + << QDir::Filters(QDir::NoDotAndDotDot) << QStringList("*") + << QStringList(); } void tst_QDirIterator::iterateRelativeDirectory() @@ -547,6 +571,28 @@ void tst_QDirIterator::relativePaths() } } +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +void tst_QDirIterator::uncPaths_data() +{ + QTest::addColumn<QString>("dirName"); + QTest::newRow("uncserver") + <<QString("//" + QtNetworkSettings::winServerName()); + QTest::newRow("uncserver/testshare") + <<QString("//" + QtNetworkSettings::winServerName() + "/testshare"); + QTest::newRow("uncserver/testshare/tmp") + <<QString("//" + QtNetworkSettings::winServerName() + "/testshare/tmp"); +} +void tst_QDirIterator::uncPaths() +{ + QFETCH(QString, dirName); + QDirIterator iterator(dirName, QDir::AllEntries|QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + while(iterator.hasNext()) { + iterator.next(); + QCOMPARE(iterator.filePath(), QDir::cleanPath(iterator.filePath())); + } +} +#endif + void tst_QDirIterator::qtbug15421_hiddenDirs_hiddenFiles() { // In Unix it is easy to create hidden files, but in Windows it requires diff --git a/tests/auto/qdirmodel/qdirmodel.pro b/tests/auto/qdirmodel/qdirmodel.pro index 36929b9..7037a79 100644 --- a/tests/auto/qdirmodel/qdirmodel.pro +++ b/tests/auto/qdirmodel/qdirmodel.pro @@ -2,11 +2,11 @@ load(qttest_p4) SOURCES += tst_qdirmodel.cpp wince*|symbian { - addit.sources = dirtest\\test1\\* + addit.files = dirtest\\test1\\* addit.path = dirtest\\test1 - tests.sources = test\\* + tests.files = test\\* tests.path = test - sourceFile.sources = tst_qdirmodel.cpp + sourceFile.files = tst_qdirmodel.cpp sourceFile.path = . DEPLOYMENT += addit tests sourceFile } diff --git a/tests/auto/qdirmodel/tst_qdirmodel.cpp b/tests/auto/qdirmodel/tst_qdirmodel.cpp index 8ebcf12..db424a2 100644 --- a/tests/auto/qdirmodel/tst_qdirmodel.cpp +++ b/tests/auto/qdirmodel/tst_qdirmodel.cpp @@ -583,19 +583,15 @@ void tst_QDirModel::unreadable() void tst_QDirModel::filePath() { +#ifdef Q_OS_SYMBIAN + QSKIP("OS doesn't support symbolic links", SkipAll); +#else QFile::remove(SRCDIR "test.lnk"); QVERIFY(QFile(SRCDIR "tst_qdirmodel.cpp").link(SRCDIR "test.lnk")); QDirModel model; model.setResolveSymlinks(false); QModelIndex index = model.index(SRCDIR "test.lnk"); QVERIFY(index.isValid()); -#if defined(Q_OS_SYMBIAN) - // Since model will force lowercase path in Symbian, make case insensitive compare - // Note: Windows should fail this, too, if test path has any uppercase letters. - QCOMPARE(model.filePath(index).toLower(), QString(SRCDIR).toLower() + "test.lnk"); - model.setResolveSymlinks(true); - QCOMPARE(model.filePath(index).toLower(), QString(SRCDIR).toLower() + "tst_qdirmodel.cpp"); -#else #ifndef Q_OS_WINCE QString path = SRCDIR; #else @@ -604,8 +600,8 @@ void tst_QDirModel::filePath() QCOMPARE(model.filePath(index), path + QString( "test.lnk")); model.setResolveSymlinks(true); QCOMPARE(model.filePath(index), path + QString( "tst_qdirmodel.cpp")); -#endif QFile::remove(SRCDIR "test.lnk"); +#endif } void tst_QDirModel::task196768_sorting() @@ -613,11 +609,6 @@ void tst_QDirModel::task196768_sorting() //this task showed that the persistent model indexes got corrupted when sorting QString path = SRCDIR; -#ifdef Q_OS_SYMBIAN - if(!RProcess().HasCapability(ECapabilityAllFiles)) - QEXPECT_FAIL("", "QTBUG-9746", Continue); -#endif - QDirModel model; /* QDirModel has a bug if we show the content of the subdirectory inside a hidden directory @@ -637,6 +628,11 @@ void tst_QDirModel::task196768_sorting() QCOMPARE(index.data(), index2.data()); view.setSortingEnabled(true); index2 = model.index(path); + +#ifdef Q_OS_SYMBIAN + if(!RProcess().HasCapability(ECapabilityAllFiles)) + QEXPECT_FAIL("", "QTBUG-9746", Continue); +#endif QCOMPARE(index.data(), index2.data()); } @@ -645,10 +641,10 @@ void tst_QDirModel::filter() QDirModel model; model.setNameFilters(QStringList() << "*.nada"); QModelIndex index = model.index(SRCDIR "test"); - Q_ASSERT(model.rowCount(index) == 0); + QCOMPARE(model.rowCount(index), 0); QModelIndex index2 = model.index(SRCDIR "test/file01.tst"); - Q_ASSERT(!index2.isValid()); - Q_ASSERT(model.rowCount(index) == 0); + QVERIFY(!index2.isValid()); + QCOMPARE(model.rowCount(index), 0); } void tst_QDirModel::task244669_remove() diff --git a/tests/auto/qdom/qdom.pro b/tests/auto/qdom/qdom.pro index 9040b91..0a3c167 100644 --- a/tests/auto/qdom/qdom.pro +++ b/tests/auto/qdom/qdom.pro @@ -5,7 +5,7 @@ QT = core xml QT -= gui wince*|symbian: { - addFiles.sources = testdata doubleNamespaces.xml umlaut.xml + addFiles.files = testdata doubleNamespaces.xml umlaut.xml addFiles.path = . DEPLOYMENT += addFiles diff --git a/tests/auto/qdom/tst_qdom.cpp b/tests/auto/qdom/tst_qdom.cpp index f30d3bc..4093010 100644 --- a/tests/auto/qdom/tst_qdom.cpp +++ b/tests/auto/qdom/tst_qdom.cpp @@ -137,7 +137,6 @@ private slots: private: static QDomDocument generateRequest(); - static QDomDocument doc(const QString &title, const QByteArray &ba); static int hasAttributesHelper( const QDomNode& node ); static bool compareDocuments( const QDomDocument &doc1, const QDomDocument &doc2 ); static bool compareNodes( const QDomNode &node1, const QDomNode &node2, bool deep ); @@ -1591,14 +1590,6 @@ void tst_QDom::reportDuplicateAttributes() const QVERIFY2(!isSuccess, "Duplicate attributes are well-formedness errors, and should be reported as such."); } -QDomDocument tst_QDom::doc(const QString &title, const QByteArray &ba) -{ - QDomDocument doc(title); - const bool ret = doc.setContent(ba, true); - Q_ASSERT(ret); - return doc; -} - void tst_QDom::namespacedAttributes() const { static const char *const xml = @@ -1611,8 +1602,13 @@ void tst_QDom::namespacedAttributes() const " <Title displayLabel='Title' >>>> SIMPLE BASIC OP - SEND - DUT AS SINK</Title>\n" "</xan:td>\n"; - QDomDocument one = doc("document", xml); - QDomDocument two = doc("document2", one.toByteArray(2)); + QDomDocument one("document"); + QString error; + bool docParsed = one.setContent(QByteArray(xml), true, &error); + QVERIFY2(docParsed, qPrintable(error)); + QDomDocument two("document2"); + docParsed = two.setContent(one.toByteArray(2), true, &error); + QVERIFY2(docParsed, qPrintable(error)); QVERIFY(isDeepEqual(one, two)); } diff --git a/tests/auto/qeasingcurve/qeasingcurve.pro b/tests/auto/qeasingcurve/qeasingcurve.pro index 2b66081..2a3a075 100644 --- a/tests/auto/qeasingcurve/qeasingcurve.pro +++ b/tests/auto/qeasingcurve/qeasingcurve.pro @@ -1,3 +1,4 @@ load(qttest_p4) QT = core SOURCES += tst_qeasingcurve.cpp +CONFIG += parallel_test diff --git a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp index cd80189..851a9d4 100644 --- a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp @@ -42,10 +42,6 @@ #include <QtTest/QtTest> -#if QT_VERSION < 0x040200 -QTEST_NOOP_MAIN -#else - #include <qeasingcurve.h> //TESTED_CLASS= @@ -578,5 +574,3 @@ void tst_QEasingCurve::metaTypes() QTEST_MAIN(tst_QEasingCurve) #include "tst_qeasingcurve.moc" - -#endif //QT_VERSION diff --git a/tests/auto/qelapsedtimer/qelapsedtimer.pro b/tests/auto/qelapsedtimer/qelapsedtimer.pro index ed75228..8768876 100644 --- a/tests/auto/qelapsedtimer/qelapsedtimer.pro +++ b/tests/auto/qelapsedtimer/qelapsedtimer.pro @@ -11,3 +11,4 @@ wince* { DEFINES += SRCDIR=\\\"$$PWD/\\\" } +CONFIG += parallel_test diff --git a/tests/auto/qelapsedtimer/tst_qelapsedtimer.cpp b/tests/auto/qelapsedtimer/tst_qelapsedtimer.cpp index a5470db..40b2d30 100644 --- a/tests/auto/qelapsedtimer/tst_qelapsedtimer.cpp +++ b/tests/auto/qelapsedtimer/tst_qelapsedtimer.cpp @@ -122,11 +122,13 @@ void tst_QElapsedTimer::basics() quint64 value1 = t1.msecsSinceReference(); qDebug() << value1 << t1; + qint64 nsecs = t1.nsecsElapsed(); qint64 elapsed = t1.restart(); QVERIFY(elapsed < minResolution); + QVERIFY(nsecs / 1000000 < minResolution); quint64 value2 = t1.msecsSinceReference(); - qDebug() << value2 << t1 << elapsed; + qDebug() << value2 << t1 << elapsed << nsecs; // in theory, elapsed == value2 - value1 // However, since QElapsedTimer keeps internally the full resolution, @@ -150,7 +152,10 @@ void tst_QElapsedTimer::elapsed() // don't check: t1.secsTo(t2) // QVERIFY(t1 - t2 < 0); + QVERIFY(t1.nsecsElapsed() > 0); QVERIFY(t1.elapsed() > 0); + // the number of elapsed nanoseconds and milliseconds should match + QVERIFY(t1.nsecsElapsed() - t1.elapsed() * 1000000 < 1000000); QVERIFY(t1.hasExpired(minResolution)); QVERIFY(!t1.hasExpired(8*minResolution)); QVERIFY(!t2.hasExpired(minResolution)); diff --git a/tests/auto/qevent/qevent.pro b/tests/auto/qevent/qevent.pro index 5c14299..6042b6c 100644 --- a/tests/auto/qevent/qevent.pro +++ b/tests/auto/qevent/qevent.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qevent.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qeventloop/qeventloop.pro b/tests/auto/qeventloop/qeventloop.pro index f6c24ae..e7489fa 100644 --- a/tests/auto/qeventloop/qeventloop.pro +++ b/tests/auto/qeventloop/qeventloop.pro @@ -5,3 +5,4 @@ QT += network win32:!wince*:LIBS += -luser32 +symbian:TARGET.CAPABILITY += NetworkServices
\ No newline at end of file diff --git a/tests/auto/qeventloop/tst_qeventloop.cpp b/tests/auto/qeventloop/tst_qeventloop.cpp index 3c0992b..b31f8cd 100644 --- a/tests/auto/qeventloop/tst_qeventloop.cpp +++ b/tests/auto/qeventloop/tst_qeventloop.cpp @@ -602,8 +602,10 @@ public slots: QTcpSocket *serverSocket = server->nextPendingConnection(); serverSocket->write(data, size); serverSocket->flush(); + QTest::qSleep(200); //allow the TCP/IP stack time to loopback the data, so our socket is ready to read QCoreApplication::processEvents(QEventLoop::ExcludeSocketNotifiers); testResult = dataArrived; + QCoreApplication::processEvents(); //check the deferred event is processed serverSocket->close(); QThread::currentThread()->exit(0); } @@ -620,9 +622,11 @@ public: if (tester->init()) exec(); testResult = tester->testResult; + dataArrived = tester->dataArrived; delete tester; } bool testResult; + bool dataArrived; }; void tst_QEventLoop::processEventsExcludeSocket() @@ -631,6 +635,7 @@ void tst_QEventLoop::processEventsExcludeSocket() thread.start(); QVERIFY(thread.wait()); QVERIFY(!thread.testResult); + QVERIFY(thread.dataArrived); } class TimerReceiver : public QObject diff --git a/tests/auto/qexplicitlyshareddatapointer/qexplicitlyshareddatapointer.pro b/tests/auto/qexplicitlyshareddatapointer/qexplicitlyshareddatapointer.pro index 8a45aa2..cf574ff 100644 --- a/tests/auto/qexplicitlyshareddatapointer/qexplicitlyshareddatapointer.pro +++ b/tests/auto/qexplicitlyshareddatapointer/qexplicitlyshareddatapointer.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qexplicitlyshareddatapointer.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qfile/largefile/largefile.pro b/tests/auto/qfile/largefile/largefile.pro index d67cb46..6407cb6 100644 --- a/tests/auto/qfile/largefile/largefile.pro +++ b/tests/auto/qfile/largefile/largefile.pro @@ -4,3 +4,5 @@ QT = core SOURCES += tst_largefile.cpp wince*: SOURCES += $$QT_SOURCE_TREE/src/corelib/kernel/qfunctions_wince.cpp + +CONFIG += parallel_test diff --git a/tests/auto/qfile/largefile/tst_largefile.cpp b/tests/auto/qfile/largefile/tst_largefile.cpp index df1664f..bf6cc68 100644 --- a/tests/auto/qfile/largefile/tst_largefile.cpp +++ b/tests/auto/qfile/largefile/tst_largefile.cpp @@ -160,13 +160,10 @@ static inline void appendRaw(QByteArray &array, T data) */ static inline void topUpWith(QByteArray &array, QByteArray filler, int size) { - Q_ASSERT(filler.size() > 0); - for (int i = (size - array.size()) / filler.size(); i > 0; --i) array.append(filler); if (array.size() < size) { - Q_ASSERT(size - array.size() < filler.size()); array.append(filler.left(size - array.size())); } } @@ -206,15 +203,12 @@ static inline QByteArray generateDataBlock(int blockSize, QString text, qint64 u QByteArray filler("0123456789"); block.append(filler.right(10 - block.size() % 10)); - topUpWith(block, filler, blockSize - 2 * sizeof(qint64)); + topUpWith(block, filler, blockSize - 3 * sizeof(qint64)); appendRaw(block, counter); appendRaw(block, userBits); appendRaw(block, randomBits); - Q_ASSERT( block.size() >= blockSize ); - block.resize(blockSize); - ++counter; return block; } diff --git a/tests/auto/qfile/qfile.pro b/tests/auto/qfile/qfile.pro index 727f660..f41d327 100644 --- a/tests/auto/qfile/qfile.pro +++ b/tests/auto/qfile/qfile.pro @@ -7,3 +7,4 @@ wince*|symbian:{ !symbian:SUBDIRS += largefile +CONFIG += parallel_test diff --git a/tests/auto/qfile/test/test.pro b/tests/auto/qfile/test/test.pro index 70c93ce..c0049b0 100644 --- a/tests/auto/qfile/test/test.pro +++ b/tests/auto/qfile/test/test.pro @@ -3,14 +3,14 @@ SOURCES += ../tst_qfile.cpp wince*|symbian { QT = core gui - files.sources += ..\\dosfile.txt ..\\noendofline.txt ..\\testfile.txt \ + files.files += ..\\dosfile.txt ..\\noendofline.txt ..\\testfile.txt \ ..\\testlog.txt ..\\two.dots.file ..\\tst_qfile.cpp \ ..\\Makefile ..\\forCopying.txt ..\\forRenaming.txt files.path = . - resour.sources += ..\\resources\\file1.ext1 + resour.files += ..\\resources\\file1.ext1 resour.path = resources - DEPLOYMENT = files resour + DEPLOYMENT += files resour } wince* { @@ -37,4 +37,6 @@ win32 { LIBS+=-lole32 -luuid } - +symbian { + LIBS+=-lefsrv +} diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 54c6bc3..b7a3373 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -70,9 +70,12 @@ #elif defined(Q_OS_WINCE) # include <qplatformdefs.h> # include <private/qfsfileengine_p.h> +#elif defined(Q_OS_SYMBIAN) +# include <f32file.h> #endif #include <stdio.h> +#include <errno.h> #include "../network-settings.h" #if defined(Q_OS_SYMBIAN) @@ -170,6 +173,7 @@ private slots: void encodeName(); void truncate(); void seekToPos(); + void seekAfterEndOfFile(); void FILEReadWrite(); void i18nFileName_data(); void i18nFileName(); @@ -210,6 +214,18 @@ private slots: void openStandardStreams(); + void resize_data(); + void resize(); + + void objectConstructors(); +#ifdef Q_OS_SYMBIAN + void platformSecurity_data(); + void platformSecurity(); +#endif + void caseSensitivity(); + + void autocloseHandle(); + // --- Task related tests below this line void task167217(); @@ -222,12 +238,20 @@ public: void invalidFile(); private: - enum FileType { OpenQFile, OpenFd, OpenStream }; + enum FileType { + OpenQFile, + OpenFd, + OpenStream, +#ifdef Q_OS_SYMBIAN + OpenRFile, +#endif + NumberOfFileTypes + }; void openStandardStreamsFileDescriptors(); void openStandardStreamsBufferedStreams(); - bool openFd(QFile &file, QIODevice::OpenMode mode) + bool openFd(QFile &file, QIODevice::OpenMode mode, QFile::FileHandleFlags handleFlags) { int fdMode = QT_OPEN_LARGEFILE | QT_OPEN_BINARY; @@ -239,10 +263,10 @@ private: fd_ = QT_OPEN(qPrintable(file.fileName()), fdMode); - return (-1 != fd_) && file.open(fd_, mode); + return (-1 != fd_) && file.open(fd_, mode, handleFlags); } - bool openStream(QFile &file, QIODevice::OpenMode mode) + bool openStream(QFile &file, QIODevice::OpenMode mode, QFile::FileHandleFlags handleFlags) { char const *streamMode = ""; @@ -254,10 +278,37 @@ private: stream_ = QT_FOPEN(qPrintable(file.fileName()), streamMode); - return stream_ && file.open(stream_, mode); + return stream_ && file.open(stream_, mode, handleFlags); + } + +#ifdef Q_OS_SYMBIAN + bool openRFile(QFile &file, QIODevice::OpenMode mode, QFile::FileHandleFlags handleFlags) + { + //connect file server first time + if (!rfs_.Handle() && rfs_.Connect() != KErrNone) + return false; + //symbian does not like ./ in filenames, so open by absolute path + QString fileName(QDir::toNativeSeparators(QFileInfo(file).absoluteFilePath())); + TPtrC fn(fileName.utf16(), fileName.length()); + TInt smode = 0; + if (mode & QIODevice::WriteOnly) + smode |= EFileWrite; + if (mode & QIODevice::ReadOnly) + smode |= EFileRead; + TInt r; + if ((mode & QIODevice::Truncate) || (!(mode & QIODevice::ReadOnly) && !(mode & QIODevice::Append))) { + r = rfile_.Replace(rfs_, fn, smode); + } else { + r = rfile_.Open(rfs_, fn, smode); + if (r == KErrNotFound && (mode & QIODevice::WriteOnly)) { + r = rfile_.Create(rfs_, fn, smode); + } + } + return (r == KErrNone) && file.open(rfile_, mode, handleFlags); } +#endif - bool openFile(QFile &file, QIODevice::OpenMode mode, FileType type = OpenQFile) + bool openFile(QFile &file, QIODevice::OpenMode mode, FileType type = OpenQFile, QFile::FileHandleFlags handleFlags = QFile::DontCloseHandle) { if (mode & QIODevice::WriteOnly && !file.exists()) { @@ -274,10 +325,14 @@ private: return file.open(mode); case OpenFd: - return openFd(file, mode); + return openFd(file, mode, handleFlags); case OpenStream: - return openStream(file, mode); + return openStream(file, mode, handleFlags); +#ifdef Q_OS_SYMBIAN + case OpenRFile: + return openRFile(file, mode, handleFlags); +#endif } return false; @@ -291,6 +346,10 @@ private: QT_CLOSE(fd_); if (stream_) ::fclose(stream_); +#ifdef Q_OS_SYMBIAN + if (rfile_.SubSessionHandle()) + rfile_.Close(); +#endif fd_ = -1; stream_ = 0; @@ -298,6 +357,10 @@ private: int fd_; FILE *stream_; +#ifdef Q_OS_SYMBIAN + RFs rfs_; + RFile rfile_; +#endif }; tst_QFile::tst_QFile() @@ -394,6 +457,7 @@ void tst_QFile::cleanupTestCase() QFile::remove("qfile_map_testfile"); QFile::remove("readAllBuffer.txt"); QFile::remove("qt_file.tmp"); + QFile::remove("File.txt"); } //------------------------------------------ @@ -402,7 +466,7 @@ void tst_QFile::cleanupTestCase() // attributes and the contents itself // will be changed as far as we have a // proper way to handle files in the -// testing enviroment. +// testing environment. //------------------------------------------ void tst_QFile::exists() @@ -1108,6 +1172,7 @@ void tst_QFile::permissions() QFETCH(bool, expected); QFile f(file); QCOMPARE(((f.permissions() & perms) == QFile::Permissions(perms)), expected); + QCOMPARE(((QFile::permissions(file) & perms) == QFile::Permissions(perms)), expected); } void tst_QFile::setPermissions() @@ -1285,17 +1350,32 @@ static QString getWorkingDirectoryForLink(const QString &linkFileName) void tst_QFile::link() { +#if defined(Q_OS_SYMBIAN) + QSKIP("Symbian does not support links", SkipAll); +#endif QFile::remove("myLink.lnk"); - QFileInfo info1("tst_qfile.cpp"); - QVERIFY(QFile::link("tst_qfile.cpp", "myLink.lnk")); + + QFileInfo info1(SRCDIR "tst_qfile.cpp"); + QString referenceTarget = QDir::cleanPath(info1.absoluteFilePath()); + + QVERIFY(QFile::link(SRCDIR "tst_qfile.cpp", "myLink.lnk")); + QFileInfo info2("myLink.lnk"); QVERIFY(info2.isSymLink()); - QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath()); + QCOMPARE(info2.symLinkTarget(), referenceTarget); + + QFile link("myLink.lnk"); + QVERIFY(link.open(QIODevice::ReadOnly)); + QCOMPARE(link.symLinkTarget(), referenceTarget); + link.close(); + + QCOMPARE(QFile::symLinkTarget("myLink.lnk"), referenceTarget); #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) QString wd = getWorkingDirectoryForLink(info2.absoluteFilePath()); - QCOMPARE(QDir::fromNativeSeparators(wd), info1.absolutePath()); + QCOMPARE(QDir::fromNativeSeparators(wd), QDir::cleanPath(info1.absolutePath())); #endif + QVERIFY(QFile::remove(info2.absoluteFilePath())); } @@ -1324,6 +1404,9 @@ void tst_QFile::linkToDir() void tst_QFile::absolutePathLinkToRelativePath() { +#if defined(Q_OS_SYMBIAN) + QSKIP("Symbian does not support links", SkipAll); +#endif QFile::remove("myDir/test.txt"); QFile::remove("myDir/myLink.lnk"); QDir dir; @@ -1346,6 +1429,9 @@ void tst_QFile::absolutePathLinkToRelativePath() void tst_QFile::readBrokenLink() { +#if defined(Q_OS_SYMBIAN) + QSKIP("Symbian does not support links", SkipAll); +#endif QFile::remove("myLink2.lnk"); QFileInfo info1("file12"); #if defined(Q_OS_SYMBIAN) @@ -1635,10 +1721,40 @@ void tst_QFile::seekToPos() } +void tst_QFile::seekAfterEndOfFile() +{ + QLatin1String filename("seekAfterEof.dat"); + QFile::remove(filename); + { + QFile file(filename); + QVERIFY(file.open(QFile::WriteOnly)); + file.write("abcd"); + QCOMPARE(file.size(), qint64(4)); + file.seek(8); + file.write("ijkl"); + QCOMPARE(file.size(), qint64(12)); + file.seek(4); + file.write("efgh"); + QCOMPARE(file.size(), qint64(12)); + file.seek(16); + file.write("----"); + QCOMPARE(file.size(), qint64(20)); + file.flush(); + } + + QFile file(filename); + QVERIFY(file.open(QFile::ReadOnly)); + QByteArray contents = file.readAll(); + QCOMPARE(contents.left(12), QByteArray("abcdefghijkl", 12)); + //bytes 12-15 are uninitialised so we don't care what they read as. + QCOMPARE(contents.mid(16), QByteArray("----", 4)); + file.close(); + QFile::remove(filename); +} void tst_QFile::FILEReadWrite() { - // Tests modifing a file. First creates it then reads in 4 bytes and then overwrites these + // Tests modifying a file. First creates it then reads in 4 bytes and then overwrites these // 4 bytes with new values. At the end check to see the file contains the new values. QFile::remove("FILEReadWrite.txt"); @@ -2150,6 +2266,9 @@ void tst_QFile::writeLargeDataBlock_data() QTest::newRow("localfile-QFile") << "./largeblockfile.txt" << (int)OpenQFile; QTest::newRow("localfile-Fd") << "./largeblockfile.txt" << (int)OpenFd; QTest::newRow("localfile-Stream") << "./largeblockfile.txt" << (int)OpenStream; +#ifdef Q_OS_SYMBIAN + QTest::newRow("localfile-RFile") << "./largeblockfile.txt" << (int)OpenRFile; +#endif #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) // Some semi-randomness to avoid collisions. @@ -2494,10 +2613,11 @@ void tst_QFile::standarderror() void tst_QFile::handle() { -#ifndef Q_OS_WINCE + int fd; +#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QFile file(SRCDIR "tst_qfile.cpp"); QVERIFY(file.open(QIODevice::ReadOnly)); - int fd = int(file.handle()); + fd = int(file.handle()); QVERIFY(fd > 2); QCOMPARE(int(file.handle()), fd); char c = '\0'; @@ -2524,6 +2644,7 @@ void tst_QFile::handle() QCOMPARE(c, '*'); #endif + //test round trip of adopted stdio file handle QFile file2; FILE *fp = fopen(SRCDIR "tst_qfile.cpp", "r"); file2.open(fp, QIODevice::ReadOnly); @@ -2531,6 +2652,7 @@ void tst_QFile::handle() QCOMPARE(int(file2.handle()), int(fileno(fp))); fclose(fp); + //test round trip of adopted posix file handle #ifdef Q_OS_UNIX QFile file3; fd = QT_OPEN(SRCDIR "tst_qfile.cpp", QT_OPEN_RDONLY); @@ -2542,6 +2664,9 @@ void tst_QFile::handle() void tst_QFile::nativeHandleLeaks() { +#ifdef Q_OS_SYMBIAN + QSKIP("test assumptions invalid for symbian", SkipAll); +#else int fd1, fd2; #ifdef Q_OS_WIN @@ -2583,6 +2708,7 @@ void tst_QFile::nativeHandleLeaks() #ifdef Q_OS_WIN QCOMPARE( handle2, handle1 ); #endif +#endif } void tst_QFile::readEof_data() @@ -2898,6 +3024,7 @@ void tst_QFile::mapOpenMode() { QFETCH(int, openMode); static const qint64 fileSize = 4096; + QByteArray pattern(fileSize, 'A'); QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile"; @@ -3028,7 +3155,7 @@ void tst_QFile::openStandardStreams() void tst_QFile::writeNothing() { - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < NumberOfFileTypes; ++i) { QFile file("file.txt"); QVERIFY( openFile(file, QIODevice::WriteOnly | QIODevice::Unbuffered, FileType(i)) ); QVERIFY( 0 == file.write((char *)0, 0) ); @@ -3037,5 +3164,241 @@ void tst_QFile::writeNothing() } } +void tst_QFile::resize_data() +{ + QTest::addColumn<int>("filetype"); + + QTest::newRow("native") << int(OpenQFile); + QTest::newRow("fileno") << int(OpenFd); + QTest::newRow("stream") << int(OpenStream); +#ifdef Q_OS_SYMBIAN + QTest::newRow("rfile") << int(OpenRFile); +#endif +} + +void tst_QFile::resize() +{ + QFETCH(int, filetype); + QString filename(QLatin1String("file.txt")); + QFile file(filename); + QVERIFY(openFile(file, QIODevice::ReadWrite, FileType(filetype))); + QVERIFY(file.resize(8)); + QCOMPARE(file.size(), qint64(8)); + closeFile(file); + QFile::resize(filename, 4); + QCOMPARE(QFileInfo(filename).size(), qint64(4)); + QVERIFY(QFile::remove(filename)); +} + +void tst_QFile::objectConstructors() +{ + QObject ob; + QFile* file1 = new QFile(SRCDIR "testfile.txt", &ob); + QFile* file2 = new QFile(&ob); + QVERIFY(file1->exists()); + QVERIFY(!file2->exists()); +} + +#ifdef Q_OS_SYMBIAN +void tst_QFile::platformSecurity_data() +{ + QTest::addColumn<QString>("file"); + QTest::addColumn<bool>("readable"); + QTest::addColumn<bool>("writable"); + + QString selfname = QCoreApplication::applicationFilePath(); + QString ownprivate = QCoreApplication::applicationDirPath(); + QString owndrive = selfname.left(2); + bool amiprivileged = RProcess().HasCapability(ECapabilityAllFiles); + QTest::newRow("resource") << owndrive + "/resource/apps/tst_qfile.rsc" << true << amiprivileged; + QTest::newRow("sys") << selfname << amiprivileged << false; + QTest::newRow("own private") << ownprivate + "/testfile.txt" << true << true; + QTest::newRow("other private") << owndrive + "/private/10003a3f/import/apps/tst_qfile_reg.rsc" << amiprivileged << amiprivileged; +} + +void tst_QFile::platformSecurity() +{ + QFETCH(QString,file); + QFETCH(bool,readable); + QFETCH(bool,writable); + + { + QFile f(file); + QCOMPARE(f.open(QIODevice::ReadOnly), readable); + } + + { + QFile f(file); + QCOMPARE(f.open(QIODevice::ReadOnly | QIODevice::Unbuffered), readable); + } + + //append mode used to avoid truncating the files. + { + QFile f(file); + QCOMPARE(f.open(QIODevice::WriteOnly | QIODevice::Append), writable); + } + + { + QFile f(file); + QCOMPARE(f.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered), writable); + } + + { + QFile f(file); + QCOMPARE(f.open(QIODevice::ReadWrite), writable); + } + + { + QFile f(file); + QCOMPARE(f.open(QIODevice::ReadWrite | QIODevice::Unbuffered), writable); + } +} +#endif + +void tst_QFile::caseSensitivity() +{ +#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WIN) || defined(Q_OS_MAC) + const bool caseSensitive = false; +#else + const bool caseSensitive = true; +#endif + QByteArray testData("a little test"); + QString filename("File.txt"); + { + QFile f(filename); + QVERIFY(f.open(QIODevice::WriteOnly)); + QVERIFY(f.write(testData)); + f.close(); + } + QStringList alternates; + QFileInfo fi(filename); + QVERIFY(fi.exists()); + alternates << "file.txt" << "File.TXT" << "fIlE.TxT" << fi.absoluteFilePath().toUpper() << fi.absoluteFilePath().toLower(); + foreach (QString alt, alternates) { + QFileInfo fi2(alt); + QCOMPARE(fi2.exists(), !caseSensitive); + QCOMPARE(fi.size() == fi2.size(), !caseSensitive); + QFile f2(alt); + QCOMPARE(f2.open(QIODevice::ReadOnly), !caseSensitive); + if (!caseSensitive) + QCOMPARE(f2.readAll(), testData); + } +} + +//MSVCRT asserts when any function is called with a closed file handle. +//This replaces the default crashing error handler with one that ignores the error (allowing EBADF to be returned) +class AutoIgnoreInvalidParameter +{ +public: +#if defined(Q_OS_WIN) && defined (Q_CC_MSVC) + static void ignore_invalid_parameter(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t) {} + AutoIgnoreInvalidParameter() + { + oldHandler = _set_invalid_parameter_handler(ignore_invalid_parameter); + //also disable the abort/retry/ignore popup + oldReportMode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); + } + ~AutoIgnoreInvalidParameter() + { + //restore previous settings + _set_invalid_parameter_handler(oldHandler); + _CrtSetReportMode(_CRT_ASSERT, oldReportMode); + } + _invalid_parameter_handler oldHandler; + int oldReportMode; +#endif +}; + +void tst_QFile::autocloseHandle() +{ +#ifdef Q_OS_SYMBIAN + // these tests are a bit different, because using a closed file handle results in a panic rather than error + { + QFile file("readonlyfile"); + QFile file2("readonlyfile"); + QVERIFY(openFile(file, QIODevice::ReadOnly, OpenRFile, QFile::AutoCloseHandle)); + // file is opened with mandatory lock, so opening again should fail + QVERIFY(!file2.open(QIODevice::ReadOnly)); + + file.close(); + // opening again should now succeed (because handle is closed) + QVERIFY(file2.open(QIODevice::ReadOnly)); + } + + { + QFile file("readonlyfile"); + QFile file2("readonlyfile"); + QVERIFY(openFile(file, QIODevice::ReadOnly, OpenRFile, QFile::DontCloseHandle)); + // file is opened with mandatory lock, so opening again should fail + QVERIFY(!file2.open(QIODevice::ReadOnly)); + + file.close(); + // opening again should still fail (because handle is not auto closed) + QVERIFY(!file2.open(QIODevice::ReadOnly)); + + rfile_.Close(); + // now it should succeed + QVERIFY(file2.open(QIODevice::ReadOnly)); + } +#endif + + { + QFile file("readonlyfile"); + QVERIFY(openFile(file, QIODevice::ReadOnly, OpenFd, QFile::AutoCloseHandle)); + int fd = fd_; + QCOMPARE(file.handle(), fd); + file.close(); + fd_ = -1; + QCOMPARE(file.handle(), -1); + AutoIgnoreInvalidParameter a; + Q_UNUSED(a); + //file is closed, read should fail + char buf; + QCOMPARE((int)QT_READ(fd, &buf, 1), -1); + QVERIFY(errno = EBADF); + } + + { + QFile file("readonlyfile"); + QVERIFY(openFile(file, QIODevice::ReadOnly, OpenFd, QFile::DontCloseHandle)); + QCOMPARE(file.handle(), fd_); + file.close(); + QCOMPARE(file.handle(), -1); + //file is not closed, read should succeed + char buf; + QCOMPARE((int)QT_READ(fd_, &buf, 1), 1); + ::close(fd_); + fd_ = -1; + } + + { + QFile file("readonlyfile"); + QVERIFY(openFile(file, QIODevice::ReadOnly, OpenStream, QFile::AutoCloseHandle)); + int fd = fileno(stream_); + QCOMPARE(file.handle(), fd); + file.close(); + stream_ = 0; + QCOMPARE(file.handle(), -1); + AutoIgnoreInvalidParameter a; + Q_UNUSED(a); + //file is closed, read should fail + char buf; + QCOMPARE((int)QT_READ(fd, &buf, 1), -1); //not using fread because the FILE* was freed by fclose + } + + { + QFile file("readonlyfile"); + QVERIFY(openFile(file, QIODevice::ReadOnly, OpenStream, QFile::DontCloseHandle)); + QCOMPARE(file.handle(), fileno(stream_)); + file.close(); + QCOMPARE(file.handle(), -1); + //file is not closed, read should succeed + char buf; + QCOMPARE(int(::fread(&buf, 1, 1, stream_)), 1); + ::fclose(stream_); + stream_ = 0; + } +} + QTEST_MAIN(tst_QFile) #include "tst_qfile.moc" diff --git a/tests/auto/qfiledialog/qfiledialog.pro b/tests/auto/qfiledialog/qfiledialog.pro index 2b87cf1..68f2e3c 100644 --- a/tests/auto/qfiledialog/qfiledialog.pro +++ b/tests/auto/qfiledialog/qfiledialog.pro @@ -7,9 +7,9 @@ load(qttest_p4) SOURCES += tst_qfiledialog.cpp wince*|symbian { - addFiles.sources = *.cpp + addFiles.files = *.cpp addFiles.path = . - filesInDir.sources = *.pro + filesInDir.files = *.pro filesInDir.path = someDir DEPLOYMENT += addFiles filesInDir } diff --git a/tests/auto/qfiledialog/resources/file.txt b/tests/auto/qfiledialog/resources/file.txt new file mode 100644 index 0000000..8a03e0e --- /dev/null +++ b/tests/auto/qfiledialog/resources/file.txt @@ -0,0 +1 @@ +This is a simple text file. diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index 23aea0b..bc076c5 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -61,9 +61,13 @@ #include <qlineedit.h> #include <qlayout.h> #include "../../shared/util.h" +#if defined QT_BUILD_INTERNAL #include "../../../src/gui/dialogs/qsidebar_p.h" #include "../../../src/gui/dialogs/qfilesystemmodel_p.h" #include "../../../src/gui/dialogs/qfiledialog_p.h" +#endif +#include <QFileDialog> +#include <QFileSystemModel> #include "../network-settings.h" @@ -183,7 +187,7 @@ public: QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const { return QSize(); } }; -// emited any time the selection model emits current changed +// emitted any time the selection model emits current changed void tst_QFiledialog::currentChangedSignal() { QNonNativeFileDialog fd; @@ -208,7 +212,7 @@ void tst_QFiledialog::currentChangedSignal() QCOMPARE(spyCurrentChanged.count(), 1); } -// only emited from the views, sidebar, or lookin combo +// only emitted from the views, sidebar, or lookin combo void tst_QFiledialog::directoryEnteredSignal() { #if defined QT_BUILD_INTERNAL @@ -269,13 +273,13 @@ void tst_QFiledialog::filesSelectedSignal_data() QTest::newRow("existingFiles") << QFileDialog::ExistingFiles; } -// emited when the dialog closes with the selected files +// emitted when the dialog closes with the selected files void tst_QFiledialog::filesSelectedSignal() { QNonNativeFileDialog fd; fd.setViewMode(QFileDialog::List); fd.setOptions(QFileDialog::DontUseNativeDialog); - QDir testDir(SRCDIR"/../../.."); + QDir testDir(SRCDIR); fd.setDirectory(testDir); QFETCH(QFileDialog::FileMode, fileMode); fd.setFileMode(fileMode); @@ -313,7 +317,7 @@ void tst_QFiledialog::filesSelectedSignal() QCOMPARE(spyFilesSelected.count(), 1); } -// only emited when the combo box is activated +// only emitted when the combo box is activated void tst_QFiledialog::filterSelectedSignal() { QNonNativeFileDialog fd; @@ -1304,6 +1308,10 @@ QString saveName(QWidget *, const QString &, const QString &, const QString &, Q void tst_QFiledialog::hooks() { +#ifdef Q_OS_SYMBIAN + if(QSysInfo::symbianVersion() < QSysInfo::SV_SF_3) + QSKIP("writing to data exports in paged dll not supported and crashes on symbian versions prior to ^3", SkipAll); +#endif qt_filedialog_existing_directory_hook = &existing; qt_filedialog_save_filename_hook = &saveName; qt_filedialog_open_filename_hook = &openName; diff --git a/tests/auto/qfiledialog2/qfiledialog2.pro b/tests/auto/qfiledialog2/qfiledialog2.pro index 4ebf977..b8924c1 100644 --- a/tests/auto/qfiledialog2/qfiledialog2.pro +++ b/tests/auto/qfiledialog2/qfiledialog2.pro @@ -7,9 +7,9 @@ load(qttest_p4) SOURCES += tst_qfiledialog2.cpp wince*|symbian { - addFiles.sources = *.cpp + addFiles.files = *.cpp addFiles.path = . - filesInDir.sources = *.pro + filesInDir.files = *.pro filesInDir.path = someDir DEPLOYMENT += addFiles filesInDir } diff --git a/tests/auto/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/qfiledialog2/tst_qfiledialog2.cpp index 1cf12f5..afa2e8f 100644 --- a/tests/auto/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/qfiledialog2/tst_qfiledialog2.cpp @@ -548,7 +548,7 @@ void tst_QFileDialog2::task226366_lowerCaseHardDriveWindows() QTest::qWait(200); QTest::keyClick(edit->completer()->popup(), Qt::Key_Down); QTest::qWait(200); - QCOMPARE(edit->text(), QString("C:")); + QCOMPARE(edit->text(), QString("C:/")); QTest::qWait(2000); //i clear my previous selection in the completer QTest::keyClick(edit->completer()->popup(), Qt::Key_Down); @@ -556,7 +556,7 @@ void tst_QFileDialog2::task226366_lowerCaseHardDriveWindows() QTest::keyClick(edit, (char)(Qt::Key_C | Qt::SHIFT)); QTest::qWait(200); QTest::keyClick(edit->completer()->popup(), Qt::Key_Down); - QCOMPARE(edit->text(), QString("C:")); + QCOMPARE(edit->text(), QString("C:/")); } #endif @@ -812,7 +812,7 @@ void tst_QFileDialog2::task239706_editableFilterCombo() break; } } - Q_ASSERT(filterCombo); + QVERIFY(filterCombo); filterCombo->setEditable(true); QTest::mouseClick(filterCombo, Qt::LeftButton); QTest::keyPress(filterCombo, Qt::Key_X); diff --git a/tests/auto/qfileinfo/qfileinfo.pro b/tests/auto/qfileinfo/qfileinfo.pro index 30656e2..b35b1e0 100644 --- a/tests/auto/qfileinfo/qfileinfo.pro +++ b/tests/auto/qfileinfo/qfileinfo.pro @@ -7,12 +7,14 @@ QT = core RESOURCES += qfileinfo.qrc wince*:|symbian: { - deploy.sources += qfileinfo.qrc tst_qfileinfo.cpp - res.sources = resources\\file1 resources\\file1.ext1 resources\\file1.ext1.ext2 + deploy.files += qfileinfo.qrc tst_qfileinfo.cpp + res.files = resources\\file1 resources\\file1.ext1 resources\\file1.ext1.ext2 res.path = resources - DEPLOYMENT = deploy res + DEPLOYMENT += deploy res } +win32*:LIBS += -ladvapi32 -lnetapi32 + symbian { TARGET.CAPABILITY=AllFiles LIBS *= -lefsrv @@ -28,3 +30,6 @@ wince* { DEFINES += SRCDIR=\\\"$$PWD/\\\" } +contains(QT_CONFIG, qt3support): QT += qt3support + +CONFIG += parallel_test diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 6291f1c..c7d9979 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -46,6 +46,7 @@ #include <qfile.h> #include <qdir.h> #include <qcoreapplication.h> +#include <qlibrary.h> #include <qtemporaryfile.h> #include <qdir.h> #include <qfileinfo.h> @@ -53,9 +54,14 @@ #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> +#include <sys/types.h> +#include <pwd.h> #endif #ifdef Q_OS_WIN +#define _WIN32_WINNT 0x500 #include <qt_windows.h> +#include <qlibrary.h> +#include <lm.h> #endif #include <qplatformdefs.h> #include <qdebug.h> @@ -65,9 +71,11 @@ #endif #include "../network-settings.h" #include <private/qfileinfo_p.h> +#include "../../shared/filesystem.h" #if defined(Q_OS_SYMBIAN) # define SRCDIR "" +# define NO_SYMLINKS #endif QT_BEGIN_NAMESPACE @@ -155,6 +163,9 @@ private slots: void isHidden_data(); void isHidden(); +#if defined(Q_OS_MAC) + void isHiddenFromFinder(); +#endif void isBundle_data(); void isBundle(); @@ -165,6 +176,8 @@ private slots: void refresh(); #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + void ntfsJunctionPointsAndSymlinks_data(); + void ntfsJunctionPointsAndSymlinks(); void brokenShortcut(); #endif @@ -178,6 +191,13 @@ private slots: void notEqualOperator() const; void detachingOperations(); + +#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) + void owner(); +#endif + void group(); + + void invalidState(); }; tst_QFileInfo::tst_QFileInfo() @@ -190,6 +210,8 @@ tst_QFileInfo::~tst_QFileInfo() QFile::remove("link.lnk"); QFile::remove("file1"); QFile::remove("dummyfile"); + QFile::remove("simplefile.txt"); + QFile::remove("longFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileNamelongFileName.txt"); #ifdef Q_OS_SYMBIAN QFile::remove("hidden.txt"); QFile::remove("nothidden.txt"); @@ -199,9 +221,17 @@ tst_QFileInfo::~tst_QFileInfo() #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) QDir().rmdir("./.hidden-directory"); + QFile::remove("link_to_tst_qfileinfo"); #endif -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) QDir().rmdir("./hidden-directory"); + QDir().rmdir("abs_symlink"); + QDir().rmdir("rel_symlink"); + QDir().rmdir("junction_pwd"); + QDir().rmdir("junction_root"); + QDir().rmdir("mountpoint"); + QFile::remove("abs_symlink.cpp"); + QFile::remove("rel_symlink.cpp"); #endif } @@ -396,6 +426,7 @@ void tst_QFileInfo::exists_data() QTest::newRow("data9") << SRCDIR "resources/file?.ext1" << false; QTest::newRow("data10") << "." << true; QTest::newRow("data11") << ". " << false; + QTest::newRow("empty") << "" << false; QTest::newRow("simple dir") << SRCDIR "resources" << true; QTest::newRow("simple dir with slash") << SRCDIR "resources/" << true; @@ -498,7 +529,11 @@ void tst_QFileInfo::absFilePath() QFETCH(QString, expected); QFileInfo fi(file); +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + QVERIFY(QString::compare(fi.absoluteFilePath(), expected, Qt::CaseInsensitive) == 0); +#else QCOMPARE(fi.absoluteFilePath(), expected); +#endif } void tst_QFileInfo::canonicalPath() @@ -584,6 +619,34 @@ void tst_QFileInfo::canonicalFilePath() } # endif #endif + +#ifdef Q_OS_WIN + typedef BOOL (WINAPI *PtrCreateSymbolicLink)(LPTSTR, LPTSTR, DWORD); + PtrCreateSymbolicLink ptrCreateSymbolicLink = + (PtrCreateSymbolicLink)QLibrary::resolve(QLatin1String("kernel32"), "CreateSymbolicLinkW"); + + if (!ptrCreateSymbolicLink) { + QSKIP("Symbolic links aren't supported by FS", SkipAll); + } else { + // CreateSymbolicLink can return TRUE & still fail to create the link, + // the error code in that case is ERROR_PRIVILEGE_NOT_HELD (1314) + SetLastError(0); + BOOL ret = ptrCreateSymbolicLink((wchar_t*)QString("res").utf16(), (wchar_t*)QString("resources").utf16(), 1); + DWORD dwErr = GetLastError(); + if (!ret) + QSKIP("Symbolic links aren't supported by FS", SkipAll); + QString currentPath = QDir::currentPath(); + bool is_res_Current = QDir::setCurrent("res"); + if (!is_res_Current && dwErr == 1314) + QSKIP("Not enough privilages to create Symbolic links", SkipAll); + QCOMPARE(is_res_Current, true); + + QCOMPARE(QFileInfo("file1").canonicalFilePath(), currentPath + "/resources/file1"); + + QCOMPARE(QDir::setCurrent(currentPath), true); + QDir::current().rmdir("res"); + } +#endif } void tst_QFileInfo::fileName_data() @@ -660,10 +723,19 @@ void tst_QFileInfo::dir() QFETCH(QString, expected); QFileInfo fi(file); - if (absPath) + if (absPath) { QCOMPARE(fi.absolutePath(), expected); - else + QCOMPARE(fi.absoluteDir().path(), expected); +#ifdef QT3_SUPPORT + QCOMPARE(fi.dir(true).path(), expected); +#endif + } else { QCOMPARE(fi.path(), expected); + QCOMPARE(fi.dir().path(), expected); +#ifdef QT3_SUPPORT + QCOMPARE(fi.dir(false).path(), expected); +#endif + } } @@ -1051,6 +1123,7 @@ void tst_QFileInfo::fileTimes_oldFile() void tst_QFileInfo::isSymLink_data() { +#ifndef NO_SYMLINKS QFile::remove("link.lnk"); QFile::remove("brokenlink.lnk"); QFile::remove("dummyfile"); @@ -1070,10 +1143,12 @@ void tst_QFileInfo::isSymLink_data() QTest::newRow("existent file") << SRCDIR "tst_qfileinfo.cpp" << false << ""; QTest::newRow("link") << "link.lnk" << true << QFileInfo(SRCDIR "tst_qfileinfo.cpp").absoluteFilePath(); QTest::newRow("broken link") << "brokenlink.lnk" << true << QFileInfo("dummyfile").absoluteFilePath(); +#endif } void tst_QFileInfo::isSymLink() { +#ifndef NO_SYMLINKS QFETCH(QString, path); QFETCH(bool, isSymLink); QFETCH(QString, linkTarget); @@ -1081,6 +1156,9 @@ void tst_QFileInfo::isSymLink() QFileInfo fi(path); QCOMPARE(fi.isSymLink(), isSymLink); QCOMPARE(fi.symLinkTarget(), linkTarget); +#else + QSKIP("no symbolic link support on this platform", SkipAll); +#endif } void tst_QFileInfo::isHidden_data() @@ -1156,6 +1234,27 @@ void tst_QFileInfo::isHidden() QCOMPARE(fi.isHidden(), isHidden); } +#if defined(Q_OS_MAC) +void tst_QFileInfo::isHiddenFromFinder() +{ + const char *filename = "test_foobar.txt"; + + QFile testFile(filename); + testFile.open(QIODevice::WriteOnly | QIODevice::Append); + testFile.write(QByteArray("world")); + testFile.close(); + + struct stat buf; + stat(filename, &buf); + chflags(filename, buf.st_flags | UF_HIDDEN); + + QFileInfo fi(filename); + QCOMPARE(fi.isHidden(), true); + + testFile.remove(); +} +#endif + void tst_QFileInfo::isBundle_data() { QTest::addColumn<QString>("path"); @@ -1193,9 +1292,10 @@ void tst_QFileInfo::isLocalFs() QFileInfo info(path); QFileInfoPrivate *privateInfo = getPrivate(info); - QVERIFY(privateInfo->fileEngine); - QCOMPARE(bool(privateInfo->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) - & QAbstractFileEngine::LocalDiskFlag), isLocalFs); + QCOMPARE((privateInfo->fileEngine == 0), isLocalFs); + if (privateInfo->fileEngine) + QCOMPARE(bool(privateInfo->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) + & QAbstractFileEngine::LocalDiskFlag), isLocalFs); } void tst_QFileInfo::refresh() @@ -1247,6 +1347,131 @@ void tst_QFileInfo::refresh() } #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data() +{ + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("isSymLink"); + QTest::addColumn<QString>("linkTarget"); + QTest::addColumn<QString>("canonicalFilePath"); + + QDir pwd; + pwd.mkdir("target"); + + QLibrary kernel32("kernel32"); + typedef BOOLEAN (WINAPI *PtrCreateSymbolicLink)(LPCWSTR, LPCWSTR, DWORD); + PtrCreateSymbolicLink createSymbolicLinkW = 0; + createSymbolicLinkW = (PtrCreateSymbolicLink) kernel32.resolve("CreateSymbolicLinkW"); + if (!createSymbolicLinkW) { + //we need at least one data set for the test not to fail when skipping _data function + QDir target("target"); + QTest::newRow("dummy") << target.path() << false << "" << target.canonicalPath(); + QSKIP("symbolic links not supported by operating system",SkipSingle); + } + { + //Directory symlinks + QDir target("target"); + QVERIFY(target.exists()); + + QString absTarget = QDir::toNativeSeparators(target.absolutePath()); + QString absSymlink = QDir::toNativeSeparators(pwd.absolutePath()).append("\\abs_symlink"); + QString relTarget = "target"; + QString relSymlink = "rel_symlink"; + QString fileInTarget(absTarget); + fileInTarget.append("\\file"); + QString fileInSymlink(absSymlink); + fileInSymlink.append("\\file"); + QFile file(fileInTarget); + file.open(QIODevice::ReadWrite); + file.close(); + + DWORD err = ERROR_SUCCESS ; + if (!pwd.exists("abs_symlink")) + if (!createSymbolicLinkW((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x1)) + err = GetLastError(); + if (err == ERROR_SUCCESS && !pwd.exists(relSymlink)) + if (!createSymbolicLinkW((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x1)) + err = GetLastError(); + if (err != ERROR_SUCCESS) { + wchar_t errstr[0x100]; + DWORD count = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, + 0, err, 0, errstr, 0x100, 0); + QString error(QString::fromUtf16(errstr, count)); + qWarning() << error; + //we need at least one data set for the test not to assert fail when skipping _data function + QDir target("target"); + QTest::newRow("dummy") << target.path() << false << "" << target.canonicalPath(); + QSKIP("link not supported by FS or insufficient privilege", SkipSingle); + } + QVERIFY(file.exists()); + + QTest::newRow("absolute dir symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalPath(); + QTest::newRow("relative dir symlink") << relSymlink << true << QDir::fromNativeSeparators(relTarget) << target.canonicalPath(); + QTest::newRow("file in symlink dir") << fileInSymlink << false << "" << target.canonicalPath().append("/file"); + } + { + //File symlinks + QFileInfo target(SRCDIR "tst_qfileinfo.cpp"); + QString absTarget = QDir::toNativeSeparators(target.absoluteFilePath()); + QString absSymlink = QDir::toNativeSeparators(pwd.absolutePath()).append("\\abs_symlink.cpp"); + QString relTarget = QDir::toNativeSeparators(pwd.relativeFilePath(target.absoluteFilePath())); + QString relSymlink = "rel_symlink.cpp"; + QVERIFY(pwd.exists("abs_symlink.cpp") || createSymbolicLinkW((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x0)); + QVERIFY(pwd.exists(relSymlink) || createSymbolicLinkW((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x0)); + + QTest::newRow("absolute file symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath(); + QTest::newRow("relative file symlink") << relSymlink << true << QDir::fromNativeSeparators(relTarget) << target.canonicalFilePath(); + } + + //Junctions + QString target = "target"; + QString junction = "junction_pwd"; + FileSystem::createNtfsJunction(target, junction); + QFileInfo targetInfo(target); + QTest::newRow("junction_pwd") << junction << true << targetInfo.absoluteFilePath() << targetInfo.canonicalFilePath(); + + QFileInfo fileInJunction(targetInfo.absoluteFilePath().append("/file")); + QFile file(fileInJunction.absoluteFilePath()); + file.open(QIODevice::ReadWrite); + file.close(); + QVERIFY(file.exists()); + QTest::newRow("file in junction") << fileInJunction.absoluteFilePath() << false << "" << fileInJunction.canonicalFilePath(); + + target = QDir::rootPath(); + junction = "junction_root"; + FileSystem::createNtfsJunction(target, junction); + targetInfo.setFile(target); + QTest::newRow("junction_root") << junction << true << targetInfo.absoluteFilePath() << targetInfo.canonicalFilePath(); + + //Mountpoint + typedef BOOLEAN (WINAPI *PtrGetVolumeNameForVolumeMountPointW)(LPCWSTR, LPWSTR, DWORD); + PtrGetVolumeNameForVolumeMountPointW getVolumeNameForVolumeMountPointW = 0; + getVolumeNameForVolumeMountPointW = (PtrGetVolumeNameForVolumeMountPointW) kernel32.resolve("GetVolumeNameForVolumeMountPointW"); + if(getVolumeNameForVolumeMountPointW) + { + wchar_t buffer[MAX_PATH]; + QString rootPath = QDir::toNativeSeparators(QDir::rootPath()); + QVERIFY(getVolumeNameForVolumeMountPointW((wchar_t*)rootPath.utf16(), buffer, MAX_PATH)); + QString rootVolume = QString::fromWCharArray(buffer); + junction = "mountpoint"; + rootVolume.replace("\\\\?\\","\\??\\"); + FileSystem::createNtfsJunction(rootVolume, junction); + QTest::newRow("mountpoint") << junction << true << QDir::fromNativeSeparators(rootPath) << QDir::rootPath(); + } +} + +void tst_QFileInfo::ntfsJunctionPointsAndSymlinks() +{ + QFETCH(QString, path); + QFETCH(bool, isSymLink); + QFETCH(QString, linkTarget); + QFETCH(QString, canonicalFilePath); + + QFileInfo fi(path); + QCOMPARE(fi.isSymLink(), isSymLink); + QCOMPARE(fi.symLinkTarget(), linkTarget); + QCOMPARE(fi.canonicalFilePath(), canonicalFilePath); +} + void tst_QFileInfo::brokenShortcut() { QString linkName("borkenlink.lnk"); @@ -1265,10 +1490,6 @@ void tst_QFileInfo::brokenShortcut() void tst_QFileInfo::isWritable() { -#ifdef Q_OS_SYMBIAN - QSKIP("Currently skipped on Symbian OS, but surely there is a writeable file somewhere???", SkipAll); -#endif - QFile tempfile("tempfile.txt"); tempfile.open(QIODevice::WriteOnly); tempfile.write("This file is generated by the QFileInfo autotest."); @@ -1286,7 +1507,7 @@ void tst_QFileInfo::isWritable() QVERIFY(fi.exists()); QVERIFY(!fi.isWritable()); #endif -#ifdef Q_OS_UNIX +#if defined (Q_OS_UNIX) && !defined (Q_OS_SYMBIAN) if (::getuid() == 0) QVERIFY(QFileInfo("/etc/passwd").isWritable()); else @@ -1297,9 +1518,6 @@ void tst_QFileInfo::isWritable() void tst_QFileInfo::isExecutable() { #ifdef Q_OS_SYMBIAN -# if defined(Q_CC_NOKIAX86) - QSKIP("Impossible to implement reading/touching of application binaries in Symbian emulator", SkipAll); -# endif QString appPath = "c:/sys/bin/tst_qfileinfo.exe"; #else QString appPath = QCoreApplication::applicationDirPath(); @@ -1433,5 +1651,160 @@ void tst_QFileInfo::detachingOperations() QVERIFY(!info1.caching()); } +#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) +#if defined (Q_OS_WIN) +BOOL IsUserAdmin() +{ + BOOL b; + SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; + PSID AdministratorsGroup; + b = AllocateAndInitializeSid( + &NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &AdministratorsGroup); + if (b) { + if (!CheckTokenMembership( NULL, AdministratorsGroup, &b)) + b = FALSE; + FreeSid(AdministratorsGroup); + } + + return(b); +} +#endif + +void tst_QFileInfo::owner() +{ + QString userName; +#if defined(Q_OS_UNIX) + { + passwd *user = getpwuid(geteuid()); + QVERIFY(user); + char *usernameBuf = user->pw_name; + userName = QString::fromLocal8Bit(usernameBuf); + } +#endif +#if defined(Q_OS_WIN) + wchar_t usernameBuf[1024]; + DWORD bufSize = 1024; + if (GetUserNameW(usernameBuf, &bufSize)) { + userName = QString::fromWCharArray(usernameBuf); + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && IsUserAdmin()) { + // Special case : If the user is a member of Administrators group, all files + // created by the current user are owned by the Administrators group. + LPLOCALGROUP_USERS_INFO_0 pBuf = NULL; + DWORD dwLevel = 0; + DWORD dwFlags = LG_INCLUDE_INDIRECT ; + DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH; + DWORD dwEntriesRead = 0; + DWORD dwTotalEntries = 0; + NET_API_STATUS nStatus; + nStatus = NetUserGetLocalGroups(0, usernameBuf, dwLevel, dwFlags, (LPBYTE *) &pBuf, + dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); + // Check if the current user is a member of Administrators group + if (nStatus == NERR_Success && pBuf){ + for (int i = 0; i < dwEntriesRead; i++) { + QString groupName = QString::fromWCharArray(pBuf[i].lgrui0_name); + if (!groupName.compare(QLatin1String("Administrators"))) + userName = groupName; + } + } + if (pBuf != NULL) + NetApiBufferFree(pBuf); + } + } + extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; + qt_ntfs_permission_lookup = 1; +#endif + if (userName.isEmpty()) + QSKIP("Can't retrieve the user name", SkipAll); + QString fileName("ownertest.txt"); + QVERIFY(!QFile::exists(fileName) || QFile::remove(fileName)); + { + QFile testFile(fileName); + QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Text)); + QByteArray testData("testfile"); + QVERIFY(testFile.write(testData) != -1); + } + QFileInfo fi(fileName); + QVERIFY(fi.exists()); + QCOMPARE(fi.owner(), userName); + + QFile::remove(fileName); +#if defined(Q_OS_WIN) + qt_ntfs_permission_lookup = 0; +#endif +} +#endif + +void tst_QFileInfo::group() +{ + QString expected; +#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) + struct group *gr; + gid_t gid = getegid(); + gr = getgrgid(gid); + expected = QString::fromLocal8Bit(gr->gr_name); +#endif + + QString fileName("ownertest.txt"); + if (QFile::exists(fileName)) + QFile::remove(fileName); + QFile testFile(fileName); + QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Text)); + QByteArray testData("testfile"); + QVERIFY(testFile.write(testData) != -1); + testFile.close(); + QFileInfo fi(fileName); + QVERIFY(fi.exists()); + + QCOMPARE(fi.group(), expected); +} + +void tst_QFileInfo::invalidState() +{ + // Shouldn't crash; + + { + QFileInfo info; + QCOMPARE(info.size(), qint64(0)); + QVERIFY(!info.exists()); + + info.setCaching(false); + + info.created(); + info.lastRead(); + info.lastModified(); + } + + { + QFileInfo info(""); + QCOMPARE(info.size(), qint64(0)); + QVERIFY(!info.exists()); + + info.setCaching(false); + + info.created(); + info.lastRead(); + info.lastModified(); + } + + { + QFileInfo info("file-doesn't-really-exist.txt"); + QCOMPARE(info.size(), qint64(0)); + QVERIFY(!info.exists()); + + info.setCaching(false); + + info.created(); + info.lastRead(); + info.lastModified(); + } + + QVERIFY(true); +} + QTEST_MAIN(tst_QFileInfo) #include "tst_qfileinfo.moc" diff --git a/tests/auto/qfileopenevent/qfileopenevent.pro b/tests/auto/qfileopenevent/qfileopenevent.pro new file mode 100644 index 0000000..45978d7 --- /dev/null +++ b/tests/auto/qfileopenevent/qfileopenevent.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = test qfileopeneventexternal diff --git a/tests/auto/qdbusperformance/serverobject.h b/tests/auto/qfileopenevent/qfileopeneventexternal/qfileopeneventexternal.cpp index 4e554e0..5d1a6a3 100644 --- a/tests/auto/qdbusperformance/serverobject.h +++ b/tests/auto/qfileopenevent/qfileopeneventexternal/qfileopeneventexternal.cpp @@ -39,77 +39,34 @@ ** ****************************************************************************/ +#include <QtGui> +#include <QApplication> +#include <QEvent> -#ifndef SERVEROBJECT_H -#define SERVEROBJECT_H - -#include <QObject> -#include <QtDBus/QtDBus> - -class ServerObject: public QObject +struct MyApplication : public QApplication { - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.trolltech.autotests.Performance") -public: - ServerObject(const QString &objectPath, QDBusConnection conn, QObject *parent = 0) - : QObject(parent) - { - conn.registerObject(objectPath, this, QDBusConnection::ExportAllSlots); - } + MyApplication(int& argc, char** argv) + : QApplication(argc, argv) + {} -public slots: - Q_NOREPLY void noReply(const QByteArray &) - { - // black hole - } - Q_NOREPLY void noReply(const QString &) - { - // black hole - } - Q_NOREPLY void noReply(const QDBusVariant &) - { - // black hole - } - - int size(const QByteArray &data) - { - return data.size(); - } - int size(const QString &data) + bool event(QEvent * event) { - return data.size(); - } - int size(const QDBusVariant &data) - { - QVariant v = data.variant(); - switch (v.type()) - { - case QVariant::ByteArray: - return v.toByteArray().size(); - case QVariant::StringList: - return v.toStringList().size(); - case QVariant::String: - default: - return v.toString().size(); + if (event->type() == QEvent::FileOpen) { + QFileOpenEvent* ev = static_cast<QFileOpenEvent *>(event); + QFile file; + bool ok = ev->openFile(file, QFile::Append | QFile::Unbuffered); + if (ok) + file.write(QByteArray("+external")); + return true; + } else { + return QApplication::event(event); } } - - QByteArray echo(const QByteArray &data) - { - return data; - } - QString echo(const QString &data) - { - return data; - } - QDBusVariant echo(const QDBusVariant &data) - { - return data; - } - - void nothing() - { - } }; -#endif +int main(int argc, char *argv[]) +{ + MyApplication a(argc, argv); + a.sendPostedEvents(&a, QEvent::FileOpen); + return 0; +} diff --git a/tests/auto/qfileopenevent/qfileopeneventexternal/qfileopeneventexternal.pro b/tests/auto/qfileopenevent/qfileopeneventexternal/qfileopeneventexternal.pro new file mode 100644 index 0000000..b95ed45 --- /dev/null +++ b/tests/auto/qfileopenevent/qfileopeneventexternal/qfileopeneventexternal.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = qfileopeneventexternal +QT += core gui +SOURCES += qfileopeneventexternal.cpp +symbian: { + RSS_RULES += "embeddability=KAppEmbeddable;" + RSS_RULES.datatype_list += "priority = EDataTypePriorityHigh; type = \"application/x-tst_qfileopenevent\";" + LIBS += -lapparc \ + -leikcore -lefsrv -lcone +} diff --git a/tests/auto/qfileopenevent/test/test.pro b/tests/auto/qfileopenevent/test/test.pro new file mode 100644 index 0000000..3f16dcf --- /dev/null +++ b/tests/auto/qfileopenevent/test/test.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +TARGET = tst_qfileopenevent +HEADERS += +SOURCES += tst_qfileopenevent.cpp +symbian { + LIBS+=-lefsrv -lapgrfx -lapmime +} diff --git a/tests/auto/qfileopenevent/test/tst_qfileopenevent.cpp b/tests/auto/qfileopenevent/test/tst_qfileopenevent.cpp new file mode 100644 index 0000000..69cc4cc --- /dev/null +++ b/tests/auto/qfileopenevent/test/tst_qfileopenevent.cpp @@ -0,0 +1,362 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QEvent> + +#ifdef Q_OS_SYMBIAN +#include <apgcli.h> +#include "private/qcore_symbian_p.h" +#endif + +class tst_qfileopenevent : public QObject +{ + Q_OBJECT +public: + tst_qfileopenevent(){} + ~tst_qfileopenevent(); + +public slots: + void initTestCase(); + +private slots: + void constructor(); + void fileOpen(); + void handleLifetime(); + void multiOpen(); + void sendAndReceive(); + void external_data(); + void external(); + +private: +#ifdef Q_OS_SYMBIAN + RFile createRFile(const TDesC& filename, const TDesC8& content); +#else + void createFile(const QString &filename, const QByteArray &content); +#endif + QFileOpenEvent * createFileAndEvent(const QString &filename, const QByteArray &content); + void checkReadAndWrite(QFileOpenEvent& event, const QByteArray& readContent, const QByteArray& writeContent, bool writeOk); + QByteArray readFileContent(QFileOpenEvent& event); + bool appendFileContent(QFileOpenEvent& event, const QByteArray& writeContent); + + bool event(QEvent *); + +private: +#ifdef Q_OS_SYMBIAN + struct AutoRFs : public RFs + { + AutoRFs() + { + qt_symbian_throwIfError(Connect()); + qt_symbian_throwIfError(ShareProtected()); + } + + ~AutoRFs() + { + Close(); + } + }; + AutoRFs fsSession; +#endif +}; + +tst_qfileopenevent::~tst_qfileopenevent() +{ +}; + +void tst_qfileopenevent::initTestCase() +{ +} + +#ifdef Q_OS_SYMBIAN +RFile tst_qfileopenevent::createRFile(const TDesC& filename, const TDesC8& content) +{ + RFile file; + qt_symbian_throwIfError(file.Replace(fsSession, filename, EFileWrite)); + qt_symbian_throwIfError(file.Write(content)); + return file; +} +#else +void tst_qfileopenevent::createFile(const QString &filename, const QByteArray &content) +{ + QFile file(filename); + file.open(QFile::WriteOnly); + file.write(content); + file.close(); +} +#endif + +QFileOpenEvent * tst_qfileopenevent::createFileAndEvent(const QString &filename, const QByteArray &content) +{ +#ifdef Q_OS_SYMBIAN + RFile rFile = createRFile(qt_QString2TPtrC(filename), TPtrC8((TText8*)content.constData(), content.size())); + QScopedPointer<RFile, QScopedPointerRCloser<RFile> > closeRFile(&rFile); + return new QFileOpenEvent(rFile); +#else + createFile(filename, content); + return new QFileOpenEvent(filename); +#endif +} + +void tst_qfileopenevent::constructor() +{ + // check that filename get/set works + QFileOpenEvent nameTest(QLatin1String("fileNameTest")); + QCOMPARE(nameTest.file(), QLatin1String("fileNameTest")); + + // check that url get/set works + QFileOpenEvent urlTest(QUrl(QLatin1String("file:///urlNameTest"))); + QCOMPARE(urlTest.url().toString(), QLatin1String("file:///urlNameTest")); + +#ifdef Q_OS_SYMBIAN + // check that RFile construction works + RFile rFile = createRFile(_L("testRFile"), _L8("test content")); + QFileOpenEvent rFileTest(rFile); + QString targetName(QLatin1String("testRFile")); + QCOMPARE(rFileTest.file().right(targetName.size()), targetName); + QCOMPARE(rFileTest.url().toString().right(targetName.size()), targetName); + rFile.Close(); +#endif +} + +QByteArray tst_qfileopenevent::readFileContent(QFileOpenEvent& event) +{ + QFile file; + event.openFile(file, QFile::ReadOnly); + file.seek(0); + QByteArray data = file.readAll(); + return data; +} + +bool tst_qfileopenevent::appendFileContent(QFileOpenEvent& event, const QByteArray& writeContent) +{ + QFile file; + bool ok = event.openFile(file, QFile::Append | QFile::Unbuffered); + if (ok) + ok = file.write(writeContent) == writeContent.size(); + return ok; +} + +void tst_qfileopenevent::checkReadAndWrite(QFileOpenEvent& event, const QByteArray& readContent, const QByteArray& writeContent, bool writeOk) +{ + QCOMPARE(readFileContent(event), readContent); + QCOMPARE(appendFileContent(event, writeContent), writeOk); + QCOMPARE(readFileContent(event), writeOk ? readContent+writeContent : readContent); +} + +void tst_qfileopenevent::fileOpen() +{ +#ifdef Q_OS_SYMBIAN + // create writeable file + { + RFile rFile = createRFile(_L("testFileOpen"), _L8("test content")); + QFileOpenEvent rFileTest(rFile); + checkReadAndWrite(rFileTest, QByteArray("test content"), QByteArray("+RFileWrite"), true); + rFile.Close(); + } + + // open read-only RFile + { + RFile rFile; + int err = rFile.Open(fsSession, _L("testFileOpen"), EFileRead); + QFileOpenEvent rFileTest(rFile); + checkReadAndWrite(rFileTest, QByteArray("test content+RFileWrite"), QByteArray("+RFileRead"), false); + rFile.Close(); + } +#else + createFile(QLatin1String("testFileOpen"), QByteArray("test content+RFileWrite")); +#endif + + // filename event + QUrl fileUrl; // need to get the URL during the file test, for use in the URL test + { + QFileOpenEvent nameTest(QLatin1String("testFileOpen")); + fileUrl = nameTest.url(); + checkReadAndWrite(nameTest, QByteArray("test content+RFileWrite"), QByteArray("+nameWrite"), true); + } + + // url event + { + QFileOpenEvent urlTest(fileUrl); + checkReadAndWrite(urlTest, QByteArray("test content+RFileWrite+nameWrite"), QByteArray("+urlWrite"), true); + } + + QFile::remove(QLatin1String("testFileOpen")); +} + +void tst_qfileopenevent::handleLifetime() +{ + QScopedPointer<QFileOpenEvent> event(createFileAndEvent(QLatin1String("testHandleLifetime"), QByteArray("test content"))); + + // open a QFile after the original RFile is closed + QFile qFile; + QCOMPARE(event->openFile(qFile, QFile::Append | QFile::Unbuffered), true); + event.reset(0); + + // write to the QFile after the event is closed + QString writeContent(QLatin1String("+closed original handles")); + QCOMPARE(int(qFile.write(writeContent.toUtf8())), writeContent.size()); + qFile.close(); + + // check the content + QFile check("testHandleLifetime"); + check.open(QFile::ReadOnly); + QString content(check.readAll()); + QCOMPARE(content, QLatin1String("test content+closed original handles")); + check.close(); + + QFile::remove(QLatin1String("testHandleLifetime")); +} + +void tst_qfileopenevent::multiOpen() +{ + QScopedPointer<QFileOpenEvent> event(createFileAndEvent(QLatin1String("testMultiOpen"), QByteArray("itlum"))); + + QFile files[5]; + for (int i=0; i<5; i++) { + QCOMPARE(event->openFile(files[i], QFile::ReadOnly), true); + } + for (int i=0; i<5; i++) + files[i].seek(i); + QString str; + for (int i=4; i>=0; i--) { + char c; + files[i].getChar(&c); + str.append(c); + files[i].close(); + } + QCOMPARE(str, QLatin1String("multi")); + + QFile::remove(QLatin1String("testMultiOpen")); +} + +bool tst_qfileopenevent::event(QEvent *event) +{ + if (event->type() != QEvent::FileOpen) + return QObject::event(event); + QFileOpenEvent* fileOpenEvent = static_cast<QFileOpenEvent *>(event); + appendFileContent(*fileOpenEvent, "+received"); + return true; +} + +void tst_qfileopenevent::sendAndReceive() +{ + QScopedPointer<QFileOpenEvent> event(createFileAndEvent(QLatin1String("testSendAndReceive"), QByteArray("sending"))); + + QCoreApplication::instance()->postEvent(this, event.take()); + QCoreApplication::instance()->processEvents(); + + // QTBUG-17468: On Mac, processEvents doesn't always process posted events + QCoreApplication::instance()->sendPostedEvents(); + + // check the content + QFile check("testSendAndReceive"); + QCOMPARE(check.open(QFile::ReadOnly), true); + QString content(check.readAll()); + QCOMPARE(content, QLatin1String("sending+received")); + check.close(); + + QFile::remove(QLatin1String("testSendAndReceive")); +} + +void tst_qfileopenevent::external_data() +{ + QTest::addColumn<QString>("filename"); + QTest::addColumn<QByteArray>("targetContent"); + QTest::addColumn<bool>("sendHandle"); + + QString privateName(QLatin1String("tst_qfileopenevent_external")); + QString publicName(QLatin1String("C:\\Data\\tst_qfileopenevent_external")); + QByteArray writeSuccess("original+external"); + QByteArray writeFail("original"); + QTest::newRow("public name") << publicName << writeSuccess << false; + QTest::newRow("data caged name") << privateName << writeFail << false; + QTest::newRow("public handle") << publicName << writeSuccess << true; + QTest::newRow("data caged handle") << privateName << writeSuccess << true; +} + +void tst_qfileopenevent::external() +{ +#ifndef Q_OS_SYMBIAN + QSKIP("external app file open test only valid in Symbian", SkipAll); +#else + + QFETCH(QString, filename); + QFETCH(QByteArray, targetContent); + QFETCH(bool, sendHandle); + + RFile rFile = createRFile(qt_QString2TPtrC(filename), _L8("original")); + + // launch app with the file + RApaLsSession apa; + QCOMPARE(apa.Connect(), KErrNone); + TThreadId threadId; + TDataType type(_L8("application/x-tst_qfileopenevent")); + if (sendHandle) { + QCOMPARE(apa.StartDocument(rFile, type, threadId), KErrNone); + rFile.Close(); + } else { + TFileName fullName; + rFile.FullName(fullName); + rFile.Close(); + QCOMPARE(apa.StartDocument(fullName, type, threadId), KErrNone); + } + + // wait for app exit + RThread appThread; + if (appThread.Open(threadId) == KErrNone) { + TRequestStatus status; + appThread.Logon(status); + User::WaitForRequest(status); + } + + // check the contents + QFile check(filename); + QCOMPARE(check.open(QFile::ReadOnly), true); + QCOMPARE(check.readAll(), targetContent); + bool ok = check.remove(); + + QFile::remove(filename); +#endif +} + +QTEST_MAIN(tst_qfileopenevent) +#include "tst_qfileopenevent.moc" diff --git a/tests/auto/qfilesystementry/qfilesystementry.pro b/tests/auto/qfilesystementry/qfilesystementry.pro new file mode 100644 index 0000000..b9b43e6 --- /dev/null +++ b/tests/auto/qfilesystementry/qfilesystementry.pro @@ -0,0 +1,8 @@ +load(qttest_p4) + +SOURCES += tst_qfilesystementry.cpp \ + ../../../src/corelib/io/qfilesystementry.cpp +HEADERS += ../../../src/corelib/io/qfilesystementry_p.h +QT = core + +CONFIG += parallel_test diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp new file mode 100644 index 0000000..016bcbf --- /dev/null +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -0,0 +1,387 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtTest/QtTest> + +#include <QtCore/private/qfilesystementry_p.h> + +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) +# define WIN_STUFF +#endif + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QFileSystemEntry : public QObject +{ + Q_OBJECT + +private slots: + void getSetCheck_data(); + void getSetCheck(); + void suffix_data(); + void suffix(); + void completeSuffix_data(); + void completeSuffix(); + void baseName_data(); + void baseName(); + void completeBaseName_data(); + void completeBaseName(); +#if defined(WIN_STUFF) + void absoluteOrRelative_data(); + void absoluteOrRelative(); +#endif +}; + +#if defined(WIN_STUFF) +void tst_QFileSystemEntry::getSetCheck_data() +{ + QTest::addColumn<QString>("nativeFilePath"); + QTest::addColumn<QString>("internalnativeFilePath"); + QTest::addColumn<QString>("filepath"); + QTest::addColumn<QString>("filename"); + QTest::addColumn<QString>("baseName"); + QTest::addColumn<QString>("completeBasename"); + QTest::addColumn<QString>("suffix"); + QTest::addColumn<QString>("completeSuffix"); + QTest::addColumn<bool>("absolute"); + QTest::addColumn<bool>("relative"); + + QString absPrefix = QLatin1String("\\\\?\\"); + QString relPrefix = absPrefix + + QDir::toNativeSeparators(QDir::currentPath()) + + QLatin1String("\\"); + + QTest::newRow("simple") + << QString("A:\\home\\qt\\in\\a\\dir.tar.gz") + << absPrefix + QString("A:\\home\\qt\\in\\a\\dir.tar.gz") + << "A:/home/qt/in/a/dir.tar.gz" + << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << true << false; + + QTest::newRow("relative") + << QString("in\\a\\dir.tar.gz") + << relPrefix + QString("in\\a\\dir.tar.gz") + << "in/a/dir.tar.gz" + << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << false <<true; + + QTest::newRow("noSuffix") + << QString("myDir\\myfile") + << relPrefix + QString("myDir\\myfile") + << "myDir/myfile" << "myfile" << "myfile" << "myfile" << "" << "" << false <<true; + + QTest::newRow("noLongSuffix") + << QString("myDir\\myfile.txt") + << relPrefix + QString("myDir\\myfile.txt") + << "myDir/myfile.txt" << "myfile.txt" << "myfile" << "myfile" << "txt" << "txt" << false << true; + + QTest::newRow("endingSlash") + << QString("myDir\\myfile.bla\\") + << relPrefix + QString("myDir\\myfile.bla\\") + << "myDir/myfile.bla/" << "" << "" << "" << "" << "" << false << true; + + QTest::newRow("absolutePath") + << QString("A:dir\\without\\leading\\backslash.bat") + << absPrefix + QString("A:\\dir\\without\\leading\\backslash.bat") + << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "backslash" << "backslash" << "bat" << "bat" << false << false; +} + +void tst_QFileSystemEntry::getSetCheck() +{ + QFETCH(QString, nativeFilePath); + QFETCH(QString, internalnativeFilePath); + QFETCH(QString, filepath); + QFETCH(QString, filename); + QFETCH(QString, baseName); + QFETCH(QString, completeBasename); + QFETCH(QString, suffix); + QFETCH(QString, completeSuffix); + QFETCH(bool, absolute); + QFETCH(bool, relative); + + QFileSystemEntry entry1(filepath); + QCOMPARE(entry1.filePath(), filepath); + QCOMPARE(entry1.nativeFilePath().toLower(), internalnativeFilePath.toLower()); + QCOMPARE(entry1.fileName(), filename); + QCOMPARE(entry1.suffix(), suffix); + QCOMPARE(entry1.completeSuffix(), completeSuffix); + QCOMPARE(entry1.isAbsolute(), absolute); + QCOMPARE(entry1.isRelative(), relative); + QCOMPARE(entry1.baseName(), baseName); + QCOMPARE(entry1.completeBaseName(), completeBasename); + + QFileSystemEntry entry2(nativeFilePath, QFileSystemEntry::FromNativePath()); + QCOMPARE(entry2.suffix(), suffix); + QCOMPARE(entry2.completeSuffix(), completeSuffix); + QCOMPARE(entry2.isAbsolute(), absolute); + QCOMPARE(entry2.isRelative(), relative); + QCOMPARE(entry2.filePath(), filepath); + // Since this entry was created using the native path, + // the object shouldnot change nativeFilePath. + QCOMPARE(entry2.nativeFilePath(), nativeFilePath); + QCOMPARE(entry2.fileName(), filename); + QCOMPARE(entry2.baseName(), baseName); + QCOMPARE(entry2.completeBaseName(), completeBasename); +} + +#else + +void tst_QFileSystemEntry::getSetCheck_data() +{ + QTest::addColumn<QByteArray>("nativeFilePath"); + QTest::addColumn<QString>("filepath"); + QTest::addColumn<QString>("filename"); + QTest::addColumn<QString>("basename"); + QTest::addColumn<QString>("completeBasename"); + QTest::addColumn<QString>("suffix"); + QTest::addColumn<QString>("completeSuffix"); + QTest::addColumn<bool>("absolute"); + + QTest::newRow("simple") + << QByteArray("/home/qt/in/a/dir.tar.gz") + << "/home/qt/in/a/dir.tar.gz" + << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << true; + QTest::newRow("relative") + << QByteArray("in/a/dir.tar.gz") + << "in/a/dir.tar.gz" + << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << false; + + QTest::newRow("noSuffix") + << QByteArray("myDir/myfile") + << "myDir/myfile" << "myfile" << "myfile" << "myfile" << "" << "" << false; + + QTest::newRow("noLongSuffix") + << QByteArray("myDir/myfile.txt") + << "myDir/myfile.txt" << "myfile.txt" << "myfile" << "myfile" << "txt" << "txt" << false; + + QTest::newRow("endingSlash") + << QByteArray("myDir/myfile.bla/") + << "myDir/myfile.bla/" << "" << "" << "" << "" << "" << false; + + QTest::newRow("relativePath") + << QByteArray("A:dir/without/leading/backslash.bat") + << "A:dir/without/leading/backslash.bat" << "backslash.bat" << "backslash" << "backslash" << "bat" << "bat" << false; +} + +void tst_QFileSystemEntry::getSetCheck() +{ + QFETCH(QByteArray, nativeFilePath); + QFETCH(QString, filepath); + QFETCH(QString, filename); + QFETCH(QString, basename); + QFETCH(QString, completeBasename); + QFETCH(QString, suffix); + QFETCH(QString, completeSuffix); + QFETCH(bool, absolute); + + QFileSystemEntry entry1(filepath); + QCOMPARE(entry1.filePath(), filepath); + QCOMPARE(entry1.nativeFilePath(), nativeFilePath); + QCOMPARE(entry1.fileName(), filename); + QCOMPARE(entry1.suffix(), suffix); + QCOMPARE(entry1.completeSuffix(), completeSuffix); + QCOMPARE(entry1.isAbsolute(), absolute); + QCOMPARE(entry1.isRelative(), !absolute); + QCOMPARE(entry1.baseName(), basename); + QCOMPARE(entry1.completeBaseName(), completeBasename); + + QFileSystemEntry entry2(nativeFilePath, QFileSystemEntry::FromNativePath()); + QCOMPARE(entry2.suffix(), suffix); + QCOMPARE(entry2.completeSuffix(), completeSuffix); + QCOMPARE(entry2.isAbsolute(), absolute); + QCOMPARE(entry2.isRelative(), !absolute); + QCOMPARE(entry2.filePath(), filepath); + QCOMPARE(entry2.nativeFilePath(), nativeFilePath); + QCOMPARE(entry2.fileName(), filename); + QCOMPARE(entry2.baseName(), basename); + QCOMPARE(entry2.completeBaseName(), completeBasename); +} +#endif + +void tst_QFileSystemEntry::suffix_data() +{ + QTest::addColumn<QString>("file"); + QTest::addColumn<QString>("expected"); + + QTest::newRow("noextension0") << "file" << ""; + QTest::newRow("noextension1") << "/path/to/file" << ""; + QTest::newRow("data0") << "file.tar" << "tar"; + QTest::newRow("data1") << "file.tar.gz" << "gz"; + QTest::newRow("data2") << "/path/file/file.tar.gz" << "gz"; + QTest::newRow("data3") << "/path/file.tar" << "tar"; + QTest::newRow("hidden1") << ".ext1" << "ext1"; + QTest::newRow("hidden1") << ".ext" << "ext"; + QTest::newRow("hidden1") << ".ex" << "ex"; + QTest::newRow("hidden1") << ".e" << "e"; + QTest::newRow("hidden2") << ".ext1.ext2" << "ext2"; + QTest::newRow("hidden2") << ".ext.ext2" << "ext2"; + QTest::newRow("hidden2") << ".ex.ext2" << "ext2"; + QTest::newRow("hidden2") << ".e.ext2" << "ext2"; + QTest::newRow("hidden2") << "..ext2" << "ext2"; + QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << "ext2"; + QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << "ext2"; +} + +void tst_QFileSystemEntry::suffix() +{ + QFETCH(QString, file); + QFETCH(QString, expected); + + QFileSystemEntry fe(file); + QCOMPARE(fe.suffix(), expected); + + QFileSystemEntry fi2(file); + // first resolve the last slash + (void) fi2.path(); + QCOMPARE(fi2.suffix(), expected); +} + +void tst_QFileSystemEntry::completeSuffix_data() +{ + QTest::addColumn<QString>("file"); + QTest::addColumn<QString>("expected"); + + QTest::newRow("noextension0") << "file" << ""; + QTest::newRow("noextension1") << "/path/to/file" << ""; + QTest::newRow("data0") << "file.tar" << "tar"; + QTest::newRow("data1") << "file.tar.gz" << "tar.gz"; + QTest::newRow("data2") << "/path/file/file.tar.gz" << "tar.gz"; + QTest::newRow("data3") << "/path/file.tar" << "tar"; + QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << ".ext2"; + QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << "file..ext2"; +} + +void tst_QFileSystemEntry::completeSuffix() +{ + QFETCH(QString, file); + QFETCH(QString, expected); + + QFileSystemEntry fi(file); + QCOMPARE(fi.completeSuffix(), expected); + + QFileSystemEntry fi2(file); + // first resolve the last slash + (void) fi2.path(); + QCOMPARE(fi2.completeSuffix(), expected); +} + +void tst_QFileSystemEntry::baseName_data() +{ + QTest::addColumn<QString>("file"); + QTest::addColumn<QString>("expected"); + + QTest::newRow("data0") << "file.tar" << "file"; + QTest::newRow("data1") << "file.tar.gz" << "file"; + QTest::newRow("data2") << "/path/file/file.tar.gz" << "file"; + QTest::newRow("data3") << "/path/file.tar" << "file"; + QTest::newRow("data4") << "/path/file" << "file"; + QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << "file"; + QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << ""; +} + +void tst_QFileSystemEntry::baseName() +{ + QFETCH(QString, file); + QFETCH(QString, expected); + + QFileSystemEntry fi(file); + QCOMPARE(fi.baseName(), expected); + + QFileSystemEntry fi2(file); + // first resolve the last slash + (void) fi2.path(); + QCOMPARE(fi2.baseName(), expected); +} + +void tst_QFileSystemEntry::completeBaseName_data() +{ + QTest::addColumn<QString>("file"); + QTest::addColumn<QString>("expected"); + + QTest::newRow("data0") << "file.tar" << "file"; + QTest::newRow("data1") << "file.tar.gz" << "file.tar"; + QTest::newRow("data2") << "/path/file/file.tar.gz" << "file.tar"; + QTest::newRow("data3") << "/path/file.tar" << "file"; + QTest::newRow("data4") << "/path/file" << "file"; + QTest::newRow("dots") << "/path/file.with.dots/file..ext2" << "file."; + QTest::newRow("dots2") << "/path/file.with.dots/.file..ext2" << ".file."; +} + +void tst_QFileSystemEntry::completeBaseName() +{ + QFETCH(QString, file); + QFETCH(QString, expected); + + QFileSystemEntry fi(file); + QCOMPARE(fi.completeBaseName(), expected); + + QFileSystemEntry fi2(file); + // first resolve the last slash + (void) fi2.path(); + QCOMPARE(fi2.completeBaseName(), expected); +} + +#if defined(WIN_STUFF) +void tst_QFileSystemEntry::absoluteOrRelative_data() +{ + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("isAbsolute"); + QTest::addColumn<bool>("isRelative"); + + QTest::newRow("data0") << "file.tar" << false << true; + QTest::newRow("data1") << "/path/file/file.tar.gz" << false << false; + QTest::newRow("data1") << "C:path/file/file.tar.gz" << false << false; + QTest::newRow("data3") << "C:/path/file" << true << false; + QTest::newRow("data3") << "//machine/share" << true << false; +} + +void tst_QFileSystemEntry::absoluteOrRelative() +{ + QFETCH(QString, path); + QFETCH(bool, isAbsolute); + QFETCH(bool, isRelative); + + QFileSystemEntry fi(path); + QCOMPARE(fi.isAbsolute(), isAbsolute); + QCOMPARE(fi.isRelative(), isRelative); +} +#endif + +QTEST_MAIN(tst_QFileSystemEntry) +#include <tst_qfilesystementry.moc> diff --git a/tests/auto/qfilesystemmodel/qfilesystemmodel.pro b/tests/auto/qfilesystemmodel/qfilesystemmodel.pro index 070eb6a..04cea48 100644 --- a/tests/auto/qfilesystemmodel/qfilesystemmodel.pro +++ b/tests/auto/qfilesystemmodel/qfilesystemmodel.pro @@ -9,7 +9,7 @@ symbian: { HEADERS += ../../../include/qtgui/private/qfileinfogatherer_p.h # need to deploy something to create the private directory - dummyDeploy.sources = tst_qfilesystemmodel.cpp + dummyDeploy.files = tst_qfilesystemmodel.cpp dummyDeploy.path = . DEPLOYMENT += dummyDeploy LIBS += -lefsrv diff --git a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp index 6d3e65c..5f61094 100644 --- a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -41,7 +41,10 @@ #include <QtTest/QtTest> +#ifdef QT_BUILD_INTERNAL #include "../../../src/gui/dialogs/qfilesystemmodel_p.h" +#endif +#include <QFileSystemModel> #include <QFileIconProvider> #include <QTreeView> #include <QHeaderView> @@ -629,7 +632,12 @@ void tst_QFileSystemModel::filters_data() QTest::addColumn<int>("rowCount"); #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QTest::newRow("no dirs") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs) << QStringList() << 2; - QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1; + QTest::newRow("no dirs - dot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 1; + QTest::newRow("no dirs - dotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 1; + QTest::newRow("no dirs - dotanddotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 0; + QTest::newRow("one dir - dot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 2; + QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 2; + QTest::newRow("one dir - dotanddotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1; QTest::newRow("one dir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs) << QStringList() << 3; QTest::newRow("no dir + hidden") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::Hidden) << QStringList() << 2; QTest::newRow("dir+hid+files") << (QStringList() << "a" << "b" << "c") << QStringList() << @@ -647,7 +655,12 @@ void tst_QFileSystemModel::filters_data() #else QTest::qWait(3000); // We need to calm down a bit... QTest::newRow("no dirs") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs) << QStringList() << 0; - QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1; + QTest::newRow("no dirs - dot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 1; + QTest::newRow("no dirs - dotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 1; + QTest::newRow("no dirs - dotanddotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 0; + QTest::newRow("one dir - dot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 2; + QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 2; + QTest::newRow("one dir - dotanddotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1; QTest::newRow("one dir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs) << QStringList() << 1; QTest::newRow("no dir + hidden") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::Hidden) << QStringList() << 0; QTest::newRow("dir+hid+files") << (QStringList() << "a" << "b" << "c") << QStringList() << @@ -696,10 +709,23 @@ void tst_QFileSystemModel::filters() // Make sure that we do what QDir does QDir xFactor(tmp); QDir::Filters filters = (QDir::Filters)dirFilters; + QStringList dirEntries; + if (nameFilters.count() > 0) - QCOMPARE(xFactor.entryList(nameFilters, filters).count(), rowCount); + dirEntries = xFactor.entryList(nameFilters, filters); else - QVERIFY(xFactor.entryList(filters).count() == rowCount); + dirEntries = xFactor.entryList(filters); + + QCOMPARE(dirEntries.count(), rowCount); + + QStringList modelEntries; + + for (int i = 0; i < rowCount; ++i) + modelEntries.append(model->data(model->index(i, 0, root), QFileSystemModel::FileNameRole).toString()); + + qSort(dirEntries); + qSort(modelEntries); + QCOMPARE(dirEntries, modelEntries); #ifdef Q_OS_LINUX if (files.count() >= 3 && rowCount >= 3 && rowCount != 5) { @@ -826,8 +852,10 @@ void tst_QFileSystemModel::sort() MyFriendFileSystemModel *myModel = new MyFriendFileSystemModel(); QTreeView *tree = new QTreeView(); +#ifdef QT_BUILD_INTERNAL if (fileDialogMode) myModel->d_func()->disableRecursiveSort = true; +#endif QDir dir(QDir::tempPath()); //initialize the randomness @@ -975,8 +1003,12 @@ void tst_QFileSystemModel::drives() model.setRootPath(path); model.fetchMore(QModelIndex()); QFileInfoList drives = QDir::drives(); + int driveCount = 0; + foreach(const QFileInfo& driveRoot, drives) + if (driveRoot.exists()) + driveCount++; QTest::qWait(5000); - QTRY_COMPARE(model.rowCount(), drives.count()); + QTRY_COMPARE(model.rowCount(), driveCount); } void tst_QFileSystemModel::dirsBeforeFiles() @@ -992,8 +1024,8 @@ void tst_QFileSystemModel::dirsBeforeFiles() } dir.rmdir(dirPath); } - dir.mkpath(dirPath); - QVERIFY(dir.exists()); + QVERIFY(dir.mkpath(dirPath)); + QVERIFY(QDir(dirPath).exists()); for (int i = 0; i < 3; ++i) { QLatin1Char c('a' + i); diff --git a/tests/auto/qfilesystemwatcher/qfilesystemwatcher.pro b/tests/auto/qfilesystemwatcher/qfilesystemwatcher.pro index 8b8616a..75e85a0 100644 --- a/tests/auto/qfilesystemwatcher/qfilesystemwatcher.pro +++ b/tests/auto/qfilesystemwatcher/qfilesystemwatcher.pro @@ -1,3 +1,5 @@ load(qttest_p4) SOURCES += tst_qfilesystemwatcher.cpp QT = core + +CONFIG += parallel_test diff --git a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index 8e0c9fe..9d46a8d 100644 --- a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -82,6 +82,8 @@ private slots: void removeFileAndUnWatch(); void cleanup(); + + void QTBUG15255_deadlock(); private: QStringList do_force_engines; bool do_force_native; @@ -550,5 +552,23 @@ void tst_QFileSystemWatcher::removeFileAndUnWatch() watcher.addPath(filename); } +class SomeSingleton : public QObject +{ +public: + SomeSingleton() : mFsWatcher(new QFileSystemWatcher(this)) { mFsWatcher->addPath(QLatin1String("/usr/lib"));} + void bla() const {} + QFileSystemWatcher* mFsWatcher; +}; + +Q_GLOBAL_STATIC(SomeSingleton, someSingleton) + +void tst_QFileSystemWatcher::QTBUG15255_deadlock() +{ + someSingleton()->bla(); + //the test must still finish + QTest::qWait(30); +} + + QTEST_MAIN(tst_QFileSystemWatcher) #include "tst_qfilesystemwatcher.moc" diff --git a/tests/auto/qflags/qflags.pro b/tests/auto/qflags/qflags.pro index cd7f759..097a218 100644 --- a/tests/auto/qflags/qflags.pro +++ b/tests/auto/qflags/qflags.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qflags.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qfont/tst_qfont.cpp b/tests/auto/qfont/tst_qfont.cpp index 62ddf1a..cfafa78 100644 --- a/tests/auto/qfont/tst_qfont.cpp +++ b/tests/auto/qfont/tst_qfont.cpp @@ -150,6 +150,13 @@ void tst_QFont::exactMatch() return; #endif +#ifdef Q_WS_X11 + QVERIFY(QFont("sans").exactMatch()); + QVERIFY(QFont("sans-serif").exactMatch()); + QVERIFY(QFont("serif").exactMatch()); + QVERIFY(QFont("monospace").exactMatch()); +#endif + QSKIP("This test is bogus on Unix with support for font aliases in fontconfig", SkipAll); return; diff --git a/tests/auto/qfontdatabase/qfontdatabase.pro b/tests/auto/qfontdatabase/qfontdatabase.pro index 35811f1..e7dfc3c 100644 --- a/tests/auto/qfontdatabase/qfontdatabase.pro +++ b/tests/auto/qfontdatabase/qfontdatabase.pro @@ -3,7 +3,7 @@ SOURCES += tst_qfontdatabase.cpp !symbian:DEFINES += SRCDIR=\\\"$$PWD\\\" wince*|symbian { - additionalFiles.sources = FreeMono.ttf + additionalFiles.files = FreeMono.ttf additionalFiles.path = . DEPLOYMENT += additionalFiles } diff --git a/tests/auto/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/qfontdatabase/tst_qfontdatabase.cpp index d75c69a..735c7e4 100644 --- a/tests/auto/qfontdatabase/tst_qfontdatabase.cpp +++ b/tests/auto/qfontdatabase/tst_qfontdatabase.cpp @@ -70,6 +70,11 @@ private slots: void fixedPitch_data(); void fixedPitch(); +#ifdef Q_WS_MAC + void trickyFonts_data(); + void trickyFonts(); +#endif + void widthTwoTimes_data(); void widthTwoTimes(); @@ -131,10 +136,16 @@ void tst_QFontDatabase::fixedPitch_data() QTest::newRow( "Times New Roman" ) << QString( "Times New Roman" ) << false; QTest::newRow( "Arial" ) << QString( "Arial" ) << false; - QTest::newRow( "Script" ) << QString( "Script" ) << false; + QTest::newRow( "Andale Mono" ) << QString( "Andale Mono" ) << true; QTest::newRow( "Courier" ) << QString( "Courier" ) << true; QTest::newRow( "Courier New" ) << QString( "Courier New" ) << true; +#ifndef Q_WS_MAC + QTest::newRow( "Script" ) << QString( "Script" ) << false; QTest::newRow( "Lucida Console" ) << QString( "Lucida Console" ) << true; +#else + QTest::newRow( "Menlo" ) << QString( "Menlo" ) << true; + QTest::newRow( "Monaco" ) << QString( "Monaco" ) << true; +#endif } void tst_QFontDatabase::fixedPitch() @@ -156,6 +167,28 @@ void tst_QFontDatabase::fixedPitch() QCOMPARE(fi.fixedPitch(), fixedPitch); } +#ifdef Q_WS_MAC +void tst_QFontDatabase::trickyFonts_data() +{ + QTest::addColumn<QString>("font"); + + QTest::newRow( "Geeza Pro" ) << QString( "Geeza Pro" ); +} + +void tst_QFontDatabase::trickyFonts() +{ + QFETCH(QString, font); + + QFontDatabase fdb; + if (!fdb.families().contains(font)) + QSKIP( "Font not installed", SkipSingle); + + QFont qfont(font); + QFontInfo fi(qfont); + QCOMPARE(fi.family(), font); +} +#endif + void tst_QFontDatabase::widthTwoTimes_data() { QTest::addColumn<QString>("font"); diff --git a/tests/auto/qfontmetrics/qfontmetrics.pro b/tests/auto/qfontmetrics/qfontmetrics.pro index 51a7057..c0dc1ab 100644 --- a/tests/auto/qfontmetrics/qfontmetrics.pro +++ b/tests/auto/qfontmetrics/qfontmetrics.pro @@ -1,4 +1,4 @@ load(qttest_p4) SOURCES += tst_qfontmetrics.cpp - +RESOURCES += testfont.qrc diff --git a/tests/auto/qfontmetrics/testfont.qrc b/tests/auto/qfontmetrics/testfont.qrc new file mode 100644 index 0000000..bc0c0b0 --- /dev/null +++ b/tests/auto/qfontmetrics/testfont.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/fonts"> + <file>ucs4font.ttf</file> + </qresource> +</RCC> diff --git a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp index 6357994..1df194d 100644 --- a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp @@ -74,6 +74,7 @@ private slots: void bypassShaping(); void elidedMultiLength(); void elidedMultiLengthF(); + void inFontUcs4(); void lineWidth(); }; @@ -267,6 +268,27 @@ void tst_QFontMetrics::elidedMultiLengthF() elidedMultiLength_helper<QFontMetricsF>(); } +void tst_QFontMetrics::inFontUcs4() +{ + int id = QFontDatabase::addApplicationFont(":/fonts/ucs4font.ttf"); + QVERIFY(id >= 0); + + QFont font("QtTestUcs4"); + { + QFontMetrics fm(font); + + QVERIFY(fm.inFontUcs4(0x1D7FF)); + } + + { + QFontMetricsF fm(font); + + QVERIFY(fm.inFontUcs4(0x1D7FF)); + } + + QFontDatabase::removeApplicationFont(id); +} + void tst_QFontMetrics::lineWidth() { // QTBUG-13009, QTBUG-13011 diff --git a/tests/auto/qfontmetrics/ucs4font.ttf b/tests/auto/qfontmetrics/ucs4font.ttf Binary files differnew file mode 100644 index 0000000..31b6997 --- /dev/null +++ b/tests/auto/qfontmetrics/ucs4font.ttf diff --git a/tests/auto/qftp/qftp.pro b/tests/auto/qftp/qftp.pro index 9618962..ac1702e 100644 --- a/tests/auto/qftp/qftp.pro +++ b/tests/auto/qftp/qftp.pro @@ -5,12 +5,12 @@ SOURCES += tst_qftp.cpp QT = core network wince*: { - addFiles.sources = rfc3252.txt + addFiles.files = rfc3252.txt addFiles.path = . DEPLOYMENT += addFiles DEFINES += SRCDIR=\\\"\\\" } else:symbian { - addFiles.sources = rfc3252.txt + addFiles.files = rfc3252.txt addFiles.path = . DEPLOYMENT += addFiles TARGET.EPOCHEAPSIZE="0x100 0x1000000" diff --git a/tests/auto/qftp/tst_qftp.cpp b/tests/auto/qftp/tst_qftp.cpp index a19ea58..7e431cf 100644 --- a/tests/auto/qftp/tst_qftp.cpp +++ b/tests/auto/qftp/tst_qftp.cpp @@ -50,6 +50,10 @@ #include <time.h> #include <stdlib.h> #include <QNetworkProxy> +#include <QNetworkConfiguration> +#include <qnetworkconfigmanager.h> +#include <QNetworkSession> +#include <QtNetwork/private/qnetworksession_p.h> #include "../network-settings.h" @@ -62,7 +66,9 @@ #define SRCDIR "" #endif - +#ifndef QT_NO_BEARERMANAGEMENT +Q_DECLARE_METATYPE(QNetworkConfiguration) +#endif class tst_QFtp : public QObject { @@ -148,6 +154,11 @@ private: void renameCleanup( const QString &host, const QString &user, const QString &password, const QString &fileToDelete ); QFtp *ftp; +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkConfigurationManager *netConfMan; + QSharedPointer<QNetworkSession> networkSessionExplicit; + QSharedPointer<QNetworkSession> networkSessionImplicit; +#endif QList<int> ids; // helper to make sure that all expected signals are emitted int current_id; @@ -186,9 +197,9 @@ private: const int bytesTotal_init = -10; const int bytesDone_init = -10; -tst_QFtp::tst_QFtp() +tst_QFtp::tst_QFtp() : + ftp(0) { - Q_SET_DEFAULT_IAP } tst_QFtp::~tst_QFtp() @@ -199,33 +210,74 @@ void tst_QFtp::initTestCase_data() { QTest::addColumn<bool>("setProxy"); QTest::addColumn<int>("proxyType"); + QTest::addColumn<bool>("setSession"); - QTest::newRow("WithoutProxy") << false << 0; - QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy); + QTest::newRow("WithoutProxy") << false << 0 << false; + QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy) << false; //### doesn't work well yet. //QTest::newRow("WithHttpProxy") << true << int(QNetworkProxy::HttpProxy); + +#ifndef QT_NO_BEARERMANAGEMENT + QTest::newRow("WithoutProxyWithSession") << false << 0 << true; + QTest::newRow("WithSocks5ProxyAndSession") << true << int(QNetworkProxy::Socks5Proxy) << true; +#endif } void tst_QFtp::initTestCase() { +#ifndef QT_NO_BEARERMANAGEMENT + netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QNetworkConfiguration networkConfiguration = netConfMan->defaultConfiguration(); + if (networkConfiguration.isValid()) { + networkSessionImplicit = QSharedPointer<QNetworkSession>(new QNetworkSession(networkConfiguration)); + if (!networkSessionImplicit->isOpen()) { + networkSessionImplicit->open(); + QVERIFY(networkSessionImplicit->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); + } +#endif } void tst_QFtp::cleanupTestCase() { +#ifndef QT_NO_BEARERMANAGEMENT + networkSessionExplicit.clear(); + networkSessionImplicit.clear(); +#endif } void tst_QFtp::init() { QFETCH_GLOBAL(bool, setProxy); + QFETCH_GLOBAL(int, proxyType); + QFETCH_GLOBAL(bool, setSession); if (setProxy) { - QFETCH_GLOBAL(int, proxyType); if (proxyType == QNetworkProxy::Socks5Proxy) { QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080)); } else if (proxyType == QNetworkProxy::HttpProxy) { QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128)); } } +#ifndef QT_NO_BEARERMANAGEMENT + if (setSession) { + if (!networkSessionImplicit) + QSKIP("test requires a valid default network configuration", SkipSingle); + networkSessionExplicit = networkSessionImplicit; + if (!networkSessionExplicit->isOpen()) { + networkSessionExplicit->open(); + QVERIFY(networkSessionExplicit->waitForOpened(30000)); + } + } else { + networkSessionExplicit.clear(); + } +#endif + delete ftp; ftp = 0; ids.clear(); @@ -262,10 +314,20 @@ void tst_QFtp::init() void tst_QFtp::cleanup() { + if (ftp) { + delete ftp; + ftp = 0; + } QFETCH_GLOBAL(bool, setProxy); if (setProxy) { QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy); } + + delete ftp; + ftp = 0; +#ifndef QT_NO_BEARERMANAGEMENT + networkSessionExplicit.clear(); +#endif } void tst_QFtp::connectToHost_data() @@ -289,6 +351,7 @@ void tst_QFtp::connectToHost() QTestEventLoop::instance().enterLoop( 61 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -337,6 +400,7 @@ void tst_QFtp::connectToUnresponsiveHost() QVERIFY( it.value().success == 0 ); delete ftp; + ftp = 0; } void tst_QFtp::login_data() @@ -369,6 +433,7 @@ void tst_QFtp::login() QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -415,6 +480,7 @@ void tst_QFtp::close() QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -482,6 +548,7 @@ void tst_QFtp::list() QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -542,6 +609,7 @@ void tst_QFtp::cd() QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) { QFAIL( "Network operation timed out" ); } @@ -617,6 +685,7 @@ void tst_QFtp::get() QTestEventLoop::instance().enterLoop( 50 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -743,6 +812,7 @@ void tst_QFtp::put() break; } delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -775,6 +845,7 @@ void tst_QFtp::put() break; } delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -792,6 +863,7 @@ void tst_QFtp::put() QTestEventLoop::instance().enterLoop( timestep ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -860,6 +932,7 @@ void tst_QFtp::mkdir() QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -884,6 +957,7 @@ void tst_QFtp::mkdir() QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -903,6 +977,7 @@ void tst_QFtp::mkdir() QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -942,6 +1017,7 @@ void tst_QFtp::mkdir2() QVERIFY(commandFinishedSpy.at(3).at(1).toBool()); delete ftp; + ftp = 0; } void tst_QFtp::mkdir2Slot(int id, bool) @@ -1019,6 +1095,7 @@ void tst_QFtp::renameInit( const QString &host, const QString &user, const QStri QTestEventLoop::instance().enterLoop( 50 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -1043,6 +1120,7 @@ void tst_QFtp::renameCleanup( const QString &host, const QString &user, const QS QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -1087,6 +1165,7 @@ void tst_QFtp::rename() QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -1273,6 +1352,7 @@ void tst_QFtp::commandSequence() QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -1330,6 +1410,7 @@ void tst_QFtp::abort() break; } delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -1367,6 +1448,7 @@ void tst_QFtp::abort() QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -1425,6 +1507,7 @@ void tst_QFtp::bytesAvailable() ftp->readAll(); QVERIFY( ftp->bytesAvailable() == 0 ); delete ftp; + ftp = 0; } void tst_QFtp::activeMode() @@ -1497,6 +1580,7 @@ void tst_QFtp::proxy() QTestEventLoop::instance().enterLoop( 50 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) { QFAIL( "Network operation timed out" ); } @@ -1512,7 +1596,6 @@ void tst_QFtp::proxy() } } - void tst_QFtp::binaryAscii() { QString file = "asciifile%1.txt"; @@ -1531,6 +1614,8 @@ void tst_QFtp::binaryAscii() addCommand(QFtp::Close, ftp->close()); QTestEventLoop::instance().enterLoop( 30 ); + delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -1551,6 +1636,8 @@ void tst_QFtp::binaryAscii() addCommand(QFtp::Close, ftp->close()); QTestEventLoop::instance().enterLoop( 30 ); + delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -1573,6 +1660,7 @@ void tst_QFtp::binaryAscii() QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -1868,6 +1956,11 @@ void tst_QFtp::dataTransferProgress( qint64 done, qint64 total ) QFtp *tst_QFtp::newFtp() { QFtp *nFtp = new QFtp( this ); +#ifndef QT_NO_BEARERMANAGEMENT + if (networkSessionExplicit) { + nFtp->setProperty("_q_networksession", QVariant::fromValue(networkSessionExplicit)); + } +#endif connect( nFtp, SIGNAL(commandStarted(int)), SLOT(commandStarted(int)) ); connect( nFtp, SIGNAL(commandFinished(int,bool)), @@ -1920,6 +2013,7 @@ bool tst_QFtp::fileExists( const QString &host, quint16 port, const QString &use inFileDirExistsFunction = TRUE; QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) { // ### make this test work qWarning("tst_QFtp::fileExists: Network operation timed out"); @@ -1970,6 +2064,7 @@ bool tst_QFtp::dirExists( const QString &host, quint16 port, const QString &user inFileDirExistsFunction = TRUE; QTestEventLoop::instance().enterLoop( 30 ); delete ftp; + ftp = 0; if ( QTestEventLoop::instance().timeout() ) { // ### make this test work // QFAIL( "Network operation timed out" ); @@ -1996,8 +2091,11 @@ void tst_QFtp::doneSignal() ftp.close(); done_success = 0; - while ( ftp.hasPendingCommands() ) - QCoreApplication::instance()->processEvents(); + connect(&ftp, SIGNAL(done(bool)), &(QTestEventLoop::instance()), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(61); + if (QTestEventLoop::instance().timeout()) + QFAIL("Network operation timed out"); + QTest::qWait(200); QCOMPARE(spy.count(), 1); diff --git a/tests/auto/qfuture/qfuture.pro b/tests/auto/qfuture/qfuture.pro index c2b16b7..d6faae7 100644 --- a/tests/auto/qfuture/qfuture.pro +++ b/tests/auto/qfuture/qfuture.pro @@ -2,3 +2,4 @@ load(qttest_p4) DEFINES += QT_STRICT_ITERATORS SOURCES += tst_qfuture.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qfuture/tst_qfuture.cpp b/tests/auto/qfuture/tst_qfuture.cpp index d78dc19..2fa329b 100644 --- a/tests/auto/qfuture/tst_qfuture.cpp +++ b/tests/auto/qfuture/tst_qfuture.cpp @@ -81,6 +81,7 @@ private slots: void voidConversions(); #ifndef QT_NO_EXCEPTIONS void exceptions(); + void exceptions_QTBUG18149(); #endif }; @@ -1431,6 +1432,33 @@ void tst_QFuture::exceptions() } + +void tst_QFuture::exceptions_QTBUG18149() +{ + class MyClass + { + public: + ~MyClass() + { + QFuture<void> f = createExceptionFuture(); + bool caught = false; + try { + f.waitForFinished(); + } catch (Exception &) { + caught = true; + } + QVERIFY(caught); + } + }; + + try { + MyClass m; + throw 0; + } catch (int) {} + +} + + #endif // QT_NO_EXCEPTIONS #include "tst_qfuture.moc" diff --git a/tests/auto/qfuture/versioncheck.h b/tests/auto/qfuture/versioncheck.h index 9e4d0c6..7101ea2 100644 --- a/tests/auto/qfuture/versioncheck.h +++ b/tests/auto/qfuture/versioncheck.h @@ -47,3 +47,7 @@ #if defined(Q_CC_MSVC) && _MSC_VER < 1400 #define QT_NO_CONCURRENT_TEST #endif + +#if defined(Q_CC_NOKIAX86) +#define QT_NO_CONCURRENT_TEST +#endif diff --git a/tests/auto/qfuturewatcher/qfuturewatcher.pro b/tests/auto/qfuturewatcher/qfuturewatcher.pro index 79d8739..67f04ef 100644 --- a/tests/auto/qfuturewatcher/qfuturewatcher.pro +++ b/tests/auto/qfuturewatcher/qfuturewatcher.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qfuturewatcher.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qfuturewatcher/tst_qfuturewatcher.cpp b/tests/auto/qfuturewatcher/tst_qfuturewatcher.cpp index 3bb6e5d..f45bd9f 100644 --- a/tests/auto/qfuturewatcher/tst_qfuturewatcher.cpp +++ b/tests/auto/qfuturewatcher/tst_qfuturewatcher.cpp @@ -47,6 +47,7 @@ #include <qfuturewatcher.h> #include <qtconcurrentrun.h> #include <qtconcurrentmap.h> +#include "../../shared/util.h" #ifndef QT_NO_CONCURRENT_TEST #include <private/qfutureinterface_p.h> @@ -81,6 +82,7 @@ private slots: void incrementalMapResults(); void incrementalFilterResults(); void qfutureSynchornizer(); + void warnRace(); }; QTEST_MAIN(tst_QFutureWatcher) @@ -466,12 +468,12 @@ void tst_QFutureWatcher::toMuchProgress() ProgressObject o; QFutureWatcher<void> f; - f.setFuture((new ProgressEmitterTask())->start()); QObject::connect(&f, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); #ifdef PRINT QObject::connect(&f, SIGNAL(progressValueChanged(int)), &o, SLOT(printProgress(int))); #endif QObject::connect(&f, SIGNAL(progressValueChanged(int)), &o, SLOT(registerProgress(int))); + f.setFuture((new ProgressEmitterTask())->start()); QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); @@ -890,6 +892,37 @@ void tst_QFutureWatcher::qfutureSynchornizer() QVERIFY(t.elapsed() < taskCount * 10); } +class DummyObject : public QObject { + Q_OBJECT +public slots: + void dummySlot() {} +public: + static void function(QMutex *m) + { + QMutexLocker lock(m); + } +}; + +void tst_QFutureWatcher::warnRace() +{ +#ifndef Q_OS_MAC //I don't know why it is not working on mac +#ifndef QT_NO_DEBUG + QTest::ignoreMessage(QtWarningMsg, "QFutureWatcher::connect: connecting after calling setFuture() is likely to produce race"); +#endif +#endif + QFutureWatcher<void> watcher; + DummyObject object; + QMutex mutex; + mutex.lock(); + + QFuture<void> future = QtConcurrent::run(DummyObject::function, &mutex); + watcher.setFuture(future); + QTRY_VERIFY(future.isStarted()); + connect(&watcher, SIGNAL(finished()), &object, SLOT(dummySlot())); + mutex.unlock(); + future.waitForFinished(); +} + #include "tst_qfuturewatcher.moc" #else diff --git a/tests/auto/qgetputenv/qgetputenv.pro b/tests/auto/qgetputenv/qgetputenv.pro index cbde272..df94f14 100644 --- a/tests/auto/qgetputenv/qgetputenv.pro +++ b/tests/auto/qgetputenv/qgetputenv.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qgetputenv.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp index cc1fa22..9c51e02 100644 --- a/tests/auto/qgl/tst_qgl.cpp +++ b/tests/auto/qgl/tst_qgl.cpp @@ -1874,11 +1874,10 @@ void tst_QGL::destroyFBOAfterContext() #ifdef QT_BUILD_INTERNAL -class tst_QGLResource : public QObject +class tst_QGLResource { - Q_OBJECT public: - tst_QGLResource(QObject *parent = 0) : QObject(parent) {} + tst_QGLResource(const QGLContext * = 0) {} ~tst_QGLResource() { ++deletions; } static int deletions; @@ -1886,12 +1885,7 @@ public: int tst_QGLResource::deletions = 0; -static void qt_shared_test_free(void *data) -{ - delete reinterpret_cast<tst_QGLResource *>(data); -} - -Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_shared_test, (qt_shared_test_free)) +Q_GLOBAL_STATIC(QGLContextGroupResource<tst_QGLResource>, qt_shared_test) #endif @@ -1911,10 +1905,9 @@ void tst_QGL::shareRegister() guard.setId(3); QVERIFY(guard.id() == 3); - // Add a resource to the first context. - tst_QGLResource *res1 = new tst_QGLResource(); - QVERIFY(!qt_shared_test()->value(glw1->context())); - qt_shared_test()->insert(glw1->context(), res1); + // Request a tst_QGLResource object for the first context. + tst_QGLResource *res1 = qt_shared_test()->value(glw1->context()); + QVERIFY(res1); QVERIFY(qt_shared_test()->value(glw1->context()) == res1); // Create another context that shares with the first. @@ -1953,10 +1946,9 @@ void tst_QGL::shareRegister() QGLSharedResourceGuard guard3(glw3->context()); guard3.setId(5); - // Add a resource to the third context. - tst_QGLResource *res3 = new tst_QGLResource(); - QVERIFY(!qt_shared_test()->value(glw3->context())); - qt_shared_test()->insert(glw3->context(), res3); + // Request a resource to the third context. + tst_QGLResource *res3 = qt_shared_test()->value(glw3->context()); + QVERIFY(res3); QVERIFY(qt_shared_test()->value(glw1->context()) == res1); QVERIFY(qt_shared_test()->value(glw2->context()) == res1); QVERIFY(qt_shared_test()->value(glw3->context()) == res3); diff --git a/tests/auto/qglfunctions/qglfunctions.pro b/tests/auto/qglfunctions/qglfunctions.pro new file mode 100644 index 0000000..aa81547 --- /dev/null +++ b/tests/auto/qglfunctions/qglfunctions.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +requires(contains(QT_CONFIG,opengl)) +QT += opengl + +win32:!wince*: DEFINES += QT_NO_EGL + +SOURCES += tst_qglfunctions.cpp diff --git a/tests/auto/qglfunctions/tst_qglfunctions.cpp b/tests/auto/qglfunctions/tst_qglfunctions.cpp new file mode 100644 index 0000000..ec87f6f --- /dev/null +++ b/tests/auto/qglfunctions/tst_qglfunctions.cpp @@ -0,0 +1,244 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtOpenGL module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtOpenGL/qglfunctions.h> + +class tst_QGLFunctions : public QObject +{ + Q_OBJECT +public: + tst_QGLFunctions() {} + ~tst_QGLFunctions() {} + +private slots: + void features(); + void multitexture(); + void blendColor(); + +private: + static bool hasExtension(const char *name); +}; + +bool tst_QGLFunctions::hasExtension(const char *name) +{ + QString extensions = + QString::fromLatin1 + (reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS))); + return extensions.split(QLatin1Char(' ')).contains + (QString::fromLatin1(name)); +} + +// Check that the reported features are consistent with the platform. +void tst_QGLFunctions::features() +{ + // Before being associated with a context, there should be + // no features enabled. + QGLFunctions funcs; + QVERIFY(!funcs.openGLFeatures()); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Multitexture)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Shaders)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Buffers)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Framebuffers)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendColor)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendEquation)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Multisample)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures)); + + // Make a context current. + QGLWidget glw; + if (!glw.isValid()) + QSKIP("Could not create a GL context", SkipAll); + glw.makeCurrent(); + funcs.initializeGLFunctions(); + + // Validate the features against what we expect for this platform. +#if defined(QT_OPENGL_ES_2) + QGLFunctions::OpenGLFeatures allFeatures = + (QGLFunctions::Multitexture | + QGLFunctions::Shaders | + QGLFunctions::Buffers | + QGLFunctions::Framebuffers | + QGLFunctions::BlendColor | + QGLFunctions::BlendEquation | + QGLFunctions::BlendEquationSeparate | + QGLFunctions::BlendFuncSeparate | + QGLFunctions::BlendSubtract | + QGLFunctions::CompressedTextures | + QGLFunctions::Multisample | + QGLFunctions::StencilSeparate | + QGLFunctions::NPOTTextures); + QVERIFY((funcs.openGLFeatures() & allFeatures) == allFeatures); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Shaders)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendColor)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures)); +#elif defined(QT_OPENGL_ES) + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures)); + QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample)); + + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Shaders)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendColor)); + QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate)); + + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers), + hasExtension("GL_OES_framebuffer_object")); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate), + hasExtension("GL_OES_blend_equation_separate")); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate), + hasExtension("GL_OES_blend_func_separate")); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract), + hasExtension("GL_OES_blend_subtract")); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures), + hasExtension("GL_OES_texture_npot")); +#else + // We check for both the extension name and the minimum OpenGL version + // for the feature. This will help us catch situations where a platform + // doesn't list an extension by name but does have the feature by virtue + // of its version number. + QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags(); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multitexture), + hasExtension("GL_ARB_multitexture") || + (versions & QGLFormat::OpenGL_Version_1_3) != 0); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Shaders), + hasExtension("GL_ARB_shader_objects") || + (versions & QGLFormat::OpenGL_Version_2_0) != 0); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Buffers), + (versions & QGLFormat::OpenGL_Version_1_5) != 0); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers), + hasExtension("GL_EXT_framebuffer_object") || + hasExtension("GL_ARB_framebuffer_object")); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendColor), + hasExtension("GL_EXT_blend_color") || + (versions & QGLFormat::OpenGL_Version_1_2) != 0); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation), + (versions & QGLFormat::OpenGL_Version_1_2) != 0); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate), + hasExtension("GL_EXT_blend_equation_separate") || + (versions & QGLFormat::OpenGL_Version_2_0) != 0); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate), + hasExtension("GL_EXT_blend_func_separate") || + (versions & QGLFormat::OpenGL_Version_1_4) != 0); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract), + hasExtension("GL_EXT_blend_subtract")); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures), + hasExtension("GL_ARB_texture_compression") || + (versions & QGLFormat::OpenGL_Version_1_3) != 0); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multisample), + hasExtension("GL_ARB_multisample") || + (versions & QGLFormat::OpenGL_Version_1_3) != 0); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate), + (versions & QGLFormat::OpenGL_Version_2_0) != 0); + QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures), + hasExtension("GL_ARB_texture_non_power_of_two") || + (versions & QGLFormat::OpenGL_Version_2_0) != 0); +#endif +} + +// Verify that the multitexture functions appear to resolve and work. +void tst_QGLFunctions::multitexture() +{ + QGLFunctions funcs; + QGLWidget glw; + if (!glw.isValid()) + QSKIP("Could not create a GL context", SkipAll); + glw.makeCurrent(); + funcs.initializeGLFunctions(); + + if (!funcs.hasOpenGLFeature(QGLFunctions::Multitexture)) + QSKIP("Multitexture functions are not supported", SkipSingle); + + funcs.glActiveTexture(GL_TEXTURE1); + + GLint active = 0; + glGetIntegerv(GL_ACTIVE_TEXTURE, &active); + QVERIFY(active == GL_TEXTURE1); + + funcs.glActiveTexture(GL_TEXTURE0); + + active = 0; + glGetIntegerv(GL_ACTIVE_TEXTURE, &active); + QVERIFY(active == GL_TEXTURE0); +} + +// Verify that the glBlendColor() function appears to resolve and work. +void tst_QGLFunctions::blendColor() +{ + QGLFunctions funcs; + QGLWidget glw; + if (!glw.isValid()) + QSKIP("Could not create a GL context", SkipAll); + glw.makeCurrent(); + funcs.initializeGLFunctions(); + + if (!funcs.hasOpenGLFeature(QGLFunctions::BlendColor)) + QSKIP("glBlendColor() is not supported", SkipSingle); + + funcs.glBlendColor(0.0f, 1.0f, 0.0f, 1.0f); + + GLfloat colors[4] = {0.5f, 0.5f, 0.5f, 0.5f}; + glGetFloatv(GL_BLEND_COLOR, colors); + + QCOMPARE(colors[0], 0.0f); + QCOMPARE(colors[1], 1.0f); + QCOMPARE(colors[2], 0.0f); + QCOMPARE(colors[3], 1.0f); +} + +QTEST_MAIN(tst_QGLFunctions) + +#include "tst_qglfunctions.moc" diff --git a/tests/auto/qglobal/qglobal.pro b/tests/auto/qglobal/qglobal.pro index 8f1e00a..a4dffac 100644 --- a/tests/auto/qglobal/qglobal.pro +++ b/tests/auto/qglobal/qglobal.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qglobal.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qglthreads/tst_qglthreads.cpp b/tests/auto/qglthreads/tst_qglthreads.cpp index e5b128b..859f47f 100644 --- a/tests/auto/qglthreads/tst_qglthreads.cpp +++ b/tests/auto/qglthreads/tst_qglthreads.cpp @@ -45,10 +45,6 @@ #include <QtOpenGL/QtOpenGL> #include "tst_qglthreads.h" -#ifdef Q_WS_X11 -#include <private/qt_x11_p.h> -#endif - #ifdef Q_OS_SYMBIAN #include <unistd.h> // for usleep #define RUNNING_TIME 2000 // save GPU mem by running shorter time. @@ -64,8 +60,6 @@ tst_QGLThreads::tst_QGLThreads(QObject *parent) { } - - /* swapInThread @@ -356,6 +350,7 @@ void renderAScene(int w, int h) class ThreadSafeGLWidget : public QGLWidget { public: + ThreadSafeGLWidget(QWidget *parent = 0) : QGLWidget(parent) {} void paintEvent(QPaintEvent *) { // ignored as we're anyway swapping as fast as we can @@ -443,7 +438,7 @@ void tst_QGLThreads::renderInThread_data() void tst_QGLThreads::renderInThread() { #ifdef Q_OS_MAC - QSKIP("OpenGL threading tests are currently disabled on mac as they were causing reboots", SkipAll); + QSKIP("OpenGL threading tests are currently disabled on Mac as they were causing reboots", SkipAll); #endif #ifdef Q_OS_SYMBIAN @@ -482,15 +477,301 @@ void tst_QGLThreads::renderInThread() QVERIFY(!thread.failure); } +class Device +{ +public: + virtual ~Device() {} + virtual QPaintDevice *realPaintDevice() = 0; + virtual void prepareDevice() {} +}; + +class GLWidgetWrapper : public Device +{ +public: + GLWidgetWrapper() { + widget.resize(150, 150); + widget.show(); + QTest::qWaitForWindowShown(&widget); + widget.doneCurrent(); + } + QPaintDevice *realPaintDevice() { return &widget; } + ThreadSafeGLWidget widget; +}; +class PixmapWrapper : public Device +{ +public: + PixmapWrapper() { pixmap = new QPixmap(512, 512); } + ~PixmapWrapper() { delete pixmap; } + QPaintDevice *realPaintDevice() { return pixmap; } -int main(int argc, char **argv) + QPixmap *pixmap; +}; + +class PixelBufferWrapper : public Device +{ +public: + PixelBufferWrapper() { pbuffer = new QGLPixelBuffer(512, 512); } + ~PixelBufferWrapper() { delete pbuffer; } + QPaintDevice *realPaintDevice() { return pbuffer; } + + QGLPixelBuffer *pbuffer; +}; + + +class FrameBufferObjectWrapper : public Device +{ +public: + FrameBufferObjectWrapper() { + widget.makeCurrent(); + fbo = new QGLFramebufferObject(512, 512); + widget.doneCurrent(); + } + ~FrameBufferObjectWrapper() { delete fbo; } + QPaintDevice *realPaintDevice() { return fbo; } + void prepareDevice() { widget.makeCurrent(); } + + ThreadSafeGLWidget widget; + QGLFramebufferObject *fbo; +}; + + +class ThreadPainter : public QObject +{ + Q_OBJECT +public: + ThreadPainter(Device *pd) : device(pd), fail(true) { + pixmap = QPixmap(40, 40); + pixmap.fill(Qt::green); + QPainter p(&pixmap); + p.drawLine(0, 0, 40, 40); + p.drawLine(0, 40, 40, 0); + } + +public slots: + void draw() { + bool beginFailed = false; + QTime time; + time.start(); + int rotAngle = 10; + device->prepareDevice(); + QPaintDevice *paintDevice = device->realPaintDevice(); + QSize s(paintDevice->width(), paintDevice->height()); + while (time.elapsed() < RUNNING_TIME) { + QPainter p; + if (!p.begin(paintDevice)) { + beginFailed = true; + break; + } + p.translate(s.width()/2, s.height()/2); + p.rotate(rotAngle); + p.translate(-s.width()/2, -s.height()/2); + p.fillRect(0, 0, s.width(), s.height(), Qt::red); + QRect rect(QPoint(0, 0), s); + p.drawPixmap(10, 10, pixmap); + p.drawTiledPixmap(50, 50, 100, 100, pixmap); + p.drawText(rect.center(), "This is a piece of text"); + p.end(); + rotAngle += 2; +#ifdef Q_WS_WIN + Sleep(20); +#else + usleep(20 * 1000); +#endif + } + + fail = beginFailed; + QThread::currentThread()->quit(); + } + + bool failed() { return fail; } + +private: + QPixmap pixmap; + Device *device; + bool fail; +}; + +template <class T> +class PaintThreadManager +{ +public: + PaintThreadManager(int count) : numThreads(count) + { + for (int i=0; i<numThreads; ++i) { + devices.append(new T); + threads.append(new QThread); + painters.append(new ThreadPainter(devices.at(i))); + painters.at(i)->moveToThread(threads.at(i)); + painters.at(i)->connect(threads.at(i), SIGNAL(started()), painters.at(i), SLOT(draw())); + } + } + + ~PaintThreadManager() { + qDeleteAll(threads); + qDeleteAll(painters); + qDeleteAll(devices); + } + + + void start() { + for (int i=0; i<numThreads; ++i) + threads.at(i)->start(); + } + + bool areRunning() { + bool running = false; + for (int i=0; i<numThreads; ++i){ + if (threads.at(i)->isRunning()) + running = true; + } + + return running; + } + + bool failed() { + for (int i=0; i<numThreads; ++i) { + if (painters.at(i)->failed()) + return true; + } + + return false; + } + +private: + QList<QThread *> threads; + QList<Device *> devices; + QList<ThreadPainter *> painters; + int numThreads; +}; + +/* + This test uses QPainter to draw onto different QGLWidgets in + different threads at the same time. The ThreadSafeGLWidget is + necessary to handle paint and resize events that might come from + the main thread at any time while the test is running. The resize + and paint events would cause makeCurrent() calls to be issued from + within the QGLWidget while the widget's context was current in + another thread, which would cause errors. +*/ +void tst_QGLThreads::painterOnGLWidgetInThread() +{ +#ifdef Q_OS_MAC + QSKIP("OpenGL threading tests are currently disabled on Mac as they were causing reboots", SkipAll); +#endif + if (!((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) || + (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0))) { + QSKIP("The OpenGL based threaded QPainter tests requires OpenGL/ES 2.0.", SkipAll); + } + + PaintThreadManager<GLWidgetWrapper> painterThreads(5); + painterThreads.start(); + + while (painterThreads.areRunning()) { + qApp->processEvents(); +#ifdef Q_WS_WIN + Sleep(100); +#else + usleep(100 * 1000); +#endif + } + QVERIFY(!painterThreads.failed()); +} + +/* + This test uses QPainter to draw onto different QPixmaps in + different threads at the same time. +*/ +void tst_QGLThreads::painterOnPixmapInThread() { #ifdef Q_WS_X11 - XInitThreads(); + QSKIP("Drawing text in threads onto X11 drawables currently crashes on some X11 servers.", SkipAll); +#endif + PaintThreadManager<PixmapWrapper> painterThreads(5); + painterThreads.start(); + + while (painterThreads.areRunning()) { + qApp->processEvents(); +#ifdef Q_WS_WIN + Sleep(100); +#else + usleep(100 * 1000); +#endif + } + QVERIFY(!painterThreads.failed()); +} + +/* This test uses QPainter to draw onto different QGLPixelBuffer + objects in different threads at the same time. +*/ +void tst_QGLThreads::painterOnPboInThread() +{ +#ifdef Q_OS_MAC + QSKIP("OpenGL threading tests are currently disabled on Mac as they were causing reboots", SkipAll); +#endif + if (!((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) || + (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0))) { + QSKIP("The OpenGL based threaded QPainter tests requires OpenGL/ES 2.0.", SkipAll); + return; + } + + if (!QGLPixelBuffer::hasOpenGLPbuffers()) { + QSKIP("This system doesn't support pbuffers.", SkipAll); + return; + } + + PaintThreadManager<PixelBufferWrapper> painterThreads(5); + painterThreads.start(); + + while (painterThreads.areRunning()) { + qApp->processEvents(); +#ifdef Q_WS_WIN + Sleep(100); +#else + usleep(100 * 1000); #endif + } + QVERIFY(!painterThreads.failed()); +} +/* This test uses QPainter to draw onto different + QGLFramebufferObjects (bound in a QGLWidget's context) in different + threads at the same time. +*/ +void tst_QGLThreads::painterOnFboInThread() +{ +#ifdef Q_OS_MAC + QSKIP("OpenGL threading tests are currently disabled on Mac as they were causing reboots", SkipAll); +#endif + if (!((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) || + (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0))) { + QSKIP("The OpenGL based threaded QPainter tests requires OpenGL/ES 2.0.", SkipAll); + return; + } + + if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) { + QSKIP("This system doesn't support framebuffer objects.", SkipAll); + return; + } + + PaintThreadManager<FrameBufferObjectWrapper> painterThreads(5); + painterThreads.start(); + + while (painterThreads.areRunning()) { + qApp->processEvents(); +#ifdef Q_WS_WIN + Sleep(100); +#else + usleep(100 * 1000); +#endif + } + QVERIFY(!painterThreads.failed()); +} + +int main(int argc, char **argv) +{ + QApplication::setAttribute(Qt::AA_X11InitThreads); QApplication app(argc, argv); QTEST_DISABLE_KEYPAD_NAVIGATION \ diff --git a/tests/auto/qglthreads/tst_qglthreads.h b/tests/auto/qglthreads/tst_qglthreads.h index d7e247a..7972638 100644 --- a/tests/auto/qglthreads/tst_qglthreads.h +++ b/tests/auto/qglthreads/tst_qglthreads.h @@ -56,6 +56,10 @@ private slots: void renderInThread_data(); void renderInThread(); + void painterOnGLWidgetInThread(); + void painterOnPixmapInThread(); + void painterOnPboInThread(); + void painterOnFboInThread(); }; #endif // TST_QGLTHREADS_H diff --git a/tests/auto/qglyphrun/qglyphrun.pro b/tests/auto/qglyphrun/qglyphrun.pro new file mode 100644 index 0000000..480ad5b --- /dev/null +++ b/tests/auto/qglyphrun/qglyphrun.pro @@ -0,0 +1,11 @@ +load(qttest_p4) +QT = core gui + +SOURCES += \ + tst_qglyphrun.cpp + +wince*|symbian*: { + DEFINES += SRCDIR=\\\"\\\" +} else { + DEFINES += SRCDIR=\\\"$$PWD/\\\" +} diff --git a/tests/auto/qglyphrun/test.ttf b/tests/auto/qglyphrun/test.ttf Binary files differnew file mode 100644 index 0000000..9043a57 --- /dev/null +++ b/tests/auto/qglyphrun/test.ttf diff --git a/tests/auto/qglyphrun/tst_qglyphrun.cpp b/tests/auto/qglyphrun/tst_qglyphrun.cpp new file mode 100644 index 0000000..3ea84e3 --- /dev/null +++ b/tests/auto/qglyphrun/tst_qglyphrun.cpp @@ -0,0 +1,582 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <qglyphrun.h> +#include <qpainter.h> +#include <qtextlayout.h> +#include <qfontdatabase.h> + +// #define DEBUG_SAVE_IMAGE + +class tst_QGlyphRun: public QObject +{ + Q_OBJECT + +#if !defined(QT_NO_RAWFONT) +private slots: + void initTestCase(); + void cleanupTestCase(); + + void constructionAndDestruction(); + void copyConstructor(); + void assignment(); + void equalsOperator_data(); + void equalsOperator(); + void textLayoutGlyphIndexes(); + void drawExistingGlyphs(); + void drawNonExistentGlyphs(); + void drawMultiScriptText1(); + void drawMultiScriptText2(); + void drawStruckOutText(); + void drawOverlinedText(); + void drawUnderlinedText(); + void drawRightToLeft(); + void detach(); + +private: + int m_testFontId; + QFont m_testFont; +#endif // QT_NO_RAWFONT + +}; + +#if !defined(QT_NO_RAWFONT) + +Q_DECLARE_METATYPE(QGlyphRun); + +void tst_QGlyphRun::initTestCase() +{ + m_testFontId = QFontDatabase::addApplicationFont(SRCDIR "test.ttf"); + QVERIFY(m_testFontId >= 0); + + m_testFont = QFont("QtsSpecialTestFont"); + + QCOMPARE(QFontInfo(m_testFont).family(), QString::fromLatin1("QtsSpecialTestFont")); +} + +void tst_QGlyphRun::cleanupTestCase() +{ + QFontDatabase::removeApplicationFont(m_testFontId); +} + +void tst_QGlyphRun::constructionAndDestruction() +{ + QGlyphRun glyphIndexes; +} + +static QGlyphRun make_dummy_indexes() +{ + QGlyphRun glyphs; + + QVector<quint32> glyphIndexes; + QVector<QPointF> positions; + QFont font; + font.setPointSize(18); + + glyphIndexes.append(1); + glyphIndexes.append(2); + glyphIndexes.append(3); + + positions.append(QPointF(1, 2)); + positions.append(QPointF(3, 4)); + positions.append(QPointF(5, 6)); + + glyphs.setRawFont(QRawFont::fromFont(font)); + glyphs.setGlyphIndexes(glyphIndexes); + glyphs.setPositions(positions); + + return glyphs; +} + +void tst_QGlyphRun::copyConstructor() +{ + QGlyphRun glyphs; + + { + QVector<quint32> glyphIndexes; + QVector<QPointF> positions; + QFont font; + font.setPointSize(18); + + glyphIndexes.append(1); + glyphIndexes.append(2); + glyphIndexes.append(3); + + positions.append(QPointF(1, 2)); + positions.append(QPointF(3, 4)); + positions.append(QPointF(5, 6)); + + glyphs.setRawFont(QRawFont::fromFont(font)); + glyphs.setGlyphIndexes(glyphIndexes); + glyphs.setPositions(positions); + } + + QGlyphRun otherGlyphs(glyphs); + QCOMPARE(otherGlyphs.rawFont(), glyphs.rawFont()); + QCOMPARE(glyphs.glyphIndexes(), otherGlyphs.glyphIndexes()); + QCOMPARE(glyphs.positions(), otherGlyphs.positions()); +} + +void tst_QGlyphRun::assignment() +{ + QGlyphRun glyphs(make_dummy_indexes()); + + QGlyphRun otherGlyphs = glyphs; + QCOMPARE(otherGlyphs.rawFont(), glyphs.rawFont()); + QCOMPARE(glyphs.glyphIndexes(), otherGlyphs.glyphIndexes()); + QCOMPARE(glyphs.positions(), otherGlyphs.positions()); +} + +void tst_QGlyphRun::equalsOperator_data() +{ + QTest::addColumn<QGlyphRun>("one"); + QTest::addColumn<QGlyphRun>("two"); + QTest::addColumn<bool>("equals"); + + QGlyphRun one(make_dummy_indexes()); + QGlyphRun two(make_dummy_indexes()); + + QTest::newRow("Identical") << one << two << true; + + { + QGlyphRun busted(two); + + QVector<QPointF> positions = busted.positions(); + positions[2] += QPointF(1, 1); + busted.setPositions(positions); + + + QTest::newRow("Different positions") << one << busted << false; + } + + { + QGlyphRun busted(two); + + QFont font; + font.setPixelSize(busted.rawFont().pixelSize() * 2); + busted.setRawFont(QRawFont::fromFont(font)); + + QTest::newRow("Different fonts") << one << busted << false; + } + + { + QGlyphRun busted(two); + + QVector<quint32> glyphIndexes = busted.glyphIndexes(); + glyphIndexes[2] += 1; + busted.setGlyphIndexes(glyphIndexes); + + QTest::newRow("Different glyph indexes") << one << busted << false; + } + +} + +void tst_QGlyphRun::equalsOperator() +{ + QFETCH(QGlyphRun, one); + QFETCH(QGlyphRun, two); + QFETCH(bool, equals); + + QCOMPARE(one == two, equals); + QCOMPARE(one != two, !equals); +} + + +void tst_QGlyphRun::textLayoutGlyphIndexes() +{ + QString s; + s.append(QLatin1Char('A')); + s.append(QChar(0xe000)); + + QTextLayout layout(s); + layout.setFont(m_testFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> listOfGlyphs = layout.glyphRuns(); + QCOMPARE(listOfGlyphs.size(), 1); + + QGlyphRun glyphs = listOfGlyphs.at(0); + + QCOMPARE(glyphs.glyphIndexes().size(), 2); + QCOMPARE(glyphs.glyphIndexes().at(0), quint32(2)); + QCOMPARE(glyphs.glyphIndexes().at(1), quint32(1)); +} + +void tst_QGlyphRun::drawExistingGlyphs() +{ + QPixmap textLayoutDraw(1000, 1000); + QPixmap drawGlyphs(1000, 1000); + + textLayoutDraw.fill(Qt::white); + drawGlyphs.fill(Qt::white); + + QString s; + s.append(QLatin1Char('A')); + s.append(QChar(0xe000)); + + QTextLayout layout(s); + layout.setFont(m_testFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QPainter p(&textLayoutDraw); + layout.draw(&p, QPointF(50, 50)); + } + + QGlyphRun glyphs = layout.glyphRuns().size() > 0 + ? layout.glyphRuns().at(0) + : QGlyphRun(); + + { + QPainter p(&drawGlyphs); + p.drawGlyphRun(QPointF(50, 50), glyphs); + } + +#if defined(DEBUG_SAVE_IMAGE) + textLayoutDraw.save("drawExistingGlyphs_textLayoutDraw.png"); + drawGlyphs.save("drawExistingGlyphs_drawGlyphIndexes.png"); +#endif + + QCOMPARE(textLayoutDraw, drawGlyphs); +} + +void tst_QGlyphRun::drawNonExistentGlyphs() +{ + QVector<quint32> glyphIndexes; + glyphIndexes.append(3); + + QVector<QPointF> glyphPositions; + glyphPositions.append(QPointF(0, 0)); + + QGlyphRun glyphs; + glyphs.setGlyphIndexes(glyphIndexes); + glyphs.setPositions(glyphPositions); + glyphs.setRawFont(QRawFont::fromFont(m_testFont)); + + QPixmap image(1000, 1000); + image.fill(Qt::white); + + QPixmap imageBefore = image; + { + QPainter p(&image); + p.drawGlyphRun(QPointF(50, 50), glyphs); + } + +#if defined(DEBUG_SAVE_IMAGE) + image.save("drawNonExistentGlyphs.png"); +#endif + + QCOMPARE(image, imageBefore); // Should be unchanged +} + +void tst_QGlyphRun::drawMultiScriptText1() +{ + QString text; + text += QChar(0x03D0); // Greek, beta + + QTextLayout textLayout(text); + textLayout.beginLayout(); + textLayout.createLine(); + textLayout.endLayout(); + + QPixmap textLayoutDraw(1000, 1000); + textLayoutDraw.fill(Qt::white); + + QPixmap drawGlyphs(1000, 1000); + drawGlyphs.fill(Qt::white); + + QList<QGlyphRun> glyphsList = textLayout.glyphRuns(); + QCOMPARE(glyphsList.size(), 1); + + { + QPainter p(&textLayoutDraw); + textLayout.draw(&p, QPointF(50, 50)); + } + + { + QPainter p(&drawGlyphs); + foreach (QGlyphRun glyphs, glyphsList) + p.drawGlyphRun(QPointF(50, 50), glyphs); + } + +#if defined(DEBUG_SAVE_IMAGE) + textLayoutDraw.save("drawMultiScriptText1_textLayoutDraw.png"); + drawGlyphs.save("drawMultiScriptText1_drawGlyphIndexes.png"); +#endif + + QCOMPARE(drawGlyphs, textLayoutDraw); +} + + +void tst_QGlyphRun::drawMultiScriptText2() +{ + QString text; + text += QChar(0x0621); // Arabic, Hamza + text += QChar(0x03D0); // Greek, beta + + QTextLayout textLayout(text); + textLayout.beginLayout(); + textLayout.createLine(); + textLayout.endLayout(); + + QPixmap textLayoutDraw(1000, 1000); + textLayoutDraw.fill(Qt::white); + + QPixmap drawGlyphs(1000, 1000); + drawGlyphs.fill(Qt::white); + + QList<QGlyphRun> glyphsList = textLayout.glyphRuns(); + QCOMPARE(glyphsList.size(), 2); + + { + QPainter p(&textLayoutDraw); + textLayout.draw(&p, QPointF(50, 50)); + } + + { + QPainter p(&drawGlyphs); + foreach (QGlyphRun glyphs, glyphsList) + p.drawGlyphRun(QPointF(50, 50), glyphs); + } + +#if defined(DEBUG_SAVE_IMAGE) + textLayoutDraw.save("drawMultiScriptText2_textLayoutDraw.png"); + drawGlyphs.save("drawMultiScriptText2_drawGlyphIndexes.png"); +#endif + + QCOMPARE(drawGlyphs, textLayoutDraw); +} + +void tst_QGlyphRun::detach() +{ + QGlyphRun glyphs; + + glyphs.setGlyphIndexes(QVector<quint32>() << 1 << 2 << 3); + + QGlyphRun otherGlyphs; + otherGlyphs = glyphs; + + QCOMPARE(otherGlyphs.glyphIndexes(), glyphs.glyphIndexes()); + + otherGlyphs.setGlyphIndexes(QVector<quint32>() << 4 << 5 << 6); + + QCOMPARE(otherGlyphs.glyphIndexes(), QVector<quint32>() << 4 << 5 << 6); + QCOMPARE(glyphs.glyphIndexes(), QVector<quint32>() << 1 << 2 << 3); +} + +void tst_QGlyphRun::drawStruckOutText() +{ + QPixmap textLayoutDraw(1000, 1000); + QPixmap drawGlyphs(1000, 1000); + + textLayoutDraw.fill(Qt::white); + drawGlyphs.fill(Qt::white); + + QString s = QString::fromLatin1("Foobar"); + + QFont font; + font.setStrikeOut(true); + + QTextLayout layout(s); + layout.setFont(font); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QPainter p(&textLayoutDraw); + layout.draw(&p, QPointF(50, 50)); + } + + QGlyphRun glyphs = layout.glyphRuns().size() > 0 + ? layout.glyphRuns().at(0) + : QGlyphRun(); + + { + QPainter p(&drawGlyphs); + p.drawGlyphRun(QPointF(50, 50), glyphs); + } + +#if defined(DEBUG_SAVE_IMAGE) + textLayoutDraw.save("drawStruckOutText_textLayoutDraw.png"); + drawGlyphs.save("drawStruckOutText_drawGlyphIndexes.png"); +#endif + + QCOMPARE(textLayoutDraw, drawGlyphs); +} + +void tst_QGlyphRun::drawOverlinedText() +{ + QPixmap textLayoutDraw(1000, 1000); + QPixmap drawGlyphs(1000, 1000); + + textLayoutDraw.fill(Qt::white); + drawGlyphs.fill(Qt::white); + + QString s = QString::fromLatin1("Foobar"); + + QFont font; + font.setOverline(true); + + QTextLayout layout(s); + layout.setFont(font); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QPainter p(&textLayoutDraw); + layout.draw(&p, QPointF(50, 50)); + } + + QGlyphRun glyphs = layout.glyphRuns().size() > 0 + ? layout.glyphRuns().at(0) + : QGlyphRun(); + + { + QPainter p(&drawGlyphs); + p.drawGlyphRun(QPointF(50, 50), glyphs); + } + +#if defined(DEBUG_SAVE_IMAGE) + textLayoutDraw.save("drawOverlineText_textLayoutDraw.png"); + drawGlyphs.save("drawOverlineText_drawGlyphIndexes.png"); +#endif + + QCOMPARE(textLayoutDraw, drawGlyphs); +} + +void tst_QGlyphRun::drawUnderlinedText() +{ + QPixmap textLayoutDraw(1000, 1000); + QPixmap drawGlyphs(1000, 1000); + + textLayoutDraw.fill(Qt::white); + drawGlyphs.fill(Qt::white); + + QString s = QString::fromLatin1("Foobar"); + + QFont font; + font.setUnderline(true); + + QTextLayout layout(s); + layout.setFont(font); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QPainter p(&textLayoutDraw); + layout.draw(&p, QPointF(50, 50)); + } + + QGlyphRun glyphs = layout.glyphRuns().size() > 0 + ? layout.glyphRuns().at(0) + : QGlyphRun(); + + { + QPainter p(&drawGlyphs); + p.drawGlyphRun(QPointF(50, 50), glyphs); + } + +#if defined(DEBUG_SAVE_IMAGE) + textLayoutDraw.save("drawUnderlineText_textLayoutDraw.png"); + drawGlyphs.save("drawUnderlineText_drawGlyphIndexes.png"); +#endif + + QCOMPARE(textLayoutDraw, drawGlyphs); +} + +void tst_QGlyphRun::drawRightToLeft() +{ + QString s; + s.append(QChar(1575)); + s.append(QChar(1578)); + + QPixmap textLayoutDraw(1000, 1000); + QPixmap drawGlyphs(1000, 1000); + + textLayoutDraw.fill(Qt::white); + drawGlyphs.fill(Qt::white); + + QFont font; + font.setUnderline(true); + + QTextLayout layout(s); + layout.setFont(font); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QPainter p(&textLayoutDraw); + layout.draw(&p, QPointF(50, 50)); + } + + QGlyphRun glyphs = layout.glyphRuns().size() > 0 + ? layout.glyphRuns().at(0) + : QGlyphRun(); + + { + QPainter p(&drawGlyphs); + p.drawGlyphRun(QPointF(50, 50), glyphs); + } + +#if defined(DEBUG_SAVE_IMAGE) + textLayoutDraw.save("drawRightToLeft_textLayoutDraw.png"); + drawGlyphs.save("drawRightToLeft_drawGlyphIndexes.png"); +#endif + + QCOMPARE(textLayoutDraw, drawGlyphs); + +} + +#endif // QT_NO_RAWFONT + +QTEST_MAIN(tst_QGlyphRun) +#include "tst_qglyphrun.moc" + diff --git a/tests/auto/qgraphicsanchorlayout/qgraphicsanchorlayout.pro b/tests/auto/qgraphicsanchorlayout/qgraphicsanchorlayout.pro index 4c065f4..8768425 100644 --- a/tests/auto/qgraphicsanchorlayout/qgraphicsanchorlayout.pro +++ b/tests/auto/qgraphicsanchorlayout/qgraphicsanchorlayout.pro @@ -1,3 +1,3 @@ load(qttest_p4) SOURCES += tst_qgraphicsanchorlayout.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 6c98c67..5987f4a 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -132,33 +132,32 @@ static void setAnchor(QGraphicsAnchorLayout *l, anchor->setSpacing(spacing); } -static bool checkReverseDirection(QGraphicsWidget *w) +static bool checkReverseDirection(QGraphicsWidget *widget) { - QGraphicsLayout *l = w->layout(); - Q_ASSERT(l); + QGraphicsLayout *layout = widget->layout(); qreal left, top, right, bottom; - l->getContentsMargins(&left, &top, &right, &bottom); - w->setLayoutDirection(Qt::LeftToRight); + layout->getContentsMargins(&left, &top, &right, &bottom); + widget->setLayoutDirection(Qt::LeftToRight); QApplication::processEvents(); - const QRectF lg = l->geometry(); + const QRectF layoutGeometry = layout->geometry(); QMap<QGraphicsLayoutItem *, QRectF> geometries; - for (int i = 0; i < l->count(); ++i) { - QGraphicsLayoutItem *w = l->itemAt(i); - geometries.insert(w, w->geometry()); + for (int i = 0; i < layout->count(); ++i) { + QGraphicsLayoutItem *item = layout->itemAt(i); + geometries.insert(item, item->geometry()); } - w->setLayoutDirection(Qt::RightToLeft); + widget->setLayoutDirection(Qt::RightToLeft); QApplication::processEvents(); - lg.adjusted(+right, +top, -left, -bottom); - for (int i = 0; i < l->count(); ++i) { - QGraphicsLayoutItem *w = l->itemAt(i); - const QRectF rtlGeom = w->geometry(); - const QRectF ltrGeom = geometries.value(w); - QRectF expectedGeom = ltrGeom; - expectedGeom.moveRight(lg.right() - (0 + ltrGeom.left())); - if (expectedGeom != rtlGeom) { - qDebug() << "layout->geometry():" << lg - << "expected:" << expectedGeom - << "actual:" << rtlGeom; + layoutGeometry.adjusted(+right, +top, -left, -bottom); + for (int i = 0; i < layout->count(); ++i) { + QGraphicsLayoutItem *item = layout->itemAt(i); + const QRectF rightToLeftGeometry = item->geometry(); + const QRectF leftToRightGeometry = geometries.value(item); + QRectF expectedGeometry = leftToRightGeometry; + expectedGeometry.moveRight(layoutGeometry.right() - leftToRightGeometry.left()); + if (expectedGeometry != rightToLeftGeometry) { + qDebug() << "layout->geometry():" << layoutGeometry + << "expected:" << expectedGeometry + << "actual:" << rightToLeftGeometry; return false; } } @@ -345,6 +344,7 @@ void tst_QGraphicsAnchorLayout::layoutDirection() p->show(); view->show(); + QVERIFY(p->layout()); QCOMPARE(checkReverseDirection(p), true); if (hasSimplification) { @@ -445,6 +445,7 @@ void tst_QGraphicsAnchorLayout::diagonal() QVERIFY(!usedSimplex(l, Qt::Vertical)); } + QVERIFY(p.layout()); QCOMPARE(checkReverseDirection(&p), true); c->setMinimumWidth(300); @@ -735,6 +736,7 @@ void tst_QGraphicsAnchorLayout::snakeOppositeDirections() QCOMPARE(c->geometry(), QRectF(90.0, 200.0, 100.0, 100.0)); QCOMPARE(p.size(), layoutMaximumSize); + QVERIFY(p.layout()); QCOMPARE(checkReverseDirection(&p), true); } diff --git a/tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro b/tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro index 27f48e0..90b7878 100644 --- a/tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro +++ b/tests/auto/qgraphicsanchorlayout1/qgraphicsanchorlayout1.pro @@ -1,3 +1,3 @@ load(qttest_p4) SOURCES += tst_qgraphicsanchorlayout1.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index 9e4bb6b..4329f13 100644 --- a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -2585,15 +2585,11 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution_data() sizeHints1.insert( Qt::MinimumSize, 30 ); sizeHints1.insert( Qt::PreferredSize, 35 ); sizeHints1.insert( Qt::MaximumSize, 40 ); - Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); SizeHintArray sizeHints2; sizeHints2.insert( Qt::MinimumSize, 5 ); sizeHints2.insert( Qt::PreferredSize, 35 ); sizeHints2.insert( Qt::MaximumSize, 300 ); - Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); const qreal width1 = 35; const qreal width2 = 100-10-10-10-width1; @@ -2605,15 +2601,11 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution_data() sizeHints1.insert( Qt::MinimumSize, 0 ); sizeHints1.insert( Qt::PreferredSize, 20 ); sizeHints1.insert( Qt::MaximumSize, 100 ); - Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); SizeHintArray sizeHints2; sizeHints2.insert( Qt::MinimumSize, 0 ); sizeHints2.insert( Qt::PreferredSize, 50 ); sizeHints2.insert( Qt::MaximumSize, 100 ); - Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); const qreal width1 = 20; const qreal width2 = 100-10-10-10-width1; @@ -2625,15 +2617,11 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution_data() sizeHints1.insert( Qt::MinimumSize, 0 ); sizeHints1.insert( Qt::PreferredSize, 40 ); sizeHints1.insert( Qt::MaximumSize, 100 ); - Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); SizeHintArray sizeHints2; sizeHints2.insert( Qt::MinimumSize, 0 ); sizeHints2.insert( Qt::PreferredSize, 60 ); sizeHints2.insert( Qt::MaximumSize, 100 ); - Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); const qreal width1 = 28; // got from manual calculation const qreal width2 = 100-10-10-10-width1; @@ -2645,15 +2633,11 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution_data() sizeHints1.insert( Qt::MinimumSize, 0 ); sizeHints1.insert( Qt::PreferredSize, 10 ); sizeHints1.insert( Qt::MaximumSize, 100 ); - Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); SizeHintArray sizeHints2; sizeHints2.insert( Qt::MinimumSize, 0 ); sizeHints2.insert( Qt::PreferredSize, 40 ); sizeHints2.insert( Qt::MaximumSize, 100 ); - Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); const qreal width1 = 22; // got from manual calculation const qreal width2 = 100-10-10-10-width1; @@ -2669,6 +2653,12 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution() QFETCH(qreal, width1); QFETCH(qreal, width2); + // sanity-check the test data - MinimumSize <= PreferredSize <= MaximumSize + QVERIFY( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); + QVERIFY( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); + QVERIFY( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); + QVERIFY( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); + // create objects QGraphicsWidget widget; TheAnchorLayout *layout = new TheAnchorLayout; diff --git a/tests/auto/qgraphicseffect/qgraphicseffect.pro b/tests/auto/qgraphicseffect/qgraphicseffect.pro index 7effaca..94b3ce6 100644 --- a/tests/auto/qgraphicseffect/qgraphicseffect.pro +++ b/tests/auto/qgraphicseffect/qgraphicseffect.pro @@ -1,3 +1,3 @@ load(qttest_p4) SOURCES += tst_qgraphicseffect.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicseffectsource/qgraphicseffectsource.pro b/tests/auto/qgraphicseffectsource/qgraphicseffectsource.pro index d506c6d..5658ad7 100644 --- a/tests/auto/qgraphicseffectsource/qgraphicseffectsource.pro +++ b/tests/auto/qgraphicseffectsource/qgraphicseffectsource.pro @@ -1,3 +1,3 @@ load(qttest_p4) SOURCES += tst_qgraphicseffectsource.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicsgridlayout/qgraphicsgridlayout.pro b/tests/auto/qgraphicsgridlayout/qgraphicsgridlayout.pro index 97e68bc..d66d639 100644 --- a/tests/auto/qgraphicsgridlayout/qgraphicsgridlayout.pro +++ b/tests/auto/qgraphicsgridlayout/qgraphicsgridlayout.pro @@ -1,4 +1,4 @@ load(qttest_p4) SOURCES += tst_qgraphicsgridlayout.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp index a3f063e..6b4ad19 100644 --- a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp +++ b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp @@ -84,6 +84,7 @@ private slots: void horizontalSpacing(); void itemAt(); void removeAt(); + void removeItem(); void rowAlignment_data(); void rowAlignment(); void rowCount_data(); @@ -126,6 +127,7 @@ private slots: void spanningItem2x3(); void spanningItem(); void heightForWidth(); + void widthForHeight(); void heightForWidthWithSpanning(); void stretchAndHeightForWidth(); void testDefaultAlignment(); @@ -245,9 +247,10 @@ struct ItemDesc return (*this); } - ItemDesc &heightForWidth(QSizeF (*fnConstraint)(Qt::SizeHint, const QSizeF &)) { + ItemDesc &dynamicConstraint(QSizeF (*fnConstraint)(Qt::SizeHint, const QSizeF &), + Qt::Orientation orientation) { m_fnConstraint = fnConstraint; - m_constraintOrientation = Qt::Vertical; + m_constraintOrientation = orientation; return (*this); } @@ -255,7 +258,7 @@ struct ItemDesc QSizePolicy sp = m_sizePolicy; if (m_fnConstraint) { sp.setHeightForWidth(m_constraintOrientation == Qt::Vertical); - //sp.setWidthForHeight(m_constraintOrientation == Qt::Horizontal); + sp.setWidthForHeight(m_constraintOrientation == Qt::Horizontal); } item->setSizePolicy(sp); @@ -1150,6 +1153,32 @@ void tst_QGraphicsGridLayout::removeAt() delete widget; } +void tst_QGraphicsGridLayout::removeItem() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + + QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); + scene.addItem(widget); + QGraphicsGridLayout *l = new QGraphicsGridLayout(); + widget->setLayout(l); + + populateLayout(l, 3, 2); + QCOMPARE(l->count(), 6); + l->removeItem(l->itemAt(5)); + l->removeItem(l->itemAt(4)); + QCOMPARE(l->count(), 4); + + // Avoid crashing. Note that the warning message might change in the future. + QTest::ignoreMessage(QtWarningMsg, QString::fromAscii("QGraphicsGridLayout::removeAt: invalid index -1").toLatin1().constData()); + l->removeItem(0); + QCOMPARE(l->count(), 4); + + QTest::ignoreMessage(QtWarningMsg, QString::fromAscii("QGraphicsGridLayout::removeAt: invalid index -1").toLatin1().constData()); + l->removeItem(new QGraphicsWidget); + QCOMPARE(l->count(), 4); +} + void tst_QGraphicsGridLayout::rowAlignment_data() { QTest::addColumn<bool>("hasHeightForWidth"); @@ -2357,10 +2386,50 @@ void tst_QGraphicsGridLayout::alignment2() static QSizeF hfw1(Qt::SizeHint, const QSizeF &constraint) { QSizeF result(constraint); - if (constraint.width() < 0 && constraint.height() < 0) { + const qreal ch = constraint.height(); + const qreal cw = constraint.width(); + if (cw < 0 && ch < 0) { return QSizeF(50, 400); - } else if (constraint.width() >= 0) { - result.setHeight(20000./constraint.width()); + } else if (cw > 0) { + result.setHeight(20000./cw); + } + return result; +} + +static QSizeF wfh1(Qt::SizeHint, const QSizeF &constraint) +{ + QSizeF result(constraint); + const qreal ch = constraint.height(); + const qreal cw = constraint.width(); + if (cw < 0 && ch < 0) { + return QSizeF(400, 50); + } else if (ch > 0) { + result.setWidth(20000./ch); + } + return result; +} + +static QSizeF wfh2(Qt::SizeHint, const QSizeF &constraint) +{ + QSizeF result(constraint); + const qreal ch = constraint.height(); + const qreal cw = constraint.width(); + if (ch < 0 && cw < 0) + return QSizeF(50, 50); + if (ch >= 0) + result.setWidth(ch); + return result; +} + +static QSizeF hfw3(Qt::SizeHint, const QSizeF &constraint) +{ + QSizeF result(constraint); + const qreal ch = constraint.height(); + const qreal cw = constraint.width(); + if (cw < 0 && ch < 0) { + return QSizeF(10, 10); + } else if (cw > 0) { + result.setHeight(100./cw); } return result; } @@ -2400,7 +2469,7 @@ void tst_QGraphicsGridLayout::geometries_data() ); // change layout height and verify - QTest::newRow("hfw-h401") << (ItemList() + QTest::newRow("hfw-100x401") << (ItemList() << ItemDesc(0,0) .minSize(QSizeF(1,1)) .preferredSize(QSizeF(50,10)) @@ -2417,15 +2486,13 @@ void tst_QGraphicsGridLayout::geometries_data() .minSize(QSizeF(40,-1)) .preferredSize(QSizeF(50,-1)) .maxSize(QSizeF(500, -1)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) << QSizeF(100, 401) << (RectList() << QRectF(0, 0, 50, 1) << QRectF(50, 0, 50, 1) << QRectF(0, 1, 50,100) << QRectF(50, 1, 50,400) ); - - QTest::newRow("hfw-h408") << (ItemList() << ItemDesc(0,0) .minSize(QSizeF(1,1)) @@ -2443,7 +2510,7 @@ void tst_QGraphicsGridLayout::geometries_data() .sizeHint(Qt::MinimumSize, QSizeF(40,40)) .sizeHint(Qt::PreferredSize, QSizeF(50,400)) .sizeHint(Qt::MaximumSize, QSizeF(500, 500)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) << QSizeF(100, 408) << (RectList() @@ -2467,7 +2534,7 @@ void tst_QGraphicsGridLayout::geometries_data() .minSize(QSizeF(40,40)) .preferredSize(QSizeF(50,400)) .maxSize(QSizeF(500, 500)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) << QSizeF(100, 410) << (RectList() @@ -2475,7 +2542,7 @@ void tst_QGraphicsGridLayout::geometries_data() << QRectF(0, 10, 50,100) << QRectF(50, 10, 50,400) ); - QTest::newRow("hfw-h470") << (ItemList() + QTest::newRow("hfw-100x470") << (ItemList() << ItemDesc(0,0) .minSize(QSizeF(1,1)) .preferredSize(QSizeF(50,10)) @@ -2492,7 +2559,7 @@ void tst_QGraphicsGridLayout::geometries_data() .sizeHint(Qt::MinimumSize, QSizeF(40,40)) .sizeHint(Qt::PreferredSize, QSizeF(50,400)) .sizeHint(Qt::MaximumSize, QSizeF(500,500)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) << QSizeF(100, 470) << (RectList() @@ -2500,6 +2567,239 @@ void tst_QGraphicsGridLayout::geometries_data() << QRectF(0, 70, 50,100) << QRectF(50, 70, 50,400) ); + // change layout width and verify + QTest::newRow("hfw-100x401") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .minSize(QSizeF(-1,-1)) + .preferredSize(QSizeF(-1,-1)) + .maxSize(QSizeF(-1, -1)) + .dynamicConstraint(hfw1, Qt::Vertical) + ) + << QSizeF(100, 401) + << (RectList() + << QRectF( 0, 0, 50, 1) << QRectF( 50, 0, 50, 1) + << QRectF( 0, 1, 50, 100) << QRectF( 50, 1, 50, 400) + ); + + QTest::newRow("hfw-160x350") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .sizeHint(Qt::MinimumSize, QSizeF(40,40)) + .sizeHint(Qt::PreferredSize, QSizeF(50,400)) + .sizeHint(Qt::MaximumSize, QSizeF(5000,5000)) + .dynamicConstraint(hfw1, Qt::Vertical) + ) + << QSizeF(160, 350) + << (RectList() + << QRectF( 0, 0, 80, 100) << QRectF( 80, 0, 80, 100) + << QRectF( 0, 100, 80, 100) << QRectF( 80, 100, 80, 250) + ); + + QTest::newRow("hfw-160x300") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .sizeHint(Qt::MinimumSize, QSizeF(40,40)) + .sizeHint(Qt::PreferredSize, QSizeF(50,400)) + .sizeHint(Qt::MaximumSize, QSizeF(5000, 5000)) + .dynamicConstraint(hfw1, Qt::Vertical) + ) + << QSizeF(160, 300) + << (RectList() + << QRectF( 0, 0, 80, 50) << QRectF( 80, 0, 80, 50) + << QRectF( 0, 50, 80, 100) << QRectF( 80, 50, 80, 250) + ); + + QTest::newRow("hfw-20x40") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,10)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .sizeHint(Qt::MinimumSize, QSizeF(1, 1)) + .sizeHint(Qt::PreferredSize, QSizeF(50, 50)) + .sizeHint(Qt::MaximumSize, QSizeF(100, 100)) + .dynamicConstraint(hfw3, Qt::Vertical) + ) + << QSizeF(20, 40) + << (RectList() + << QRectF(0, 0, 10, 20) << QRectF(10, 0, 10, 20) + << QRectF(0, 20, 10, 20) << QRectF(10, 20, 10, 10) + ); + + QTest::newRow("wfh-300x160") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(10,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(10,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(10,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .sizeHint(Qt::MinimumSize, QSizeF(10,10)) + .sizeHint(Qt::PreferredSize, QSizeF(400,50)) + .sizeHint(Qt::MaximumSize, QSizeF(5000, 5000)) + .dynamicConstraint(wfh1, Qt::Horizontal) + ) + << QSizeF(300, 160) + << (RectList() + << QRectF( 0, 0, 50, 80) << QRectF( 50, 0, 100, 80) + << QRectF( 0, 80, 50, 80) << QRectF( 50, 80, 250, 80) + ); + + QTest::newRow("wfh-40x20") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + // Note, must be 10 in order to match stretching of wfh item + // below (the same stretch makes it easier to test) + .minSize(QSizeF(10,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .sizeHint(Qt::MinimumSize, QSizeF(1,1)) + .sizeHint(Qt::PreferredSize, QSizeF(50,50)) + .sizeHint(Qt::MaximumSize, QSizeF(100, 100)) + .dynamicConstraint(wfh2, Qt::Horizontal) + ) + << QSizeF(40, 20) + << (RectList() + << QRectF(0, 0, 20, 10) << QRectF(20, 0, 20, 10) + << QRectF(0, 10, 20, 10) << QRectF(20, 10, 10, 10) + ); + + QTest::newRow("wfh-400x160") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .sizeHint(Qt::MinimumSize, QSizeF(1,1)) + .sizeHint(Qt::PreferredSize, QSizeF(50,50)) + .sizeHint(Qt::MaximumSize, QSizeF(100, 100)) + .dynamicConstraint(wfh2, Qt::Horizontal) + ) + + << QSizeF(400, 160) + << (RectList() + << QRectF(0, 0, 100, 80) << QRectF(100, 0, 100, 80) + << QRectF(0, 80, 100, 80) << QRectF(100, 80, 80, 80) + ); + + QTest::newRow("wfh-160x100") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + // Note, preferred width must be 50 in order to match + // preferred width of wfh item below. + // (The same preferred size makes the stretch the same, and + // makes it easier to test) (The stretch algorithm is a + // blackbox) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(10,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(10,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .sizeHint(Qt::MinimumSize, QSizeF(1,1)) + .sizeHint(Qt::PreferredSize, QSizeF(10,50)) + .sizeHint(Qt::MaximumSize, QSizeF(500, 500)) + .dynamicConstraint(wfh2, Qt::Horizontal) + ) + << QSizeF(160, 100) + << (RectList() + << QRectF(0, 0, 80, 50) << QRectF( 80, 0, 80, 50) + << QRectF(0, 50, 80, 50) << QRectF( 80, 50, 50, 50) + ); + + QTest::newRow("hfw-h470") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,10)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .sizeHint(Qt::MinimumSize, QSizeF(40,40)) + .sizeHint(Qt::PreferredSize, QSizeF(50,400)) + .sizeHint(Qt::MaximumSize, QSizeF(500,500)) + .dynamicConstraint(hfw1, Qt::Vertical) + ) + << QSizeF(100, 470) + << (RectList() + << QRectF(0, 0, 50,70) << QRectF(50, 0, 50,70) + << QRectF(0, 70, 50,100) << QRectF(50, 70, 50,400) + ); // change layout width and verify QTest::newRow("hfw-w100") << (ItemList() @@ -2519,7 +2819,7 @@ void tst_QGraphicsGridLayout::geometries_data() .sizeHint(Qt::MinimumSize, QSizeF(40,40)) .sizeHint(Qt::PreferredSize, QSizeF(50,400)) .sizeHint(Qt::MaximumSize, QSizeF(5000,5000)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) << QSizeF(100, 401) << (RectList() @@ -2544,7 +2844,7 @@ void tst_QGraphicsGridLayout::geometries_data() .sizeHint(Qt::MinimumSize, QSizeF(40,40)) .sizeHint(Qt::PreferredSize, QSizeF(50,400)) .sizeHint(Qt::MaximumSize, QSizeF(5000,5000)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) << QSizeF(160, 350) << (RectList() @@ -2569,7 +2869,7 @@ void tst_QGraphicsGridLayout::geometries_data() .sizeHint(Qt::MinimumSize, QSizeF(40,40)) .sizeHint(Qt::PreferredSize, QSizeF(50,400)) .sizeHint(Qt::MaximumSize, QSizeF(5000,5000)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) << QSizeF(500, 200) << (RectList() @@ -2581,11 +2881,11 @@ void tst_QGraphicsGridLayout::geometries_data() << ItemDesc(0,0) .minSize(QSizeF(100, 100)) .maxSize(QSizeF(100, 100)) - .heightForWidth(hfw2) + .dynamicConstraint(hfw2, Qt::Vertical) << ItemDesc(1,0) .minSize(QSizeF(200, 200)) .maxSize(QSizeF(200, 200)) - .heightForWidth(hfw2) + .dynamicConstraint(hfw2, Qt::Vertical) << ItemDesc(2,0) .minSize(QSizeF(300, 300)) .maxSize(QSizeF(300, 300)) @@ -2601,12 +2901,12 @@ void tst_QGraphicsGridLayout::geometries_data() << ItemDesc(0,0) .minSize(QSizeF(100, 100)) .maxSize(QSizeF(100, 100)) - .heightForWidth(hfw2) + .dynamicConstraint(hfw2, Qt::Vertical) .alignment(Qt::AlignRight) << ItemDesc(1,0) .minSize(QSizeF(200, 200)) .maxSize(QSizeF(200, 200)) - .heightForWidth(hfw2) + .dynamicConstraint(hfw2, Qt::Vertical) .alignment(Qt::AlignHCenter) << ItemDesc(2,0) .minSize(QSizeF(300, 300)) @@ -2689,14 +2989,6 @@ void tst_QGraphicsGridLayout::task236367_maxSizeHint() QCOMPARE(widget->size(), QSizeF(w, h)); } -/* -static qreal hfw(qreal w) -{ - if (w == 0) - return 20000; - return 20000/w; -} -*/ static QSizeF hfw(Qt::SizeHint /*which*/, const QSizeF &constraint) { QSizeF result(constraint); @@ -2713,43 +3005,19 @@ static QSizeF hfw(Qt::SizeHint /*which*/, const QSizeF &constraint) } else if (ch == 0) { result.setWidth(20000); } - return result; } -static qreal growthFactorBelowPreferredSize(qreal desired, qreal sumAvailable, qreal sumDesired) -{ - Q_ASSERT(sumDesired != 0.0); - return desired * qPow(sumAvailable / sumDesired, desired / sumDesired); -} - -static void expectedWidth(qreal minSize1, qreal prefSize1, - qreal minSize2, qreal prefSize2, - qreal targetSize, qreal *width1, qreal *width2) +static QSizeF wfh(Qt::SizeHint /*which*/, const QSizeF &constraint) { - qreal sumAvail,factor1,factor2; - // stretch behaviour is different below and above preferred size... - if (targetSize < prefSize1 + prefSize2) { - sumAvail = targetSize - minSize1 - minSize2; - const qreal desired1 = prefSize1 - minSize1; - const qreal desired2 = prefSize2 - minSize2; - const qreal sumDesired = desired1 + desired2; - factor1 = growthFactorBelowPreferredSize(desired1, sumAvail, sumDesired); - factor2 = growthFactorBelowPreferredSize(desired2, sumAvail, sumDesired); - const qreal sumFactors = factor1 + factor2; - *width1 = sumAvail*factor1/sumFactors + minSize1; - *width2 = sumAvail*factor2/sumFactors + minSize2; - } else { - sumAvail = targetSize - prefSize1 - prefSize2; - factor1 = prefSize1; - factor2 = prefSize2; - const qreal sumFactors = factor1 + factor2; - *width1 = sumAvail*factor1/sumFactors + prefSize1; - *width2 = sumAvail*factor2/sumFactors + prefSize2; + QSizeF result(constraint); + const qreal ch = constraint.height(); + if (ch >= 0) { + result.setWidth(ch); } + return result; } - bool qFuzzyCompare(const QSizeF &a, const QSizeF &b) { return qFuzzyCompare(a.width(), b.width()) && qFuzzyCompare(a.height(), b.height()); @@ -2796,35 +3064,104 @@ void tst_QGraphicsGridLayout::heightForWidth() QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(2, -1)), QSizeF(2, 20001)); QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(2, -1)), QSizeF(2, 20010)); QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(2, -1)), QSizeF(2, 20100)); - qreal width1; - qreal width2; - expectedWidth(1, 10, 1, 200, 20, &width1, &width2); - QSizeF expectedSize = hfw(Qt::MinimumSize, QSizeF(width2, -1)) + QSizeF(width1, 1); - QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(20, -1)), expectedSize); - expectedSize.rheight()+=9; - QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(20, -1)), expectedSize); - expectedSize.rheight()+=90; - QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(20, -1)), expectedSize); - - expectedWidth(1, 10, 1, 200, 300, &width1, &width2); - expectedSize = hfw(Qt::MinimumSize, QSizeF(width2, -1)) + QSizeF(width1, 1); - QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(300, -1)), expectedSize); - expectedSize.rheight()+=9; - QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(300, -1)), expectedSize); - // the height of the hfw widget is shorter than the one to the left, which is 100, so - // the total height of the last row is 100 (which leaves the layout height to be 200) - QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(300, -1)), QSizeF(300, 200)); - - // the hfw item is shorter than the item to the left - expectedWidth(1, 10, 1, 200, 500, &width1, &width2); - expectedSize = hfw(Qt::MinimumSize, QSizeF(width2, -1)) + QSizeF(width1, 1); - QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(500, -1)), expectedSize); - expectedSize.rheight()+=9; - QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(500, -1)), expectedSize); + + // Since 20 is somewhere between "minimum width hint" (2) and + // "preferred width hint" (210), it will try to do distribution by + // stretching them with different factors. + // Since column 1 has a "preferred width" of 200 it means that + // column 1 will be a bit wider than column 0. Thus it will also be a bit + // shorter than 2001, (the expected height if all columns had width=10) + QSizeF sh = layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(20, -1)); + // column 1 cannot be wider than 19, which means that it must be taller than 20000/19~=1052 + QVERIFY(sh.height() < 2000 + 1 && sh.height() > 1052 + 1); + + sh = layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(20, -1)); + QVERIFY(sh.height() < 2000 + 10 && sh.height() > 1052 + 10); + + sh = layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(20, -1)); + QVERIFY(sh.height() < 2000 + 100 && sh.height() > 1052 + 100); + // the height of the hfw widget is shorter than the one to the left, which is 100, so // the total height of the last row is 100 (which leaves the layout height to be 200) - QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(500, -1)), QSizeF(500, 200)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(500, -1)), QSizeF(500, 100 + 100)); + +} + +void tst_QGraphicsGridLayout::widthForHeight() +{ + QGraphicsWidget *widget = new QGraphicsWidget; + QGraphicsGridLayout *layout = new QGraphicsGridLayout; + widget->setLayout(layout); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + + RectWidget *w00 = new RectWidget; + w00->setMinimumSize(1, 1); + w00->setPreferredSize(50, 50); + w00->setMaximumSize(100, 100); + + layout->addItem(w00, 0, 0); + + RectWidget *w01 = new RectWidget; + w01->setMinimumSize(1,1); + w01->setPreferredSize(50,50); + w01->setMaximumSize(100,100); + layout->addItem(w01, 0, 1); + + RectWidget *w10 = new RectWidget; + w10->setMinimumSize(1,1); + w10->setPreferredSize(50,50); + w10->setMaximumSize(100,100); + layout->addItem(w10, 1, 0); + + RectWidget *w11 = new RectWidget; + w11->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); + w11->setSizeHint(Qt::PreferredSize, QSizeF(50,50)); + w11->setSizeHint(Qt::MaximumSize, QSizeF(30000,30000)); + + // This will make sure its always square. + w11->setConstraintFunction(wfh); + QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); + sp.setWidthForHeight(true); + w11->setSizePolicy(sp); + layout->addItem(w11, 1, 1); + + /* + | 1, 50, 100 | 1, 50, 100 | + -----+--------------+--------------+ + 1| | | + 50| | | + 100| | | + -----|--------------+--------------+ + 1| | | + 50| | WFH | + 100| | | + -----------------------------------+ + */ + + + QSizeF prefSize = layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)); + QCOMPARE(prefSize, QSizeF(50+50, 50+50)); + + // wfh(1): = 1 + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, 2)), QSizeF(1 + 1, 2)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, 2)), QSizeF(50 + 50, 2)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(-1, 2)), QSizeF(100 + 100, 2)); + + // wfh(40) = 40 + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, 80)), QSizeF(1 + 40, 80)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, 80)), QSizeF(50 + 50, 80)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(-1, 80)), QSizeF(100 + 100, 80)); + + // wfh(80) = 80 + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, 160)), QSizeF(1 + 80, 160)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, 160)), QSizeF(50 + 80, 160)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(-1, 160)), QSizeF(100 + 100, 160)); + // wfh(200) = 200 + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, 300)), QSizeF(1 + 200, 300)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, 300)), QSizeF(50 + 200, 300)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(-1, 300)), QSizeF(100 + 200, 300)); } void tst_QGraphicsGridLayout::heightForWidthWithSpanning() diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 15ed242..9b7b228 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -10732,7 +10732,7 @@ void tst_QGraphicsItem::deviceCoordinateCache_simpleRotations() QTRY_VERIFY(view.repaints > 0); QGraphicsItemCache *itemCache = QGraphicsItemPrivate::get(item)->extraItemCache(); - Q_ASSERT(itemCache); + QVERIFY(itemCache); QPixmapCache::Key currentKey = itemCache->deviceData.value(view.viewport()).key; // Trigger an update and verify that the cache is unchanged. diff --git a/tests/auto/qgraphicsitemanimation/qgraphicsitemanimation.pro b/tests/auto/qgraphicsitemanimation/qgraphicsitemanimation.pro index 6be3bfe..01875c7 100644 --- a/tests/auto/qgraphicsitemanimation/qgraphicsitemanimation.pro +++ b/tests/auto/qgraphicsitemanimation/qgraphicsitemanimation.pro @@ -1,5 +1,5 @@ load(qttest_p4) SOURCES += tst_qgraphicsitemanimation.cpp DEFINES += QT_NO_CAST_TO_ASCII - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicslayout/qgraphicslayout.pro b/tests/auto/qgraphicslayout/qgraphicslayout.pro index 1dc916a..eafd213 100644 --- a/tests/auto/qgraphicslayout/qgraphicslayout.pro +++ b/tests/auto/qgraphicslayout/qgraphicslayout.pro @@ -5,4 +5,4 @@ load(qttest_p4) SOURCES += tst_qgraphicslayout.cpp DEFINES += QT_USE_USING_NAMESPACE - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicslayoutitem/qgraphicslayoutitem.pro b/tests/auto/qgraphicslayoutitem/qgraphicslayoutitem.pro index 6c8bf0c..816224b 100644 --- a/tests/auto/qgraphicslayoutitem/qgraphicslayoutitem.pro +++ b/tests/auto/qgraphicslayoutitem/qgraphicslayoutitem.pro @@ -1,4 +1,4 @@ load(qttest_p4) SOURCES += tst_qgraphicslayoutitem.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicslinearlayout/qgraphicslinearlayout.pro b/tests/auto/qgraphicslinearlayout/qgraphicslinearlayout.pro index 114e5e9..df5a827 100644 --- a/tests/auto/qgraphicslinearlayout/qgraphicslinearlayout.pro +++ b/tests/auto/qgraphicslinearlayout/qgraphicslinearlayout.pro @@ -1,4 +1,4 @@ load(qttest_p4) SOURCES += tst_qgraphicslinearlayout.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicsobject/qgraphicsobject.pro b/tests/auto/qgraphicsobject/qgraphicsobject.pro index 965b319..2418845 100644 --- a/tests/auto/qgraphicsobject/qgraphicsobject.pro +++ b/tests/auto/qgraphicsobject/qgraphicsobject.pro @@ -1,2 +1,3 @@ load(qttest_p4) SOURCES += tst_qgraphicsobject.cpp +CONFIG += parallel_test
\ No newline at end of file diff --git a/tests/auto/qgraphicspixmapitem/qgraphicspixmapitem.pro b/tests/auto/qgraphicspixmapitem/qgraphicspixmapitem.pro index f6d6c8f..6b4db95 100644 --- a/tests/auto/qgraphicspixmapitem/qgraphicspixmapitem.pro +++ b/tests/auto/qgraphicspixmapitem/qgraphicspixmapitem.pro @@ -1,4 +1,4 @@ load(qttest_p4) SOURCES += tst_qgraphicspixmapitem.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicspolygonitem/qgraphicspolygonitem.pro b/tests/auto/qgraphicspolygonitem/qgraphicspolygonitem.pro index d54b78b..4da949b 100644 --- a/tests/auto/qgraphicspolygonitem/qgraphicspolygonitem.pro +++ b/tests/auto/qgraphicspolygonitem/qgraphicspolygonitem.pro @@ -1,4 +1,4 @@ load(qttest_p4) SOURCES += tst_qgraphicspolygonitem.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index b15ee1a..29c6591 100644 --- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -183,6 +183,7 @@ private slots: void inputMethod(); void clickFocus(); void windowFrameMargins(); + void QTBUG_6986_sendMouseEventToAlienWidget(); }; // Subclass that exposes the protected functions. @@ -3583,6 +3584,70 @@ void tst_QGraphicsProxyWidget::windowFrameMargins() QVERIFY(top > 0); } +class HoverButton : public QPushButton +{ +public: + HoverButton(QWidget *parent = 0) : QPushButton(parent), hoverLeaveReceived(false) + {} + + bool hoverLeaveReceived; + + bool event(QEvent* e) + { + if(QEvent::HoverLeave == e->type()) + hoverLeaveReceived = true; + return QPushButton::event(e); + } +}; + +class Scene : public QGraphicsScene +{ +Q_OBJECT +public: + Scene() { + QWidget *background = new QWidget; + background->setGeometry(0, 0, 500, 500); + hoverButton = new HoverButton; + hoverButton->setParent(background); + hoverButton->setText("Second button"); + hoverButton->setGeometry(10, 10, 200, 50); + addWidget(background); + + QPushButton *hideButton = new QPushButton("I'm a button with a very very long text"); + hideButton->setGeometry(10, 10, 400, 50); + topButton = addWidget(hideButton); + connect(hideButton, SIGNAL(clicked()), this, SLOT(hideButton())); + topButton->setFocus(); + } + + QGraphicsProxyWidget *topButton; + HoverButton *hoverButton; + +public slots: + void hideButton() { + QCursor::setPos(600,600); + topButton->hide(); + } +}; + +void tst_QGraphicsProxyWidget::QTBUG_6986_sendMouseEventToAlienWidget() +{ +#if defined(Q_OS_MAC) || defined(Q_OS_WIN) || defined(QT_NO_CURSOR) + QSKIP("Test case unstable on this platform", SkipAll); +#endif + QGraphicsView view; + Scene scene; + view.setScene(&scene); + view.resize(600, 600); + QApplication::setActiveWindow(&view); + view.show(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), &view); + QCursor::setPos(view.mapToGlobal(view.mapFromScene(scene.topButton->boundingRect().center()))); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(scene.topButton->scenePos())); + QTRY_COMPARE(scene.hoverButton->hoverLeaveReceived, true); +} + QTEST_MAIN(tst_QGraphicsProxyWidget) #include "tst_qgraphicsproxywidget.moc" diff --git a/tests/auto/qgraphicsscene/qgraphicsscene.pro b/tests/auto/qgraphicsscene/qgraphicsscene.pro index cc6f585..82fa423 100644 --- a/tests/auto/qgraphicsscene/qgraphicsscene.pro +++ b/tests/auto/qgraphicsscene/qgraphicsscene.pro @@ -7,9 +7,9 @@ win32:!wince*: LIBS += -lUser32 DEFINES += QT_NO_CAST_TO_ASCII wince*|symbian: { - rootFiles.sources = Ash_European.jpg graphicsScene_selection.data + rootFiles.files = Ash_European.jpg graphicsScene_selection.data rootFiles.path = . - renderFiles.sources = testData\\render\\* + renderFiles.files = testData\\render\\* renderFiles.path = testData\\render DEPLOYMENT += rootFiles renderFiles } diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index b0e60b0..b8741fe 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -3594,7 +3594,7 @@ void tst_QGraphicsScene::task160653_selectionChanged() item->flags() | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable); item->setSelected(true); } - Q_ASSERT(scene.items().size() > 1); + QVERIFY(scene.items().size() > 1); QCOMPARE(scene.items().size(), scene.selectedItems().size()); QSignalSpy spy(&scene, SIGNAL(selectionChanged())); diff --git a/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro b/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro index d1bf3cc..1fdd176 100644 --- a/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro +++ b/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro @@ -1,4 +1,4 @@ load(qttest_p4) requires(contains(QT_CONFIG,private_tests)) SOURCES += tst_qgraphicssceneindex.cpp - +CONFIG += parallel_test diff --git a/tests/auto/qgraphicstransform/qgraphicstransform.pro b/tests/auto/qgraphicstransform/qgraphicstransform.pro index 709cff6..67c939e 100644 --- a/tests/auto/qgraphicstransform/qgraphicstransform.pro +++ b/tests/auto/qgraphicstransform/qgraphicstransform.pro @@ -1,2 +1,3 @@ load(qttest_p4) SOURCES += tst_qgraphicstransform.cpp +CONFIG += parallel_test diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 26c8bc6..66a9e47 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -246,6 +246,7 @@ private slots: void QTBUG_4151_clipAndIgnore(); void QTBUG_5859_exposedRect(); void QTBUG_7438_cursor(); + void hoverLeave(); void QTBUG_16063_microFocusRect(); public slots: @@ -2966,7 +2967,7 @@ protected: void tst_QGraphicsView::task186827_deleteReplayedItem() { // make sure the mouse is not over the window, causing spontaneous mouse moves - QCursor::setPos(0, 0); + QCursor::setPos(1, 1); QGraphicsScene scene; scene.addRect(0, 0, 50, 50); @@ -3356,6 +3357,10 @@ void tst_QGraphicsView::moveItemWhileScrolling() int a = adjustForAntialiasing ? 2 : 1; expectedRegion += QRect(40, 50, 10, 10).adjusted(-a, -a, a, a); expectedRegion += QRect(40, 60, 10, 10).adjusted(-a, -a, a, a); +#ifdef QT_MAC_USE_COCOA + if (QApplicationPrivate::graphicsSystem() == 0) + QEXPECT_FAIL("", "This will fail with Cocoa because paint events are not send in the order expected by graphicsview", Continue); +#endif COMPARE_REGIONS(view.lastPaintedRegion, expectedRegion); } @@ -4459,6 +4464,60 @@ void tst_QGraphicsView::QTBUG_7438_cursor() #endif } +class GraphicsItemWithHover : public QGraphicsRectItem +{ +public: + GraphicsItemWithHover() + : receivedEnterEvent(false), receivedLeaveEvent(false), + enterWidget(0), leaveWidget(0) + { + setRect(0, 0, 100, 100); + setAcceptHoverEvents(true); + } + + bool sceneEvent(QEvent *event) + { + if (event->type() == QEvent::GraphicsSceneHoverEnter) { + receivedEnterEvent = true; + enterWidget = static_cast<QGraphicsSceneHoverEvent *>(event)->widget(); + } else if (event->type() == QEvent::GraphicsSceneHoverLeave) { + receivedLeaveEvent = true; + leaveWidget = static_cast<QGraphicsSceneHoverEvent *>(event)->widget(); + } + return QGraphicsRectItem::sceneEvent(event); + } + + bool receivedEnterEvent; + bool receivedLeaveEvent; + QWidget *enterWidget; + QWidget *leaveWidget; +}; + +void tst_QGraphicsView::hoverLeave() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + GraphicsItemWithHover *item = new GraphicsItemWithHover; + scene.addItem(item); + + // move the cursor out of the way + QCursor::setPos(1,1); + + view.show(); + QTest::qWaitForWindowShown(&view); + + QPoint pos = view.viewport()->mapToGlobal(view.mapFromScene(item->mapToScene(10, 10))); + QCursor::setPos(pos); + QTest::qWait(200); + QVERIFY(item->receivedEnterEvent); + QCOMPARE(item->enterWidget, view.viewport()); + + QCursor::setPos(1,1); + QTest::qWait(200); + QVERIFY(item->receivedLeaveEvent); + QCOMPARE(item->leaveWidget, view.viewport()); +} + class IMItem : public QGraphicsRectItem { public: diff --git a/tests/auto/qhash/qhash.pro b/tests/auto/qhash/qhash.pro index 86b98a2..16c9eab 100644 --- a/tests/auto/qhash/qhash.pro +++ b/tests/auto/qhash/qhash.pro @@ -6,3 +6,4 @@ symbian: { TARGET.EPOCSTACKSIZE =0x5000 TARGET.EPOCHEAPSIZE="0x100000 0x1000000" # // Min 1Mb, max 16Mb } +CONFIG += parallel_test diff --git a/tests/auto/qhash/tst_qhash.cpp b/tests/auto/qhash/tst_qhash.cpp index 3bfafe3..18654cf 100644 --- a/tests/auto/qhash/tst_qhash.cpp +++ b/tests/auto/qhash/tst_qhash.cpp @@ -60,6 +60,7 @@ private slots: void erase(); void key(); + void swap(); void count(); // copied from tst_QMap void clear(); // copied from tst_QMap void empty(); // copied from tst_QMap @@ -553,6 +554,16 @@ void tst_QHash::key() } } +void tst_QHash::swap() +{ + QHash<int,QString> h1, h2; + h1[0] = "h1[0]"; + h2[1] = "h2[1]"; + h1.swap(h2); + QCOMPARE(h1.value(1),QLatin1String("h2[1]")); + QCOMPARE(h2.value(0),QLatin1String("h1[0]")); +} + // copied from tst_QMap void tst_QHash::clear() { diff --git a/tests/auto/qheaderview/tst_qheaderview.cpp b/tests/auto/qheaderview/tst_qheaderview.cpp index 52eeee4..a6ffea3 100644 --- a/tests/auto/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/qheaderview/tst_qheaderview.cpp @@ -195,6 +195,8 @@ private slots: void QTBUG8650_crashOnInsertSections(); void QTBUG12268_hiddenMovedSectionSorting(); + void initialSortOrderRole(); + protected: QWidget *topLevel; QHeaderView *view; @@ -1114,7 +1116,7 @@ void tst_QHeaderView::moveAndInsertSection() void tst_QHeaderView::resizeMode() { - // Q_ASSERT's when resizeMode is called with an invalid index + // resizeMode must not be called with an invalid index int last = view->count() - 1; view->setResizeMode(QHeaderView::Interactive); QCOMPARE(view->resizeMode(last), QHeaderView::Interactive); @@ -2107,5 +2109,40 @@ void tst_QHeaderView::QTBUG12268_hiddenMovedSectionSorting() QCOMPARE(view.horizontalHeader()->hiddenSectionCount(), 1); } +void tst_QHeaderView::initialSortOrderRole() +{ + QTableView view; + QStandardItemModel *model = new QStandardItemModel(4, 3, &view); + for (int i = 0; i< model->rowCount(); ++i) + for (int j = 0; j< model->columnCount(); ++j) + model->setData(model->index(i,j), QString("item [%1,%2]").arg(i).arg(j)); + QStandardItem *ascendingItem = new QStandardItem(); + QStandardItem *descendingItem = new QStandardItem(); + ascendingItem->setData(Qt::AscendingOrder, Qt::InitialSortOrderRole); + descendingItem->setData(Qt::DescendingOrder, Qt::InitialSortOrderRole); + model->setHorizontalHeaderItem(1, ascendingItem); + model->setHorizontalHeaderItem(2, descendingItem); + view.setModel(model); + view.setSortingEnabled(true); + view.sortByColumn(0, Qt::AscendingOrder); + view.show(); + QTest::qWaitForWindowShown(&view); + + const int column1Pos = view.horizontalHeader()->sectionViewportPosition(1) + 5; // +5 not to be on the handle + QTest::mouseClick(view.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(column1Pos, 0)); + QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), 1); + QCOMPARE(view.horizontalHeader()->sortIndicatorOrder(), Qt::AscendingOrder); + + const int column2Pos = view.horizontalHeader()->sectionViewportPosition(2) + 5; // +5 not to be on the handle + QTest::mouseClick(view.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(column2Pos, 0)); + QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), 2); + QCOMPARE(view.horizontalHeader()->sortIndicatorOrder(), Qt::DescendingOrder); + + const int column0Pos = view.horizontalHeader()->sectionViewportPosition(0) + 5; // +5 not to be on the handle + QTest::mouseClick(view.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(column0Pos, 0)); + QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), 0); + QCOMPARE(view.horizontalHeader()->sortIndicatorOrder(), Qt::AscendingOrder); +} + QTEST_MAIN(tst_QHeaderView) #include "tst_qheaderview.moc" diff --git a/tests/auto/qhelpcontentmodel/qhelpcontentmodel.pro b/tests/auto/qhelpcontentmodel/qhelpcontentmodel.pro index 889aac9..a9a8ed9 100644 --- a/tests/auto/qhelpcontentmodel/qhelpcontentmodel.pro +++ b/tests/auto/qhelpcontentmodel/qhelpcontentmodel.pro @@ -9,9 +9,9 @@ DEFINES += QT_USE_USING_NAMESPACE wince*: { DEFINES += SRCDIR=\\\"./\\\" QT += network - addFiles.sources = $$PWD/data/*.* + addFiles.files = $$PWD/data/*.* addFiles.path = data - clucene.sources = $$QT_BUILD_TREE/lib/QtCLucene*.dll + clucene.files = $$QT_BUILD_TREE/lib/QtCLucene*.dll DEPLOYMENT += addFiles DEPLOYMENT += clucene diff --git a/tests/auto/qhelpenginecore/qhelpenginecore.pro b/tests/auto/qhelpenginecore/qhelpenginecore.pro index 27ebd0f..4166fe2 100644 --- a/tests/auto/qhelpenginecore/qhelpenginecore.pro +++ b/tests/auto/qhelpenginecore/qhelpenginecore.pro @@ -10,9 +10,9 @@ DEFINES += QT_USE_USING_NAMESPACE wince*: { DEFINES += SRCDIR=\\\"./\\\" QT += network - addFiles.sources = $$PWD/data/*.* + addFiles.files = $$PWD/data/*.* addFiles.path = data - clucene.sources = $$QT_BUILD_TREE/lib/QtCLucene*.dll + clucene.files = $$QT_BUILD_TREE/lib/QtCLucene*.dll DEPLOYMENT += addFiles DEPLOYMENT += clucene diff --git a/tests/auto/qhostaddress/tst_qhostaddress.cpp b/tests/auto/qhostaddress/tst_qhostaddress.cpp index 8fd1cd2..08eb63c 100644 --- a/tests/auto/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/qhostaddress/tst_qhostaddress.cpp @@ -164,21 +164,27 @@ void tst_QHostAddress::setAddress_QString_data() QTest::newRow("ip4_04") << QString("255.3.2.1\r ") << (bool)TRUE << QString("255.3.2.1") << 4; QTest::newRow("ip4_05") << QString("0.0.0.0") << (bool)TRUE << QString("0.0.0.0") << 4; - // for the format of IPv6 addresses see also RFC 1884 + // for the format of IPv6 addresses see also RFC 5952 QTest::newRow("ip6_00") << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << (bool)TRUE << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << 6; - QTest::newRow("ip6_01") << QString("1080:0000:0000:0000:0008:0800:200C:417A") << (bool)TRUE << QString("1080:0:0:0:8:800:200C:417A") << 6; - QTest::newRow("ip6_02") << QString("1080:0:0:0:8:800:200C:417A") << (bool)TRUE << QString("1080:0:0:0:8:800:200C:417A") << 6; - QTest::newRow("ip6_03") << QString("1080::8:800:200C:417A") << (bool)TRUE << QString("1080:0:0:0:8:800:200C:417A") << 6; - QTest::newRow("ip6_04") << QString("FF01::43") << (bool)TRUE << QString("FF01:0:0:0:0:0:0:43") << 6; - QTest::newRow("ip6_05") << QString("::1") << (bool)TRUE << QString("0:0:0:0:0:0:0:1") << 6; - QTest::newRow("ip6_06") << QString("1::") << (bool)TRUE << QString("1:0:0:0:0:0:0:0") << 6; - QTest::newRow("ip6_07") << QString("::") << (bool)TRUE << QString("0:0:0:0:0:0:0:0") << 6; - QTest::newRow("ip6_08") << QString("0:0:0:0:0:0:13.1.68.3") << (bool)TRUE << QString("0:0:0:0:0:0:D01:4403") << 6; - QTest::newRow("ip6_09") << QString("::13.1.68.3") << (bool)TRUE << QString("0:0:0:0:0:0:D01:4403") << 6; - QTest::newRow("ip6_10") << QString("0:0:0:0:0:FFFF:129.144.52.38") << (bool)TRUE << QString("0:0:0:0:0:FFFF:8190:3426") << 6; - QTest::newRow("ip6_11") << QString("::FFFF:129.144.52.38") << (bool)TRUE << QString("0:0:0:0:0:FFFF:8190:3426") << 6; - QTest::newRow("ip6_12") << QString("1::FFFF:129.144.52.38") << (bool)TRUE << QString("1:0:0:0:0:FFFF:8190:3426") << 6; - QTest::newRow("ip6_13") << QString("A:B::D:E") << (bool)TRUE << QString("A:B:0:0:0:0:D:E") << 6; + QTest::newRow("ip6_01") << QString("1080:0000:0000:0000:0008:0800:200C:417A") << (bool)TRUE << QString("1080::8:800:200C:417A") << 6; + QTest::newRow("ip6_02") << QString("1080:0:0:0:8:800:200C:417A") << (bool)TRUE << QString("1080::8:800:200C:417A") << 6; + QTest::newRow("ip6_03") << QString("1080::8:800:200C:417A") << (bool)TRUE << QString("1080::8:800:200C:417A") << 6; + QTest::newRow("ip6_04") << QString("FF01::43") << (bool)TRUE << QString("FF01::43") << 6; + QTest::newRow("ip6_05") << QString("::1") << (bool)TRUE << QString("::1") << 6; + QTest::newRow("ip6_06") << QString("1::") << (bool)TRUE << QString("1::") << 6; + QTest::newRow("ip6_07") << QString("::") << (bool)TRUE << QString("::") << 6; + QTest::newRow("ip6_08") << QString("0:0:0:0:0:0:13.1.68.3") << (bool)TRUE << QString("::D01:4403") << 6; + QTest::newRow("ip6_09") << QString("::13.1.68.3") << (bool)TRUE << QString("::D01:4403") << 6; + QTest::newRow("ip6_10") << QString("0:0:0:0:0:FFFF:129.144.52.38") << (bool)TRUE << QString("::FFFF:8190:3426") << 6; + QTest::newRow("ip6_11") << QString("::FFFF:129.144.52.38") << (bool)TRUE << QString("::FFFF:8190:3426") << 6; + QTest::newRow("ip6_12") << QString("1::FFFF:129.144.52.38") << (bool)TRUE << QString("1::FFFF:8190:3426") << 6; + QTest::newRow("ip6_13") << QString("A:B::D:E") << (bool)TRUE << QString("A:B::D:E") << 6; + QTest::newRow("ip6_14") << QString("1080:0:1:0:8:800:200C:417A") << (bool)TRUE << QString("1080:0:1:0:8:800:200C:417A") << 6; + QTest::newRow("ip6_15") << QString("1080:0:1:0:8:800:200C:0") << (bool)TRUE << QString("1080:0:1:0:8:800:200C:0") << 6; + QTest::newRow("ip6_16") << QString("1080:0:1:0:8:800:0:0") << (bool)TRUE << QString("1080:0:1:0:8:800::") << 6; + QTest::newRow("ip6_17") << QString("1080:0:0:0:8:800:0:0") << (bool)TRUE << QString("1080::8:800:0:0") << 6; + QTest::newRow("ip6_18") << QString("0:1:1:1:8:800:0:0") << (bool)TRUE << QString("0:1:1:1:8:800::") << 6; + QTest::newRow("ip6_19") << QString("0:1:1:1:8:800:0:1") << (bool)TRUE << QString("0:1:1:1:8:800:0:1") << 6; QTest::newRow("error_00") << QString("foobarcom") << (bool)FALSE << QString() << 0; QTest::newRow("error_01") << QString("foo.bar.com") << (bool)FALSE << QString() << 0; @@ -329,16 +335,16 @@ void tst_QHostAddress::scopeId() { QHostAddress address("fe80::2e0:4cff:fefb:662a%eth0"); QCOMPARE(address.scopeId(), QString("eth0")); - QCOMPARE(address.toString().toLower(), QString("fe80:0:0:0:2e0:4cff:fefb:662a%eth0")); + QCOMPARE(address.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%eth0")); QHostAddress address2("fe80::2e0:4cff:fefb:662a"); QCOMPARE(address2.scopeId(), QString()); address2.setScopeId(QString("en0")); - QCOMPARE(address2.toString().toLower(), QString("fe80:0:0:0:2e0:4cff:fefb:662a%en0")); + QCOMPARE(address2.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%en0")); address2 = address; QCOMPARE(address2.scopeId(), QString("eth0")); - QCOMPARE(address2.toString().toLower(), QString("fe80:0:0:0:2e0:4cff:fefb:662a%eth0")); + QCOMPARE(address2.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%eth0")); } void tst_QHostAddress::hashKey() diff --git a/tests/auto/qhostinfo/tst_qhostinfo.cpp b/tests/auto/qhostinfo/tst_qhostinfo.cpp index 2b0312a..2fa5e76 100644 --- a/tests/auto/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/qhostinfo/tst_qhostinfo.cpp @@ -62,6 +62,12 @@ #include <private/qthread_p.h> #include <QTcpServer> +#ifndef QT_NO_BEARERMANAGEMENT +#include <QtNetwork/qnetworkconfigmanager.h> +#include <QtNetwork/qnetworkconfiguration.h> +#include <QtNetwork/qnetworksession.h> +#endif + #include <time.h> #include <qlibrary.h> #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) @@ -126,6 +132,7 @@ private slots: void raceCondition(); void threadSafety(); + void threadSafetyAsynchronousAPI(); void multipleSameLookups(); void multipleDifferentLookups_data(); @@ -133,6 +140,8 @@ private slots: void cache(); + void abortHostLookup(); + void abortHostLookupInDifferentThread(); protected slots: void resultsReady(const QHostInfo &); @@ -142,6 +151,11 @@ private: bool lookupDone; int lookupsDoneCounter; QHostInfo lookupResults; +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkConfigurationManager *netConfMan; + QNetworkConfiguration networkConfiguration; + QScopedPointer<QNetworkSession> networkSession; +#endif }; // Testing get/set functions @@ -182,8 +196,36 @@ tst_QHostInfo::~tst_QHostInfo() void tst_QHostInfo::initTestCase() { +#ifndef QT_NO_BEARERMANAGEMENT + netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + networkConfiguration = netConfMan->defaultConfiguration(); + if (networkConfiguration.isValid()) { + networkSession.reset(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); + } +#endif + +#ifdef Q_OS_SYMBIAN + ipv6Available = true; + ipv6LookupsAvailable = true; +#else ipv6Available = false; ipv6LookupsAvailable = false; + + QTcpServer server; + if (server.listen(QHostAddress("::1"))) { + // We have IPv6 support + ipv6Available = true; + } + #if !defined(QT_NO_GETADDRINFO) // check if the system getaddrinfo can do IPv6 lookups struct addrinfo hint, *result = 0; @@ -204,13 +246,7 @@ void tst_QHostInfo::initTestCase() } } #endif - - QTcpServer server; - if (server.listen(QHostAddress("::1"))) { - // We have IPv6 support - ipv6Available = true; - } - +#endif // run each testcase with and without test enabled QTest::addColumn<bool>("cache"); @@ -237,18 +273,14 @@ void tst_QHostInfo::lookupIPv4_data() QTest::addColumn<QString>("addresses"); QTest::addColumn<int>("err"); -#ifdef Q_OS_SYMBIAN // Test server lookup QTest::newRow("lookup_01") << QtNetworkSettings::serverName() << QtNetworkSettings::serverIP().toString() << int(QHostInfo::NoError); - QTest::newRow("literal_ip4") << QtNetworkSettings::serverIP().toString() << QtNetworkSettings::serverIP().toString() << int(QHostInfo::NoError); - QTest::newRow("multiple_ip4") << "multi.dev.troll.no" << "1.2.3.4 1.2.3.5 10.3.3.31" << int(QHostInfo::NoError); -#else QTest::newRow("empty") << "" << "" << int(QHostInfo::HostNotFound); QTest::newRow("single_ip4") << "lupinella.troll.no" << lupinellaIp << int(QHostInfo::NoError); QTest::newRow("multiple_ip4") << "multi.dev.troll.no" << "1.2.3.4 1.2.3.5 10.3.3.31" << int(QHostInfo::NoError); QTest::newRow("literal_ip4") << lupinellaIp << lupinellaIp << int(QHostInfo::NoError); -#endif + QTest::newRow("notfound") << "this-name-does-not-exist-hopefully." << "" << int(QHostInfo::HostNotFound); QTest::newRow("idn-ace") << "xn--alqualond-34a.troll.no" << "10.3.3.55" << int(QHostInfo::NoError); @@ -290,12 +322,16 @@ void tst_QHostInfo::lookupIPv6_data() QTest::addColumn<QString>("addresses"); QTest::addColumn<int>("err"); - QTest::newRow("ip6") << "www.ipv6-net.org" << "62.93.217.177 2001:618:1401:0:0:0:0:4" << int(QHostInfo::NoError); + QTest::newRow("ipv6-net") << "www.ipv6-net.org" << "62.93.217.177 2001:618:1401::4" << int(QHostInfo::NoError); + QTest::newRow("ipv6-test") << "ipv6-test.dev.troll.no" << "2001:638:a00:2::2" << int(QHostInfo::NoError); + QTest::newRow("dns6-test") << "dns6-test-dev.troll.no" << "2001:470:1f01:115::10" << int(QHostInfo::NoError); + QTest::newRow("multi-dns6") << "multi-dns6-test-dev.troll.no" << "2001:470:1f01:115::11 2001:470:1f01:115::12" << int(QHostInfo::NoError); + QTest::newRow("dns46-test") << "dns46-test-dev.troll.no" << "10.3.4.90 2001:470:1f01:115::13" << int(QHostInfo::NoError); // avoid using real IPv6 addresses here because this will do a DNS query // real addresses are between 2000:: and 3fff:ffff:ffff:ffff:ffff:ffff:ffff QTest::newRow("literal_ip6") << "f001:6b0:1:ea:202:a5ff:fecd:13a6" << "f001:6b0:1:ea:202:a5ff:fecd:13a6" << int(QHostInfo::NoError); - QTest::newRow("literal_shortip6") << "f001:618:1401::4" << "f001:618:1401:0:0:0:0:4" << int(QHostInfo::NoError); + QTest::newRow("literal_shortip6") << "f001:618:1401::4" << "f001:618:1401::4" << int(QHostInfo::NoError); } void tst_QHostInfo::lookupIPv6() @@ -310,7 +346,7 @@ void tst_QHostInfo::lookupIPv6() lookupDone = false; QHostInfo::lookupHost(hostname, this, SLOT(resultsReady(const QHostInfo&))); - QTestEventLoop::instance().enterLoop(3); + QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(lookupDone); @@ -337,7 +373,7 @@ void tst_QHostInfo::reverseLookup_data() // ### Use internal DNS instead. Discussed with Andreas. //QTest::newRow("classical.hexago.com") << QString("2001:5c0:0:2::24") << QStringList(QString("classical.hexago.com")) << 0; - QTest::newRow("origin.cisco.com") << QString("12.159.148.94") << QStringList(QString("origin.cisco.com")) << 0; + QTest::newRow("gitorious.org") << QString("87.238.52.168") << QStringList(QString("gitorious.org")) << 0; QTest::newRow("bogus-name") << QString("1::2::3::4") << QStringList() << 1; } @@ -411,6 +447,8 @@ protected: inline void run() { QHostInfo info = QHostInfo::fromName("qt.nokia.com"); + QCOMPARE(info.error(), QHostInfo::NoError); + QVERIFY(info.addresses().count() > 0); QCOMPARE(info.addresses().at(0).toString(), QString("87.238.50.178")); } }; @@ -418,7 +456,7 @@ protected: void tst_QHostInfo::threadSafety() { const int nattempts = 5; -#if defined(Q_OS_WINCE) +#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) const int runs = 10; #else const int runs = 100; @@ -432,6 +470,56 @@ void tst_QHostInfo::threadSafety() } } +class LookupReceiver : public QObject +{ + Q_OBJECT +public slots: + void start(); + void resultsReady(const QHostInfo&); +public: + QHostInfo result; + int numrequests; +}; + +void LookupReceiver::start() +{ + for (int i=0;i<numrequests;i++) + QHostInfo::lookupHost(QString("qt.nokia.com"), this, SLOT(resultsReady(const QHostInfo&))); +} + +void LookupReceiver::resultsReady(const QHostInfo &info) +{ + result = info; + numrequests--; + if (numrequests == 0 || info.error() != QHostInfo::NoError) + QThread::currentThread()->quit(); +} + +void tst_QHostInfo::threadSafetyAsynchronousAPI() +{ + const int nattempts = 10; + const int lookupsperthread = 10; + QList<QThread*> threads; + QList<LookupReceiver*> receivers; + for (int i = 0; i < nattempts; ++i) { + QThread* thread = new QThread; + LookupReceiver* receiver = new LookupReceiver; + receiver->numrequests = lookupsperthread; + receivers.append(receiver); + receiver->moveToThread(thread); + connect(thread, SIGNAL(started()), receiver, SLOT(start())); + thread->start(); + threads.append(thread); + } + for (int k = threads.count() - 1; k >= 0; --k) + QVERIFY(threads.at(k)->wait(60000)); + foreach (LookupReceiver* receiver, receivers) { + QCOMPARE(receiver->result.error(), QHostInfo::NoError); + QCOMPARE(receiver->result.addresses().at(0).toString(), QString("87.238.50.178")); + QCOMPARE(receiver->numrequests, 0); + } +} + // this test is for the multi-threaded QHostInfo rewrite. It is about getting results at all, // not about getting correct IPs void tst_QHostInfo::multipleSameLookups() @@ -478,8 +566,9 @@ void tst_QHostInfo::multipleDifferentLookups() QElapsedTimer timer; timer.start(); - while (timer.elapsed() < 10000 && lookupsDoneCounter < repeats*COUNT) { + while (timer.elapsed() < 60000 && lookupsDoneCounter < repeats*COUNT) { QTestEventLoop::instance().enterLoop(2); + //qDebug() << "t:" << timer.elapsed(); } QCOMPARE(lookupsDoneCounter, repeats*COUNT); } @@ -520,7 +609,7 @@ void tst_QHostInfo::cache() QVERIFY(result.addresses().isEmpty()); // the slot should have been called 2 times. - QVERIFY(lookupsDoneCounter == 2); + QCOMPARE(lookupsDoneCounter, 2); } void tst_QHostInfo::resultsReady(const QHostInfo &hi) @@ -531,5 +620,52 @@ void tst_QHostInfo::resultsReady(const QHostInfo &hi) QMetaObject::invokeMethod(&QTestEventLoop::instance(), "exitLoop", Qt::QueuedConnection); } +void tst_QHostInfo::abortHostLookup() +{ + //reset counter + lookupsDoneCounter = 0; + bool valid = false; + int id = -1; + QHostInfo result = qt_qhostinfo_lookup("qt.nokia.com", this, SLOT(resultsReady(QHostInfo)), &valid, &id); + QVERIFY(!valid); + //it is assumed that the DNS request/response in the backend is slower than it takes to call abort + QHostInfo::abortHostLookup(id); + QTestEventLoop::instance().enterLoop(5); + QCOMPARE(lookupsDoneCounter, 0); +} + +class LookupAborter : public QObject +{ + Q_OBJECT +public slots: + void abort() + { + QHostInfo::abortHostLookup(id); + QThread::currentThread()->quit(); + } +public: + int id; +}; + +void tst_QHostInfo::abortHostLookupInDifferentThread() +{ + //reset counter + lookupsDoneCounter = 0; + bool valid = false; + int id = -1; + QHostInfo result = qt_qhostinfo_lookup("qt.nokia.com", this, SLOT(resultsReady(QHostInfo)), &valid, &id); + QVERIFY(!valid); + QThread thread; + LookupAborter aborter; + aborter.id = id; + aborter.moveToThread(&thread); + connect(&thread, SIGNAL(started()), &aborter, SLOT(abort())); + //it is assumed that the DNS request/response in the backend is slower than it takes to schedule the thread and call abort + thread.start(); + QVERIFY(thread.wait(5000)); + QTestEventLoop::instance().enterLoop(5); + QCOMPARE(lookupsDoneCounter, 0); +} + QTEST_MAIN(tst_QHostInfo) #include "tst_qhostinfo.moc" diff --git a/tests/auto/qhttp/qhttp.pro b/tests/auto/qhttp/qhttp.pro index c0be518..49eebd5 100644 --- a/tests/auto/qhttp/qhttp.pro +++ b/tests/auto/qhttp/qhttp.pro @@ -5,22 +5,22 @@ SOURCES += tst_qhttp.cpp QT = core network wince*: { - webFiles.sources = webserver/* + webFiles.files = webserver/* webFiles.path = webserver - cgi.sources = webserver/cgi-bin/* + cgi.files = webserver/cgi-bin/* cgi.path = webserver/cgi-bin - addFiles.sources = rfc3252.txt trolltech + addFiles.files = rfc3252.txt trolltech addFiles.path = . - DEPLOYMENT = addFiles webFiles cgi + DEPLOYMENT += addFiles webFiles cgi DEFINES += SRCDIR=\\\"\\\" } else:symbian { - webFiles.sources = webserver/* + webFiles.files = webserver/* webFiles.path = webserver - cgi.sources = webserver/cgi-bin/* + cgi.files = webserver/cgi-bin/* cgi.path = webserver/cgi-bin - addFiles.sources = rfc3252.txt trolltech + addFiles.files = rfc3252.txt trolltech addFiles.path = . - DEPLOYMENT = addFiles webFiles cgi + DEPLOYMENT += addFiles webFiles cgi TARGET.CAPABILITY = NetworkServices } else:vxworks*: { DEFINES += SRCDIR=\\\"\\\" diff --git a/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp b/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp index 3b02a9b..20b6646 100644 --- a/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp +++ b/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp @@ -110,6 +110,8 @@ private Q_SLOTS: void getEmptyWithPipelining(); + void getAndEverythingShouldBePipelined(); + void getAndThenDeleteObject(); void getAndThenDeleteObject_data(); }; @@ -193,8 +195,8 @@ void tst_QHttpNetworkConnection::head() QCOMPARE(reply->statusCode(), statusCode); QCOMPARE(reply->reasonPhrase(), statusString); - // only check it if it is set - if (reply->contentLength() != -1) + // only check it if it is set and expected + if (reply->contentLength() != -1 && contentLength != -1) QCOMPARE(reply->contentLength(), qint64(contentLength)); QVERIFY(reply->isFinished()); @@ -217,8 +219,8 @@ void tst_QHttpNetworkConnection::get_data() QTest::newRow("success-internal") << "http://" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962 << 25962; QTest::newRow("success-external") << "http://" << "www.ietf.org" << "/rfc/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962 << 25962; - QTest::newRow("failure-path") << "http://" << QtNetworkSettings::serverName() << "/t" << ushort(80) << false << 404 << "Not Found" << -1 << 997 + QtNetworkSettings::serverName().size(); - QTest::newRow("failure-protocol") << "" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 400 << "Bad Request" << -1 << 930 + QtNetworkSettings::serverName().size(); + QTest::newRow("failure-path") << "http://" << QtNetworkSettings::serverName() << "/t" << ushort(80) << false << 404 << "Not Found" << -1 << -1; + QTest::newRow("failure-protocol") << "" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 400 << "Bad Request" << -1 << -1; } void tst_QHttpNetworkConnection::get() @@ -253,8 +255,8 @@ void tst_QHttpNetworkConnection::get() QCOMPARE(reply->statusCode(), statusCode); QCOMPARE(reply->reasonPhrase(), statusString); - // only check it if it is set - if (reply->contentLength() != -1) + // only check it if it is set and expected + if (reply->contentLength() != -1 && contentLength != -1) QCOMPARE(reply->contentLength(), qint64(contentLength)); stopWatch.start(); @@ -268,7 +270,12 @@ void tst_QHttpNetworkConnection::get() } while (!reply->isFinished()); QVERIFY(reply->isFinished()); - QCOMPARE(ba.size(), downloadSize); + //do not require server generated error pages to be a fixed size + if (downloadSize != -1) + QCOMPARE(ba.size(), downloadSize); + //but check against content length if it was sent + if (reply->contentLength() != -1) + QCOMPARE(ba.size(), (int)reply->contentLength()); delete reply; } @@ -383,7 +390,7 @@ void tst_QHttpNetworkConnection::post_data() QTest::addColumn<int>("downloadSize"); QTest::newRow("success-internal") << "http://" << QtNetworkSettings::serverName() << "/qtest/cgi-bin/echo.cgi" << ushort(80) << false << "7 bytes" << 200 << "OK" << 7 << 7; - QTest::newRow("failure-internal") << "http://" << QtNetworkSettings::serverName() << "/t" << ushort(80) << false << "Hello World" << 404 << "Not Found" << -1 << 997 + QtNetworkSettings::serverName().size(); + QTest::newRow("failure-internal") << "http://" << QtNetworkSettings::serverName() << "/t" << ushort(80) << false << "Hello World" << 404 << "Not Found" << -1 << -1; } void tst_QHttpNetworkConnection::post() @@ -427,13 +434,16 @@ void tst_QHttpNetworkConnection::post() QCOMPARE(reply->reasonPhrase(), statusString); qint64 cLen = reply->contentLength(); - if (cLen==-1) { - // HTTP 1.1 server may respond with chunked encoding and in that - // case contentLength is not present in reply -> verify that it is the case - QByteArray transferEnc = reply->headerField("Transfer-Encoding"); - QCOMPARE(transferEnc, QByteArray("chunked")); - } else { - QCOMPARE(cLen, qint64(contentLength)); + if (contentLength != -1) { + // only check the content length if test expected it to be set + if (cLen==-1) { + // HTTP 1.1 server may respond with chunked encoding and in that + // case contentLength is not present in reply -> verify that it is the case + QByteArray transferEnc = reply->headerField("Transfer-Encoding"); + QCOMPARE(transferEnc, QByteArray("chunked")); + } else { + QCOMPARE(cLen, qint64(contentLength)); + } } stopWatch.start(); @@ -447,7 +457,12 @@ void tst_QHttpNetworkConnection::post() } while (!reply->isFinished()); QVERIFY(reply->isFinished()); - QCOMPARE(ba.size(), downloadSize); + //don't require fixed size for generated error pages + if (downloadSize != -1) + QCOMPARE(ba.size(), downloadSize); + //but do compare with content length if possible + if (cLen != -1) + QCOMPARE(ba.size(), (int)cLen); delete reply; } @@ -628,7 +643,8 @@ void tst_QHttpNetworkConnection::compression() QCOMPARE(reply->statusCode(), statusCode); QCOMPARE(reply->reasonPhrase(), statusString); bool isLengthOk = (reply->contentLength() == qint64(contentLength) - || reply->contentLength() == qint64(downloadSize)); + || reply->contentLength() == qint64(downloadSize) + || reply->contentLength() == -1); //apache2 does not send content-length for compressed pages QVERIFY(isLengthOk); @@ -1020,6 +1036,52 @@ void tst_QHttpNetworkConnection::getEmptyWithPipelining() qDeleteAll(replies); } +class GetAndEverythingShouldBePipelinedReceiver : public QObject +{ + Q_OBJECT +public: + int receivedCount; + int requestCount; + GetAndEverythingShouldBePipelinedReceiver(int rq) : receivedCount(0),requestCount(rq) { } +public Q_SLOTS: + void finishedSlot() { + QHttpNetworkReply *reply = (QHttpNetworkReply*) sender(); + receivedCount++; + + if (receivedCount == requestCount) + QTestEventLoop::instance().exitLoop(); + } +}; + +void tst_QHttpNetworkConnection::getAndEverythingShouldBePipelined() +{ + quint16 requestCount = 100; + // use 1 connection. + QHttpNetworkConnection connection(1, QtNetworkSettings::serverName()); + QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"); + QList<QHttpNetworkRequest*> requests; + QList<QHttpNetworkReply*> replies; + + GetAndEverythingShouldBePipelinedReceiver receiver(requestCount); + + for (int i = 0; i < requestCount; i++) { + QHttpNetworkRequest *request = 0; + request = new QHttpNetworkRequest(url, QHttpNetworkRequest::Get); + request->setPipeliningAllowed(true); + requests.append(request); + QHttpNetworkReply *reply = connection.sendRequest(*request); + connect(reply, SIGNAL(finished()), &receiver, SLOT(finishedSlot())); + replies.append(reply); + } + QTestEventLoop::instance().enterLoop(40); + QVERIFY(!QTestEventLoop::instance().timeout()); + + qDeleteAll(requests); + qDeleteAll(replies); + +} + + void tst_QHttpNetworkConnection::getAndThenDeleteObject_data() { QTest::addColumn<bool>("replyFirst"); diff --git a/tests/auto/qhttpsocketengine/qhttpsocketengine.pro b/tests/auto/qhttpsocketengine/qhttpsocketengine.pro index d76ebb6..6df6192 100644 --- a/tests/auto/qhttpsocketengine/qhttpsocketengine.pro +++ b/tests/auto/qhttpsocketengine/qhttpsocketengine.pro @@ -2,7 +2,7 @@ load(qttest_p4) SOURCES += tst_qhttpsocketengine.cpp -include(../qnativesocketengine/qsocketengine.pri) +include(../platformsocketengine/platformsocketengine.pri) MOC_DIR=tmp diff --git a/tests/auto/qicoimageformat/qicoimageformat.pro b/tests/auto/qicoimageformat/qicoimageformat.pro index cabab3f..c150c9a 100644 --- a/tests/auto/qicoimageformat/qicoimageformat.pro +++ b/tests/auto/qicoimageformat/qicoimageformat.pro @@ -3,21 +3,21 @@ SOURCES+= tst_qicoimageformat.cpp wince*: { DEFINES += SRCDIR=\\\".\\\" - addFiles.sources = icons + addFiles.files = icons addFiles.path = . CONFIG(debug, debug|release):{ - addPlugins.sources = $$QT_BUILD_TREE/plugins/imageformats/qico4d.dll + addPlugins.files = $$QT_BUILD_TREE/plugins/imageformats/qico4d.dll } else { - addPlugins.sources = $$QT_BUILD_TREE/plugins/imageformats/qico4.dll + addPlugins.files = $$QT_BUILD_TREE/plugins/imageformats/qico4.dll } addPlugins.path = imageformats DEPLOYMENT += addFiles addPlugins } else:symbian { - addFiles.sources = icons + addFiles.files = icons addFiles.path = . DEPLOYMENT += addFiles qt_not_deployed { - addPlugins.sources = qico.dll + addPlugins.files = qico.dll addPlugins.path = imageformats DEPLOYMENT += addPlugins } diff --git a/tests/auto/qicon/qicon.pro b/tests/auto/qicon/qicon.pro index 68b888d..975aaf2 100644 --- a/tests/auto/qicon/qicon.pro +++ b/tests/auto/qicon/qicon.pro @@ -5,10 +5,10 @@ RESOURCES = tst_qicon.qrc wince* { QT += xml svg - addFiles.sources += $$_PRO_FILE_PWD_/*.png - addFiles.sources += $$_PRO_FILE_PWD_/*.svg - addFiles.sources += $$_PRO_FILE_PWD_/*.svgz - addFiles.sources += $$_PRO_FILE_PWD_/tst_qicon.cpp + addFiles.files += $$_PRO_FILE_PWD_/*.png + addFiles.files += $$_PRO_FILE_PWD_/*.svg + addFiles.files += $$_PRO_FILE_PWD_/*.svgz + addFiles.files += $$_PRO_FILE_PWD_/tst_qicon.cpp addFiles.path = . DEPLOYMENT += addFiles @@ -16,11 +16,11 @@ wince* { DEFINES += SRCDIR=\\\".\\\" } else:symbian { QT += xml svg - addFiles.sources = *.png tst_qicon.cpp *.svg *.svgz + addFiles.files = *.png tst_qicon.cpp *.svg *.svgz addFiles.path = . DEPLOYMENT += addFiles qt_not_deployed { - plugins.sources = qsvgicon.dll + plugins.files = qsvgicon.dll plugins.path = iconengines DEPLOYMENT += plugins } diff --git a/tests/auto/qicon/tst_qicon.cpp b/tests/auto/qicon/tst_qicon.cpp index b8682cf..cd3f84f 100644 --- a/tests/auto/qicon/tst_qicon.cpp +++ b/tests/auto/qicon/tst_qicon.cpp @@ -70,6 +70,7 @@ private slots: void actualSize2(); void svgActualSize(); void isNull(); + void swap(); void bestMatch(); void cacheKey(); void detach(); @@ -259,6 +260,21 @@ void tst_QIcon::isNull() { QVERIFY(iconSupportedFormat.actualSize(QSize(32, 32)).isValid()); } +void tst_QIcon::swap() +{ + QPixmap p1(1, 1), p2(2, 2); + p1.fill(Qt::black); + p2.fill(Qt::black); + + QIcon i1(p1), i2(p2); + const qint64 i1k = i1.cacheKey(); + const qint64 i2k = i2.cacheKey(); + QVERIFY(i1k != i2k); + i1.swap(i2); + QCOMPARE(i1.cacheKey(), i2k); + QCOMPARE(i2.cacheKey(), i1k); +} + void tst_QIcon::bestMatch() { QPixmap p1(1, 1); diff --git a/tests/auto/qidentityproxymodel/qidentityproxymodel.pro b/tests/auto/qidentityproxymodel/qidentityproxymodel.pro new file mode 100644 index 0000000..f529e20 --- /dev/null +++ b/tests/auto/qidentityproxymodel/qidentityproxymodel.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +INCLUDEPATH += $$PWD/../modeltest + +SOURCES += tst_qidentityproxymodel.cpp ../modeltest/dynamictreemodel.cpp ../modeltest/modeltest.cpp +HEADERS += ../modeltest/dynamictreemodel.h ../modeltest/modeltest.h diff --git a/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp new file mode 100644 index 0000000..7a3a8e5 --- /dev/null +++ b/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp @@ -0,0 +1,334 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include "../../shared/util.h" + +#include <QtCore> +#include <QtGui> + +#include "dynamictreemodel.h" +#include "qidentityproxymodel.h" + +//TESTED CLASS= +//TESTED_FILES= + +Q_DECLARE_METATYPE(QModelIndex) + +class tst_QIdentityProxyModel : public QObject +{ + Q_OBJECT + +public: + + tst_QIdentityProxyModel(); + virtual ~tst_QIdentityProxyModel(); + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void insertRows(); + void removeRows(); + void moveRows(); + void reset(); + +protected: + void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex()); + +private: + QStandardItemModel *m_model; + QIdentityProxyModel *m_proxy; +}; + +tst_QIdentityProxyModel::tst_QIdentityProxyModel() + : m_model(0), m_proxy(0) +{ + +} + +tst_QIdentityProxyModel::~tst_QIdentityProxyModel() +{ + +} + +void tst_QIdentityProxyModel::initTestCase() +{ + qRegisterMetaType<QModelIndex>("QModelIndex"); + + m_model = new QStandardItemModel(0, 1); + m_proxy = new QIdentityProxyModel(); +} + +void tst_QIdentityProxyModel::cleanupTestCase() +{ + delete m_proxy; + delete m_model; +} + +void tst_QIdentityProxyModel::init() +{ +} + +void tst_QIdentityProxyModel::cleanup() +{ + m_model->clear(); + m_model->insertColumns(0, 1); +} + +void tst_QIdentityProxyModel::verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent) +{ + const int rows = model->rowCount(parent); + const int columns = model->columnCount(parent); + const QModelIndex proxyParent = m_proxy->mapFromSource(parent); + + QVERIFY(m_proxy->mapToSource(proxyParent) == parent); + QVERIFY(rows == m_proxy->rowCount(proxyParent)); + QVERIFY(columns == m_proxy->columnCount(proxyParent)); + + for (int row = 0; row < rows; ++row) { + for (int column = 0; column < columns; ++column) { + const QModelIndex idx = model->index(row, column, parent); + const QModelIndex proxyIdx = m_proxy->mapFromSource(idx); + QVERIFY(proxyIdx.model() == m_proxy); + QVERIFY(m_proxy->mapToSource(proxyIdx) == idx); + QVERIFY(proxyIdx.isValid()); + QVERIFY(proxyIdx.row() == row); + QVERIFY(proxyIdx.column() == column); + QVERIFY(proxyIdx.parent() == proxyParent); + QVERIFY(proxyIdx.data() == idx.data()); + QVERIFY(proxyIdx.flags() == idx.flags()); + const int childCount = m_proxy->rowCount(proxyIdx); + const bool hasChildren = m_proxy->hasChildren(proxyIdx); + QVERIFY(model->hasChildren(idx) == hasChildren); + QVERIFY((childCount > 0) == hasChildren); + + if (hasChildren) + verifyIdentity(model, idx); + } + } +} + +/* + tests +*/ + +void tst_QIdentityProxyModel::insertRows() +{ + QStandardItem *parentItem = m_model->invisibleRootItem(); + for (int i = 0; i < 4; ++i) { + QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); + parentItem->appendRow(item); + parentItem = item; + } + + m_proxy->setSourceModel(m_model); + + 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))); + + QStandardItem *item = new QStandardItem(QString("new item")); + parentItem->appendRow(item); + + QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); + QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + + QVERIFY(modelBeforeSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>())); + QVERIFY(modelBeforeSpy.first().at(1) == proxyBeforeSpy.first().at(1)); + QVERIFY(modelBeforeSpy.first().at(2) == proxyBeforeSpy.first().at(2)); + + QVERIFY(modelAfterSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyAfterSpy.first().first().value<QModelIndex>())); + QVERIFY(modelAfterSpy.first().at(1) == proxyAfterSpy.first().at(1)); + QVERIFY(modelAfterSpy.first().at(2) == proxyAfterSpy.first().at(2)); + + verifyIdentity(m_model); + +} + +void tst_QIdentityProxyModel::removeRows() +{ + QStandardItem *parentItem = m_model->invisibleRootItem(); + for (int i = 0; i < 4; ++i) { + QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); + parentItem->appendRow(item); + parentItem = item; + } + + m_proxy->setSourceModel(m_model); + + 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))); + + const QModelIndex topLevel = m_model->index(0, 0, QModelIndex()); + const QModelIndex secondLevel = m_model->index(0, 0, topLevel); + const QModelIndex thirdLevel = m_model->index(0, 0, secondLevel); + + QVERIFY(thirdLevel.isValid()); + + m_model->removeRow(0, secondLevel); + + QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); + QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + + QVERIFY(modelBeforeSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>())); + QVERIFY(modelBeforeSpy.first().at(1) == proxyBeforeSpy.first().at(1)); + QVERIFY(modelBeforeSpy.first().at(2) == proxyBeforeSpy.first().at(2)); + + QVERIFY(modelAfterSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyAfterSpy.first().first().value<QModelIndex>())); + QVERIFY(modelAfterSpy.first().at(1) == proxyAfterSpy.first().at(1)); + QVERIFY(modelAfterSpy.first().at(2) == proxyAfterSpy.first().at(2)); + + verifyIdentity(m_model); +} + +void tst_QIdentityProxyModel::moveRows() +{ + DynamicTreeModel model; + + { + ModelInsertCommand insertCommand(&model); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + { + ModelInsertCommand insertCommand(&model); + insertCommand.setAncestorRowNumbers(QList<int>() << 5); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + + m_proxy->setSourceModel(&model); + + 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))); + + { + ModelMoveCommand moveCommand(&model, 0); + moveCommand.setAncestorRowNumbers(QList<int>() << 5); + moveCommand.setStartRow(3); + moveCommand.setEndRow(4); + moveCommand.setDestRow(1); + moveCommand.doCommand(); + } + + QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); + QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + + QVERIFY(modelBeforeSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>())); + QVERIFY(modelBeforeSpy.first().at(1) == proxyBeforeSpy.first().at(1)); + QVERIFY(modelBeforeSpy.first().at(2) == proxyBeforeSpy.first().at(2)); + QVERIFY(modelBeforeSpy.first().at(3).value<QModelIndex>() == m_proxy->mapToSource(proxyBeforeSpy.first().at(3).value<QModelIndex>())); + QVERIFY(modelBeforeSpy.first().at(4) == proxyBeforeSpy.first().at(4)); + + QVERIFY(modelAfterSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyAfterSpy.first().first().value<QModelIndex>())); + QVERIFY(modelAfterSpy.first().at(1) == proxyAfterSpy.first().at(1)); + QVERIFY(modelAfterSpy.first().at(2) == proxyAfterSpy.first().at(2)); + QVERIFY(modelAfterSpy.first().at(3).value<QModelIndex>() == m_proxy->mapToSource(proxyAfterSpy.first().at(3).value<QModelIndex>())); + QVERIFY(modelAfterSpy.first().at(4) == proxyAfterSpy.first().at(4)); + + verifyIdentity(&model); + + m_proxy->setSourceModel(0); +} + +void tst_QIdentityProxyModel::reset() +{ + DynamicTreeModel model; + + { + ModelInsertCommand insertCommand(&model); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + { + ModelInsertCommand insertCommand(&model); + insertCommand.setAncestorRowNumbers(QList<int>() << 5); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + + m_proxy->setSourceModel(&model); + + verifyIdentity(&model); + + QSignalSpy modelBeforeSpy(&model, SIGNAL(modelAboutToBeReset())); + QSignalSpy modelAfterSpy(&model, SIGNAL(modelReset())); + QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(modelAboutToBeReset())); + QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(modelReset())); + + { + ModelResetCommandFixed resetCommand(&model, 0); + resetCommand.setAncestorRowNumbers(QList<int>() << 5); + resetCommand.setStartRow(3); + resetCommand.setEndRow(4); + resetCommand.setDestRow(1); + resetCommand.doCommand(); + } + + QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); + QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + + verifyIdentity(&model); + m_proxy->setSourceModel(0); +} + +QTEST_MAIN(tst_QIdentityProxyModel) +#include "tst_qidentityproxymodel.moc" diff --git a/tests/auto/qimage/qimage.pro b/tests/auto/qimage/qimage.pro index 6469211..798c82e 100644 --- a/tests/auto/qimage/qimage.pro +++ b/tests/auto/qimage/qimage.pro @@ -2,17 +2,17 @@ load(qttest_p4) SOURCES += tst_qimage.cpp wince*: { - addImages.sources = images/* + addImages.files = images/* addImages.path = images DEPLOYMENT += addImages DEFINES += SRCDIR=\\\".\\\" } else:symbian { TARGET.EPOCHEAPSIZE = 0x200000 0x800000 - addImages.sources = images/* + addImages.files = images/* addImages.path = images DEPLOYMENT += addImages qt_not_deployed { - imagePlugins.sources = qjpeg.dll qgif.dll qmng.dll qtiff.dll qico.dll + imagePlugins.files = qjpeg.dll qgif.dll qmng.dll qtiff.dll qico.dll imagePlugins.path = imageformats DEPLOYMENT += imagePlugins } diff --git a/tests/auto/qimage/tst_qimage.cpp b/tests/auto/qimage/tst_qimage.cpp index f74315b..6f44033 100644 --- a/tests/auto/qimage/tst_qimage.cpp +++ b/tests/auto/qimage/tst_qimage.cpp @@ -59,6 +59,7 @@ #endif Q_DECLARE_METATYPE(QImage::Format) +Q_DECLARE_METATYPE(Qt::GlobalColor) class tst_QImage : public QObject { @@ -68,6 +69,7 @@ public: tst_QImage(); private slots: + void swap(); void create(); void createInvalidXPM(); void createFromUChar(); @@ -140,6 +142,11 @@ private slots: void compareIndexed(); + void fillColor_data(); + void fillColor(); + + void fillColorWithAlpha(); + void rgbSwapped_data(); void rgbSwapped(); @@ -152,6 +159,20 @@ tst_QImage::tst_QImage() { } +void tst_QImage::swap() +{ + QImage i1( 16, 16, QImage::Format_RGB32 ), i2( 32, 32, QImage::Format_RGB32 ); + i1.fill( Qt::white ); + i2.fill( Qt::black ); + const qint64 i1k = i1.cacheKey(); + const qint64 i2k = i2.cacheKey(); + i1.swap(i2); + QCOMPARE(i1.cacheKey(), i2k); + QCOMPARE(i1.size(), QSize(32,32)); + QCOMPARE(i2.cacheKey(), i1k); + QCOMPARE(i2.size(), QSize(16,16)); +} + // Test if QImage (or any functions called from QImage) throws an // exception when creating an extremely large image. // QImage::create() should return "false" in this case. @@ -1826,6 +1847,112 @@ void tst_QImage::compareIndexed() QCOMPARE(img, imgInverted); } +void tst_QImage::fillColor_data() +{ + QTest::addColumn<QImage::Format>("format"); + QTest::addColumn<Qt::GlobalColor>("color"); + QTest::addColumn<uint>("pixelValue"); + + QTest::newRow("Mono, color0") << QImage::Format_Mono << Qt::color0 << 0u; + QTest::newRow("Mono, color1") << QImage::Format_Mono << Qt::color1 << 1u; + + QTest::newRow("MonoLSB, color0") << QImage::Format_MonoLSB << Qt::color0 << 0u; + QTest::newRow("MonoLSB, color1") << QImage::Format_MonoLSB << Qt::color1 << 1u; + + const char *names[] = { + "Indexed8", + "RGB32", + "ARGB32", + "ARGB32pm", + "RGB16", + "ARGB8565pm", + "RGB666", + "ARGB6666pm", + "RGB555", + "ARGB8555pm", + "RGB888", + "RGB444", + "ARGB4444pm", + 0 + }; + + QImage::Format formats[] = { + QImage::Format_Indexed8, + QImage::Format_RGB32, + QImage::Format_ARGB32, + QImage::Format_ARGB32_Premultiplied, + QImage::Format_RGB16, + QImage::Format_ARGB8565_Premultiplied, + QImage::Format_RGB666, + QImage::Format_ARGB6666_Premultiplied, + QImage::Format_RGB555, + QImage::Format_ARGB8555_Premultiplied, + QImage::Format_RGB888, + QImage::Format_RGB444, + QImage::Format_ARGB4444_Premultiplied + }; + + for (int i=0; names[i] != 0; ++i) { + QByteArray name; + name.append(names[i]).append(", "); + + QTest::newRow(QByteArray(name).append("black").constData()) << formats[i] << Qt::black << 0xff000000; + QTest::newRow(QByteArray(name).append("white").constData()) << formats[i] << Qt::white << 0xffffffff; + QTest::newRow(QByteArray(name).append("red").constData()) << formats[i] << Qt::red << 0xffff0000; + QTest::newRow(QByteArray(name).append("green").constData()) << formats[i] << Qt::green << 0xff00ff00; + QTest::newRow(QByteArray(name).append("blue").constData()) << formats[i] << Qt::blue << 0xff0000ff; + } + + QTest::newRow("RGB16, transparent") << QImage::Format_RGB16 << Qt::transparent << 0xff000000; + QTest::newRow("RGB32, transparent") << QImage::Format_RGB32 << Qt::transparent << 0xff000000; + QTest::newRow("ARGB32, transparent") << QImage::Format_ARGB32 << Qt::transparent << 0x00000000u; + QTest::newRow("ARGB32pm, transparent") << QImage::Format_ARGB32_Premultiplied << Qt::transparent << 0x00000000u; +} + +void tst_QImage::fillColor() +{ + QFETCH(QImage::Format, format); + QFETCH(Qt::GlobalColor, color); + QFETCH(uint, pixelValue); + + QImage image(1, 1, format); + + if (image.depth() == 8) { + QVector<QRgb> table; + table << 0xff000000; + table << 0xffffffff; + table << 0xffff0000; + table << 0xff00ff00; + table << 0xff0000ff; + image.setColorTable(table); + } + + image.fill(color); + if (image.depth() == 1) { + QCOMPARE(image.pixelIndex(0, 0), (int) pixelValue); + } else { + QCOMPARE(image.pixel(0, 0), pixelValue); + } + + image.fill(QColor(color)); + if (image.depth() == 1) { + QCOMPARE(image.pixelIndex(0, 0), (int) pixelValue); + } else { + QCOMPARE(image.pixel(0, 0), pixelValue); + } +} + +void tst_QImage::fillColorWithAlpha() +{ + QImage argb32(1, 1, QImage::Format_ARGB32); + argb32.fill(QColor(255, 0, 0, 127)); + QCOMPARE(argb32.pixel(0, 0), qRgba(255, 0, 0, 127)); + + QImage argb32pm(1, 1, QImage::Format_ARGB32_Premultiplied); + argb32pm.fill(QColor(255, 0, 0, 127)); + QCOMPARE(argb32pm.pixel(0, 0), 0x7f7f0000u); +} + void tst_QImage::rgbSwapped_data() { QTest::addColumn<QImage::Format>("format"); diff --git a/tests/auto/qimagereader/images/txts.png b/tests/auto/qimagereader/images/txts.png Binary files differnew file mode 100755 index 0000000..99be1eb --- /dev/null +++ b/tests/auto/qimagereader/images/txts.png diff --git a/tests/auto/qimagereader/qimagereader.pro b/tests/auto/qimagereader/qimagereader.pro index f8fc7fa..827819d 100644 --- a/tests/auto/qimagereader/qimagereader.pro +++ b/tests/auto/qimagereader/qimagereader.pro @@ -17,10 +17,10 @@ win32-msvc.net:QMAKE_CXXFLAGS -= -Zm300 win32-msvc.net:QMAKE_CXXFLAGS += -Zm1100 wince*: { - images.sources = images + images.files = images images.path = . - imagePlugins.sources = $$QT_BUILD_TREE/plugins/imageformats/*.dll + imagePlugins.files = $$QT_BUILD_TREE/plugins/imageformats/*.dll imagePlugins.path = imageformats DEPLOYMENT += images imagePlugins @@ -28,13 +28,13 @@ wince*: { } symbian: { - images.sources = images + images.files = images images.path = . DEPLOYMENT += images qt_not_deployed { - imagePlugins.sources = qjpeg.dll qgif.dll qmng.dll + imagePlugins.files = qjpeg.dll qgif.dll qmng.dll imagePlugins.path = imageformats DEPLOYMENT += imagePlugins diff --git a/tests/auto/qimagereader/qimagereader.qrc b/tests/auto/qimagereader/qimagereader.qrc index 5536b38..632b73a 100644 --- a/tests/auto/qimagereader/qimagereader.qrc +++ b/tests/auto/qimagereader/qimagereader.qrc @@ -64,5 +64,6 @@ <file>images/corrupt.svg</file> <file>images/corrupt.svgz</file> <file>images/qtbug13653-no_eoi.jpg</file> + <file>images/txts.png</file> </qresource> </RCC> diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp index b8a07b4..5c65cb3 100644 --- a/tests/auto/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/qimagereader/tst_qimagereader.cpp @@ -182,6 +182,12 @@ private slots: void saveFormat_data(); void saveFormat(); + + void readText_data(); + void readText(); + + void preserveTexts_data(); + void preserveTexts(); }; static const QLatin1String prefix(SRCDIR "/images/"); @@ -1104,6 +1110,11 @@ void tst_QImageReader::readFromDevice() QCOMPARE(image1, expectedImage); } +#if defined (Q_OS_SYMBIAN) && defined (__WINS__) + //the emulator hangs in socket write (this is a test bug, it assumes the TCP stack can accept a whole image to its buffers) + if(imageData.size() > 16384) + QSKIP("image larger than socket buffer (test needs to be rewritten)", SkipSingle); +#endif Server server(imageData); QEventLoop loop; connect(&server, SIGNAL(ready()), &loop, SLOT(quit())); @@ -1255,7 +1266,10 @@ void tst_QImageReader::devicePosition() buf.seek(preLen); QImageReader reader(&buf, format); QCOMPARE(expected, reader.read()); - if (format != "ppm" && format != "gif") // Known not to work + if (format != "ppm" && + format != "pgm" && + format != "pbm" && + format != "gif") // Known not to work QCOMPARE(buf.pos(), qint64(preLen+imageDataSize)); } @@ -1957,5 +1971,89 @@ void tst_QImageReader::saveFormat() } +void tst_QImageReader::readText_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::addColumn<QString>("key"); + QTest::addColumn<QString>("text"); + + QTest::newRow("png, tEXt before img") << "txts.png" << "Title" << "PNG"; + QTest::newRow("png, zTXt before img") << "txts.png" << "Comment" << "Some compressed text."; + QTest::newRow("png, tEXt after img") << "txts.png" << "Disclaimer" << "For testing only."; + QTest::newRow("png, zTXt after img") << "txts.png" << "Description" << "Rendered by Persistence of Vision (tm) Ray Tracer"; +} + + +void tst_QImageReader::readText() +{ + QFETCH(QString, fileName); + QFETCH(QString, key); + QFETCH(QString, text); + + QImage img(prefix + fileName); + QVERIFY(img.textKeys().contains(key)); + QCOMPARE(img.text(key), text); +} + + +void tst_QImageReader::preserveTexts_data() +{ + QTest::addColumn<QString>("text"); + + QTest::newRow("Simple") << "simpletext"; + QTest::newRow("Whitespace") << " A text with whitespace "; + QTest::newRow("Newline") << "A text\nwith newlines\n"; + QTest::newRow("Double newlines") << "A text\n\nwith double newlines\n\n"; + QTest::newRow("Long") << QString("A rather long text, at least after many repetitions. ").repeated(100); + QString latin1set; + int c; + for(c = 0x20; c <= 0x7e; c++) + latin1set.append(QLatin1Char(c)); + for(c = 0xa0; c <= 0xff; c++) + latin1set.append(QLatin1Char(c)); + QTest::newRow("All Latin1 chars") << latin1set; + +#if 0 + // Depends on iTXt support in libpng + QTest::newRow("Multibyte string") << QString::fromUtf8("\341\233\222\341\233\226\341\232\251\341\232\271\341\232\242\341\233\232\341\232\240"); +#endif +} + + +void tst_QImageReader::preserveTexts() +{ + QFETCH(QString, text); + QString key("testkey"); + QString key2("testkey2"); + QString text2("Some other text."); + QString key3("testkey3"); + QString text3("Some more other text."); + + QImage img(":/images/kollada.png"); + img.setText(key, text); + img.setText(key2, text2); + QBuffer buf; + buf.open(QIODevice::WriteOnly); + QVERIFY(img.save(&buf, "png")); + buf.close(); + QImage stored = QImage::fromData(buf.buffer(), "png"); + QCOMPARE(stored.text(key), text); + QCOMPARE(stored.text(key2), text2); + + QImage img2(":/images/kollada.png"); + img2.setText(key3, text3); + QBuffer buf2; + QImageWriter w(&buf2, "png"); + w.setText(key, text); + w.setText(key2, text2); + QVERIFY(w.write(img2)); + buf2.close(); + QImageReader r(&buf2, "png"); + QCOMPARE(r.text(key), text.simplified()); + QCOMPARE(r.text(key2), text2.simplified()); + QCOMPARE(r.text(key3), text3.simplified()); +} + + QTEST_MAIN(tst_QImageReader) #include "tst_qimagereader.moc" diff --git a/tests/auto/qimagewriter/qimagewriter.pro b/tests/auto/qimagewriter/qimagewriter.pro index f25472f..bab2419 100644 --- a/tests/auto/qimagewriter/qimagewriter.pro +++ b/tests/auto/qimagewriter/qimagewriter.pro @@ -6,16 +6,16 @@ win32-msvc:QMAKE_CXXFLAGS -= -Zm200 win32-msvc:QMAKE_CXXFLAGS += -Zm800 wince*: { - addFiles.sources = images\\*.* + addFiles.files = images\\*.* addFiles.path = images DEPLOYMENT += addFiles DEFINES += SRCDIR=\\\".\\\" } else:symbian { - addFiles.sources = images\\*.* + addFiles.files = images\\*.* addFiles.path = images DEPLOYMENT += addFiles qt_not_deployed { - imagePlugins.sources = qjpeg.dll qtiff.dll + imagePlugins.files = qjpeg.dll qtiff.dll imagePlugins.path = imageformats DEPLOYMENT += imagePlugins } diff --git a/tests/auto/qinputdialog/tst_qinputdialog.cpp b/tests/auto/qinputdialog/tst_qinputdialog.cpp index 2587dbc..5c74ab2 100644 --- a/tests/auto/qinputdialog/tst_qinputdialog.cpp +++ b/tests/auto/qinputdialog/tst_qinputdialog.cpp @@ -193,12 +193,12 @@ void testGetNumeric(QInputDialog *dialog, SpinBoxType * = 0, ValueType * = 0) void testGetText(QInputDialog *dialog) { QLineEdit *ledit = qFindChild<QLineEdit *>(dialog); - Q_ASSERT(ledit); + QVERIFY(ledit); QDialogButtonBox *bbox = qFindChild<QDialogButtonBox *>(dialog); - Q_ASSERT(bbox); + QVERIFY(bbox); QPushButton *okButton = bbox->button(QDialogButtonBox::Ok); - Q_ASSERT(okButton); + QVERIFY(okButton); QVERIFY(ledit->hasAcceptableInput()); QCOMPARE(ledit->selectedText(), ledit->text()); @@ -211,12 +211,12 @@ void testGetText(QInputDialog *dialog) void testGetItem(QInputDialog *dialog) { QComboBox *cbox = qFindChild<QComboBox *>(dialog); - Q_ASSERT(cbox); + QVERIFY(cbox); QDialogButtonBox *bbox = qFindChild<QDialogButtonBox *>(dialog); - Q_ASSERT(bbox); + QVERIFY(bbox); QPushButton *okButton = bbox->button(QDialogButtonBox::Ok); - Q_ASSERT(okButton); + QVERIFY(okButton); QVERIFY(okButton->isEnabled()); const int origIndex = cbox->currentIndex(); @@ -249,7 +249,7 @@ void tst_QInputDialog::timerEvent(QTimerEvent *event) { killTimer(event->timerId()); QInputDialog *dialog = qFindChild<QInputDialog *>(parent); - Q_ASSERT(dialog); + QVERIFY(dialog); if (testFunc) testFunc(dialog); dialog->done(doneCode); // cause static function call to return @@ -270,7 +270,7 @@ void tst_QInputDialog::getInteger() { QFETCH(int, min); QFETCH(int, max); - Q_ASSERT(min < max); + QVERIFY(min < max); parent = new QWidget; doneCode = QDialog::Accepted; testFunc = &tst_QInputDialog::testFuncGetInteger; @@ -310,7 +310,7 @@ void tst_QInputDialog::getDouble() QFETCH(double, min); QFETCH(double, max); QFETCH(int, decimals); - Q_ASSERT(min < max && decimals >= 0 && decimals <= 13); + QVERIFY(min < max && decimals >= 0 && decimals <= 13); parent = new QWidget; doneCode = QDialog::Accepted; testFunc = &tst_QInputDialog::testFuncGetDouble; diff --git a/tests/auto/qiodevice/qiodevice.pro b/tests/auto/qiodevice/qiodevice.pro index 716cdce..29b0a05 100644 --- a/tests/auto/qiodevice/qiodevice.pro +++ b/tests/auto/qiodevice/qiodevice.pro @@ -4,14 +4,14 @@ SOURCES += tst_qiodevice.cpp QT = core network wince*: { - addFiles.sources = tst_qiodevice.cpp + addFiles.files = tst_qiodevice.cpp addFiles.path = . DEPLOYMENT += addFiles DEFINES += SRCDIR=\\\"\\\" !wince50standard-x86-msvc2005: DEFINES += WINCE_EMULATOR_TEST=1 } else:symbian { # SRCDIR defined in code in symbian - addFiles.sources = tst_qiodevice.cpp + addFiles.files = tst_qiodevice.cpp addFiles.path = . DEPLOYMENT += addFiles TARGET.CAPABILITY = NetworkServices diff --git a/tests/auto/qiodevice/tst_qiodevice.cpp b/tests/auto/qiodevice/tst_qiodevice.cpp index bcc07a1..0af5036 100644 --- a/tests/auto/qiodevice/tst_qiodevice.cpp +++ b/tests/auto/qiodevice/tst_qiodevice.cpp @@ -81,6 +81,8 @@ private slots: void readLine2_data(); void readLine2(); + + void peekBug(); }; // Testing get/set functions @@ -591,5 +593,62 @@ void tst_QIODevice::readLine2() } } + +class PeekBug : public QIODevice { + Q_OBJECT +public: + char alphabet[27]; + qint64 counter; + PeekBug() : QIODevice(), counter(0) { + memcpy(alphabet,"abcdefghijklmnopqrstuvqxyz",27); + }; + qint64 readData(char *data, qint64 maxlen) { + qint64 pos = 0; + while (pos < maxlen) { + *(data + pos) = alphabet[counter]; + pos++; + counter++; + if (counter == 26) + counter = 0; + } + return maxlen; + } + qint64 writeData(const char *data, qint64 maxlen) { + return -1; + } + +}; + +// This is a testcase for the bug fixed with bd287865 +void tst_QIODevice::peekBug() +{ + PeekBug peekBug; + peekBug.open(QIODevice::ReadOnly | QIODevice::Unbuffered); + + char onetwo[2]; + peekBug.peek(onetwo, 2); + QCOMPARE(onetwo[0], 'a'); + QCOMPARE(onetwo[1], 'b'); + + peekBug.read(onetwo, 1); + QCOMPARE(onetwo[0], 'a'); + + peekBug.peek(onetwo, 2); + QCOMPARE(onetwo[0], 'b'); + QCOMPARE(onetwo[1], 'c'); + + peekBug.read(onetwo, 1); + QCOMPARE(onetwo[0], 'b'); + peekBug.read(onetwo, 1); + QCOMPARE(onetwo[0], 'c'); + peekBug.read(onetwo, 1); + QCOMPARE(onetwo[0], 'd'); + + peekBug.peek(onetwo, 2); + QCOMPARE(onetwo[0], 'e'); + QCOMPARE(onetwo[1], 'f'); + +} + QTEST_MAIN(tst_QIODevice) #include "tst_qiodevice.moc" diff --git a/tests/auto/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/qitemdelegate/tst_qitemdelegate.cpp index 0b49854..3dcf54a 100644 --- a/tests/auto/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/qitemdelegate/tst_qitemdelegate.cpp @@ -235,6 +235,7 @@ private slots: void enterKey(); void task257859_finalizeEdit(); + void QTBUG4435_keepSelectionOnCheck(); }; @@ -1168,6 +1169,31 @@ void tst_QItemDelegate::task257859_finalizeEdit() QTRY_VERIFY(!editor); } +void tst_QItemDelegate::QTBUG4435_keepSelectionOnCheck() +{ + QStandardItemModel model(3, 1); + for (int i = 0; i < 3; ++i) { + QStandardItem *item = new QStandardItem(QLatin1String("Item ") + QString::number(i)); + item->setCheckable(true); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + model.setItem(i, item); + } + QTableView view; + view.setModel(&model); + view.setItemDelegate(new TestItemDelegate); + view.show(); + view.selectAll(); + QTest::qWaitForWindowShown(&view); + QStyleOptionViewItem option; + option.rect = view.visualRect(model.index(0, 0)); + const int checkMargin = qApp->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, 0) + 1; + QPoint pos = qApp->style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &option, 0).center() + + QPoint(checkMargin, 0); + QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, pos); + QTRY_VERIFY(view.selectionModel()->isColumnSelected(0, QModelIndex())); + QCOMPARE(model.item(0)->checkState(), Qt::Checked); +} + // ### _not_ covered: diff --git a/tests/auto/qitemmodel/modelstotest.cpp b/tests/auto/qitemmodel/modelstotest.cpp index 59a9d38..772f72b 100644 --- a/tests/auto/qitemmodel/modelstotest.cpp +++ b/tests/auto/qitemmodel/modelstotest.cpp @@ -227,7 +227,6 @@ QAbstractItemModel *ModelsToTest::createModel(const QString &modelType) return widget->model(); } - Q_ASSERT(false); return 0; } @@ -309,15 +308,23 @@ QModelIndex ModelsToTest::populateTestArea(QAbstractItemModel *model) */ } QModelIndex returnIndex = model->index(0,0); - Q_ASSERT(returnIndex.isValid()); + if (!returnIndex.isValid()) + qFatal("%s: model index to be returned is invalid", Q_FUNC_INFO); return returnIndex; } if (QDirModel *dirModel = qobject_cast<QDirModel *>(model)) { - // Don't risk somthing bad happening, assert if this fails - Q_ASSERT(QDir(QDir::currentPath()).mkdir("test")); - for (int i = 0; i < 26; ++i) - Q_ASSERT(QDir(QDir::currentPath()).mkdir(QString("test/foo_%1").arg(i))); + if (!QDir::current().mkdir("test")) + qFatal("%s: cannot create directory %s", + Q_FUNC_INFO, + qPrintable(QDir::toNativeSeparators(QDir::currentPath()+"/test"))); + for (int i = 0; i < 26; ++i) { + QString subdir = QString("test/foo_%1").arg(i); + if (!QDir::current().mkdir(subdir)) + qFatal("%s: cannot create directory %s", + Q_FUNC_INFO, + qPrintable(QDir::toNativeSeparators(QDir::currentPath()+"/"+subdir))); + } return dirModel->index(QDir::currentPath()+"/test"); } @@ -373,7 +380,7 @@ QModelIndex ModelsToTest::populateTestArea(QAbstractItemModel *model) return QModelIndex(); } - Q_ASSERT(false); + qFatal("%s: unknown type of model", Q_FUNC_INFO); return QModelIndex(); } @@ -387,9 +394,17 @@ void ModelsToTest::cleanupTestArea(QAbstractItemModel *model) { if (QDir(QDir::currentPath()+"/test").exists()) { - for (int i = 0; i < 26; ++i) - QDir::current().rmdir(QString("test/foo_%1").arg(i)); - Q_ASSERT(QDir::current().rmdir("test")); + for (int i = 0; i < 26; ++i) { + QString subdir(QString("test/foo_%1").arg(i)); + if (!QDir::current().rmdir(subdir)) + qFatal("%s: cannot remove directory %s", + Q_FUNC_INFO, + qPrintable(QDir::toNativeSeparators(QDir::currentPath()+"/"+subdir))); + } + if (!QDir::current().rmdir("test")) + qFatal("%s: cannot remove directory %s", + Q_FUNC_INFO, + qPrintable(QDir::toNativeSeparators(QDir::currentPath()+"/test"))); } } else if (qobject_cast<QSqlQueryModel *>(model)) { QSqlQuery q("DROP TABLE test"); diff --git a/tests/auto/qitemmodel/qitemmodel.pro b/tests/auto/qitemmodel/qitemmodel.pro index 92709fe..b348a18 100644 --- a/tests/auto/qitemmodel/qitemmodel.pro +++ b/tests/auto/qitemmodel/qitemmodel.pro @@ -9,7 +9,7 @@ QT += sql # memory on Windows Mobile 5. #wince*: { -# plugFiles.sources = $$QT_BUILD_TREE/plugins/sqldrivers/*.dll +# plugFiles.files = $$QT_BUILD_TREE/plugins/sqldrivers/*.dll # plugFiles.path = sqldrivers # DEPLOYMENT += plugFiles #} @@ -19,7 +19,7 @@ symbian { qt_not_deployed { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { sqlite.path = /sys/bin - sqlite.sources = sqlite3.dll + sqlite.files = sqlite3.dll DEPLOYMENT += sqlite } } diff --git a/tests/auto/qitemmodel/tst_qitemmodel.cpp b/tests/auto/qitemmodel/tst_qitemmodel.cpp index 16f63a7..4bdfadd 100644 --- a/tests/auto/qitemmodel/tst_qitemmodel.cpp +++ b/tests/auto/qitemmodel/tst_qitemmodel.cpp @@ -199,6 +199,7 @@ void tst_QItemModel::nonDestructiveBasicTest() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QCOMPARE(currentModel->buddy(QModelIndex()), QModelIndex()); currentModel->canFetchMore(QModelIndex()); @@ -244,6 +245,7 @@ void tst_QItemModel::rowCount() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QFETCH(bool, isEmpty); if (isEmpty) { @@ -291,6 +293,7 @@ void tst_QItemModel::columnCount() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QFETCH(bool, isEmpty); if (isEmpty) { @@ -325,6 +328,7 @@ void tst_QItemModel::hasIndex() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); // Make sure that invalid values returns an invalid index QCOMPARE(currentModel->hasIndex(-2, -2), false); @@ -359,6 +363,7 @@ void tst_QItemModel::index() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); // Make sure that invalid values returns an invalid index QCOMPARE(currentModel->index(-2, -2), QModelIndex()); @@ -489,6 +494,7 @@ void tst_QItemModel::parent() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); // Make sure the model wont crash and will return an invalid QModelIndex // when asked for the parent of an invalid index. @@ -538,6 +544,7 @@ void tst_QItemModel::data() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); // Invalid index should return an invalid qvariant QVERIFY(!currentModel->data(QModelIndex()).isValid()); @@ -618,6 +625,7 @@ void tst_QItemModel::setData() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); qRegisterMetaType<QModelIndex>("QModelIndex"); QSignalSpy spy(currentModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &))); QCOMPARE(currentModel->setData(QModelIndex(), QVariant()), false); @@ -660,6 +668,7 @@ void tst_QItemModel::setHeaderData() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QCOMPARE(currentModel->setHeaderData(-1, Qt::Horizontal, QVariant()), false); QCOMPARE(currentModel->setHeaderData(-1, Qt::Vertical, QVariant()), false); @@ -708,6 +717,7 @@ void tst_QItemModel::sort() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QFETCH(bool, isEmpty); if (isEmpty) @@ -819,6 +829,7 @@ void tst_QItemModel::remove() QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QFETCH(bool, readOnly); if (readOnly) @@ -1160,6 +1171,7 @@ void tst_QItemModel::insert() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QFETCH(bool, readOnly); if (readOnly) diff --git a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp index dad1fd5..9673041 100644 --- a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -94,8 +94,14 @@ private slots: void task260134_layoutChangedWithAllSelected(); void QTBUG5671_layoutChangedWithAllSelected(); void QTBUG2804_layoutChangedTreeSelection(); + void deselectRemovedMiddleRange(); + void rangeOperatorLessThan_data(); + void rangeOperatorLessThan(); + + void testDifferentModels(); void testValidRangesInSelectionsAfterReset(); + void testChainedSelectionClear(); private: QAbstractItemModel *model; @@ -2355,6 +2361,237 @@ void tst_QItemSelectionModel::QTBUG2804_layoutChangedTreeSelection() QCOMPARE(selModel.selectedIndexes().count(), 4); } +class RemovalObserver : public QObject +{ + Q_OBJECT + QItemSelectionModel *m_itemSelectionModel; +public: + RemovalObserver(QItemSelectionModel *selectionModel) + : m_itemSelectionModel(selectionModel) + { + connect(m_itemSelectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(selectionChanged(QItemSelection, QItemSelection))); + } + +public slots: + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) + { + foreach(const QModelIndex &index, deselected.indexes()) { + QVERIFY(!m_itemSelectionModel->selection().contains(index)); + } + QVERIFY(m_itemSelectionModel->selection().size() == 2); + } + +}; + +void tst_QItemSelectionModel::deselectRemovedMiddleRange() +{ + QStandardItemModel model(8, 0); + + for (int row = 0; row < 8; ++row) { + static const int column = 0; + QStandardItem *item = new QStandardItem(QString::number(row)); + model.setItem(row, column, item); + } + + QItemSelectionModel selModel(&model); + + selModel.select(QItemSelection(model.index(3, 0), model.index(6, 0)), QItemSelectionModel::Select); + + QVERIFY(selModel.selection().size() == 1); + + RemovalObserver ro(&selModel); + + QSignalSpy spy(&selModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection))); + bool ok = model.removeRows(4, 2); + + QVERIFY(ok); + QVERIFY(spy.size() == 1); +} + +static QStandardItemModel* getModel(QObject *parent) +{ + QStandardItemModel *model = new QStandardItemModel(parent); + + for (int i = 0; i < 4; ++i) { + QStandardItem *parentItem = model->invisibleRootItem(); + QList<QStandardItem*> list; + for (int j = 0; j < 4; ++j) { + list.append(new QStandardItem(QString("item %1, %2").arg(i).arg(j))); + } + parentItem->appendRow(list); + parentItem = list.first(); + for (int j = 0; j < 4; ++j) { + QList<QStandardItem*> list; + for (int k = 0; k < 4; ++k) { + list.append(new QStandardItem(QString("item %1, %2").arg(i).arg(j))); + } + parentItem->appendRow(list); + } + } + return model; +} + +enum Result { + LessThan, + NotLessThan, + NotEqual +}; + +Q_DECLARE_METATYPE(Result); + +void tst_QItemSelectionModel::rangeOperatorLessThan_data() +{ + QTest::addColumn<int>("parent1"); + QTest::addColumn<int>("top1"); + QTest::addColumn<int>("left1"); + QTest::addColumn<int>("bottom1"); + QTest::addColumn<int>("right1"); + QTest::addColumn<int>("parent2"); + QTest::addColumn<int>("top2"); + QTest::addColumn<int>("left2"); + QTest::addColumn<int>("bottom2"); + QTest::addColumn<int>("right2"); + QTest::addColumn<Result>("result"); + + QTest::newRow("lt01") << -1 << 0 << 0 << 3 << 3 + << -1 << 0 << 0 << 3 << 3 << NotLessThan; + + QTest::newRow("lt02") << -1 << 0 << 0 << 2 << 3 + << -1 << 0 << 0 << 3 << 3 << LessThan; + QTest::newRow("lt03") << -1 << 0 << 0 << 3 << 2 + << -1 << 0 << 0 << 3 << 3 << LessThan; + QTest::newRow("lt04") << -1 << 0 << 0 << 2 << 2 + << -1 << 0 << 0 << 3 << 3 << LessThan; + + QTest::newRow("lt05") << -1 << 0 << 0 << 3 << 3 + << -1 << 0 << 0 << 2 << 3 << NotLessThan; + QTest::newRow("lt06") << -1 << 0 << 0 << 3 << 3 + << -1 << 0 << 0 << 3 << 2 << NotLessThan; + QTest::newRow("lt07") << -1 << 0 << 0 << 3 << 3 + << -1 << 0 << 0 << 2 << 2 << NotLessThan; + + QTest::newRow("lt08") << -1 << 0 << 0 << 3 << 3 + << 0 << 0 << 0 << 3 << 3 << NotEqual; + QTest::newRow("lt09") << 1 << 0 << 0 << 3 << 3 + << 0 << 0 << 0 << 3 << 3 << NotEqual; + QTest::newRow("lt10") << 1 << 0 << 0 << 1 << 1 + << 0 << 2 << 2 << 3 << 3 << NotEqual; + QTest::newRow("lt11") << 1 << 2 << 2 << 3 << 3 + << 0 << 0 << 0 << 1 << 1 << NotEqual; + + QTest::newRow("lt12") << -1 << 0 << 0 << 1 << 1 + << -1 << 2 << 2 << 3 << 3 << LessThan; + QTest::newRow("lt13") << -1 << 2 << 2 << 3 << 3 + << -1 << 0 << 0 << 1 << 1 << NotLessThan; + QTest::newRow("lt14") << 1 << 0 << 0 << 1 << 1 + << 1 << 2 << 2 << 3 << 3 << LessThan; + QTest::newRow("lt15") << 1 << 2 << 2 << 3 << 3 + << 1 << 0 << 0 << 1 << 1 << NotLessThan; + + QTest::newRow("lt16") << -1 << 0 << 0 << 2 << 2 + << -1 << 1 << 1 << 3 << 3 << LessThan; + QTest::newRow("lt17") << -1 << 1 << 1 << 3 << 3 + << -1 << 0 << 0 << 2 << 2 << NotLessThan; + QTest::newRow("lt18") << 1 << 0 << 0 << 2 << 2 + << 1 << 1 << 1 << 3 << 3 << LessThan; + QTest::newRow("lt19") << 1 << 1 << 1 << 3 << 3 + << 1 << 0 << 0 << 2 << 2 << NotLessThan; +} + +void tst_QItemSelectionModel::rangeOperatorLessThan() +{ + QStandardItemModel *model1 = getModel(this); + QStandardItemModel *model2 = getModel(this); + + QFETCH(int, parent1); + QFETCH(int, top1); + QFETCH(int, left1); + QFETCH(int, bottom1); + QFETCH(int, right1); + QFETCH(int, parent2); + QFETCH(int, top2); + QFETCH(int, left2); + QFETCH(int, bottom2); + QFETCH(int, right2); + QFETCH(Result, result); + + QModelIndex p1 = model1->index(parent1, 0); + + QModelIndex tl1 = model1->index(top1, left1, p1); + QModelIndex br1 = model1->index(bottom1, right1, p1); + + QItemSelectionRange r1(tl1, br1); + + QModelIndex p2 = model1->index(parent2, 0); + + QModelIndex tl2 = model1->index(top2, left2, p2); + QModelIndex br2 = model1->index(bottom2, right2, p2); + + QItemSelectionRange r2(tl2, br2); + + if (result == LessThan) + QVERIFY(r1 < r2); + else if (result == NotLessThan) + QVERIFY(!(r1 < r2)); + else if (result == NotEqual) + if (!(r1 < r2)) + QVERIFY(r2 < r1); + + // Ranges in different models are always non-equal + + QModelIndex p3 = model2->index(parent1, 0); + + QModelIndex tl3 = model2->index(top1, left1, p3); + QModelIndex br3 = model2->index(bottom1, right1, p3); + + QItemSelectionRange r3(tl3, br3); + + if (!(r1 < r3)) + QVERIFY(r3 < r1); + + if (!(r2 < r3)) + QVERIFY(r3 < r2); + + QModelIndex p4 = model2->index(parent2, 0); + + QModelIndex tl4 = model2->index(top2, left2, p4); + QModelIndex br4 = model2->index(bottom2, right2, p4); + + QItemSelectionRange r4(tl4, br4); + + if (!(r1 < r4)) + QVERIFY(r4 < r1); + + if (!(r2 < r4)) + QVERIFY(r4 < r2); +} + +void tst_QItemSelectionModel::testDifferentModels() +{ + QStandardItemModel model1; + QStandardItemModel model2; + QStandardItem top11("Child1"), top12("Child2"), top13("Child3"); + QStandardItem top21("Child1"), top22("Child2"), top23("Child3"); + + model1.appendColumn(QList<QStandardItem*>() << &top11 << &top12 << &top13); + model2.appendColumn(QList<QStandardItem*>() << &top21 << &top22 << &top23); + + + QModelIndex topIndex1 = model1.index(0, 0); + QModelIndex bottomIndex1 = model1.index(2, 0); + QModelIndex topIndex2 = model2.index(0, 0); + + QItemSelectionRange range(topIndex1, bottomIndex1); + + QVERIFY(range.intersects(QItemSelectionRange(topIndex1, topIndex1))); + QVERIFY(!range.intersects(QItemSelectionRange(topIndex2, topIndex2))); + + QItemSelection newSelection; + QItemSelection::split(range, QItemSelectionRange(topIndex2, topIndex2), &newSelection); + + QVERIFY(newSelection.isEmpty()); +} + class SelectionObserver : public QObject { Q_OBJECT @@ -2417,6 +2654,58 @@ void tst_QItemSelectionModel::testValidRangesInSelectionsAfterReset() observer.setSelectionModel(&selectionModel); model.setStringList(strings); +} + +class DuplicateItemSelectionModel : public QItemSelectionModel +{ + Q_OBJECT +public: + DuplicateItemSelectionModel(QItemSelectionModel *target, QAbstractItemModel *model, QObject *parent = 0) + : QItemSelectionModel(model, parent), m_target(target) + { + + } + + void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) + { + QItemSelectionModel::select(selection, command); + m_target->select(selection, command); + } + + using QItemSelectionModel::select; + +private: + QItemSelectionModel *m_target; + +}; + +void tst_QItemSelectionModel::testChainedSelectionClear() +{ + QStringListModel model(QStringList() << "Apples" << "Pears"); + + QItemSelectionModel selectionModel(&model, 0); + DuplicateItemSelectionModel duplicate(&selectionModel, &model, 0); + + duplicate.select(model.index(0, 0), QItemSelectionModel::Select); + + { + QModelIndexList selectedIndexes = selectionModel.selection().indexes(); + QModelIndexList duplicatedIndexes = duplicate.selection().indexes(); + + QVERIFY(selectedIndexes.size() == duplicatedIndexes.size()); + QVERIFY(selectedIndexes.size() == 1); + QVERIFY(selectedIndexes.first() == model.index(0, 0)); + } + + duplicate.clearSelection(); + + { + QModelIndexList selectedIndexes = selectionModel.selection().indexes(); + QModelIndexList duplicatedIndexes = duplicate.selection().indexes(); + + QVERIFY(selectedIndexes.size() == duplicatedIndexes.size()); + QVERIFY(selectedIndexes.size() == 0); + } } diff --git a/tests/auto/qitemview/tst_qitemview.cpp b/tests/auto/qitemview/tst_qitemview.cpp index 8528a77..1f43568 100644 --- a/tests/auto/qitemview/tst_qitemview.cpp +++ b/tests/auto/qitemview/tst_qitemview.cpp @@ -148,12 +148,18 @@ public: CheckerModel() : QStandardItemModel() {}; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole ) const { - Q_ASSERT(index.isValid()); + if (!index.isValid()) { + qWarning("%s: index is not valid", Q_FUNC_INFO); + return QVariant(); + } return QStandardItemModel::data(index, role); }; Qt::ItemFlags flags(const QModelIndex & index) const { - Q_ASSERT(index.isValid()); + if (!index.isValid()) { + qWarning("%s: index is not valid", Q_FUNC_INFO); + return Qt::ItemFlags(); + } if (index.row() == 2 || index.row() == rowCount() - 3 || index.column() == 2 || index.column() == columnCount() - 3) { Qt::ItemFlags f = QStandardItemModel::flags(index); @@ -164,14 +170,26 @@ public: }; QModelIndex parent ( const QModelIndex & child ) const { - Q_ASSERT(child.isValid()); + if (!child.isValid()) { + qWarning("%s: child index is not valid", Q_FUNC_INFO); + return QModelIndex(); + } return QStandardItemModel::parent(child); }; QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const { - Q_ASSERT(section >= 0); - if (orientation == Qt::Horizontal) { Q_ASSERT(section <= columnCount());}; - if (orientation == Qt::Vertical) { Q_ASSERT(section <= rowCount());}; + if (orientation == Qt::Horizontal + && (section < 0 || section > columnCount())) { + qWarning("%s: invalid section %d, must be in range 0..%d", + Q_FUNC_INFO, section, columnCount()); + return QVariant(); + } + if (orientation == Qt::Vertical + && (section < 0 || section > rowCount())) { + qWarning("%s: invalid section %d, must be in range 0..%d", + Q_FUNC_INFO, section, rowCount()); + return QVariant(); + } return QStandardItemModel::headerData(section, orientation, role); } @@ -180,23 +198,46 @@ public: }; bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole ) { - Q_ASSERT(index.isValid()); + if (!index.isValid()) { + qWarning("%s: index is not valid", Q_FUNC_INFO); + return false; + } return QStandardItemModel::setData(index, value, role); } void sort( int column, Qt::SortOrder order = Qt::AscendingOrder ) { - Q_ASSERT(column >= 0 && column <= columnCount()); - QStandardItemModel::sort(column, order); + if (column < 0 || column > columnCount()) + qWarning("%s: invalid column %d, must be in range 0..%d", + Q_FUNC_INFO, column, columnCount()); + else + QStandardItemModel::sort(column, order); }; QModelIndexList match ( const QModelIndex & start, int role, const QVariant & value, int hits = 1, Qt::MatchFlags flags = Qt::MatchFlags( Qt::MatchStartsWith | Qt::MatchWrap ) ) const { - Q_ASSERT(hits > 0); - Q_ASSERT(value.isValid()); + if (hits <= 0) { + qWarning("%s: hits must be greater than zero", Q_FUNC_INFO); + return QModelIndexList(); + } + if (!value.isValid()) { + qWarning("%s: value is not valid", Q_FUNC_INFO); + return QModelIndexList(); + } return QAbstractItemModel::match(start, role, value, hits, flags); }; bool setHeaderData ( int section, Qt::Orientation orientation, const QVariant & value, int role = Qt::EditRole ) { - Q_ASSERT(section >= 0); + if (orientation == Qt::Horizontal + && (section < 0 || section > columnCount())) { + qWarning("%s: invalid section %d, must be in range 0..%d", + Q_FUNC_INFO, section, columnCount()); + return false; + } + if (orientation == Qt::Vertical + && (section < 0 || section > rowCount())) { + qWarning("%s: invalid section %d, must be in range 0..%d", + Q_FUNC_INFO, section, rowCount()); + return false; + } return QAbstractItemModel::setHeaderData(section, orientation, value, role); }; }; @@ -297,9 +338,11 @@ void tst_QItemView::nonDestructiveBasicTest() #endif QFETCH(QString, viewType); - view = testViews->createView(viewType); QFETCH(int, vscroll); QFETCH(int, hscroll); + + view = testViews->createView(viewType); + QVERIFY(view); view->setVerticalScrollMode((QAbstractItemView::ScrollMode)vscroll); view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); @@ -454,9 +497,11 @@ void tst_QItemView::spider() QSKIP("This test takes too long to execute on IRIX", SkipAll); #endif QFETCH(QString, viewType); - view = testViews->createView(viewType); QFETCH(int, vscroll); QFETCH(int, hscroll); + + view = testViews->createView(viewType); + QVERIFY(view); view->setVerticalScrollMode((QAbstractItemView::ScrollMode)vscroll); view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); view->setModel(treeModel); @@ -489,9 +534,11 @@ void tst_QItemView::resize() // This test needs to be re-thought out, it takes too long and // doesn't really catch theproblem. QFETCH(QString, viewType); - view = testViews->createView(viewType); QFETCH(int, vscroll); QFETCH(int, hscroll); + + view = testViews->createView(viewType); + QVERIFY(view); view->setVerticalScrollMode((QAbstractItemView::ScrollMode)vscroll); view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); view->setModel(treeModel); @@ -517,9 +564,11 @@ void tst_QItemView::visualRect() QSKIP("This test takes too long to execute on IRIX", SkipAll); #endif QFETCH(QString, viewType); - view = testViews->createView(viewType); QFETCH(int, vscroll); QFETCH(int, hscroll); + + view = testViews->createView(viewType); + QVERIFY(view); view->setVerticalScrollMode((QAbstractItemView::ScrollMode)vscroll); view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); QCOMPARE(view->visualRect(QModelIndex()), QRect()); @@ -651,9 +700,11 @@ void tst_QItemView::indexAt() QSKIP("This test takes too long to execute on IRIX", SkipAll); #endif QFETCH(QString, viewType); - view = testViews->createView(viewType); QFETCH(int, vscroll); QFETCH(int, hscroll); + + view = testViews->createView(viewType); + QVERIFY(view); view->setVerticalScrollMode((QAbstractItemView::ScrollMode)vscroll); view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); view->show(); @@ -685,9 +736,11 @@ void tst_QItemView::scrollTo() QSKIP("This test takes too long to execute on IRIX", SkipAll); #endif QFETCH(QString, viewType); - view = testViews->createView(viewType); QFETCH(int, vscroll); QFETCH(int, hscroll); + + view = testViews->createView(viewType); + QVERIFY(view); view->setVerticalScrollMode((QAbstractItemView::ScrollMode)vscroll); view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); view->setModel(treeModel); @@ -735,6 +788,7 @@ void tst_QItemView::moveCursor() #endif QFETCH(QString, viewType); view = testViews->createView(viewType); + QVERIFY(view); if (view->objectName() == "QHeaderView") return; diff --git a/tests/auto/qitemview/viewstotest.cpp b/tests/auto/qitemview/viewstotest.cpp index 9a29e50..690e1c2 100644 --- a/tests/auto/qitemview/viewstotest.cpp +++ b/tests/auto/qitemview/viewstotest.cpp @@ -141,7 +141,6 @@ QAbstractItemView *ViewsToTest::createView(const QString &viewType) view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); view->setSelectionBehavior(QAbstractItemView::SelectItems); } - Q_ASSERT(view); return view; } diff --git a/tests/auto/qkeysequence/tst_qkeysequence.cpp b/tests/auto/qkeysequence/tst_qkeysequence.cpp index 5e675cd..517e44f 100644 --- a/tests/auto/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/qkeysequence/tst_qkeysequence.cpp @@ -112,6 +112,7 @@ public: virtual ~tst_QKeySequence(); private slots: + void swap(); void operatorQString_data(); void operatorQString(); void compareConstructors_data(); @@ -176,6 +177,15 @@ void tst_QKeySequence::initTestCase() qtTranslator->load(":/qt_de"); } +void tst_QKeySequence::swap() +{ + QKeySequence ks1(Qt::CTRL+Qt::Key_O); + QKeySequence ks2(Qt::CTRL+Qt::Key_L); + ks1.swap(ks2); + QCOMPARE(ks1[0], int(Qt::CTRL+Qt::Key_L)); + QCOMPARE(ks2[0], int(Qt::CTRL+Qt::Key_O)); +} + void tst_QKeySequence::operatorQString_data() { QTest::addColumn<int>("modifiers"); diff --git a/tests/auto/qlabel/qlabel.pro b/tests/auto/qlabel/qlabel.pro index 297f868..057a6f1 100644 --- a/tests/auto/qlabel/qlabel.pro +++ b/tests/auto/qlabel/qlabel.pro @@ -3,7 +3,7 @@ SOURCES += tst_qlabel.cpp wince*::DEFINES += SRCDIR=\\\"\\\" else:!symbian:DEFINES += SRCDIR=\\\"$$PWD/\\\" wince*|symbian { - addFiles.sources = *.png \ + addFiles.files = *.png \ testdata addFiles.path = . DEPLOYMENT += addFiles diff --git a/tests/auto/qlayout/qlayout.pro b/tests/auto/qlayout/qlayout.pro index d3b76e3..bb1ae4a 100644 --- a/tests/auto/qlayout/qlayout.pro +++ b/tests/auto/qlayout/qlayout.pro @@ -7,7 +7,7 @@ load(qttest_p4) SOURCES += tst_qlayout.cpp contains(QT_CONFIG, qt3support): QT += qt3support wince*|symbian: { - addFiles.sources = baseline + addFiles.files = baseline addFiles.path = . DEPLOYMENT += addFiles } else { diff --git a/tests/auto/qlibrary/qlibrary.pro b/tests/auto/qlibrary/qlibrary.pro index fd5790b..5dc129f 100644 --- a/tests/auto/qlibrary/qlibrary.pro +++ b/tests/auto/qlibrary/qlibrary.pro @@ -15,3 +15,4 @@ TARGET = tst_qlibrary # no special install rule for subdir INSTALLS = +CONFIG += parallel_test diff --git a/tests/auto/qlibrary/tst/tst.pro b/tests/auto/qlibrary/tst/tst.pro index 4c647c0..28c40b0 100644 --- a/tests/auto/qlibrary/tst/tst.pro +++ b/tests/auto/qlibrary/tst/tst.pro @@ -12,18 +12,18 @@ win32 { } wince*: { - addFiles.sources = ../*.dll ../*.dl2 ../mylib_noextension + addFiles.files = ../*.dll ../*.dl2 ../mylib_noextension addFiles.path = . DEPLOYMENT += addFiles DEFINES += SRCDIR=\\\"\\\" }else:symbian { - binDep.sources = \ + binDep.files = \ mylib.dll \ system.trolltech.test.mylib.dll binDep.path = /sys/bin #mylib.dl2 nonstandard binary deployment will cause warning in emulator, #but it can be safely ignored. - custBinDep.sources = mylib.dl2 + custBinDep.files = mylib.dl2 custBinDep.path = /sys/bin DEPLOYMENT += binDep custBinDep diff --git a/tests/auto/qlibrary/tst_qlibrary.cpp b/tests/auto/qlibrary/tst_qlibrary.cpp index 6ea9ed4..0c31fdd 100644 --- a/tests/auto/qlibrary/tst_qlibrary.cpp +++ b/tests/auto/qlibrary/tst_qlibrary.cpp @@ -53,6 +53,7 @@ #define a_VALID false #define so_VALID false #define dll_VALID false +#define DLL_VALID false #if defined(Q_OS_DARWIN) # undef bundle_VALID @@ -88,6 +89,8 @@ #elif defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) # undef dll_VALID # define dll_VALID true +# undef DLL_VALID +# define DLL_VALID true # define SUFFIX ".dll" # define PREFIX "" @@ -200,6 +203,7 @@ void tst_QLibrary::version() VersionFunction fnVersion = (VersionFunction)library.resolve("mylibversion"); QVERIFY(fnVersion); QCOMPARE(fnVersion(), resultversion); + QVERIFY(library.unload()); #else Q_UNUSED(lib); Q_UNUSED(loadversion); @@ -246,6 +250,7 @@ void tst_QLibrary::load() bool ok = library.load(); if ( result ) { QVERIFY( ok ); + QVERIFY(library.unload()); } else { QVERIFY( !ok ); } @@ -335,6 +340,7 @@ void tst_QLibrary::resolve() } else { QVERIFY( func == 0 ); } + library.unload(); } void tst_QLibrary::library_data() @@ -352,6 +358,7 @@ void tst_QLibrary::isLibrary_data() QTest::newRow(".a") << QString("mylib.a") << a_VALID; QTest::newRow(".bundle") << QString("mylib.bundle") << bundle_VALID; QTest::newRow(".dll") << QString("mylib.dll") << dll_VALID; + QTest::newRow(".DLL") << QString("MYLIB.DLL") << DLL_VALID; QTest::newRow(".dl2" ) << QString("mylib.dl2") << false; QTest::newRow(".dylib") << QString("mylib.dylib") << dylib_VALID; QTest::newRow(".sl") << QString("mylib.sl") << sl_VALID; @@ -461,11 +468,13 @@ void tst_QLibrary::errorString() } break;} default: - Q_ASSERT(0); + QFAIL(qPrintable(QString("Unknown operation: %1").arg(operation))); break; } QRegExp re(errorString); - QVERIFY2(re.exactMatch(lib.errorString()), qPrintable(lib.errorString())); + QString libErrorString = lib.errorString(); + QVERIFY(!lib.isLoaded() || lib.unload()); + QVERIFY2(re.exactMatch(libErrorString), qPrintable(libErrorString)); QCOMPARE(ok, success); } @@ -521,6 +530,7 @@ void tst_QLibrary::loadHints() bool ok = library.load(); if ( result ) { QVERIFY( ok ); + QVERIFY(library.unload()); } else { QVERIFY( !ok ); } @@ -556,7 +566,12 @@ void tst_QLibrary::fileName() } QVERIFY(ok); +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + QCOMPARE(lib.fileName().toLower(), expectedFilename.toLower()); +#else QCOMPARE(lib.fileName(), expectedFilename); +#endif + QVERIFY(lib.unload()); } @@ -568,29 +583,42 @@ void tst_QLibrary::multipleInstancesForOneLibrary() QString lib = QDir::currentPath() + "/mylib"; #endif - QLibrary lib1(lib); - QLibrary lib2(lib); - QCOMPARE(lib1.isLoaded(), false); - QCOMPARE(lib2.isLoaded(), false); - lib1.load(); - QCOMPARE(lib1.isLoaded(), true); - QCOMPARE(lib2.isLoaded(), true); - QCOMPARE(lib1.unload(), true); - QCOMPARE(lib1.isLoaded(), false); - QCOMPARE(lib2.isLoaded(), false); - lib1.load(); - lib2.load(); - QCOMPARE(lib1.isLoaded(), true); - QCOMPARE(lib2.isLoaded(), true); - QCOMPARE(lib1.unload(), false); - QCOMPARE(lib1.isLoaded(), true); - QCOMPARE(lib2.isLoaded(), true); - QCOMPARE(lib2.unload(), true); - QCOMPARE(lib1.isLoaded(), false); - QCOMPARE(lib2.isLoaded(), false); + { + QLibrary lib1(lib); + QLibrary lib2(lib); + QCOMPARE(lib1.isLoaded(), false); + QCOMPARE(lib2.isLoaded(), false); + lib1.load(); + QCOMPARE(lib1.isLoaded(), true); + QCOMPARE(lib2.isLoaded(), true); + QCOMPARE(lib1.unload(), true); + QCOMPARE(lib1.isLoaded(), false); + QCOMPARE(lib2.isLoaded(), false); + lib1.load(); + lib2.load(); + QCOMPARE(lib1.isLoaded(), true); + QCOMPARE(lib2.isLoaded(), true); + QCOMPARE(lib1.unload(), false); + QCOMPARE(lib1.isLoaded(), true); + QCOMPARE(lib2.isLoaded(), true); + QCOMPARE(lib2.unload(), true); + QCOMPARE(lib1.isLoaded(), false); + QCOMPARE(lib2.isLoaded(), false); + + // Finally; unload on that is already unloaded + QCOMPARE(lib1.unload(), false); + } - // Finally; unload on that is already unloaded - QCOMPARE(lib1.unload(), false); + //now let's try with a 3rd one that will go out of scope + { + QLibrary lib1(lib); + QCOMPARE(lib1.isLoaded(), false); + lib1.load(); + QCOMPARE(lib1.isLoaded(), true); + } + QLibrary lib2(lib); + //lib2 should be loaded because lib1 was loaded and never unloaded + QCOMPARE(lib2.isLoaded(), true); /* lib1.setLoadHints(QLibrary::ResolveAllSymbolsHint); diff --git a/tests/auto/qline/qline.pro b/tests/auto/qline/qline.pro index 4651fd3..6e9af24 100644 --- a/tests/auto/qline/qline.pro +++ b/tests/auto/qline/qline.pro @@ -4,3 +4,4 @@ SOURCES += tst_qline.cpp unix:!mac:!symbian:!vxworks:LIBS+=-lm +CONFIG += parallel_test diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index 9f4d158..f0f1685 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -282,6 +282,12 @@ private slots: void validateAndSet(); #endif + void bidiVisualMovement_data(); + void bidiVisualMovement(); + + void bidiLogicalMovement_data(); + void bidiLogicalMovement(); + protected slots: #ifdef QT3_SUPPORT void lostFocus(); @@ -3760,5 +3766,135 @@ void tst_QLineEdit::QTBUG13520_textNotVisible() } +void tst_QLineEdit::bidiVisualMovement_data() +{ + QTest::addColumn<QString>("logical"); + QTest::addColumn<int>("basicDir"); + QTest::addColumn<IntList>("positionList"); + + QTest::newRow("Latin text") + << QString::fromUtf8("abc") + << (int) QChar::DirL + << (IntList() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text, one item") + << QString::fromUtf8("\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text after Latin text") + << QString::fromUtf8("abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3); + QTest::newRow("Latin text after Hebrew text") + << QString::fromUtf8("\327\220\327\221\327\222abc") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3); + QTest::newRow("LTR, 3 items") + << QString::fromUtf8("abc\327\220\327\221\327\222abc") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9); + QTest::newRow("RTL, 3 items") + << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9); + QTest::newRow("LTR, 4 items") + << QString::fromUtf8("abc\327\220\327\221\327\222abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9); + QTest::newRow("RTL, 4 items") + << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222abc") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9); +} + +void tst_QLineEdit::bidiVisualMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + QFETCH(IntList, positionList); + + QLineEdit le; + le.setText(logical); + + le.setCursorMoveStyle(Qt::VisualMoveStyle); + le.setCursorPosition(0); + + bool moved; + int i = 0, oldPos, newPos = 0; + + do { + oldPos = newPos; + QVERIFY(oldPos == positionList[i]); + if (basicDir == QChar::DirL) { + QTest::keyClick(&le, Qt::Key_Right); + } else + QTest::keyClick(&le, Qt::Key_Left); + newPos = le.cursorPosition(); + moved = (oldPos != newPos); + i++; + } while (moved); + + QVERIFY(i == positionList.size()); + + do { + i--; + oldPos = newPos; + QVERIFY(oldPos == positionList[i]); + if (basicDir == QChar::DirL) { + QTest::keyClick(&le, Qt::Key_Left); + } else + { + QTest::keyClick(&le, Qt::Key_Right); + } + newPos = le.cursorPosition(); + moved = (oldPos != newPos); + } while (moved && i >= 0); +} + +void tst_QLineEdit::bidiLogicalMovement_data() +{ + bidiVisualMovement_data(); +} + +void tst_QLineEdit::bidiLogicalMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + QLineEdit le; + le.setText(logical); + + le.setCursorMoveStyle(Qt::LogicalMoveStyle); + le.setCursorPosition(0); + + bool moved; + int i = 0, oldPos, newPos = 0; + + do { + oldPos = newPos; + QVERIFY(oldPos == i); + if (basicDir == QChar::DirL) { + QTest::keyClick(&le, Qt::Key_Right); + } else + QTest::keyClick(&le, Qt::Key_Left); + newPos = le.cursorPosition(); + moved = (oldPos != newPos); + i++; + } while (moved); + + do { + i--; + oldPos = newPos; + QVERIFY(oldPos == i); + if (basicDir == QChar::DirL) { + QTest::keyClick(&le, Qt::Key_Left); + } else + { + QTest::keyClick(&le, Qt::Key_Right); + } + newPos = le.cursorPosition(); + moved = (oldPos != newPos); + } while (moved && i >= 0); +} + QTEST_MAIN(tst_QLineEdit) #include "tst_qlineedit.moc" diff --git a/tests/auto/qlist/tst_qlist.cpp b/tests/auto/qlist/tst_qlist.cpp index 001524c..3901b6f 100644 --- a/tests/auto/qlist/tst_qlist.cpp +++ b/tests/auto/qlist/tst_qlist.cpp @@ -89,6 +89,8 @@ private slots: void testSTLIterators() const; void testOperators() const; + + void initializeList() const; }; void tst_QList::length() const @@ -500,6 +502,13 @@ void tst_QList::swap() const // swap again list.swap(1, 2); QCOMPARE(list, QList<QString>() << "baz" << "foo" << "bar"); + + QList<QString> list2; + list2 << "alpha" << "beta"; + + list.swap(list2); + QCOMPARE(list, QList<QString>() << "alpha" << "beta"); + QCOMPARE(list2, QList<QString>() << "baz" << "foo" << "bar"); } void tst_QList::takeAt() const @@ -665,5 +674,19 @@ void tst_QList::testSTLIterators() const QCOMPARE(*it, QLatin1String("foo")); } +void tst_QList::initializeList() const +{ +#ifdef Q_COMPILER_INITIALIZER_LISTS + QList<int> v1{2,3,4}; + QCOMPARE(v1, QList<int>() << 2 << 3 << 4); + QCOMPARE(v1, (QList<int>{2,3,4})); + + QList<QList<int>> v2{ v1, {1}, QList<int>(), {2,3,4} }; + QList<QList<int>> v3; + v3 << v1 << (QList<int>() << 1) << QList<int>() << v1; + QCOMPARE(v3, v2); +#endif +} + QTEST_APPLESS_MAIN(tst_QList) #include "tst_qlist.moc" diff --git a/tests/auto/qlistwidget/tst_qlistwidget.cpp b/tests/auto/qlistwidget/tst_qlistwidget.cpp index ea5f501..50ad339 100644 --- a/tests/auto/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/qlistwidget/tst_qlistwidget.cpp @@ -133,6 +133,7 @@ private slots: void task217070_scrollbarsAdjusted(); void task258949_keypressHangup(); void QTBUG8086_currentItemChangedOnClick(); + void QTBUG14363_completerWithAnyKeyPressedEditTriggers(); protected slots: @@ -1649,5 +1650,44 @@ void tst_QListWidget::QTBUG8086_currentItemChangedOnClick() } +class ItemDelegate : public QItemDelegate +{ +public: + ItemDelegate(QObject *parent = 0) : QItemDelegate(parent) + {} + virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const + { + QLineEdit *lineEdit = new QLineEdit(parent); + lineEdit->setFrame(false); + QCompleter *completer = new QCompleter(QStringList() << "completer", lineEdit); + completer->setCompletionMode(QCompleter::InlineCompletion); + lineEdit->setCompleter(completer); + return lineEdit; + } +}; + +void tst_QListWidget::QTBUG14363_completerWithAnyKeyPressedEditTriggers() +{ + QListWidget listWidget; + listWidget.setEditTriggers(QAbstractItemView::AnyKeyPressed); + listWidget.setItemDelegate(new ItemDelegate); + QListWidgetItem *item = new QListWidgetItem(QLatin1String("select an item (don't start editing)"), &listWidget); + item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable|Qt::ItemIsEditable); + new QListWidgetItem(QLatin1String("try to type the letter 'c'"), &listWidget); + new QListWidgetItem(QLatin1String("completer"), &listWidget); + listWidget.show(); + listWidget.setCurrentItem(item); + QTest::qWaitForWindowShown(&listWidget); + + QTest::keyClick(listWidget.viewport(), Qt::Key_C); + + QLineEdit *le = qobject_cast<QLineEdit*>(listWidget.itemWidget(item)); + QVERIFY(le); + QCOMPARE(le->text(), QString("completer")); + QCOMPARE(le->completer()->currentCompletion(), QString("completer")); +} + + + QTEST_MAIN(tst_QListWidget) #include "tst_qlistwidget.moc" diff --git a/tests/auto/qlocale/test/test.pro b/tests/auto/qlocale/test/test.pro index 6512e19..8117708 100644 --- a/tests/auto/qlocale/test/test.pro +++ b/tests/auto/qlocale/test/test.pro @@ -22,7 +22,7 @@ QT += network embedded: QT += gui wince*: { - addFiles.sources = \ + addFiles.files = \ ../syslocaleapp addFiles.path = "\\Program Files\\tst_qlocale" diff --git a/tests/auto/qlocale/tst_qlocale.cpp b/tests/auto/qlocale/tst_qlocale.cpp index f84b580..b9e5fd9 100644 --- a/tests/auto/qlocale/tst_qlocale.cpp +++ b/tests/auto/qlocale/tst_qlocale.cpp @@ -140,6 +140,11 @@ private slots: #endif void ampm(); + void currency(); + void quoteString(); + void uiLanguages(); + void weekendDays(); + void listPatterns(); private: QString m_decimal, m_thousand, m_sdate, m_ldate, m_time; @@ -181,6 +186,7 @@ void tst_QLocale::ctor() QCOMPARE(l.language(), QLocale::C); QCOMPARE(l.country(), QLocale::AnyCountry); } + TEST_CTOR(AnyLanguage, AnyCountry, default_lang, default_country) TEST_CTOR(C, AnyCountry, QLocale::C, QLocale::AnyCountry) TEST_CTOR(Aymara, AnyCountry, default_lang, default_country) TEST_CTOR(Aymara, France, default_lang, default_country) @@ -306,6 +312,7 @@ void tst_QLocale::ctor() TEST_CTOR("en@", English, UnitedStates) TEST_CTOR("en.@", English, UnitedStates) TEST_CTOR("en_", English, UnitedStates) + TEST_CTOR("en_U", English, UnitedStates) TEST_CTOR("en_.", English, UnitedStates) TEST_CTOR("en_.@", English, UnitedStates) TEST_CTOR("en.bla", English, UnitedStates) @@ -316,8 +323,10 @@ void tst_QLocale::ctor() TEST_CTOR("en_GB.bla", English, UnitedKingdom) TEST_CTOR("en_GB@.bla", English, UnitedKingdom) TEST_CTOR("en_GB@bla", English, UnitedKingdom) + TEST_CTOR("en-GB", English, UnitedKingdom) + TEST_CTOR("en-GB@bla", English, UnitedKingdom) - Q_ASSERT(QLocale::Norwegian == QLocale::NorwegianBokmal); + QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal); TEST_CTOR("no", Norwegian, Norway) TEST_CTOR("nb", Norwegian, Norway) TEST_CTOR("nn", NorwegianNynorsk, Norway) @@ -326,13 +335,38 @@ void tst_QLocale::ctor() TEST_CTOR("nn_NO", NorwegianNynorsk, Norway) TEST_CTOR("es_ES", Spanish, Spain) TEST_CTOR("es_419", Spanish, LatinAmericaAndTheCaribbean) + TEST_CTOR("es-419", Spanish, LatinAmericaAndTheCaribbean) // test default countries for languages + TEST_CTOR("zh", Chinese, China) + TEST_CTOR("zh-Hans", Chinese, China) TEST_CTOR("mn", Mongolian, Mongolia) TEST_CTOR("ne", Nepali, Nepal) #undef TEST_CTOR +#define TEST_CTOR(req_lc, exp_lang, exp_script, exp_country) \ + { \ + QLocale l(req_lc); \ + QVERIFY2(l.language() == QLocale::exp_lang \ + && l.script() == QLocale::exp_script \ + && l.country() == QLocale::exp_country, \ + QString("requested: \"" + QString(req_lc) + "\", got: " \ + + QLocale::languageToString(l.language()) \ + + "/" + QLocale::scriptToString(l.script()) \ + + "/" + QLocale::countryToString(l.country())).toLatin1().constData()); \ + } + + TEST_CTOR("zh_CN", Chinese, AnyScript, China) + TEST_CTOR("zh_Hans_CN", Chinese, SimplifiedHanScript, China) + TEST_CTOR("zh_Hans", Chinese, SimplifiedHanScript, China) + TEST_CTOR("zh_Hant", Chinese, TraditionalHanScript, HongKong) + TEST_CTOR("zh_Hans_MO", Chinese, SimplifiedHanScript, Macau) + TEST_CTOR("zh_Hant_MO", Chinese, TraditionalHanScript, Macau) + TEST_CTOR("az_Latn_AZ", Azerbaijani, LatinScript, Azerbaijan) + TEST_CTOR("ha_Arab_NG", Hausa, ArabicScript, Nigeria) + TEST_CTOR("ha_Latn_NG", Hausa, LatinScript, Nigeria) +#undef TEST_CTOR } void tst_QLocale::emptyCtor() @@ -397,7 +431,7 @@ void tst_QLocale::emptyCtor() TEST_CTOR("en_GB@bla", "en_GB") TEST_CTOR("de", "de_DE") - Q_ASSERT(QLocale::Norwegian == QLocale::NorwegianBokmal); + QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal); TEST_CTOR("no", "nb_NO") TEST_CTOR("nb", "nb_NO") TEST_CTOR("nn", "nn_NO") @@ -405,11 +439,12 @@ void tst_QLocale::emptyCtor() TEST_CTOR("nb_NO", "nb_NO") TEST_CTOR("nn_NO", "nn_NO") + TEST_CTOR("DE", "de_DE"); + TEST_CTOR("EN", "en_US"); + TEST_CTOR("en/", defaultLoc) - TEST_CTOR("DE", defaultLoc); TEST_CTOR("asdfghj", defaultLoc); TEST_CTOR("123456", defaultLoc); - TEST_CTOR("EN", defaultLoc); #undef TEST_CTOR #endif @@ -1095,6 +1130,11 @@ void tst_QLocale::macDefaultLocale() const QString timeString = locale.toString(QTime(1,2,3), QLocale::LongFormat); QVERIFY(timeString.contains(QString("1:02:03"))); + QCOMPARE(locale.toCurrencyString(qulonglong(1234)), QString("$1,234.00")); + QCOMPARE(locale.toCurrencyString(qlonglong(-1234)), QString("($1,234.00)")); + QCOMPARE(locale.toCurrencyString(double(1234.56)), QString("$1,234.56")); + QCOMPARE(locale.toCurrencyString(double(-1234.56)), QString("($1,234.56)")); + // Depending on the configured time zone, the time string might not // contain a GMT specifier. (Sometimes it just names the zone, like "CEST") if (timeString.contains(QString("GMT"))) { @@ -1107,12 +1147,23 @@ void tst_QLocale::macDefaultLocale() expectedGMTSpecifier.append(QString("0%1").arg(qAbs(diff))); else expectedGMTSpecifier.append(QString("%1").arg(qAbs(diff))); - QVERIFY(timeString.contains(expectedGMTSpecifier)); + QVERIFY2(timeString.contains(expectedGMTSpecifier), qPrintable( + QString("timeString `%1', expectedGMTSpecifier `%2'") + .arg(timeString) + .arg(expectedGMTSpecifier) + )); } QCOMPARE(locale.dayName(1), QString("Monday")); QCOMPARE(locale.dayName(7), QString("Sunday")); QCOMPARE(locale.monthName(1), QString("January")); QCOMPARE(locale.monthName(12), QString("December")); + QCOMPARE(locale.firstDayOfWeek(), Qt::Sunday); + QCOMPARE(locale.quoteString("string"), QString::fromUtf8("\xe2\x80\x9c" "string" "\xe2\x80\x9d")); + QCOMPARE(locale.quoteString("string", QLocale::AlternateQuotation), QString::fromUtf8("\xe2\x80\x98" "string" "\xe2\x80\x99")); + + QList<Qt::DayOfWeek> days; + days << Qt::Monday << Qt::Tuesday << Qt::Wednesday << Qt::Thursday << Qt::Friday; + QCOMPARE(locale.weekdays(), days); } @@ -1768,6 +1819,7 @@ void tst_QLocale::measurementSystems_data() void tst_QLocale::measurementSystems() { + QSKIP("Meh, skip the test as we do not reread the environment variables anymore", SkipAll); QFETCH(QString, localeName); QFETCH(int, mSystem); @@ -1829,6 +1881,7 @@ void tst_QLocale::systemMeasurementSystems_data() void tst_QLocale::systemMeasurementSystems() { + QSKIP("Meh, skip the test as we do not reread the environment variables anymore", SkipAll); // Theoretically, we could include HPUX in this test, but its setenv implementation // stinks. It's called putenv, and it requires you to keep the variable you pass // to it around forever. @@ -1951,6 +2004,7 @@ void tst_QLocale::queryMeasureSystem_data() void tst_QLocale::queryMeasureSystem() { + QSKIP("Meh, skip the test as we do not reread the environment variables anymore", SkipAll); // Theoretically, we could include HPUX in this test, but its setenv implementation // stinks. It's called putenv, and it requires you to keep the variable you pass // to it around forever. @@ -2066,6 +2120,10 @@ void tst_QLocale::monthName() QCOMPARE(ru.monthName(1, QLocale::LongFormat), QString::fromUtf8("\321\217\320\275\320\262\320\260\321\200\321\217")); QCOMPARE(ru.monthName(1, QLocale::ShortFormat), QString::fromUtf8("\321\217\320\275\320\262\56")); QCOMPARE(ru.monthName(1, QLocale::NarrowFormat), QString::fromUtf8("\320\257")); + + // check that our CLDR scripts handle surrogate pairs correctly + QLocale dsrt("en-Dsrt-US"); + QCOMPARE(dsrt.monthName(1, QLocale::LongFormat), QString::fromUtf8("\xf0\x90\x90\x96\xf0\x90\x90\xb0\xf0\x90\x91\x8c\xf0\x90\x90\xb7\xf0\x90\x90\xad\xf0\x90\x90\xaf\xf0\x90\x91\x89\xf0\x90\x90\xa8")); } void tst_QLocale::standaloneMonthName() @@ -2123,5 +2181,102 @@ void tst_QLocale::symbianSystemLocale() } #endif +void tst_QLocale::currency() +{ + const QLocale c(QLocale::C); + QCOMPARE(c.toCurrencyString(qulonglong(1234)), QString("1234")); + QCOMPARE(c.toCurrencyString(qlonglong(-1234)), QString("-1234")); + QCOMPARE(c.toCurrencyString(double(1234.56)), QString("1234.56")); + QCOMPARE(c.toCurrencyString(double(-1234.56)), QString("-1234.56")); + + const QLocale ru_RU("ru_RU"); + QCOMPARE(ru_RU.toCurrencyString(qulonglong(1234)), QString::fromUtf8("1234\xc2\xa0\xd1\x80\xd1\x83\xd0\xb1.")); + QCOMPARE(ru_RU.toCurrencyString(qlonglong(-1234)), QString::fromUtf8("-1234\xc2\xa0\xd1\x80\xd1\x83\xd0\xb1.")); + QCOMPARE(ru_RU.toCurrencyString(double(1234.56)), QString::fromUtf8("1234,56\xc2\xa0\xd1\x80\xd1\x83\xd0\xb1.")); + QCOMPARE(ru_RU.toCurrencyString(double(-1234.56)), QString::fromUtf8("-1234,56\xc2\xa0\xd1\x80\xd1\x83\xd0\xb1.")); + + const QLocale de_DE("de_DE"); + QCOMPARE(de_DE.toCurrencyString(qulonglong(1234)), QString::fromUtf8("1234\xc2\xa0\xe2\x82\xac")); + QCOMPARE(de_DE.toCurrencyString(qulonglong(1234), QLatin1String("BAZ")), QString::fromUtf8("1234\xc2\xa0" "BAZ")); + QCOMPARE(de_DE.toCurrencyString(qlonglong(-1234)), QString::fromUtf8("-1234\xc2\xa0\xe2\x82\xac")); + QCOMPARE(de_DE.toCurrencyString(qlonglong(-1234), QLatin1String("BAZ")), QString::fromUtf8("-1234\xc2\xa0" "BAZ")); + QCOMPARE(de_DE.toCurrencyString(double(1234.56)), QString::fromUtf8("1234,56\xc2\xa0\xe2\x82\xac")); + QCOMPARE(de_DE.toCurrencyString(double(-1234.56)), QString::fromUtf8("-1234,56\xc2\xa0\xe2\x82\xac")); + QCOMPARE(de_DE.toCurrencyString(double(-1234.56), QLatin1String("BAZ")), QString::fromUtf8("-1234,56\xc2\xa0" "BAZ")); + + const QLocale system = QLocale::system(); + QVERIFY(system.toCurrencyString(1, QLatin1String("FOO")).contains(QLatin1String("FOO"))); +} + +void tst_QLocale::quoteString() +{ + const QString someText("text"); + const QLocale c(QLocale::C); + QCOMPARE(c.quoteString(someText), QString::fromUtf8("\x22" "text" "\x22")); + QCOMPARE(c.quoteString(someText, QLocale::AlternateQuotation), QString::fromUtf8("\x27" "text" "\x27")); + + const QLocale de_CH("de_CH"); + QCOMPARE(de_CH.quoteString(someText), QString::fromUtf8("\xc2\xab" "text" "\xc2\xbb")); + QCOMPARE(de_CH.quoteString(someText, QLocale::AlternateQuotation), QString::fromUtf8("\xe2\x80\xb9" "text" "\xe2\x80\xba")); + +} + +void tst_QLocale::uiLanguages() +{ + const QLocale c(QLocale::C); + QCOMPARE(c.uiLanguages().size(), 1); + QCOMPARE(c.uiLanguages().at(0), QLatin1String("C")); + + const QLocale en_US("en_US"); + QCOMPARE(en_US.uiLanguages().size(), 1); + QCOMPARE(en_US.uiLanguages().at(0), QLatin1String("en-US")); + + const QLocale ru_RU("ru_RU"); + QCOMPARE(ru_RU.uiLanguages().size(), 1); + QCOMPARE(ru_RU.uiLanguages().at(0), QLatin1String("ru-RU")); +} + +void tst_QLocale::weekendDays() +{ + const QLocale c(QLocale::C); + QList<Qt::DayOfWeek> days; + days << Qt::Monday << Qt::Tuesday << Qt::Wednesday << Qt::Thursday << Qt::Friday; + QCOMPARE(c.weekdays(), days); +} + +void tst_QLocale::listPatterns() +{ + QStringList sl1; + QStringList sl2; + sl2 << "aaa"; + QStringList sl3; + sl3 << "aaa" << "bbb"; + QStringList sl4; + sl4 << "aaa" << "bbb" << "ccc"; + QStringList sl5; + sl5 << "aaa" << "bbb" << "ccc" << "ddd"; + + const QLocale c(QLocale::C); + QCOMPARE(c.createSeparatedList(sl1), QString("")); + QCOMPARE(c.createSeparatedList(sl2), QString("aaa")); + QCOMPARE(c.createSeparatedList(sl3), QString("aaa, bbb")); + QCOMPARE(c.createSeparatedList(sl4), QString("aaa, bbb, ccc")); + QCOMPARE(c.createSeparatedList(sl5), QString("aaa, bbb, ccc, ddd")); + + const QLocale en_US("en_US"); + QCOMPARE(en_US.createSeparatedList(sl1), QString("")); + QCOMPARE(en_US.createSeparatedList(sl2), QString("aaa")); + QCOMPARE(en_US.createSeparatedList(sl3), QString("aaa and bbb")); + QCOMPARE(en_US.createSeparatedList(sl4), QString("aaa, bbb, and ccc")); + QCOMPARE(en_US.createSeparatedList(sl5), QString("aaa, bbb, ccc, and ddd")); + + const QLocale zh_CN("zh_CN"); + QCOMPARE(zh_CN.createSeparatedList(sl1), QString("")); + QCOMPARE(zh_CN.createSeparatedList(sl2), QString("aaa")); + QCOMPARE(zh_CN.createSeparatedList(sl3), QString::fromUtf8("aaa" "\xe5\x92\x8c" "bbb")); + QCOMPARE(zh_CN.createSeparatedList(sl4), QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe5\x92\x8c" "ccc")); + QCOMPARE(zh_CN.createSeparatedList(sl5), QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe3\x80\x81" "ccc" "\xe5\x92\x8c" "ddd")); +} + QTEST_APPLESS_MAIN(tst_QLocale) #include "tst_qlocale.moc" diff --git a/tests/auto/qlocalsocket/test/test.pro b/tests/auto/qlocalsocket/test/test.pro index 687aae2..b2755b5 100644 --- a/tests/auto/qlocalsocket/test/test.pro +++ b/tests/auto/qlocalsocket/test/test.pro @@ -28,21 +28,21 @@ CONFIG(debug_and_release) { } wince* { - additionalFiles.sources = ../lackey/lackey.exe + additionalFiles.files = ../lackey/lackey.exe additionalFiles.path = lackey } symbian { - additionalFiles.sources = lackey.exe + additionalFiles.files = lackey.exe additionalFiles.path = \\sys\\bin TARGET.UID3 = 0xE0340005 DEFINES += SYMBIAN_SRCDIR_UID=$$lower($$replace(TARGET.UID3,"0x","")) } wince*|symbian { - scriptFiles.sources = ../lackey/scripts/*.js + scriptFiles.files = ../lackey/scripts/*.js scriptFiles.path = lackey/scripts - DEPLOYMENT = additionalFiles scriptFiles + DEPLOYMENT += additionalFiles scriptFiles QT += script # for easy deployment of QtScript requires(contains(QT_CONFIG,script)) diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index b6afce1..3dc5e73 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -391,6 +391,8 @@ void tst_QLocalSocket::listenAndConnect() QVERIFY(socket->fullServerName().contains(name)); sockets.append(socket); if (canListen) { + QVERIFY(socket->waitForConnected()); + QVERIFY(socket->isValid()); QCOMPARE(socket->errorString(), QString("Unknown error")); QCOMPARE(socket->error(), QLocalSocket::UnknownSocketError); QCOMPARE(socket->state(), QLocalSocket::ConnectedState); diff --git a/tests/auto/qdbusperformance/server/server.cpp b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/simple/main.cpp index 3731be5..5597ef2 100644 --- a/tests/auto/qdbusperformance/server/server.cpp +++ b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/simple/main.cpp @@ -38,27 +38,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include <QtCore/QtCore> -#include <QtDBus/QtDBus> -#include "../serverobject.h" -static const char serviceName[] = "com.trolltech.autotests.performance"; -static const char objectPath[] = "/"; - -int main(int argc, char *argv[]) +int main(int,char**) { - QCoreApplication app(argc, argv); - - QDBusConnection con = QDBusConnection::sessionBus(); - if (!con.isConnected()) - exit(1); - - if (!con.registerService(serviceName)) - exit(2); - - ServerObject obj(objectPath, con); - printf("ready.\n"); - return app.exec(); } - diff --git a/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/simple/simple.pro b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/simple/simple.pro new file mode 100644 index 0000000..2db08a2 --- /dev/null +++ b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/simple/simple.pro @@ -0,0 +1,5 @@ +TEMPLATE = app +SOURCES = main.cpp + +extratarget.commands = @echo extra target worked OK +QMAKE_EXTRA_TARGETS += extratarget diff --git a/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/subdir.pro b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/subdir.pro new file mode 100644 index 0000000..be0d80a --- /dev/null +++ b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/subdir.pro @@ -0,0 +1,7 @@ +TEMPLATE = subdirs +SUBDIRS = simple + +extratarget.CONFIG = recursive +extratarget.recurse = $$SUBDIRS +extratarget.recurse_target = extratarget +QMAKE_EXTRA_TARGETS += extratarget diff --git a/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/subdir_via_pro_file_extra_target.pro b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/subdir_via_pro_file_extra_target.pro new file mode 100644 index 0000000..7c07859 --- /dev/null +++ b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/subdir_via_pro_file_extra_target.pro @@ -0,0 +1,7 @@ +TEMPLATE = subdirs +SUBDIRS = subdir.pro + +extratarget.CONFIG = recursive +extratarget.recurse = $$SUBDIRS +extratarget.recurse_target = extratarget +QMAKE_EXTRA_TARGETS += extratarget diff --git a/tests/auto/qmake/tst_qmake.cpp b/tests/auto/qmake/tst_qmake.cpp index fdeeef7..2775b53 100644 --- a/tests/auto/qmake/tst_qmake.cpp +++ b/tests/auto/qmake/tst_qmake.cpp @@ -69,6 +69,7 @@ private slots: void simple_lib(); void simple_dll(); void subdirs(); + void subdir_via_pro_file_extra_target(); void functions(); void operators(); void variables(); @@ -234,6 +235,19 @@ void tst_qmake::subdirs() QVERIFY( test_compiler.removeMakefile( workDir ) ); } +void tst_qmake::subdir_via_pro_file_extra_target() +{ + QString workDir = base_path + "/testdata/subdir_via_pro_file_extra_target"; + + QDir D; + D.remove( workDir + "/Makefile"); + D.remove( workDir + "/Makefile.subdir"); + D.remove( workDir + "/simple/Makefile"); + D.remove( workDir + "/simple/Makefile.subdir"); + QVERIFY( test_compiler.qmake( workDir, "subdir_via_pro_file_extra_target" )); + QVERIFY( test_compiler.make( workDir, "extratarget" )); +} + void tst_qmake::functions() { QString workDir = base_path + "/testdata/functions"; diff --git a/tests/auto/qmap/qmap.pro b/tests/auto/qmap/qmap.pro index 00b84d1..eaed926 100644 --- a/tests/auto/qmap/qmap.pro +++ b/tests/auto/qmap/qmap.pro @@ -4,3 +4,4 @@ QT = core SOURCES += tst_qmap.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qmap/tst_qmap.cpp b/tests/auto/qmap/tst_qmap.cpp index b5eab8a..141e693 100644 --- a/tests/auto/qmap/tst_qmap.cpp +++ b/tests/auto/qmap/tst_qmap.cpp @@ -65,6 +65,8 @@ private slots: void beginEnd(); void key(); + void swap(); + void operator_eq(); void empty(); @@ -392,6 +394,16 @@ void tst_QMap::key() } } +void tst_QMap::swap() +{ + QMap<int,QString> m1, m2; + m1[0] = "m1[0]"; + m2[1] = "m2[1]"; + m1.swap(m2); + QCOMPARE(m1.value(1),QLatin1String("m2[1]")); + QCOMPARE(m2.value(0),QLatin1String("m1[0]")); +} + void tst_QMap::operator_eq() { { diff --git a/tests/auto/qmargins/qmargins.pro b/tests/auto/qmargins/qmargins.pro index 5a6aa4f..0404da0 100644 --- a/tests/auto/qmargins/qmargins.pro +++ b/tests/auto/qmargins/qmargins.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qmargins.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qmath/qmath.pro b/tests/auto/qmath/qmath.pro index 03134ee..e5784ce 100644 --- a/tests/auto/qmath/qmath.pro +++ b/tests/auto/qmath/qmath.pro @@ -4,3 +4,4 @@ QT = core SOURCES += tst_qmath.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp index 7eed347..1b4d770 100644 --- a/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp +++ b/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp @@ -2822,10 +2822,9 @@ void tst_QMatrixNxN::convertGeneric() 9.0f, 10.0f, 11.0f, 12.0f, 0.0f, 0.0f, 0.0f, 1.0f }; -#if !defined(QT_NO_MEMBER_TEMPLATES) QMatrix4x4 m4(m1); QVERIFY(isSame(m4, unique4x4)); -#endif + QMatrix4x4 m5 = qGenericMatrixToMatrix4x4(m1); QVERIFY(isSame(m5, unique4x4)); @@ -2835,10 +2834,9 @@ void tst_QMatrixNxN::convertGeneric() 9.0f, 10.0f, 11.0f, 12.0f }; QMatrix4x4 m9(uniqueValues4); -#if !defined(QT_NO_MEMBER_TEMPLATES) + QMatrix4x3 m10 = m9.toGenericMatrix<4, 3>(); QVERIFY(isSame(m10, conv4x4)); -#endif QMatrix4x3 m11 = qGenericMatrixFromMatrix4x4<4, 3>(m9); QVERIFY(isSame(m11, conv4x4)); diff --git a/tests/auto/qmdiarea/tst_qmdiarea.cpp b/tests/auto/qmdiarea/tst_qmdiarea.cpp index 6f22896..c752362 100644 --- a/tests/auto/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/qmdiarea/tst_qmdiarea.cpp @@ -287,6 +287,8 @@ private slots: void setActivationOrder(); void tabBetweenSubWindows(); void setViewMode(); + void setTabsClosable(); + void setTabsMovable(); void setTabShape(); void setTabPosition_data(); void setTabPosition(); @@ -2464,6 +2466,77 @@ void tst_QMdiArea::setViewMode() QCOMPARE(mdiArea.viewMode(), QMdiArea::SubWindowView); } +void tst_QMdiArea::setTabsClosable() +{ + QMdiArea mdiArea; + mdiArea.addSubWindow(new QWidget); + + // test default + QCOMPARE(mdiArea.tabsClosable(), false); + + // change value before tab bar exists + QTabBar *tabBar = qFindChild<QTabBar *>(&mdiArea); + QVERIFY(!tabBar); + mdiArea.setTabsClosable(true); + QCOMPARE(mdiArea.tabsClosable(), true); + + // force tab bar creation + mdiArea.setViewMode(QMdiArea::TabbedView); + tabBar = qFindChild<QTabBar *>(&mdiArea); + QVERIFY(tabBar); + + // value must've been propagated + QCOMPARE(tabBar->tabsClosable(), true); + + // change value when tab bar exists + mdiArea.setTabsClosable(false); + QCOMPARE(mdiArea.tabsClosable(), false); + QCOMPARE(tabBar->tabsClosable(), false); +} + +void tst_QMdiArea::setTabsMovable() +{ + QMdiArea mdiArea; + QMdiSubWindow *subWindow1 = mdiArea.addSubWindow(new QWidget); + QMdiSubWindow *subWindow2 = mdiArea.addSubWindow(new QWidget); + QMdiSubWindow *subWindow3 = mdiArea.addSubWindow(new QWidget); + + // test default + QCOMPARE(mdiArea.tabsMovable(), false); + + // change value before tab bar exists + QTabBar *tabBar = qFindChild<QTabBar *>(&mdiArea); + QVERIFY(!tabBar); + mdiArea.setTabsMovable(true); + QCOMPARE(mdiArea.tabsMovable(), true); + + // force tab bar creation + mdiArea.setViewMode(QMdiArea::TabbedView); + tabBar = qFindChild<QTabBar *>(&mdiArea); + QVERIFY(tabBar); + + // value must've been propagated + QCOMPARE(tabBar->isMovable(), true); + + // test tab moving + QList<QMdiSubWindow *> subWindows; + subWindows << subWindow1 << subWindow2 << subWindow3; + QCOMPARE(mdiArea.subWindowList(QMdiArea::CreationOrder), subWindows); + tabBar->moveTab(1, 2); // 1,3,2 + subWindows.clear(); + subWindows << subWindow1 << subWindow3 << subWindow2; + QCOMPARE(mdiArea.subWindowList(QMdiArea::CreationOrder), subWindows); + tabBar->moveTab(0, 2); // 3,2,1 + subWindows.clear(); + subWindows << subWindow3 << subWindow2 << subWindow1; + QCOMPARE(mdiArea.subWindowList(QMdiArea::CreationOrder), subWindows); + + // change value when tab bar exists + mdiArea.setTabsMovable(false); + QCOMPARE(mdiArea.tabsMovable(), false); + QCOMPARE(tabBar->isMovable(), false); +} + void tst_QMdiArea::setTabShape() { QMdiArea mdiArea; diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp index 26b31ee..d99df95 100644 --- a/tests/auto/qmenu/tst_qmenu.cpp +++ b/tests/auto/qmenu/tst_qmenu.cpp @@ -789,7 +789,7 @@ void tst_QMenu::task250673_activeMultiColumnSubMenuPosition() while (main.columnCount() < 2) { main.addAction(QString("Item %1").arg(i)); ++i; - Q_ASSERT(i<1000); + QVERIFY(i<1000); } main.setActiveAction(menuAction); sub.setActiveAction(subAction); diff --git a/tests/auto/qmessagebox/tst_qmessagebox.cpp b/tests/auto/qmessagebox/tst_qmessagebox.cpp index 8352041..ed085ce 100644 --- a/tests/auto/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/qmessagebox/tst_qmessagebox.cpp @@ -47,6 +47,7 @@ #include <QTimer> #include <QApplication> #include <QPushButton> +#include <QDialogButtonBox> #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) #include <QMacStyle> #endif @@ -54,6 +55,8 @@ #include <QCleanlooksStyle> #endif +#include "../../shared/util.h" + //TESTED_CLASS= //TESTED_FILES= @@ -106,7 +109,7 @@ class tst_QMessageBox : public QObject public: tst_QMessageBox(); int exec(QMessageBox *msgBox, int key = -1); - int sendReturn(); + void sendKeySoon(); public slots: void sendKey(); @@ -119,6 +122,7 @@ private slots: void statics(); void about(); void detailsText(); + void detailsButtonText(); void shortcut(); @@ -134,8 +138,12 @@ private slots: void setInformativeText(); void iconPixmap(); + void init(); + void initTestCase(); + private: int keyToSend; + QTimer keySendTimer; }; tst_QMessageBox::tst_QMessageBox() : keyToSend(-1) @@ -150,22 +158,16 @@ int tst_QMessageBox::exec(QMessageBox *msgBox, int key) QTimer::singleShot(1000, msgBox, SLOT(close())); } else { keyToSend = key; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); } return msgBox->exec(); } -int tst_QMessageBox::sendReturn() -{ - keyToSend = Qt::Key_Return; - QTimer::singleShot(1000, this, SLOT(sendKey())); - return 0; -} - void tst_QMessageBox::sendKey() { if (keyToSend == -2) { QApplication::activeModalWidget()->close(); + keyToSend = -1; return; } if (keyToSend == -1) @@ -175,6 +177,24 @@ void tst_QMessageBox::sendKey() keyToSend = -1; } +void tst_QMessageBox::sendKeySoon() +{ + keySendTimer.start(); +} + +void tst_QMessageBox::init() +{ + // if there is any pending key send from the last test, cancel it. + keySendTimer.stop(); +} + +void tst_QMessageBox::initTestCase() +{ + keySendTimer.setInterval(1000); + keySendTimer.setSingleShot(true); + QVERIFY(QObject::connect(&keySendTimer, SIGNAL(timeout()), this, SLOT(sendKey()))); +} + void tst_QMessageBox::sanityTest() { QMessageBox msgBox; @@ -315,32 +335,36 @@ void tst_QMessageBox::statics() for (int i = 0; i < 4; i++) { keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); QMessageBox::StandardButton sb = (*statics[i])(0, "caption", "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help | QMessageBox::Cancel, QMessageBox::NoButton); QCOMPARE(sb, QMessageBox::Cancel); + QCOMPARE(keyToSend, -1); keyToSend = -2; // close() - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); sb = (*statics[i])(0, "caption", "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help | QMessageBox::Cancel, QMessageBox::NoButton); QCOMPARE(sb, QMessageBox::Cancel); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); sb = (*statics[i])(0, "caption", "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help, QMessageBox::Yes); QCOMPARE(sb, QMessageBox::Yes); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); sb = (*statics[i])(0, "caption", "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help, QMessageBox::No); QCOMPARE(sb, QMessageBox::No); + QCOMPARE(keyToSend, -1); } } @@ -359,16 +383,28 @@ void tst_QMessageBox::shortcut() void tst_QMessageBox::about() { keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); QMessageBox::about(0, "Caption", "This is an auto test"); + // On Mac, about and aboutQt are not modal, so we need to + // explicitly run the event loop +#ifdef Q_WS_MAC + QTRY_COMPARE(keyToSend, -1); +#else + QCOMPARE(keyToSend, -1); +#endif #if !defined(Q_OS_WINCE) keyToSend = Qt::Key_Enter; #else keyToSend = Qt::Key_Escape; #endif - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); QMessageBox::aboutQt(0, "Caption"); +#ifdef Q_WS_MAC + QTRY_COMPARE(keyToSend, -1); +#else + QCOMPARE(keyToSend, -1); +#endif } // Old message box enums @@ -390,7 +426,7 @@ void tst_QMessageBox::staticSourceCompat() // source compat tests for < 4.2 keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes, QMessageBox::No); int expectedButton = int(QMessageBox::Yes); #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) @@ -401,43 +437,51 @@ void tst_QMessageBox::staticSourceCompat() expectedButton = int(QMessageBox::No); #endif QCOMPARE(ret, expectedButton); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No); QCOMPARE(ret, int(QMessageBox::Yes)); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes, QMessageBox::No | QMessageBox::Default); QCOMPARE(ret, int(QMessageBox::No)); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape); QCOMPARE(ret, int(QMessageBox::Yes)); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Escape, QMessageBox::No | QMessageBox::Default); QCOMPARE(ret, int(QMessageBox::No)); + QCOMPARE(keyToSend, -1); // the button text versions keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 1); QCOMPARE(ret, 1); + QCOMPARE(keyToSend, -1); if (0) { // dont run these tests since the dialog wont close! keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 1); QCOMPARE(ret, -1); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 0, 1); QCOMPARE(ret, 1); + QCOMPARE(keyToSend, -1); } } @@ -470,7 +514,7 @@ void tst_QMessageBox::staticBinaryCompat() // binary compat tests for < 4.2 keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", Old_Yes, Old_No, 0); int expectedButton = int(Old_Yes); #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) @@ -481,33 +525,39 @@ void tst_QMessageBox::staticBinaryCompat() expectedButton = int(Old_No); #endif QCOMPARE(ret, expectedButton); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", Old_Yes | Old_Escape, Old_No, 0); QCOMPARE(ret, int(Old_Yes)); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Enter; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", Old_Yes | Old_Default, Old_No, 0); QCOMPARE(ret, int(Old_Yes)); + QCOMPARE(keyToSend, -1); #if 0 keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", Old_Yes, Old_No | Old_Default, 0); QCOMPARE(ret, -1); + QCOMPARE(keyToSend, -1); #endif keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", Old_Yes | Old_Escape, Old_No | Old_Default, 0); QCOMPARE(ret, Old_Yes); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); ret = QMessageBox::information(0, "title", "text", Old_Yes | Old_Default, Old_No | Old_Escape, 0); QCOMPARE(ret, Old_No); + QCOMPARE(keyToSend, -1); } @@ -559,48 +609,43 @@ void tst_QMessageBox::testSymbols() button = QMessageBox::FlagMask; mb1.setText("Foo"); - QString text = mb1.text(); - Q_ASSERT(text == "Foo"); + QCOMPARE(mb1.text(), "Foo"); icon = mb1.icon(); - Q_ASSERT(icon == QMessageBox::NoIcon); + QVERIFY(icon == QMessageBox::NoIcon); mb1.setIcon(QMessageBox::Question); - Q_ASSERT(mb1.icon() == QMessageBox::Question); + QVERIFY(mb1.icon() == QMessageBox::Question); QPixmap iconPixmap = mb1.iconPixmap(); mb1.setIconPixmap(iconPixmap); - Q_ASSERT(mb1.icon() == QMessageBox::NoIcon); + QVERIFY(mb1.icon() == QMessageBox::NoIcon); - QString bt0 = mb1.buttonText(QMessageBox::Ok); - QString bt1 = mb1.buttonText(QMessageBox::Cancel); - QString bt2 = mb1.buttonText(QMessageBox::Ok | QMessageBox::Default); - - Q_ASSERT(bt0 == "OK"); - Q_ASSERT(bt1.isEmpty()); - Q_ASSERT(bt2.isEmpty()); + QCOMPARE(mb1.buttonText(QMessageBox::Ok), "OK"); + QCOMPARE(mb1.buttonText(QMessageBox::Cancel), QString()); + QCOMPARE(mb1.buttonText(QMessageBox::Ok | QMessageBox::Default), QString()); mb2.setButtonText(QMessageBox::Cancel, "Foo"); mb2.setButtonText(QMessageBox::Ok, "Bar"); mb2.setButtonText(QMessageBox::Ok | QMessageBox::Default, "Baz"); - Q_ASSERT(mb2.buttonText(QMessageBox::Cancel).isEmpty()); - Q_ASSERT(mb2.buttonText(QMessageBox::Ok) == "Bar"); + QCOMPARE(mb2.buttonText(QMessageBox::Cancel), QString()); + QCOMPARE(mb2.buttonText(QMessageBox::Ok), "Bar"); - Q_ASSERT(mb3b.buttonText(QMessageBox::Yes).endsWith("Yes")); - Q_ASSERT(mb3b.buttonText(QMessageBox::YesAll).isEmpty()); - Q_ASSERT(mb3b.buttonText(QMessageBox::Ok).isEmpty()); + QVERIFY(mb3b.buttonText(QMessageBox::Yes).endsWith("Yes")); + QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString()); + QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString()); mb3b.setButtonText(QMessageBox::Yes, "Blah"); mb3b.setButtonText(QMessageBox::YesAll, "Zoo"); mb3b.setButtonText(QMessageBox::Ok, "Zoo"); - Q_ASSERT(mb3b.buttonText(QMessageBox::Yes) == "Blah"); - Q_ASSERT(mb3b.buttonText(QMessageBox::YesAll).isEmpty()); - Q_ASSERT(mb3b.buttonText(QMessageBox::Ok).isEmpty()); + QCOMPARE(mb3b.buttonText(QMessageBox::Yes), "Blah"); + QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString()); + QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString()); - Q_ASSERT(mb1.textFormat() == Qt::AutoText); + QCOMPARE(mb1.textFormat(), Qt::AutoText); mb1.setTextFormat(Qt::PlainText); - Q_ASSERT(mb1.textFormat() == Qt::PlainText); + QCOMPARE(mb1.textFormat(), Qt::PlainText); CONVENIENCE_FUNC_SYMS(information); CONVENIENCE_FUNC_SYMS_EXTRA(information); @@ -610,7 +655,7 @@ void tst_QMessageBox::testSymbols() CONVENIENCE_FUNC_SYMS(critical); QSize sizeHint = mb1.sizeHint(); - Q_ASSERT(sizeHint.width() > 20 && sizeHint.height() > 20); + QVERIFY(sizeHint.width() > 20 && sizeHint.height() > 20); #ifdef QT3_SUPPORT //test QT3_SUPPORT stuff @@ -622,8 +667,8 @@ void tst_QMessageBox::testSymbols() QPixmap pm = QMessageBox::standardIcon(QMessageBox::Question, Qt::GUIStyle(1)); QPixmap pm2 = QMessageBox::standardIcon(QMessageBox::Question); - Q_ASSERT(pm.toImage() == iconPixmap.toImage()); - Q_ASSERT(pm2.toImage() == iconPixmap.toImage()); + QVERIFY(pm.toImage() == iconPixmap.toImage()); + QVERIFY(pm2.toImage() == iconPixmap.toImage()); int ret1 = QMessageBox::message("title", "text"); int ret2 = QMessageBox::message("title", "text", "OK"); @@ -642,10 +687,10 @@ void tst_QMessageBox::testSymbols() Q_UNUSED(ret5); QPixmap pm3 = QMessageBox::standardIcon(QMessageBox::NoIcon); - Q_ASSERT(pm3.isNull()); + QVERIFY(pm3.isNull()); pm3 = QMessageBox::standardIcon(QMessageBox::Information); - Q_ASSERT(!pm3.isNull()); + QVERIFY(!pm3.isNull()); #endif //QT3_SUPPORT QMessageBox::about(&mb1, "title", "text"); @@ -661,25 +706,49 @@ void tst_QMessageBox::detailsText() QCOMPARE(box.detailedText(), text); } +void tst_QMessageBox::detailsButtonText() +{ + QMessageBox box; + box.setDetailedText("bla"); + box.open(); + QApplication::postEvent(&box, new QEvent(QEvent::LanguageChange)); + QApplication::processEvents(); + QDialogButtonBox* bb = box.findChild<QDialogButtonBox*>("qt_msgbox_buttonbox"); + QVERIFY(bb); //get the detail button + + QList<QAbstractButton *> list = bb->buttons(); + QAbstractButton* btn = NULL; + foreach(btn, list) { + if (btn && (btn->inherits("QPushButton"))) { + if (btn->text() != QMessageBox::tr("OK") && btn->text() != QMessageBox::tr("Show Details...")) { + QFAIL(qPrintable(QString("Unexpected messagebox button text: %1").arg(btn->text()))); + } + } + } +} + void tst_QMessageBox::incorrectDefaultButton() { keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); //Do not crash here QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); QMessageBox::question( 0, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save ); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); QMessageBox::question( 0, "", "I've been hit!",QFlag(QMessageBox::Ok | QMessageBox::Cancel),QMessageBox::Save ); + QCOMPARE(keyToSend, -1); keyToSend = Qt::Key_Escape; - QTimer::singleShot(1000, this, SLOT(sendKey())); + sendKeySoon(); QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); //do not crash here -> call old function of QMessageBox in this case QMessageBox::question( 0, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Ok); + QCOMPARE(keyToSend, -1); } void tst_QMessageBox::updateSize() diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp index 3e62d04..a813a91 100644 --- a/tests/auto/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp @@ -155,6 +155,7 @@ private slots: void connectSlotsByName(); void invokeMetaMember(); void invokeQueuedMetaMember(); + void invokeBlockingQueuedMetaMember(); void invokeCustomTypes(); void invokeMetaConstructor(); void invokeTypedefTypes(); @@ -174,6 +175,9 @@ private slots: void metaMethod(); + void indexOfMethod_data(); + void indexOfMethod(); + signals: void value6Changed(); void value7Changed(const QString &); @@ -240,7 +244,12 @@ public: QObject *child; public slots: - void on_child1_destroyed(QObject *obj = 0) { ++invokeCount1; Q_ASSERT(obj && obj == child); } + void on_child1_destroyed(QObject *obj = 0) + { + ++invokeCount1; + if (!obj || obj != child) + qWarning() << "on_child1_destroyed invoked with wrong child object"; + } void on_child2_destroyed() { ++invokeCount2; } }; @@ -264,7 +273,12 @@ public: } private slots: - void on_child1_destroyed(QObject *obj) { ++invokeCount1; Q_ASSERT(obj && obj == child); } + void on_child1_destroyed(QObject *obj) + { + ++invokeCount1; + if (!obj || obj != child) + qWarning() << "on_child1_destroyed invoked with wrong child object"; + } void on_child1_destroyed() { ++invokeCount2; } }; @@ -336,6 +350,9 @@ public slots: void testLongLong(qint64 ll1, quint64 ll2); + void moveToThread(QThread *t) + { QObject::moveToThread(t); } + signals: void sig0(); QString sig1(QString s1); @@ -583,6 +600,138 @@ void tst_QMetaObject::invokeQueuedMetaMember() QCOMPARE(obj.slotResult, QString("testLongLong:-1,0")); } +void tst_QMetaObject::invokeBlockingQueuedMetaMember() +{ + QThread t; + t.start(); + QtTestObject obj; + obj.moveToThread(&t); + + QString t1("1"); QString t2("2"); QString t3("3"); QString t4("4"); QString t5("5"); + QString t6("6"); QString t7("7"); QString t8("8"); QString t9("9"); QString t10("X"); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Qt::BlockingQueuedConnection, Q_ARG(QString, t1))); + QCOMPARE(obj.slotResult, QString("sl1:1")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl2", Qt::BlockingQueuedConnection, Q_ARG(const QString, t1), Q_ARG(QString, t2))); + QCOMPARE(obj.slotResult, QString("sl2:12")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl3", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), Q_ARG(QString, t3))); + QCOMPARE(obj.slotResult, QString("sl3:123")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl4", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), + Q_ARG(QString, t3), Q_ARG(QString, t4))); + QCOMPARE(obj.slotResult, QString("sl4:1234")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl5", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), + Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, "5"))); + QCOMPARE(obj.slotResult, QString("sl5:12345")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl6", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), + Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6))); + QCOMPARE(obj.slotResult, QString("sl6:123456")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl7", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), + Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6), + Q_ARG(QString, t7))); + QCOMPARE(obj.slotResult, QString("sl7:1234567")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl8", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), + Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6), + Q_ARG(QString, t7), Q_ARG(QString, t8))); + QCOMPARE(obj.slotResult, QString("sl8:12345678")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl9", Qt::BlockingQueuedConnection, Q_ARG(QString, t1), Q_ARG(QString, t2), + Q_ARG(QString, t3), Q_ARG(QString, t4), Q_ARG(QString, t5), Q_ARG(QString, t6), + Q_ARG(QString, t7), Q_ARG(QString, t8), Q_ARG(QString, t9))); + QCOMPARE(obj.slotResult, QString("sl9:123456789")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection)); + QCOMPARE(obj.slotResult, QString("sl11")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "testSender", Qt::BlockingQueuedConnection)); + QCOMPARE(obj.slotResult, QString("0x0")); + + QString refStr("whatever"); + QVERIFY(QMetaObject::invokeMethod(&obj, "testReference", Qt::BlockingQueuedConnection, QGenericArgument("QString&", &refStr))); + QCOMPARE(obj.slotResult, QString("testReference:whatever")); + QCOMPARE(refStr, QString("gotcha")); + + qint64 ll1 = -1; + quint64 ll2 = 0; + QVERIFY(QMetaObject::invokeMethod(&obj, + "testLongLong", + Qt::BlockingQueuedConnection, + Q_ARG(qint64, ll1), + Q_ARG(quint64, ll2))); + QCOMPARE(obj.slotResult, QString("testLongLong:-1,0")); + + QString exp; + QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, exp), Q_ARG(QString, "bubu"))); + QCOMPARE(exp, QString("yessir")); + QCOMPARE(obj.slotResult, QString("sl1:bubu")); + + QObject *ptr = 0; + QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QObject*,ptr))); + QCOMPARE(ptr, (QObject *)&obj); + QCOMPARE(obj.slotResult, QString("sl11")); + // try again with a space: + ptr = 0; + QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QObject * , ptr))); + QCOMPARE(ptr, (QObject *)&obj); + QCOMPARE(obj.slotResult, QString("sl11")); + + const char *ptr2 = 0; + QVERIFY(QMetaObject::invokeMethod(&obj, "sl12", Qt::BlockingQueuedConnection, Q_RETURN_ARG(const char*, ptr2))); + QVERIFY(ptr2 != 0); + QCOMPARE(obj.slotResult, QString("sl12")); + // try again with a space: + ptr2 = 0; + QVERIFY(QMetaObject::invokeMethod(&obj, "sl12", Qt::BlockingQueuedConnection, Q_RETURN_ARG(char const * , ptr2))); + QVERIFY(ptr2 != 0); + QCOMPARE(obj.slotResult, QString("sl12")); + + // test w/ template args + QList<QString> returnValue, argument; + argument << QString("one") << QString("two") << QString("three"); + QVERIFY(QMetaObject::invokeMethod(&obj, "sl13", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(QList<QString>, returnValue), + Q_ARG(QList<QString>, argument))); + QCOMPARE(returnValue, argument); + QCOMPARE(obj.slotResult, QString("sl13")); + + //test signals + QVERIFY(QMetaObject::invokeMethod(&obj, "sig0", Qt::BlockingQueuedConnection)); + QCOMPARE(obj.slotResult, QString("sl0")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Qt::BlockingQueuedConnection, Q_ARG(QString, "baba"))); + QCOMPARE(obj.slotResult, QString("sl1:baba")); + + exp.clear(); + QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, exp), Q_ARG(QString, "hehe"))); + QCOMPARE(exp, QString("yessir")); + QCOMPARE(obj.slotResult, QString("sl1:hehe")); + + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::doesNotExist()"); + 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)"); + QVERIFY(!QMetaObject::invokeMethod(&obj, "sl3", Qt::BlockingQueuedConnection, Q_ARG(QString, "arg"))); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,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. + QCOMPARE(exp, QString("yessir")); + QCOMPARE(obj.slotResult, QString("sl1:hehe")); + + QVERIFY(QMetaObject::invokeMethod(&obj, "moveToThread", Qt::BlockingQueuedConnection, Q_ARG(QThread*, QThread::currentThread()))); + t.quit(); + QVERIFY(t.wait()); + +} + + void tst_QMetaObject::qtMetaObjectInheritance() { @@ -941,5 +1090,31 @@ void tst_QMetaObject::metaMethod() QCOMPARE(obj.slotResult, QString("sl13")); } +void tst_QMetaObject::indexOfMethod_data() +{ + QTest::addColumn<QObject *>("object"); + QTest::addColumn<QByteArray>("name"); + QTest::addColumn<bool>("isSignal"); + QTest::newRow("indexOfMethod_data") << (QObject*)this << QByteArray("indexOfMethod_data()") << false; + QTest::newRow("deleteLater") << (QObject*)this << QByteArray("deleteLater()") << false; + QTest::newRow("value6changed") << (QObject*)this << QByteArray("value6Changed()") << true; + QTest::newRow("value7changed") << (QObject*)this << QByteArray("value7Changed(QString)") << true; + QTest::newRow("destroyed") << (QObject*)this << QByteArray("destroyed()") << true; + QTest::newRow("destroyed2") << (QObject*)this << QByteArray("destroyed(QObject*)") << true; +} + +void tst_QMetaObject::indexOfMethod() +{ + QFETCH(QObject *, object); + QFETCH(QByteArray, name); + QFETCH(bool, isSignal); + int idx = object->metaObject()->indexOfMethod(name); + QVERIFY(idx >= 0); + QCOMPARE(object->metaObject()->method(idx).signature(), name.constData()); + QCOMPARE(object->metaObject()->indexOfSlot(name), isSignal ? -1 : idx); + QCOMPARE(object->metaObject()->indexOfSignal(name), !isSignal ? -1 : idx); +} + + QTEST_MAIN(tst_QMetaObject) #include "tst_qmetaobject.moc" diff --git a/tests/auto/qmetatype/qmetatype.pro b/tests/auto/qmetatype/qmetatype.pro index a84d238..ed1de83 100644 --- a/tests/auto/qmetatype/qmetatype.pro +++ b/tests/auto/qmetatype/qmetatype.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qmetatype.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qmetatype/tst_qmetatype.cpp b/tests/auto/qmetatype/tst_qmetatype.cpp index 9b75684..897664e 100644 --- a/tests/auto/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/qmetatype/tst_qmetatype.cpp @@ -96,10 +96,18 @@ struct Bar Bar() { // check re-entrancy - Q_ASSERT(QMetaType::isRegistered(qRegisterMetaType<Foo>("Foo"))); + if (!QMetaType::isRegistered(qRegisterMetaType<Foo>("Foo"))) { + qWarning("%s: re-entrancy test failed", Q_FUNC_INFO); + ++failureCount; + } } + +public: + static int failureCount; }; +int Bar::failureCount = 0; + class MetaTypeTorturer: public QThread { Q_OBJECT @@ -113,17 +121,35 @@ protected: #ifdef Q_OS_LINUX pthread_yield(); #endif - Q_ASSERT(QMetaType::isRegistered(tp)); - Q_ASSERT(QMetaType::type(nm) == tp); - Q_ASSERT(QMetaType::typeName(tp) == name); + if (!QMetaType::isRegistered(tp)) { + ++failureCount; + qWarning() << name << "is not a registered metatype"; + } + if (QMetaType::type(nm) != tp) { + ++failureCount; + qWarning() << "Wrong metatype returned for" << name; + } + if (QMetaType::typeName(tp) != name) { + ++failureCount; + qWarning() << "Wrong typeName returned for" << tp; + } void *buf = QMetaType::construct(tp, 0); void *buf2 = QMetaType::construct(tp, buf); - Q_ASSERT(buf); - Q_ASSERT(buf2); + if (!buf) { + ++failureCount; + qWarning() << "Null buffer returned by QMetaType::construct(tp, 0)"; + } + if (!buf2) { + ++failureCount; + qWarning() << "Null buffer returned by QMetaType::construct(tp, buf)"; + } QMetaType::destroy(tp, buf); QMetaType::destroy(tp, buf2); } } +public: + MetaTypeTorturer() : failureCount(0) { } + int failureCount; }; void tst_QMetaType::threadSafety() @@ -139,6 +165,11 @@ void tst_QMetaType::threadSafety() QVERIFY(t1.wait()); QVERIFY(t2.wait()); QVERIFY(t3.wait()); + + QCOMPARE(t1.failureCount, 0); + QCOMPARE(t2.failureCount, 0); + QCOMPARE(t3.failureCount, 0); + QCOMPARE(Bar::failureCount, 0); } namespace TestSpace @@ -160,6 +191,11 @@ void tst_QMetaType::qMetaTypeId() QCOMPARE(::qMetaTypeId<QString>(), int(QMetaType::QString)); QCOMPARE(::qMetaTypeId<int>(), int(QMetaType::Int)); QCOMPARE(::qMetaTypeId<TestSpace::Foo>(), QMetaType::type("TestSpace::Foo")); + + QCOMPARE(::qMetaTypeId<char>(), QMetaType::type("char")); + QCOMPARE(::qMetaTypeId<uchar>(), QMetaType::type("unsigned char")); + QCOMPARE(::qMetaTypeId<signed char>(), QMetaType::type("signed char")); + QCOMPARE(::qMetaTypeId<qint8>(), QMetaType::type("qint8")); } void tst_QMetaType::properties() diff --git a/tests/auto/qmovie/animations/corrupt.gif b/tests/auto/qmovie/animations/corrupt.gif Binary files differnew file mode 100644 index 0000000..c1545eb --- /dev/null +++ b/tests/auto/qmovie/animations/corrupt.gif diff --git a/tests/auto/qmovie/qmovie.pro b/tests/auto/qmovie/qmovie.pro index 510a70e..855eb9e 100644 --- a/tests/auto/qmovie/qmovie.pro +++ b/tests/auto/qmovie/qmovie.pro @@ -7,19 +7,20 @@ MOC_DIR=tmp !contains(QT_CONFIG, no-mng):DEFINES += QTEST_HAVE_MNG wince*: { - addFiles.sources = animations\\* + addFiles.files = animations\\* addFiles.path = animations DEPLOYMENT += addFiles } +RESOURCES += resources.qrc symbian: { - addFiles.sources = animations\\* + addFiles.files = animations\\* addFiles.path = animations DEPLOYMENT += addFiles qt_not_deployed { - imagePlugins.sources = qjpeg.dll qgif.dll qmng.dll + imagePlugins.files = qjpeg.dll qgif.dll qmng.dll imagePlugins.path = imageformats DEPLOYMENT += imagePlugins } diff --git a/tests/auto/qmovie/resources.qrc b/tests/auto/qmovie/resources.qrc new file mode 100644 index 0000000..ce459a0 --- /dev/null +++ b/tests/auto/qmovie/resources.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>animations/corrupt.gif</file> +</qresource> +</RCC> diff --git a/tests/auto/qmovie/tst_qmovie.cpp b/tests/auto/qmovie/tst_qmovie.cpp index 1f6ddde..15c7f85 100644 --- a/tests/auto/qmovie/tst_qmovie.cpp +++ b/tests/auto/qmovie/tst_qmovie.cpp @@ -72,6 +72,7 @@ private slots: void jumpToFrame_data(); void jumpToFrame(); void changeMovieFile(); + void infiniteLoop(); }; // Testing get/set functions @@ -208,5 +209,17 @@ void tst_QMovie::changeMovieFile() QVERIFY(movie.currentFrameNumber() == -1); } +void tst_QMovie::infiniteLoop() +{ + QLabel label; + label.show(); + QMovie *movie = new QMovie(QLatin1String(":animations/corrupt.gif"), QByteArray(), &label); + label.setMovie(movie); + movie->start(); + + QTestEventLoop::instance().enterLoop(1); + QTestEventLoop::instance().timeout(); +} + QTEST_MAIN(tst_QMovie) #include "tst_qmovie.moc" diff --git a/tests/auto/qmutex/qmutex.pro b/tests/auto/qmutex/qmutex.pro index bd24dcb..760dcfd 100644 --- a/tests/auto/qmutex/qmutex.pro +++ b/tests/auto/qmutex/qmutex.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qmutex.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qmutex/tst_qmutex.cpp b/tests/auto/qmutex/tst_qmutex.cpp index 3c4d849..0a9fc0a 100644 --- a/tests/auto/qmutex/tst_qmutex.cpp +++ b/tests/auto/qmutex/tst_qmutex.cpp @@ -129,27 +129,57 @@ void tst_QMutex::tryLock() testsTurn.release(); threadsTurn.acquire(); + QVERIFY(!normalMutex.tryLock(0)); + testsTurn.release(); + + threadsTurn.acquire(); + timer.start(); + QVERIFY(normalMutex.tryLock(0)); + QVERIFY(timer.elapsed() < 1000); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(!normalMutex.tryLock(0)); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + normalMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); } }; Thread thread; thread.start(); + // thread can't acquire lock + testsTurn.acquire(); + normalMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + threadsTurn.release(); + + // thread can acquire lock + testsTurn.acquire(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + normalMutex.unlock(); + threadsTurn.release(); + + // thread can't acquire lock, timeout = 1000 testsTurn.acquire(); normalMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); threadsTurn.release(); + // thread can acquire lock, timeout = 1000 testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); threadsTurn.release(); + // thread can't acquire lock, timeout = 0 testsTurn.acquire(); normalMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); threadsTurn.release(); + // thread can acquire lock, timeout = 0 testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(1, 0)); normalMutex.unlock(); @@ -190,6 +220,7 @@ void tst_QMutex::tryLock() timer.start(); QVERIFY(!recursiveMutex.tryLock(1000)); QVERIFY(timer.elapsed() >= 1000); + QVERIFY(!recursiveMutex.tryLock(0)); testsTurn.release(); threadsTurn.acquire(); @@ -206,12 +237,47 @@ void tst_QMutex::tryLock() testsTurn.release(); threadsTurn.acquire(); + QVERIFY(!recursiveMutex.tryLock(0)); + QVERIFY(!recursiveMutex.tryLock(0)); + testsTurn.release(); + + threadsTurn.acquire(); + timer.start(); + QVERIFY(recursiveMutex.tryLock(0)); + QVERIFY(timer.elapsed() < 1000); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + QVERIFY(recursiveMutex.tryLock(0)); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + testsTurn.release(); + + threadsTurn.acquire(); } }; Thread thread; thread.start(); + // thread can't acquire lock + testsTurn.acquire(); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(0, 1)); + recursiveMutex.lock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 2)); + threadsTurn.release(); + + // thread can acquire lock + testsTurn.acquire(); + QVERIFY(lockCount.testAndSetRelaxed(2, 1)); + recursiveMutex.unlock(); + QVERIFY(lockCount.testAndSetRelaxed(1, 0)); + recursiveMutex.unlock(); + threadsTurn.release(); + + // thread can't acquire lock, timeout = 1000 testsTurn.acquire(); recursiveMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); @@ -219,6 +285,7 @@ void tst_QMutex::tryLock() QVERIFY(lockCount.testAndSetRelaxed(1, 2)); threadsTurn.release(); + // thread can acquire lock, timeout = 1000 testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(2, 1)); recursiveMutex.unlock(); @@ -226,6 +293,7 @@ void tst_QMutex::tryLock() recursiveMutex.unlock(); threadsTurn.release(); + // thread can't acquire lock, timeout = 0 testsTurn.acquire(); recursiveMutex.lock(); QVERIFY(lockCount.testAndSetRelaxed(0, 1)); @@ -233,6 +301,7 @@ void tst_QMutex::tryLock() QVERIFY(lockCount.testAndSetRelaxed(1, 2)); threadsTurn.release(); + // thread can acquire lock, timeout = 0 testsTurn.acquire(); QVERIFY(lockCount.testAndSetRelaxed(2, 1)); recursiveMutex.unlock(); @@ -393,6 +462,7 @@ public: static QBasicAtomicInt lockCount; static QBasicAtomicInt sentinel; static QMutex mutex; + static int errorCount; void start() { t.start(); @@ -402,13 +472,13 @@ public: { while (t.elapsed() < one_minute) { mutex.lock(); - Q_ASSERT(!sentinel.ref()); - Q_ASSERT(sentinel.deref()); + if (sentinel.ref()) ++errorCount; + if (!sentinel.deref()) ++errorCount; lockCount.ref(); mutex.unlock(); if (mutex.tryLock()) { - Q_ASSERT(!sentinel.ref()); - Q_ASSERT(sentinel.deref()); + if (sentinel.ref()) ++errorCount; + if (!sentinel.deref()) ++errorCount; lockCount.ref(); mutex.unlock(); } @@ -418,6 +488,7 @@ public: QMutex StressTestThread::mutex; QBasicAtomicInt StressTestThread::lockCount = Q_BASIC_ATOMIC_INITIALIZER(0); QBasicAtomicInt StressTestThread::sentinel = Q_BASIC_ATOMIC_INITIALIZER(-1); +int StressTestThread::errorCount = 0; void tst_QMutex::stressTest() { @@ -427,6 +498,7 @@ void tst_QMutex::stressTest() QVERIFY(threads[0].wait(one_minute + 10000)); for (int i = 1; i < threadCount; ++i) QVERIFY(threads[i].wait(10000)); + QCOMPARE(StressTestThread::errorCount, 0); qDebug("locked %d times", int(StressTestThread::lockCount)); } @@ -465,7 +537,12 @@ void tst_QMutex::tryLockRace() TryLockRaceThread::mutex.unlock(); } +// Variable that will be protected by the mutex. Volatile so that the +// the optimiser doesn't mess with it based on the increment-then-decrement +// usage pattern. static volatile int qtbug16115_trylock_counter; +// Counter for how many times the protected variable has an incorrect value. +static int qtbug16115_failure_count = 0; void tst_QMutex::qtbug16115_trylock() { @@ -476,8 +553,10 @@ void tst_QMutex::qtbug16115_trylock() void run() { for (int i = 0; i < 1000000; ++i) { if (mut.tryLock(0)) { - Q_ASSERT((++qtbug16115_trylock_counter) == 1); - Q_ASSERT((--qtbug16115_trylock_counter) == 0); + if ((++qtbug16115_trylock_counter) != 1) + ++qtbug16115_failure_count; + if ((--qtbug16115_trylock_counter) != 0) + ++qtbug16115_failure_count; mut.unlock(); } } @@ -493,13 +572,16 @@ void tst_QMutex::qtbug16115_trylock() for (int i = 0; i < 1000000; ++i) { mut.lock(); - Q_ASSERT((++qtbug16115_trylock_counter) == 1); - Q_ASSERT((--qtbug16115_trylock_counter) == 0); + if ((++qtbug16115_trylock_counter) != 1) + ++qtbug16115_failure_count; + if ((--qtbug16115_trylock_counter) != 0) + ++qtbug16115_failure_count; mut.unlock(); } t1.wait(); t2.wait(); t3.wait(); + QCOMPARE(qtbug16115_failure_count, 0); } QTEST_MAIN(tst_QMutex) diff --git a/tests/auto/qmutexlocker/qmutexlocker.pro b/tests/auto/qmutexlocker/qmutexlocker.pro index ff8a3da..01c3691 100644 --- a/tests/auto/qmutexlocker/qmutexlocker.pro +++ b/tests/auto/qmutexlocker/qmutexlocker.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qmutexlocker.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qnativesocketengine/.gitignore b/tests/auto/qnativesocketengine/.gitignore deleted file mode 100644 index 4700e5e..0000000 --- a/tests/auto/qnativesocketengine/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tst_qnativesocketengine diff --git a/tests/auto/qnativesocketengine/qnativesocketengine.pro b/tests/auto/qnativesocketengine/qnativesocketengine.pro deleted file mode 100644 index 0275d37..0000000 --- a/tests/auto/qnativesocketengine/qnativesocketengine.pro +++ /dev/null @@ -1,13 +0,0 @@ -load(qttest_p4) -SOURCES += tst_qnativesocketengine.cpp - -include(../qnativesocketengine/qsocketengine.pri) - -requires(contains(QT_CONFIG,private_tests)) - -MOC_DIR=tmp - -QT = core network - -symbian: TARGET.CAPABILITY = NetworkServices - diff --git a/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp b/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp index df5845f..3373cf5 100644 --- a/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp +++ b/tests/auto/qnetworkaccessmanager_and_qprogressdialog/tst_qnetworkaccessmanager_and_qprogressdialog.cpp @@ -58,6 +58,7 @@ public: tst_QNetworkAccessManager_And_QProgressDialog(); private slots: void downloadCheck(); + void downloadCheck_data(); }; class DownloadCheckWidget : public QWidget @@ -72,9 +73,14 @@ public: QMetaObject::invokeMethod(this, "go", Qt::QueuedConnection); } bool lateReadyRead; + bool zeroCopy; public slots: void go() { + QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile")); + if (zeroCopy) + request.setAttribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute, 10*1024*1024); + QNetworkReply *reply = netmanager.get( QNetworkRequest( QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile") @@ -106,20 +112,30 @@ public slots: QTestEventLoop::instance().exitLoop(); } - private: QProgressDialog progressDlg; QNetworkAccessManager netmanager; }; + tst_QNetworkAccessManager_And_QProgressDialog::tst_QNetworkAccessManager_And_QProgressDialog() { Q_SET_DEFAULT_IAP } +void tst_QNetworkAccessManager_And_QProgressDialog::downloadCheck_data() +{ + QTest::addColumn<bool>("useZeroCopy"); + QTest::newRow("with-zeroCopy") << true; + QTest::newRow("without-zeroCopy") << false; +} + void tst_QNetworkAccessManager_And_QProgressDialog::downloadCheck() { + QFETCH(bool, useZeroCopy); + DownloadCheckWidget widget; + widget.zeroCopy = useZeroCopy; widget.show(); // run and exit on finished() QTestEventLoop::instance().enterLoop(10); diff --git a/tests/auto/qnetworkcachemetadata/qnetworkcachemetadata.pro b/tests/auto/qnetworkcachemetadata/qnetworkcachemetadata.pro index 77ad347..ae0941e 100644 --- a/tests/auto/qnetworkcachemetadata/qnetworkcachemetadata.pro +++ b/tests/auto/qnetworkcachemetadata/qnetworkcachemetadata.pro @@ -1,4 +1,5 @@ load(qttest_p4) +QT -= gui QT += network SOURCES += tst_qnetworkcachemetadata.cpp diff --git a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp index 0071a24..a83f6dd 100644 --- a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp +++ b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp @@ -182,6 +182,14 @@ void tst_QNetworkCookie::parseSingleCookie_data() cookie.setValue("\"\\\"a, b; c\\\"\""); QTest::newRow("with-value-with-special5") << "a = \"\\\"a, b; c\\\"\"" << cookie; + cookie.setValue("b c"); + QTest::newRow("with-value-with-whitespace") << "a = b c" << cookie; + + cookie.setValue("\"b\""); + QTest::newRow("quoted-value") << "a = \"b\"" << cookie; + cookie.setValue("\"b c\""); + QTest::newRow("quoted-value-with-whitespace") << "a = \"b c\"" << cookie; + cookie.setValue("b"); cookie.setSecure(true); QTest::newRow("secure") << "a=b;secure" << cookie; @@ -707,6 +715,7 @@ void tst_QNetworkCookie::parseMultipleCookies_data() cookie.setDomain("!@#$%^&*();:."); // the ';' is actually problematic, because it is a separator list = QList<QNetworkCookie>(); QTest::newRow("domain-non-alpha-numeric") << "NonAlphNumDomName=NonAlphNumDomValue; domain=!@#$%^&*()" << list; + QTest::newRow("expiration-3digit1") << "a=b; expires=123" << list; // used to ASSERT } void tst_QNetworkCookie::parseMultipleCookies() diff --git a/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp b/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp index d59a510..1b4256b 100644 --- a/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp +++ b/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp @@ -42,7 +42,7 @@ #include <QtTest/QtTest> #include <QtNetwork/QNetworkCookieJar> -#include "private/qnetworkcookiejar_p.h" +#include "private/qtldurl_p.h" class tst_QNetworkCookieJar: public QObject { @@ -438,7 +438,7 @@ void tst_QNetworkCookieJar::effectiveTLDs() #endif QFETCH(QString, domain); QFETCH(bool, isTLD); - QCOMPARE(QNetworkCookieJarPrivate::isEffectiveTLD(domain), isTLD); + QCOMPARE(qIsEffectiveTLD(domain), isTLD); } QTEST_MAIN(tst_QNetworkCookieJar) diff --git a/tests/auto/qnetworkdiskcache/qnetworkdiskcache.pro b/tests/auto/qnetworkdiskcache/qnetworkdiskcache.pro index 3b13087..c05171d 100644 --- a/tests/auto/qnetworkdiskcache/qnetworkdiskcache.pro +++ b/tests/auto/qnetworkdiskcache/qnetworkdiskcache.pro @@ -1,4 +1,5 @@ load(qttest_p4) +QT -= gui QT += network SOURCES += tst_qnetworkdiskcache.cpp diff --git a/tests/auto/qnetworkdiskcache/tst_qnetworkdiskcache.cpp b/tests/auto/qnetworkdiskcache/tst_qnetworkdiskcache.cpp index 63d6d0e..224d1cb 100644 --- a/tests/auto/qnetworkdiskcache/tst_qnetworkdiskcache.cpp +++ b/tests/auto/qnetworkdiskcache/tst_qnetworkdiskcache.cpp @@ -46,6 +46,8 @@ #include "../../shared/util.h" #define EXAMPLE_URL "http://user:pass@www.example.com/#foo" +//cached objects are organized into these many subdirs +#define NUM_SUBDIRECTORIES 16 class tst_QNetworkDiskCache : public QObject { @@ -176,10 +178,10 @@ void tst_QNetworkDiskCache::initTestCase() cache.clear(); QString s = QDir::tempPath() + "/diskCache/"; QDir dir; - dir.rmdir(s + "http"); - dir.rmdir(s + "https"); + dir.rmdir(s + "data7"); // the number is the internal cache version dir.rmdir(s + "prepared"); dir.rmdir(s); + dir.rmdir(s + "http"); // delete directory used by 4.7 and earlier (would make the tests fail) } // This will be called after the last test function is executed. @@ -277,16 +279,16 @@ void tst_QNetworkDiskCache::clear() QVERIFY(cache.cacheSize() > qint64(0)); QString cacheDirectory = cache.cacheDirectory(); - QCOMPARE(countFiles(cacheDirectory).count(), 3); + QCOMPARE(countFiles(cacheDirectory).count(), NUM_SUBDIRECTORIES + 3); cache.clear(); - QCOMPARE(countFiles(cacheDirectory).count(), 2); + QCOMPARE(countFiles(cacheDirectory).count(), NUM_SUBDIRECTORIES + 2); // don't delete files that it didn't create - QTemporaryFile file(cacheDirectory + "/cache_XXXXXX"); + QTemporaryFile file(cacheDirectory + "/XXXXXX"); if (file.open()) { - QCOMPARE(countFiles(cacheDirectory).count(), 3); + QCOMPARE(countFiles(cacheDirectory).count(), NUM_SUBDIRECTORIES + 3); cache.clear(); - QCOMPARE(countFiles(cacheDirectory).count(), 3); + QCOMPARE(countFiles(cacheDirectory).count(), NUM_SUBDIRECTORIES + 3); } } @@ -309,20 +311,11 @@ void tst_QNetworkDiskCache::data_data() // public QIODevice* data(QUrl const& url) void tst_QNetworkDiskCache::data() { -#ifdef Q_OS_SYMBIAN - QSKIP("Due to mmap(...) bug in Open C [Temtrack DEF142242]", SkipAll); -#endif QFETCH(QNetworkCacheMetaData, data); SubQNetworkDiskCache cache; QUrl url(EXAMPLE_URL); cache.setupWithOne(url, data); - // flush the cache - QTemporaryFile file(cache.cacheDirectory() + "/cache_XXXXXX.cache"); - if (file.open()) { - cache.call_fileMetaData(file.fileName()); - } - for (int i = 0; i < 3; ++i) { QIODevice *d = cache.data(url); QVERIFY(d); @@ -362,9 +355,9 @@ void tst_QNetworkDiskCache::remove() QUrl url(EXAMPLE_URL); cache.setupWithOne(url); QString cacheDirectory = cache.cacheDirectory(); - QCOMPARE(countFiles(cacheDirectory).count(), 3); + QCOMPARE(countFiles(cacheDirectory).count(), NUM_SUBDIRECTORIES + 3); cache.remove(url); - QCOMPARE(countFiles(cacheDirectory).count(), 2); + QCOMPARE(countFiles(cacheDirectory).count(), NUM_SUBDIRECTORIES + 2); } void tst_QNetworkDiskCache::setCacheDirectory_data() @@ -388,9 +381,6 @@ void tst_QNetworkDiskCache::setCacheDirectory() // public void updateMetaData(QNetworkCacheMetaData const& metaData) void tst_QNetworkDiskCache::updateMetaData() { -#ifdef Q_OS_SYMBIAN - QSKIP("Due to mmap(...) bug in Open C [Temtrack DEF142242]", SkipAll); -#endif QUrl url(EXAMPLE_URL); SubQNetworkDiskCache cache; cache.setupWithOne(url); @@ -414,7 +404,7 @@ void tst_QNetworkDiskCache::fileMetaData() QString cacheDirectory = cache.cacheDirectory(); QStringList list = countFiles(cacheDirectory); - QCOMPARE(list.count(), 3); + QCOMPARE(list.count(), NUM_SUBDIRECTORIES + 3); foreach(QString fileName, list) { QFileInfo info(fileName); if (info.isFile()) { @@ -491,7 +481,7 @@ void tst_QNetworkDiskCache::oldCacheVersionFile() if (pass == 0) { QString name; { - QTemporaryFile file(cache.cacheDirectory() + "/cache_XXXXXX.cache"); + QTemporaryFile file(cache.cacheDirectory() + "/XXXXXX.d"); file.setAutoRemove(false); QVERIFY(file.open()); QDataStream out(&file); @@ -507,7 +497,7 @@ void tst_QNetworkDiskCache::oldCacheVersionFile() QVERIFY(!QFile::exists(name)); } else { QStringList files = countFiles(cache.cacheDirectory()); - QCOMPARE(files.count(), 3); + QCOMPARE(files.count(), NUM_SUBDIRECTORIES + 3); // find the file QString cacheFile; foreach (QString file, files) { diff --git a/tests/auto/qnetworkinterface/tst_qnetworkinterface.cpp b/tests/auto/qnetworkinterface/tst_qnetworkinterface.cpp index 68684f2..2077717 100644 --- a/tests/auto/qnetworkinterface/tst_qnetworkinterface.cpp +++ b/tests/auto/qnetworkinterface/tst_qnetworkinterface.cpp @@ -45,6 +45,8 @@ #include <qcoreapplication.h> #include <qnetworkinterface.h> #include <qtcpsocket.h> +#include <QNetworkConfigurationManager> +#include <QNetworkSession> #include "../network-settings.h" //TESTED_FILES=qnetworkinterface.cpp qnetworkinterface.h qnetworkinterface_unix.cpp qnetworkinterface_win.cpp @@ -58,23 +60,59 @@ public: virtual ~tst_QNetworkInterface(); private slots: + void initTestCase(); + void cleanupTestCase(); void dump(); void loopbackIPv4(); void loopbackIPv6(); void localAddress(); void interfaceFromXXX(); void copyInvalidInterface(); + +private: +#ifndef QT_NO_BEARER_MANAGEMENT + QNetworkConfigurationManager *netConfMan; + QNetworkConfiguration networkConfiguration; + QScopedPointer<QNetworkSession> networkSession; +#endif }; tst_QNetworkInterface::tst_QNetworkInterface() { - Q_SET_DEFAULT_IAP } tst_QNetworkInterface::~tst_QNetworkInterface() { } +void tst_QNetworkInterface::initTestCase() +{ +#ifndef QT_NO_BEARERMANAGEMENT + netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + networkConfiguration = netConfMan->defaultConfiguration(); + if (networkConfiguration.isValid()) { + networkSession.reset(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); + } +#endif +} + +void tst_QNetworkInterface::cleanupTestCase() +{ +#ifndef QT_NO_BEARERMANAGEMENT + if (networkSession && networkSession->isOpen()) { + networkSession->close(); + } +#endif +} void tst_QNetworkInterface::dump() { @@ -127,10 +165,6 @@ void tst_QNetworkInterface::loopbackIPv4() void tst_QNetworkInterface::loopbackIPv6() { -#ifdef Q_OS_SYMBIAN - QSKIP( "Symbian: IPv6 is not yet supported", SkipAll ); -#else - QList<QHostAddress> all = QNetworkInterface::allAddresses(); bool loopbackfound = false; @@ -144,7 +178,6 @@ void tst_QNetworkInterface::loopbackIPv6() anyIPv6 = true; QVERIFY(!anyIPv6 || loopbackfound); -#endif } void tst_QNetworkInterface::localAddress() diff --git a/tests/auto/qnetworkproxyfactory/qnetworkproxyfactory.pro b/tests/auto/qnetworkproxyfactory/qnetworkproxyfactory.pro index f05c423..17ad403 100644 --- a/tests/auto/qnetworkproxyfactory/qnetworkproxyfactory.pro +++ b/tests/auto/qnetworkproxyfactory/qnetworkproxyfactory.pro @@ -7,5 +7,5 @@ QT = core network SOURCES += tst_qnetworkproxyfactory.cpp -symbian: TARGET.CAPABILITY = NetworkServices +symbian: TARGET.CAPABILITY = NetworkServices ReadUserData diff --git a/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp b/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp index c56fedb..136d4d8 100644 --- a/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp +++ b/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp @@ -47,24 +47,63 @@ #include <qdebug.h> #include <qnetworkproxy.h> #include <QThread> +#include <QNetworkConfiguration> +#include <QNetworkConfigurationManager> +#include <QNetworkSession> +#include <QNetworkAccessManager> +#include <QNetworkReply> +#include <QNetworkRequest> +#include <QList> + +Q_DECLARE_METATYPE(QNetworkConfiguration); +Q_DECLARE_METATYPE(QList<QNetworkProxy>); class tst_QNetworkProxyFactory : public QObject { Q_OBJECT + +public: + tst_QNetworkProxyFactory(); + + class QDebugProxyFactory : public QNetworkProxyFactory + { + public: + virtual QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery()) + { + returnedList = QNetworkProxyFactory::systemProxyForQuery(query); + requestCounter++; + return returnedList; + } + QList<QNetworkProxy> returnedList; + int requestCounter; + }; + private slots: void systemProxyForQueryCalledFromThread(); void systemProxyForQuery() const; +#ifndef QT_NO_BEARERMANAGEMENT + void fromConfigurations(); + void inNetworkAccessManager_data(); + void inNetworkAccessManager(); +#endif private: QString formatProxyName(const QNetworkProxy & proxy) const; + QDebugProxyFactory *factory; }; +tst_QNetworkProxyFactory::tst_QNetworkProxyFactory() +{ + factory = new QDebugProxyFactory; + QNetworkProxyFactory::setApplicationProxyFactory(factory); +} + QString tst_QNetworkProxyFactory::formatProxyName(const QNetworkProxy & proxy) const { QString proxyName; if (!proxy.user().isNull()) proxyName.append("%1:%2@").arg(proxy.user(), proxy.password()); - proxyName.append("%1:%2").arg(proxy.hostName(), proxy.port()); - proxyName.append(" (type=%1, capabilities=%2)").arg(proxy.type(), proxy.capabilities()); + proxyName.append(QString("%1:%2").arg(proxy.hostName()).arg(proxy.port())); + proxyName.append(QString(" (type=%1, capabilities=%2)").arg(proxy.type()).arg(proxy.capabilities())); return proxyName; } @@ -125,5 +164,111 @@ void tst_QNetworkProxyFactory::systemProxyForQueryCalledFromThread() QCOMPARE(thread.proxies, QNetworkProxyFactory::systemProxyForQuery(query)); } +#ifndef QT_NO_BEARERMANAGEMENT + +//Purpose of this test is just to check systemProxyForQuery doesn't hang or crash +//with any given configuration including no configuration. +//We can't test it returns the right proxies without implementing the native proxy code +//again here, which would be testing our implementation against itself. +//Therefore it's just testing that something valid is returned (at least a NoProxy entry) +void tst_QNetworkProxyFactory::fromConfigurations() +{ + QNetworkConfigurationManager manager; + //update is done to get the active / discovered states + manager.updateConfigurations(); + connect(&manager, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QList<QNetworkProxy> proxies; + QUrl url(QLatin1String("http://qt.nokia.com")); + //get from known configurations + foreach (QNetworkConfiguration config, manager.allConfigurations()) { + QNetworkProxyQuery query(config, url, QNetworkProxyQuery::UrlRequest); + proxies = QNetworkProxyFactory::systemProxyForQuery(query); + QVERIFY(!proxies.isEmpty()); + foreach (QNetworkProxy proxy, proxies) { + qDebug() << config.name() << " - " << config.identifier() << " - " << formatProxyName(proxy); + } + } + + //get from default configuration + QNetworkProxyQuery defaultquery(url, QNetworkProxyQuery::UrlRequest); + proxies = QNetworkProxyFactory::systemProxyForQuery(defaultquery); + QVERIFY(!proxies.isEmpty()); + foreach (QNetworkProxy proxy, proxies) { + qDebug() << "default - " << formatProxyName(proxy); + } + + //get from active configuration + QNetworkSession session(manager.defaultConfiguration()); + session.open(); + QVERIFY(session.waitForOpened(30000)); + proxies = QNetworkProxyFactory::systemProxyForQuery(defaultquery); + QVERIFY(!proxies.isEmpty()); + foreach (QNetworkProxy proxy, proxies) { + qDebug() << "active - " << formatProxyName(proxy); + } + + //get from known configurations while there is one active + foreach (QNetworkConfiguration config, manager.allConfigurations()) { + QNetworkProxyQuery query(config, url, QNetworkProxyQuery::UrlRequest); + proxies = QNetworkProxyFactory::systemProxyForQuery(query); + QVERIFY(!proxies.isEmpty()); + foreach (QNetworkProxy proxy, proxies) { + qDebug() << config.name() << " - " << config.identifier() << " - " << formatProxyName(proxy); + } + } +} + +void tst_QNetworkProxyFactory::inNetworkAccessManager_data() +{ + QTest::addColumn<QNetworkConfiguration>("config"); + QTest::addColumn<QList<QNetworkProxy> >("proxies"); + QNetworkConfigurationManager manager; + //get from known configurations + foreach (QNetworkConfiguration config, manager.allConfigurations()) { + QNetworkProxyQuery query(config, QUrl(QString("http://qt.nokia.com")), QNetworkProxyQuery::UrlRequest); + QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery(query); + QTest::newRow(config.name().toUtf8()) << config << proxies; + } +} + +//Purpose of this test is to check that QNetworkAccessManager uses the proxy from the configuration it +//has been given. Needs two or more working configurations to be a good test. +void tst_QNetworkProxyFactory::inNetworkAccessManager() +{ + QFETCH(QNetworkConfiguration, config); + QFETCH(QList<QNetworkProxy>, proxies); + + int count = factory->requestCounter; + + QNetworkAccessManager manager; + manager.setConfiguration(config); + + //using an internet server, because cellular APs won't have a route to the test server. + QNetworkRequest req(QUrl(QString("http://qt.nokia.com"))); + QNetworkReply *reply = manager.get(req); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(30); + delete reply; + + if (count == factory->requestCounter) { + //RND phones are preconfigured with several test access points which won't work without a matching SIM + //If the network fails to start, QNAM won't ask the factory for proxies so we can't test. + QSKIP("network configuration didn't start", SkipSingle); + } + + qDebug() << "testing network configuration for" << config.name(); + foreach (QNetworkProxy proxy, factory->returnedList) { + qDebug() << formatProxyName(proxy); + } + qDebug() << " <vs> "; + foreach (QNetworkProxy proxy, proxies) { + qDebug() << formatProxyName(proxy); + } + QCOMPARE(factory->returnedList, proxies); +} + +#endif //QT_NO_BEARERMANAGEMENT + QTEST_MAIN(tst_QNetworkProxyFactory) #include "tst_qnetworkproxyfactory.moc" diff --git a/tests/auto/qnetworkreply/image1.jpg b/tests/auto/qnetworkreply/image1.jpg Binary files differnew file mode 100644 index 0000000..dba31c1 --- /dev/null +++ b/tests/auto/qnetworkreply/image1.jpg diff --git a/tests/auto/qnetworkreply/image2.jpg b/tests/auto/qnetworkreply/image2.jpg Binary files differnew file mode 100644 index 0000000..72936e2 --- /dev/null +++ b/tests/auto/qnetworkreply/image2.jpg diff --git a/tests/auto/qnetworkreply/image3.jpg b/tests/auto/qnetworkreply/image3.jpg Binary files differnew file mode 100644 index 0000000..cede519 --- /dev/null +++ b/tests/auto/qnetworkreply/image3.jpg diff --git a/tests/auto/qnetworkreply/test/test.pro b/tests/auto/qnetworkreply/test/test.pro index 6e1b1e3..d1f6707 100644 --- a/tests/auto/qnetworkreply/test/test.pro +++ b/tests/auto/qnetworkreply/test/test.pro @@ -1,4 +1,5 @@ load(qttest_p4) +QT -= gui SOURCES += ../tst_qnetworkreply.cpp TARGET = ../tst_qnetworkreply @@ -15,24 +16,21 @@ win32 { QT = core network RESOURCES += ../qnetworkreply.qrc -wince*: { - addFiles.sources = ../empty ../rfc3252.txt ../resource +symbian|wince*:{ + # For cross compiled targets, reference data files need to be deployed + addFiles.files = ../empty ../rfc3252.txt ../resource ../bigfile ../*.jpg addFiles.path = . DEPLOYMENT += addFiles -} -symbian:{ - addFiles.sources = ../empty ../rfc3252.txt ../resource ../bigfile - addFiles.path = . - DEPLOYMENT += addFiles - - certFiles.sources = ../certs + certFiles.files = ../certs certFiles.path = . DEPLOYMENT += certFiles +} +symbian:{ # Symbian toolchain does not support correct include semantics INCLUDEPATH+=..\\..\\..\\..\\include\\QtNetwork\\private # bigfile test case requires more heap - TARGET.EPOCHEAPSIZE="0x100 0x1000000" + TARGET.EPOCHEAPSIZE="0x100 0x10000000" TARGET.CAPABILITY="ALL -TCB" } diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index ebf8295..25925bd 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -47,6 +47,7 @@ #include <QtCore/QEventLoop> #include <QtCore/QFile> #include <QtCore/QSharedPointer> +#include <QtCore/QScopedPointer> #include <QtCore/QTemporaryFile> #include <QtNetwork/QTcpServer> #include <QtNetwork/QTcpSocket> @@ -60,10 +61,17 @@ #include <QtNetwork/qnetworkrequest.h> #include <QtNetwork/qnetworkreply.h> #include <QtNetwork/qnetworkcookie.h> +#include <QtNetwork/QHttpPart> +#include <QtNetwork/QHttpMultiPart> #ifndef QT_NO_OPENSSL #include <QtNetwork/qsslerror.h> #include <QtNetwork/qsslconfiguration.h> #endif +#ifndef QT_NO_BEARERMANAGEMENT +#include <QtNetwork/qnetworkconfigmanager.h> +#include <QtNetwork/qnetworkconfiguration.h> +#include <QtNetwork/qnetworksession.h> +#endif #include <time.h> @@ -75,6 +83,7 @@ #include "../network-settings.h" +Q_DECLARE_METATYPE(QSharedPointer<char>) Q_DECLARE_METATYPE(QNetworkReply*) Q_DECLARE_METATYPE(QAuthenticator*) Q_DECLARE_METATYPE(QNetworkProxy) @@ -82,8 +91,11 @@ Q_DECLARE_METATYPE(QNetworkProxyQuery) Q_DECLARE_METATYPE(QList<QNetworkProxy>) Q_DECLARE_METATYPE(QNetworkReply::NetworkError) Q_DECLARE_METATYPE(QBuffer*) - -const int SynchronousRequestAttribute = QNetworkRequest::DownloadBufferAttribute + 1; +Q_DECLARE_METATYPE(QHttpMultiPart *) +Q_DECLARE_METATYPE(QList<QFile*>) // for multiparts +#ifndef QT_NO_OPENSSL +Q_DECLARE_METATYPE(QSslConfiguration) +#endif class QNetworkReplyPtr: public QSharedPointer<QNetworkReply> { @@ -134,12 +146,19 @@ class tst_QNetworkReply: public QObject QSslConfiguration storedSslConfiguration; QList<QSslError> storedExpectedSslErrors; #endif +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkConfigurationManager *netConfMan; + QNetworkConfiguration networkConfiguration; + QScopedPointer<QNetworkSession> networkSession; +#endif public: tst_QNetworkReply(); ~tst_QNetworkReply(); QString runSimpleRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QNetworkReplyPtr &reply, const QByteArray &data = QByteArray()); + QString runMultipartRequest(const QNetworkRequest &request, QNetworkReplyPtr &reply, + QHttpMultiPart *multiPart, const QByteArray &verb); QString runCustomRequest(const QNetworkRequest &request, QNetworkReplyPtr &reply, const QByteArray &verb, QIODevice *data); @@ -186,16 +205,22 @@ private Q_SLOTS: void putToHttp(); void putToHttpSynchronous_data(); void putToHttpSynchronous(); + void putToHttpMultipart_data(); + void putToHttpMultipart(); void postToHttp_data(); void postToHttp(); void postToHttpSynchronous_data(); void postToHttpSynchronous(); + void postToHttpMultipart_data(); + void postToHttpMultipart(); void deleteFromHttp_data(); void deleteFromHttp(); void putGetDeleteGetFromHttp_data(); void putGetDeleteGetFromHttp(); void sendCustomRequestToHttp_data(); void sendCustomRequestToHttp(); + void connectToIPv6Address_data(); + void connectToIPv6Address(); void ioGetFromData_data(); void ioGetFromData(); @@ -310,6 +335,8 @@ private Q_SLOTS: void ignoreSslErrorsList(); void ignoreSslErrorsListWithSlot_data(); void ignoreSslErrorsListWithSlot(); + void sslConfiguration_data(); + void sslConfiguration(); #endif void getAndThenDeleteObject_data(); @@ -317,7 +344,16 @@ private Q_SLOTS: void symbianOpenCDataUrlCrash(); + void getFromHttpIntoBuffer_data(); + void getFromHttpIntoBuffer(); + void getFromHttpIntoBuffer2_data(); + void getFromHttpIntoBuffer2(); + + void ioGetFromHttpWithoutContentLength(); + + void ioGetFromHttpBrokenChunkedEncoding(); void qtbug12908compressedHttpReply(); + void compressedHttpReplyBrokenGzip(); void getFromUnreachableIp(); @@ -333,7 +369,11 @@ private Q_SLOTS: void synchronousRequest_data(); void synchronousRequest(); +#ifndef QT_NO_OPENSSL void synchronousRequestSslFailure(); +#endif + + void httpAbort(); void dontInsertPartialContentIntoTheCache(); @@ -406,22 +446,34 @@ public: QTcpSocket *client; // always the last one that was received QByteArray dataToTransmit; QByteArray receivedData; + QSemaphore ready; bool doClose; bool doSsl; + bool ipv6; bool multiple; int totalConnections; - MiniHttpServer(const QByteArray &data, bool ssl = false) - : client(0), dataToTransmit(data), doClose(true), doSsl(ssl), + MiniHttpServer(const QByteArray &data, bool ssl = false, QThread *thread = 0, bool useipv6 = false) + : client(0), dataToTransmit(data), doClose(true), doSsl(ssl), ipv6(useipv6), multiple(false), totalConnections(0) { - listen(); + if(useipv6) { + listen(QHostAddress::AnyIPv6); + } else { + listen(); + } + if (thread) { + connect(thread, SIGNAL(started()), this, SLOT(threadStartedSlot())); + moveToThread(thread); + thread->start(); + ready.acquire(); + } } protected: void incomingConnection(int socketDescriptor) { - //qDebug() << "incomingConnection" << socketDescriptor; + //qDebug() << "incomingConnection" << socketDescriptor << "doSsl:" << doSsl << "ipv6:" << ipv6; if (!doSsl) { client = new QTcpSocket; client->setSocketDescriptor(socketDescriptor); @@ -450,6 +502,7 @@ private: { //qDebug() << "connectSocketSignals" << client; connect(client, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); + connect(client, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWrittenSlot())); connect(client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotError(QAbstractSocket::SocketError))); } @@ -477,17 +530,25 @@ public slots: if (multiple) receivedData.remove(0, doubleEndlPos+4); - client->write(dataToTransmit); - while (client->bytesToWrite() > 0) - client->waitForBytesWritten(); + // we need to emulate the bytesWrittenSlot call if the data is empty. + if (dataToTransmit.size() == 0) + QMetaObject::invokeMethod(this, "bytesWrittenSlot", Qt::QueuedConnection); + else + client->write(dataToTransmit); + } + } - if (doClose) { - client->disconnectFromHost(); - disconnect(client, 0, this, 0); - client = 0; - } + void bytesWrittenSlot() { + if (doClose && client->bytesToWrite() == 0) { + client->disconnectFromHost(); + disconnect(client, 0, this, 0); } } + + void threadStartedSlot() + { + ready.release(); + } }; class MyCookieJar: public QNetworkCookieJar @@ -568,9 +629,14 @@ public: } QIODevice *prepare(const QNetworkCacheMetaData &) - { Q_ASSERT(0 && "Should not have tried to add to the cache"); return 0; } + { + qFatal("%s: Should not have tried to add to the cache", Q_FUNC_INFO); + return 0; + } void insert(QIODevice *) - { Q_ASSERT(0 && "Should not have tried to add to the cache"); } + { + qFatal("%s: Should not have tried to add to the cache", Q_FUNC_INFO); + } void clear() { cache.clear(); } }; @@ -720,7 +786,9 @@ public: QTcpSocket* waitForNextConnectionSocket() { waitForNewConnection(-1); if (doSsl) { - Q_ASSERT(sslSocket); + if (!sslSocket) + qFatal("%s: sslSocket should not be null after calling waitForNewConnection()", + Q_FUNC_INFO); return sslSocket; } else { //qDebug() << "returning nextPendingConnection"; @@ -892,7 +960,8 @@ protected: while (dataIndex < wantedSize) { const int remainingBytes = wantedSize - measuredSentBytes; const int bytesToWrite = qMin(remainingBytes, static_cast<int>(BlockSize)); - Q_ASSERT(bytesToWrite); + if (bytesToWrite <= 0) + qFatal("%s: attempt to write %d bytes", Q_FUNC_INFO, bytesToWrite); measuredSentBytes += writeNextData(client, bytesToWrite); while (client->bytesToWrite() > 0) { @@ -951,7 +1020,8 @@ public: // Wait for data to be readyRead bool ok = connect(&senderObj, SIGNAL(dataReady()), this, SLOT(slotDataReady())); - Q_ASSERT(ok); + if (!ok) + qFatal("%s: Cannot connect dataReady signal", Q_FUNC_INFO); } void wrapUp() @@ -974,9 +1044,9 @@ protected: void timerEvent(QTimerEvent *) { //qDebug() << "RateControlledReader: timerEvent bytesAvailable=" << device->bytesAvailable(); - if (readBufferSize > 0) { - // This asserts passes all the time, except in the final flush. - //Q_ASSERT(device->bytesAvailable() <= readBufferSize); + if (readBufferSize > 0 && device->bytesAvailable() > readBufferSize) { + // This passes all the time, except in the final flush. + //qFatal("%s: Too many bytes available", Q_FUNC_INFO); } qint64 bytesRead = 0; @@ -1011,7 +1081,9 @@ tst_QNetworkReply::tst_QNetworkReply() qRegisterMetaType<QNetworkReply *>(); // for QSignalSpy qRegisterMetaType<QAuthenticator *>(); qRegisterMetaType<QNetworkProxy>(); +#ifndef QT_NO_OPENSSL qRegisterMetaType<QList<QSslError> >(); +#endif qRegisterMetaType<QNetworkReply::NetworkError>(); Q_SET_DEFAULT_IAP @@ -1074,6 +1146,38 @@ void tst_QNetworkReply::storeSslConfiguration() } #endif +QString tst_QNetworkReply::runMultipartRequest(const QNetworkRequest &request, + QNetworkReplyPtr &reply, + QHttpMultiPart *multiPart, + const QByteArray &verb) +{ + if (verb == "POST") + reply = manager.post(request, multiPart); + else + reply = manager.put(request, multiPart); + + // the code below is copied from tst_QNetworkReply::runSimpleRequest, see below + reply->setParent(this); + connect(reply, SIGNAL(finished()), SLOT(finished())); + connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(gotError())); + multiPart->setParent(reply); + + returnCode = Timeout; + loop = new QEventLoop; + QTimer::singleShot(25000, loop, SLOT(quit())); + int code = returnCode == Timeout ? loop->exec() : returnCode; + delete loop; + loop = 0; + + switch (code) { + case Failure: + return "Request failed: " + reply->errorString(); + case Timeout: + return "Network timeout"; + } + return QString(); +} + QString tst_QNetworkReply::runSimpleRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QNetworkReplyPtr &reply, @@ -1101,14 +1205,14 @@ QString tst_QNetworkReply::runSimpleRequest(QNetworkAccessManager::Operation op, break; default: - Q_ASSERT_X(false, "tst_QNetworkReply", "Invalid/unknown operation requested"); + qFatal("%s: Invalid/unknown operation requested", Q_FUNC_INFO); } reply->setParent(this); returnCode = Timeout; int code = Success; - if (request.attribute(static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute)).toBool()) { + if (request.attribute(QNetworkRequest::SynchronousRequestAttribute).toBool()) { if (reply->isFinished()) code = reply->error() != QNetworkReply::NoError ? Failure : Success; else @@ -1181,6 +1285,25 @@ void tst_QNetworkReply::initTestCase() #endif QDir::setSearchPaths("srcdir", QStringList() << SRCDIR); +#ifndef QT_NO_OPENSSL + QSslSocket::defaultCaCertificates(); //preload certificates +#endif +#ifndef QT_NO_BEARERMANAGEMENT + netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + networkConfiguration = netConfMan->defaultConfiguration(); + if (networkConfiguration.isValid()) { + networkSession.reset(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); + } +#endif } void tst_QNetworkReply::cleanupTestCase() @@ -1188,6 +1311,9 @@ void tst_QNetworkReply::cleanupTestCase() #if !defined Q_OS_WIN QFile::remove(wronlyFileName); #endif + if (networkSession && networkSession->isOpen()) { + networkSession->close(); + } } void tst_QNetworkReply::init() @@ -1491,6 +1617,12 @@ void tst_QNetworkReply::getErrors_data() QTest::addColumn<int>("httpStatusCode"); QTest::addColumn<bool>("dataIsEmpty"); + // empties + QTest::newRow("empty-url") << QString() << int(QNetworkReply::ProtocolUnknownError) << 0 << true; + QTest::newRow("empty-scheme-host") << SRCDIR "/rfc3252.txt" << int(QNetworkReply::ProtocolUnknownError) << 0 << true; + QTest::newRow("empty-scheme") << "//" + QtNetworkSettings::winServerName() + "/testshare/test.pri" + << int(QNetworkReply::ProtocolUnknownError) << 0 << true; + // file: errors QTest::newRow("file-host") << "file://this-host-doesnt-exist.troll.no/foo.txt" #if !defined Q_OS_WIN @@ -1539,6 +1671,12 @@ void tst_QNetworkReply::getErrors() { QFETCH(QString, url); QNetworkRequest request(url); + +#if defined(Q_OS_WIN) || defined (Q_OS_SYMBIAN) + if (qstrcmp(QTest::currentDataTag(), "empty-scheme-host") == 0 && QFileInfo(url).isAbsolute()) + QTest::ignoreMessage(QtWarningMsg, "QNetworkAccessFileBackendFactory: URL has no schema set, use file:// for files"); +#endif + QNetworkReplyPtr reply = manager.get(request); reply->setParent(this); // we have expect-fails @@ -1553,6 +1691,10 @@ void tst_QNetworkReply::getErrors() //qDebug() << reply->errorString(); QFETCH(int, error); +#if defined(Q_OS_WIN) || defined (Q_OS_SYMBIAN) + if (QFileInfo(url).isAbsolute()) + QEXPECT_FAIL("empty-scheme-host", "this is expected to fail on Windows and Symbian, QTBUG-17731", Abort); +#endif QEXPECT_FAIL("ftp-is-dir", "QFtp cannot provide enough detail", Abort); // the line below is not necessary QEXPECT_FAIL("ftp-dir-not-readable", "QFtp cannot provide enough detail", Abort); @@ -1725,7 +1867,7 @@ void tst_QNetworkReply::putToHttpSynchronous() QFETCH(QByteArray, data); request.setAttribute( - static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute), + QNetworkRequest::SynchronousRequestAttribute, true); RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::PutOperation, request, reply, data)); @@ -1757,6 +1899,7 @@ void tst_QNetworkReply::postToHttp() QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi"); QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); QNetworkReplyPtr reply; QFETCH(QByteArray, data); @@ -1783,9 +1926,10 @@ void tst_QNetworkReply::postToHttpSynchronous() QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi"); QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); request.setAttribute( - static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute), + QNetworkRequest::SynchronousRequestAttribute, true); QNetworkReplyPtr reply; @@ -1804,6 +1948,307 @@ void tst_QNetworkReply::postToHttpSynchronous() QCOMPARE(uploadedData, md5sum.toHex()); } +void tst_QNetworkReply::postToHttpMultipart_data() +{ + QTest::addColumn<QUrl>("url"); + QTest::addColumn<QHttpMultiPart *>("multiPart"); + QTest::addColumn<QByteArray>("expectedReplyData"); + QTest::addColumn<QByteArray>("contentType"); + + QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/multipart.cgi"); + QByteArray expectedData; + + + // empty parts + + QHttpMultiPart *emptyMultiPart = new QHttpMultiPart; + QTest::newRow("empty") << url << emptyMultiPart << expectedData << QByteArray("mixed"); + + QHttpMultiPart *emptyRelatedMultiPart = new QHttpMultiPart; + emptyRelatedMultiPart->setContentType(QHttpMultiPart::RelatedType); + QTest::newRow("empty-related") << url << emptyRelatedMultiPart << expectedData << QByteArray("related"); + + QHttpMultiPart *emptyAlternativeMultiPart = new QHttpMultiPart; + emptyAlternativeMultiPart->setContentType(QHttpMultiPart::AlternativeType); + QTest::newRow("empty-alternative") << url << emptyAlternativeMultiPart << expectedData << QByteArray("alternative"); + + + // text-only parts + + QHttpPart textPart; + textPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain")); + textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"text\"")); + textPart.setBody("7 bytes"); + QHttpMultiPart *multiPart1 = new QHttpMultiPart; + multiPart1->setContentType(QHttpMultiPart::FormDataType); + multiPart1->append(textPart); + expectedData = "key: text, value: 7 bytes\n"; + QTest::newRow("text") << url << multiPart1 << expectedData << QByteArray("form-data"); + + QHttpMultiPart *customMultiPart = new QHttpMultiPart; + customMultiPart->append(textPart); + expectedData = "header: Content-Type, value: 'text/plain'\n" + "header: Content-Disposition, value: 'form-data; name=\"text\"'\n" + "content: 7 bytes\n" + "\n"; + QTest::newRow("text-custom") << url << customMultiPart << expectedData << QByteArray("custom"); + + QHttpPart textPart2; + textPart2.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain")); + textPart2.setRawHeader("myRawHeader", "myValue"); + textPart2.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"text2\"")); + textPart2.setBody("some more bytes"); + textPart2.setBodyDevice((QIODevice *) 1); // test whether setting and unsetting of the device works + textPart2.setBodyDevice(0); + QHttpMultiPart *multiPart2 = new QHttpMultiPart; + multiPart2->setContentType(QHttpMultiPart::FormDataType); + multiPart2->append(textPart); + multiPart2->append(textPart2); + expectedData = "key: text2, value: some more bytes\n" + "key: text, value: 7 bytes\n"; + QTest::newRow("text-text") << url << multiPart2 << expectedData << QByteArray("form-data"); + + + QHttpPart textPart3; + textPart3.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain")); + textPart3.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"text3\"")); + textPart3.setRawHeader("Content-Location", "http://my.test.location.tld"); + textPart3.setBody("even more bytes"); + QHttpMultiPart *multiPart3 = new QHttpMultiPart; + multiPart3->setContentType(QHttpMultiPart::AlternativeType); + multiPart3->append(textPart); + multiPart3->append(textPart2); + multiPart3->append(textPart3); + expectedData = "header: Content-Type, value: 'text/plain'\n" + "header: Content-Disposition, value: 'form-data; name=\"text\"'\n" + "content: 7 bytes\n" + "\n" + "header: Content-Type, value: 'text/plain'\n" + "header: myRawHeader, value: 'myValue'\n" + "header: Content-Disposition, value: 'form-data; name=\"text2\"'\n" + "content: some more bytes\n" + "\n" + "header: Content-Type, value: 'text/plain'\n" + "header: Content-Disposition, value: 'form-data; name=\"text3\"'\n" + "header: Content-Location, value: 'http://my.test.location.tld'\n" + "content: even more bytes\n\n"; + QTest::newRow("text-text-text") << url << multiPart3 << expectedData << QByteArray("alternative"); + + + + // text and image parts + + QHttpPart imagePart11; + imagePart11.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); + imagePart11.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage\"")); + imagePart11.setRawHeader("Content-Location", "http://my.test.location.tld"); + imagePart11.setRawHeader("Content-ID", "my@id.tld"); + QFile *file11 = new QFile(SRCDIR "/image1.jpg"); + file11->open(QIODevice::ReadOnly); + imagePart11.setBodyDevice(file11); + QHttpMultiPart *imageMultiPart1 = new QHttpMultiPart(QHttpMultiPart::FormDataType); + imageMultiPart1->append(imagePart11); + file11->setParent(imageMultiPart1); + expectedData = "key: testImage, value: 87ef3bb319b004ba9e5e9c9fa713776e\n"; // md5 sum of file + QTest::newRow("image") << url << imageMultiPart1 << expectedData << QByteArray("form-data"); + + QHttpPart imagePart21; + imagePart21.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); + imagePart21.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage1\"")); + imagePart21.setRawHeader("Content-Location", "http://my.test.location.tld"); + imagePart21.setRawHeader("Content-ID", "my@id.tld"); + QFile *file21 = new QFile(SRCDIR "/image1.jpg"); + file21->open(QIODevice::ReadOnly); + imagePart21.setBodyDevice(file21); + QHttpMultiPart *imageMultiPart2 = new QHttpMultiPart(); + imageMultiPart2->setContentType(QHttpMultiPart::FormDataType); + imageMultiPart2->append(textPart); + imageMultiPart2->append(imagePart21); + file21->setParent(imageMultiPart2); + QHttpPart imagePart22; + imagePart22.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); + imagePart22.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage2\"")); + QFile *file22 = new QFile(SRCDIR "/image2.jpg"); + file22->open(QIODevice::ReadOnly); + imagePart22.setBodyDevice(file22); + imageMultiPart2->append(imagePart22); + file22->setParent(imageMultiPart2); + expectedData = "key: testImage1, value: 87ef3bb319b004ba9e5e9c9fa713776e\n" + "key: text, value: 7 bytes\n" + "key: testImage2, value: 483761b893f7fb1bd2414344cd1f3dfb\n"; + QTest::newRow("text-image-image") << url << imageMultiPart2 << expectedData << QByteArray("form-data"); + + + QHttpPart imagePart31; + imagePart31.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); + imagePart31.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage1\"")); + imagePart31.setRawHeader("Content-Location", "http://my.test.location.tld"); + imagePart31.setRawHeader("Content-ID", "my@id.tld"); + QFile *file31 = new QFile(SRCDIR "/image1.jpg"); + file31->open(QIODevice::ReadOnly); + imagePart31.setBodyDevice(file31); + QHttpMultiPart *imageMultiPart3 = new QHttpMultiPart(QHttpMultiPart::FormDataType); + imageMultiPart3->append(imagePart31); + file31->setParent(imageMultiPart3); + QHttpPart imagePart32; + imagePart32.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); + imagePart32.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage2\"")); + QFile *file32 = new QFile(SRCDIR "/image2.jpg"); + file32->open(QIODevice::ReadOnly); + imagePart32.setBodyDevice(file31); // check that resetting works + imagePart32.setBodyDevice(file32); + imageMultiPart3->append(imagePart32); + file32->setParent(imageMultiPart3); + QHttpPart imagePart33; + imagePart33.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); + imagePart33.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage3\"")); + QFile *file33 = new QFile(SRCDIR "/image3.jpg"); + file33->open(QIODevice::ReadOnly); + imagePart33.setBodyDevice(file33); + imageMultiPart3->append(imagePart33); + file33->setParent(imageMultiPart3); + expectedData = "key: testImage1, value: 87ef3bb319b004ba9e5e9c9fa713776e\n" + "key: testImage2, value: 483761b893f7fb1bd2414344cd1f3dfb\n" + "key: testImage3, value: ab0eb6fd4fcf8b4436254870b4513033\n"; + QTest::newRow("3-images") << url << imageMultiPart3 << expectedData << QByteArray("form-data"); + + + // note: nesting multiparts is not working currently; for that, the outputDevice would need to be public + +// QHttpPart imagePart41; +// imagePart41.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); +// QFile *file41 = new QFile(SRCDIR "/image1.jpg"); +// file41->open(QIODevice::ReadOnly); +// imagePart41.setBodyDevice(file41); +// +// QHttpMultiPart *innerMultiPart = new QHttpMultiPart(); +// innerMultiPart->setContentType(QHttpMultiPart::FormDataType); +// textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant()); +// innerMultiPart->append(textPart); +// innerMultiPart->append(imagePart41); +// textPart2.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant()); +// innerMultiPart->append(textPart2); +// +// QHttpPart nestedPart; +// nestedPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"nestedMessage")); +// nestedPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("multipart/alternative; boundary=\"" + innerMultiPart->boundary() + "\"")); +// innerMultiPart->outputDevice()->open(QIODevice::ReadOnly); +// nestedPart.setBodyDevice(innerMultiPart->outputDevice()); +// +// QHttpMultiPart *outerMultiPart = new QHttpMultiPart; +// outerMultiPart->setContentType(QHttpMultiPart::FormDataType); +// outerMultiPart->append(textPart); +// outerMultiPart->append(nestedPart); +// outerMultiPart->append(textPart2); +// expectedData = "nothing"; // the CGI.pm module running on the test server does not understand nested multiparts +// openFiles.clear(); +// openFiles << file41; +// QTest::newRow("nested") << url << outerMultiPart << expectedData << openFiles; + + + // test setting large chunks of content with a byte array instead of a device (DISCOURAGED because of high memory consumption, + // but we need to test that the behavior is correct) + QHttpPart imagePart51; + imagePart51.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); + imagePart51.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"testImage\"")); + QFile *file51 = new QFile(SRCDIR "/image1.jpg"); + file51->open(QIODevice::ReadOnly); + QByteArray imageData = file51->readAll(); + file51->close(); + delete file51; + imagePart51.setBody("7 bytes"); // check that resetting works + imagePart51.setBody(imageData); + QHttpMultiPart *imageMultiPart5 = new QHttpMultiPart; + imageMultiPart5->setContentType(QHttpMultiPart::FormDataType); + imageMultiPart5->append(imagePart51); + expectedData = "key: testImage, value: 87ef3bb319b004ba9e5e9c9fa713776e\n"; // md5 sum of file + QTest::newRow("image-as-content") << url << imageMultiPart5 << expectedData << QByteArray("form-data"); +} + +void tst_QNetworkReply::postToHttpMultipart() +{ + QFETCH(QUrl, url); + + static QSet<QByteArray> boundaries; + + QNetworkRequest request(url); + QNetworkReplyPtr reply; + + QFETCH(QHttpMultiPart *, multiPart); + QFETCH(QByteArray, expectedReplyData); + QFETCH(QByteArray, contentType); + + // hack for testing the setting of the content-type header by hand: + if (contentType == "custom") { + QByteArray contentType("multipart/custom; boundary=\"" + multiPart->boundary() + "\""); + request.setHeader(QNetworkRequest::ContentTypeHeader, contentType); + } + + QVERIFY2(! boundaries.contains(multiPart->boundary()), "boundary '" + multiPart->boundary() + "' has been created twice"); + boundaries.insert(multiPart->boundary()); + + RUN_REQUEST(runMultipartRequest(request, reply, multiPart, "POST")); + multiPart->deleteLater(); + + QCOMPARE(reply->url(), url); + QCOMPARE(reply->error(), QNetworkReply::NoError); + + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); // 200 Ok + + QVERIFY(multiPart->boundary().count() > 20); // check that there is randomness after the "boundary_.oOo._" string + QVERIFY(multiPart->boundary().count() < 70); + QByteArray replyData = reply->readAll(); + + expectedReplyData.prepend("content type: multipart/" + contentType + "; boundary=\"" + multiPart->boundary() + "\"\n"); +// QEXPECT_FAIL("nested", "the server does not understand nested multipart messages", Continue); // see above + QCOMPARE(replyData, expectedReplyData); +} + +void tst_QNetworkReply::putToHttpMultipart_data() +{ + postToHttpMultipart_data(); +} + +void tst_QNetworkReply::putToHttpMultipart() +{ + QSKIP("test server script cannot handle PUT data yet", SkipAll); + QFETCH(QUrl, url); + + static QSet<QByteArray> boundaries; + + QNetworkRequest request(url); + QNetworkReplyPtr reply; + + QFETCH(QHttpMultiPart *, multiPart); + QFETCH(QByteArray, expectedReplyData); + QFETCH(QByteArray, contentType); + + // hack for testing the setting of the content-type header by hand: + if (contentType == "custom") { + QByteArray contentType("multipart/custom; boundary=\"" + multiPart->boundary() + "\""); + request.setHeader(QNetworkRequest::ContentTypeHeader, contentType); + } + + QVERIFY2(! boundaries.contains(multiPart->boundary()), "boundary '" + multiPart->boundary() + "' has been created twice"); + boundaries.insert(multiPart->boundary()); + + RUN_REQUEST(runMultipartRequest(request, reply, multiPart, "PUT")); + multiPart->deleteLater(); + + QCOMPARE(reply->url(), url); + QCOMPARE(reply->error(), QNetworkReply::NoError); + + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); // 200 Ok + + QVERIFY(multiPart->boundary().count() > 20); // check that there is randomness after the "boundary_.oOo._" string + QVERIFY(multiPart->boundary().count() < 70); + QByteArray replyData = reply->readAll(); + + expectedReplyData.prepend("content type: multipart/" + contentType + "; boundary=\"" + multiPart->boundary() + "\"\n"); +// QEXPECT_FAIL("nested", "the server does not understand nested multipart messages", Continue); // see above + QCOMPARE(replyData, expectedReplyData); +} + void tst_QNetworkReply::deleteFromHttp_data() { QTest::addColumn<QUrl>("url"); @@ -1895,6 +2340,49 @@ void tst_QNetworkReply::putGetDeleteGetFromHttp() } +void tst_QNetworkReply::connectToIPv6Address_data() +{ + QTest::addColumn<QUrl>("url"); + QTest::addColumn<QNetworkReply::NetworkError>("error"); + QTest::addColumn<QByteArray>("dataToSend"); + QTest::addColumn<QByteArray>("hostfield"); + QTest::newRow("localhost") << QUrl(QByteArray("http://[::1]")) << QNetworkReply::NoError<< QByteArray("localhost") << QByteArray("[::1]"); + //QTest::newRow("ipv4localhost") << QUrl(QByteArray("http://127.0.0.1")) << QNetworkReply::NoError<< QByteArray("ipv4localhost") << QByteArray("127.0.0.1"); + //to add more test data here +} + +void tst_QNetworkReply::connectToIPv6Address() +{ + QFETCH(QUrl, url); + QFETCH(QNetworkReply::NetworkError, error); + QFETCH(QByteArray, dataToSend); + QFETCH(QByteArray, hostfield); + + QByteArray httpResponse = QByteArray("HTTP/1.0 200 OK\r\nContent-Length: "); + httpResponse += QByteArray::number(dataToSend.size()); + httpResponse += "\r\n\r\n"; + httpResponse += dataToSend; + + MiniHttpServer server(httpResponse, false, NULL/*thread*/, true/*useipv6*/); + server.doClose = true; + + url.setPort(server.serverPort()); + QNetworkRequest request(url); + + QNetworkReplyPtr reply = manager.get(request); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + QByteArray content = reply->readAll(); + //qDebug() << server.receivedData; + QByteArray hostinfo = "\r\nHost: " + hostfield + ":" + QByteArray::number(server.serverPort()) + "\r\n"; + QSKIP("Fix this -- Host Info verification failed on Windows XP", SkipAll); + QVERIFY(server.receivedData.contains(hostinfo)); + QVERIFY(content == dataToSend); + QCOMPARE(reply->url(), request.url()); + QVERIFY(reply->error() == error); +} + void tst_QNetworkReply::sendCustomRequestToHttp_data() { QTest::addColumn<QUrl>("url"); @@ -2300,7 +2788,7 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth() // now check with synchronous calls: { request.setAttribute( - static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute), + QNetworkRequest::SynchronousRequestAttribute, true); QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); @@ -2324,7 +2812,7 @@ void tst_QNetworkReply::ioGetFromHttpWithAuthSynchronous() QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt")); request.setAttribute( - static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute), + QNetworkRequest::SynchronousRequestAttribute, true); QSignalSpy authspy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); @@ -2409,7 +2897,7 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuth() reference.seek(0); { request.setAttribute( - static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute), + QNetworkRequest::SynchronousRequestAttribute, true); QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); @@ -2435,7 +2923,7 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuthSynchronous() QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); manager.setProxy(proxy); request.setAttribute( - static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute), + QNetworkRequest::SynchronousRequestAttribute, true); QSignalSpy authspy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); @@ -2815,16 +3303,16 @@ void tst_QNetworkReply::ioGetFromHttpWithCache_data() QTest::newRow("must-revalidate,200,prefer-network") << reply200 << "Reloaded" << content << int(QNetworkRequest::PreferNetwork) << QStringList() << false << true; QTest::newRow("must-revalidate,200,prefer-cache") - << reply200 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << QStringList() << true << false; + << reply200 << "Reloaded" << content << int(QNetworkRequest::PreferCache) << QStringList() << false << true; QTest::newRow("must-revalidate,200,always-cache") - << reply200 << "Not-reloaded" << content << int(QNetworkRequest::AlwaysCache) << QStringList() << true << false; + << reply200 << "" << content << int(QNetworkRequest::AlwaysCache) << QStringList() << false << false; QTest::newRow("must-revalidate,304,prefer-network") << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferNetwork) << QStringList() << true << true; QTest::newRow("must-revalidate,304,prefer-cache") - << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << QStringList() << true << false; + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << QStringList() << true << true; QTest::newRow("must-revalidate,304,always-cache") - << reply304 << "Not-reloaded" << content << int(QNetworkRequest::AlwaysCache) << QStringList() << true << false; + << reply304 << "" << content << int(QNetworkRequest::AlwaysCache) << QStringList() << false << false; // // Partial content @@ -3241,8 +3729,7 @@ void tst_QNetworkReply::ioPutToFileFromLocalSocket() QString socketname = "networkreplytest"; QLocalServer server; if (!server.listen(socketname)) { - if (QFile::exists(server.fullServerName())) - QFile::remove(server.fullServerName()); + QLocalServer::removeServer(socketname); QVERIFY(server.listen(socketname)); } QLocalSocket active; @@ -3287,7 +3774,7 @@ void tst_QNetworkReply::ioPutToFileFromProcess() { #if defined(Q_OS_WINCE) || defined (Q_OS_SYMBIAN) QSKIP("Currently no stdin/out supported for Windows CE / Symbian OS", SkipAll); -#endif +#else #ifdef Q_OS_WIN if (qstrcmp(QTest::currentDataTag(), "small") == 0) @@ -3325,6 +3812,7 @@ void tst_QNetworkReply::ioPutToFileFromProcess() QByteArray contents = file.readAll(); QCOMPARE(contents, data); #endif +#endif } void tst_QNetworkReply::ioPutToFtpFromFile_data() @@ -3438,6 +3926,8 @@ void tst_QNetworkReply::ioPostToHttpFromFile() QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi"); QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); + QNetworkReplyPtr reply = manager.post(request, &sourceFile); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -3514,8 +4004,10 @@ void tst_QNetworkReply::ioPostToHttpFromSocket() socketpair.endPoints[0]->write(data); QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); + manager.setProxy(proxy); - QNetworkReplyPtr reply = manager.post(QNetworkRequest(url), socketpair.endPoints[1]); + QNetworkReplyPtr reply = manager.post(request, socketpair.endPoints[1]); socketpair.endPoints[0]->close(); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -3588,8 +4080,9 @@ void tst_QNetworkReply::ioPostToHttpFromSocketSynchronous() QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi"); QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); request.setAttribute( - static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute), + QNetworkRequest::SynchronousRequestAttribute, true); QNetworkReplyPtr reply = manager.post(request, socketpair.endPoints[1]); @@ -3617,7 +4110,8 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileToEnd() QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; QNetworkRequest request(url); - QNetworkReplyPtr reply = manager.post(QNetworkRequest(url), &sourceFile); + request.setRawHeader("Content-Type", "application/octet-stream"); + QNetworkReplyPtr reply = manager.post(request, &sourceFile); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), @@ -3643,6 +4137,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileFiveBytes() QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); // only send 5 bytes request.setHeader(QNetworkRequest::ContentLengthHeader, 5); QVERIFY(request.header(QNetworkRequest::ContentLengthHeader).isValid()); @@ -3674,6 +4169,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfQBufferFiveBytes() QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); QNetworkReplyPtr reply = manager.post(request, &uploadBuffer); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -3703,6 +4199,7 @@ void tst_QNetworkReply::ioPostToHttpNoBufferFlag() QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); // disallow buffering request.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, true); request.setHeader(QNetworkRequest::ContentLengthHeader, data.size()); @@ -3765,6 +4262,7 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress() // create the request QUrl url = QUrl(QString("https://127.0.0.1:%1/").arg(server.serverPort())); QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); QNetworkReplyPtr reply = manager.post(request, &sourceFile); QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); connect(&server, SIGNAL(newEncryptedConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -3781,32 +4279,26 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress() incomingSocket->setReadBufferSize(1*1024); QTestEventLoop::instance().enterLoop(2); // some progress should have been made + QVERIFY(!spy.isEmpty()); QList<QVariant> args = spy.last(); - qDebug() << "tst_QNetworkReply::ioPostToHttpsUploadProgress" - << args.at(0).toLongLong() - << sourceFile.size() - << spy.size(); - QVERIFY(!args.isEmpty()); QVERIFY(args.at(0).toLongLong() > 0); - // FIXME this is where it messes up - QEXPECT_FAIL("", "Either the readBufferSize of QSslSocket is broken or we do upload too much. Hm.", Abort); QVERIFY(args.at(0).toLongLong() != sourceFile.size()); incomingSocket->setReadBufferSize(32*1024); incomingSocket->read(16*1024); QTestEventLoop::instance().enterLoop(2); // some more progress than before + QVERIFY(!spy.isEmpty()); QList<QVariant> args2 = spy.last(); - QVERIFY(!args2.isEmpty()); QVERIFY(args2.at(0).toLongLong() > args.at(0).toLongLong()); // set the read buffer to unlimited incomingSocket->setReadBufferSize(0); QTestEventLoop::instance().enterLoop(10); // progress should be finished + QVERIFY(!spy.isEmpty()); QList<QVariant> args3 = spy.last(); - QVERIFY(!args3.isEmpty()); QVERIFY(args3.at(0).toLongLong() > args2.at(0).toLongLong()); QCOMPARE(args3.at(0).toLongLong(), args3.at(1).toLongLong()); QCOMPARE(args3.at(0).toLongLong(), sourceFile.size()); @@ -3839,6 +4331,7 @@ void tst_QNetworkReply::ioGetFromBuiltinHttp_data() void tst_QNetworkReply::ioGetFromBuiltinHttp() { + QSKIP("Limiting is broken right now, check QTBUG-15065", SkipAll); QFETCH(bool, https); QFETCH(int, bufferSize); @@ -3877,7 +4370,7 @@ void tst_QNetworkReply::ioGetFromBuiltinHttp() connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QTime loopTime; loopTime.start(); - QTestEventLoop::instance().enterLoop(11); + QTestEventLoop::instance().enterLoop(30); const int elapsedTime = loopTime.elapsed(); server.wait(); reader.wrapUp(); @@ -3896,6 +4389,8 @@ void tst_QNetworkReply::ioGetFromBuiltinHttp() if (reader.data.size() < testData.size()) { // oops? QCOMPARE(reader.data, testData.mid(0, reader.data.size())); qDebug() << "The data is incomplete, the last" << testData.size() - reader.data.size() << "bytes are missing"; + QEXPECT_FAIL("http+limited", "Limiting is broken right now, check QTBUG-15065", Abort); + QEXPECT_FAIL("https+limited", "Limiting is broken right now, check QTBUG-15065", Abort); } QCOMPARE(reader.data.size(), testData.size()); QCOMPARE(reader.data, testData); @@ -3907,10 +4402,9 @@ void tst_QNetworkReply::ioGetFromBuiltinHttp() const int minRate = rate * 1024 * (100-allowedDeviation) / 100; const int maxRate = rate * 1024 * (100+allowedDeviation) / 100; qDebug() << minRate << "<="<< server.transferRate << "<=" << maxRate << "?"; - QVERIFY(server.transferRate >= minRate); - QEXPECT_FAIL("http+limited", "Limiting is broken right now", Continue); - QEXPECT_FAIL("https+limited", "Limiting is broken right now", Continue); - QVERIFY(server.transferRate <= maxRate); + QEXPECT_FAIL("http+limited", "Limiting is broken right now, check QTBUG-15065", Continue); + QEXPECT_FAIL("https+limited", "Limiting is broken right now, check QTBUG-15065", Continue); + QVERIFY(server.transferRate >= minRate && server.transferRate <= maxRate); } } @@ -3926,6 +4420,7 @@ void tst_QNetworkReply::ioPostToHttpUploadProgress() // create the request QUrl url = QUrl(QString("http://127.0.0.1:%1/").arg(server.serverPort())); QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); QNetworkReplyPtr reply = manager.post(request, &sourceFile); QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -3938,19 +4433,13 @@ void tst_QNetworkReply::ioPostToHttpUploadProgress() disconnect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); incomingSocket->setReadBufferSize(1*1024); - QTestEventLoop::instance().enterLoop(2); + QTestEventLoop::instance().enterLoop(5); // some progress should have been made QList<QVariant> args = spy.last(); QVERIFY(!args.isEmpty()); QVERIFY(args.at(0).toLongLong() > 0); - - incomingSocket->setReadBufferSize(32*1024); - incomingSocket->read(16*1024); - QTestEventLoop::instance().enterLoop(2); - // some more progress than before - QList<QVariant> args2 = spy.last(); - QVERIFY(!args2.isEmpty()); - QVERIFY(args2.at(0).toLongLong() > args.at(0).toLongLong()); + // but not everything! + QVERIFY(args.at(0).toLongLong() != sourceFile.size()); // set the read buffer to unlimited incomingSocket->setReadBufferSize(0); @@ -3958,8 +4447,10 @@ void tst_QNetworkReply::ioPostToHttpUploadProgress() // progress should be finished QList<QVariant> args3 = spy.last(); QVERIFY(!args3.isEmpty()); - QVERIFY(args3.at(0).toLongLong() > args2.at(0).toLongLong()); + // More progress than before + QVERIFY(args3.at(0).toLongLong() > args.at(0).toLongLong()); QCOMPARE(args3.at(0).toLongLong(), args3.at(1).toLongLong()); + // And actually finished.. QCOMPARE(args3.at(0).toLongLong(), sourceFile.size()); // after sending this, the QNAM should emit finished() @@ -3989,6 +4480,7 @@ void tst_QNetworkReply::ioPostToHttpEmptyUploadProgress() // create the request QUrl url = QUrl(QString("http://127.0.0.1:%1/").arg(server.serverPort())); QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); QNetworkReplyPtr reply = manager.post(request, &buffer); QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -4335,6 +4827,7 @@ void tst_QNetworkReply::receiveCookiesFromHttp() QByteArray data = cookieString.toLatin1() + '\n'; QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/set-cookie.cgi"); QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); QNetworkReplyPtr reply; RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::PostOperation, request, reply, data)); @@ -4362,9 +4855,9 @@ void tst_QNetworkReply::receiveCookiesFromHttpSynchronous() QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/set-cookie.cgi"); QNetworkRequest request(url); - + request.setRawHeader("Content-Type", "application/octet-stream"); request.setAttribute( - static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute), + QNetworkRequest::SynchronousRequestAttribute, true); QNetworkReplyPtr reply; @@ -4456,7 +4949,7 @@ void tst_QNetworkReply::sendCookiesSynchronous() QNetworkRequest request(url); request.setAttribute( - static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute), + QNetworkRequest::SynchronousRequestAttribute, true); QNetworkReplyPtr reply; @@ -4542,16 +5035,21 @@ void tst_QNetworkReply::httpProxyCommands() QNetworkRequest request(url); request.setRawHeader("User-Agent", "QNetworkReplyAutoTest/1.0"); QNetworkReplyPtr reply = manager.get(request); - manager.setProxy(QNetworkProxy()); + //clearing the proxy here causes the test to fail. + //the proxy isn't used until after the bearer has been started + //which is correct in general, because system proxy isn't known until that time. + //removing this line is safe, as the proxy is also reset by the cleanup() function + //manager.setProxy(QNetworkProxy()); // wait for the finished signal connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(1); + QTestEventLoop::instance().enterLoop(15); QVERIFY(!QTestEventLoop::instance().timeout()); //qDebug() << reply->error() << reply->errorString(); + //qDebug() << proxyServer.receivedData; // we don't really care if the request succeeded // especially since it won't succeed in the HTTPS case @@ -4586,6 +5084,26 @@ void tst_QNetworkReply::httpProxyCommandsSynchronous_data() httpProxyCommands_data(); } +struct QThreadCleanup +{ + static inline void cleanup(QThread *thread) + { + thread->quit(); + if (thread->wait(3000)) + delete thread; + else + qWarning("thread hung, leaking memory so test can finish"); + } +}; + +struct QDeleteLaterCleanup +{ + static inline void cleanup(QObject *o) + { + o->deleteLater(); + } +}; + void tst_QNetworkReply::httpProxyCommandsSynchronous() { QFETCH(QUrl, url); @@ -4595,25 +5113,21 @@ void tst_QNetworkReply::httpProxyCommandsSynchronous() // when using synchronous commands, we need a different event loop for // the server thread, because the client is never returning to the // event loop - MiniHttpServer proxyServer(responseToSend); - QThread serverThread; - proxyServer.moveToThread(&serverThread); - serverThread.start(); - QNetworkProxy proxy(QNetworkProxy::HttpProxy, "127.0.0.1", proxyServer.serverPort()); + QScopedPointer<QThread, QThreadCleanup> serverThread(new QThread); + QScopedPointer<MiniHttpServer, QDeleteLaterCleanup> proxyServer(new MiniHttpServer(responseToSend, false, serverThread.data())); + QNetworkProxy proxy(QNetworkProxy::HttpProxy, "127.0.0.1", proxyServer->serverPort()); manager.setProxy(proxy); QNetworkRequest request(url); // send synchronous request request.setAttribute( - static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute), + QNetworkRequest::SynchronousRequestAttribute, true); QNetworkReplyPtr reply = manager.get(request); QVERIFY(reply->isFinished()); // synchronous manager.setProxy(QNetworkProxy()); - serverThread.quit(); - serverThread.wait(3000); //qDebug() << reply->error() << reply->errorString(); @@ -4621,7 +5135,7 @@ void tst_QNetworkReply::httpProxyCommandsSynchronous() // especially since it won't succeed in the HTTPS case // so just check that the command was correct - QString receivedHeader = proxyServer.receivedData.left(expectedCommand.length()); + QString receivedHeader = proxyServer->receivedData.left(expectedCommand.length()); QCOMPARE(receivedHeader, expectedCommand); } @@ -4666,7 +5180,7 @@ void tst_QNetworkReply::proxyChange() manager.setProxy(dummyProxy); QNetworkReplyPtr reply3 = manager.get(req); connect(reply3, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(1); + QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(int(reply3->error()) > 0); @@ -4719,6 +5233,7 @@ void tst_QNetworkReply::authorizationError() QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), httpStatusCode); QFETCH(QString, httpBody); + QCOMPARE(qint64(reply->size()), qint64(httpBody.size())); QCOMPARE(QString(reply->readAll()), httpBody); } @@ -5003,6 +5518,37 @@ void tst_QNetworkReply::ignoreSslErrorsListWithSlot() QCOMPARE(reply->error(), expectedNetworkError); } +void tst_QNetworkReply::sslConfiguration_data() +{ + QTest::addColumn<QSslConfiguration>("configuration"); + QTest::addColumn<bool>("works"); + + QTest::newRow("empty") << QSslConfiguration() << false; + QSslConfiguration conf = QSslConfiguration::defaultConfiguration(); + QTest::newRow("default") << conf << false; // does not contain test server cert + QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(SRCDIR "/certs/qt-test-server-cacert.pem"); + conf.setCaCertificates(testServerCert); + QTest::newRow("set-root-cert") << conf << true; + conf.setProtocol(QSsl::SecureProtocols); + QTest::newRow("secure") << conf << true; +} + +void tst_QNetworkReply::sslConfiguration() +{ + QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + "/index.html")); + QFETCH(QSslConfiguration, configuration); + request.setSslConfiguration(configuration); + QNetworkReplyPtr reply = manager.get(request); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QFETCH(bool, works); + QNetworkReply::NetworkError expectedError = works ? QNetworkReply::NoError : QNetworkReply::SslHandshakeFailedError; + QCOMPARE(reply->error(), expectedError); +} + #endif // QT_NO_OPENSSL void tst_QNetworkReply::getAndThenDeleteObject_data() @@ -5063,6 +5609,264 @@ void tst_QNetworkReply::symbianOpenCDataUrlCrash() QCOMPARE(reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), qint64(598)); } +void tst_QNetworkReply::getFromHttpIntoBuffer_data() +{ + QTest::addColumn<QUrl>("url"); + + QTest::newRow("rfc-internal") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"); +} + +// Please note that the whole "zero copy" download buffer API is private right now. Do not use it. +void tst_QNetworkReply::getFromHttpIntoBuffer() +{ + QFETCH(QUrl, url); + QNetworkRequest request(url); + request.setAttribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute, 1024*128); // 128 kB + + QNetworkAccessManager manager; + QNetworkReply *reply = manager.get(request); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(reply->isFinished()); + + QFile reference(SRCDIR "/rfc3252.txt"); + QVERIFY(reference.open(QIODevice::ReadOnly)); + + QCOMPARE(reference.bytesAvailable(), reply->bytesAvailable()); + QCOMPARE(reference.size(), reply->size()); + + // Compare the memory buffer + QVariant downloadBufferAttribute = reply->attribute(QNetworkRequest::DownloadBufferAttribute); + QVERIFY(downloadBufferAttribute.isValid()); + QSharedPointer<char> sharedPointer = downloadBufferAttribute.value<QSharedPointer<char> >(); + bool memoryComparison = + (0 == memcmp(static_cast<void*>(reference.readAll().data()), + sharedPointer.data(), reference.size())); + QVERIFY(memoryComparison); + + // Make sure the normal reading works + reference.seek(0); + QCOMPARE(reply->read(42), reference.read(42)); + QCOMPARE(reply->getChar(0), reference.getChar(0)); + QCOMPARE(reply->peek(23), reference.peek(23)); + QCOMPARE(reply->readLine(), reference.readLine()); + QCOMPARE(reference.bytesAvailable(), reply->bytesAvailable()); + QCOMPARE(reply->readAll(), reference.readAll()); + QVERIFY(reply->atEnd()); +} + +// FIXME we really need to consolidate all those server implementations +class GetFromHttpIntoBuffer2Server : QObject { + Q_OBJECT + qint64 dataSize; + qint64 dataSent; + QTcpServer server; + QTcpSocket *client; + bool serverSendsContentLength; + bool chunkedEncoding; + +public: + GetFromHttpIntoBuffer2Server (qint64 ds, bool sscl, bool ce) : dataSize(ds), dataSent(0), + client(0), serverSendsContentLength(sscl), chunkedEncoding(ce) { + server.listen(); + connect(&server, SIGNAL(newConnection()), this, SLOT(newConnectionSlot())); + } + + int serverPort() { + return server.serverPort(); + } + +public slots: + + void newConnectionSlot() { + client = server.nextPendingConnection(); + client->setParent(this); + connect(client, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); + connect(client, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWrittenSlot(qint64))); + } + + void readyReadSlot() { + client->readAll(); + client->write("HTTP/1.0 200 OK\n"); + if (serverSendsContentLength) + client->write(QString("Content-Length: " + QString::number(dataSize) + "\n").toAscii()); + if (chunkedEncoding) + client->write(QString("Transfer-Encoding: chunked\n").toAscii()); + client->write("Connection: close\n\n"); + } + + void bytesWrittenSlot(qint64 amount) { + Q_UNUSED(amount); + if (dataSent == dataSize && client) { + // close eventually + + // chunked encoding: we have to send a last "empty" chunk + if (chunkedEncoding) + client->write(QString("0\r\n\r\n").toAscii()); + + client->disconnectFromHost(); + server.close(); + client = 0; + return; + } + + // send data + if (client && client->bytesToWrite() < 100*1024 && dataSent < dataSize) { + qint64 amount = qMin(qint64(16*1024), dataSize - dataSent); + QByteArray data(amount, '@'); + + if (chunkedEncoding) { + client->write(QString(QString("%1").arg(amount,0,16).toUpper() + "\r\n").toAscii()); + client->write(data.constData(), amount); + client->write(QString("\r\n").toAscii()); + } else { + client->write(data.constData(), amount); + } + + dataSent += amount; + } + } +}; + +class GetFromHttpIntoBuffer2Client : QObject { + Q_OBJECT +private: + bool useDownloadBuffer; + QNetworkReply *reply; + qint64 uploadSize; + QList<qint64> bytesAvailableList; +public: + GetFromHttpIntoBuffer2Client (QNetworkReply *reply, bool useDownloadBuffer, qint64 uploadSize) + : useDownloadBuffer(useDownloadBuffer), reply(reply), uploadSize(uploadSize) + { + connect(reply, SIGNAL(metaDataChanged()), this, SLOT(metaDataChangedSlot())); + connect(reply, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); + connect(reply, SIGNAL(finished()), this, SLOT(finishedSlot())); + } + + public slots: + void metaDataChangedSlot() { + if (useDownloadBuffer) { + QSharedPointer<char> sharedPointer = qvariant_cast<QSharedPointer<char> >(reply->attribute(QNetworkRequest::DownloadBufferAttribute)); + QVERIFY(!sharedPointer.isNull()); // It will be 0 if it failed + } + + // metaDataChanged needs to come before everything else + QVERIFY(bytesAvailableList.isEmpty()); + } + + void readyReadSlot() { + QVERIFY(!reply->isFinished()); + + qint64 bytesAvailable = reply->bytesAvailable(); + + // bytesAvailable must never be 0 + QVERIFY(bytesAvailable != 0); + + if (bytesAvailableList.length() < 5) { + // We assume that the first few times the bytes available must be less than the complete size, e.g. + // the bytesAvailable() function works correctly in case of a downloadBuffer. + QVERIFY(bytesAvailable < uploadSize); + } + if (!bytesAvailableList.isEmpty()) { + // Also check that the same bytesAvailable is not coming twice in a row + QVERIFY(bytesAvailableList.last() != bytesAvailable); + } + + bytesAvailableList.append(bytesAvailable); + // Add bytesAvailable to a list an parse + } + + void finishedSlot() { + // We should have already received all readyRead + QVERIFY(!bytesAvailableList.isEmpty()); + QVERIFY(bytesAvailableList.last() == uploadSize); + } +}; + +void tst_QNetworkReply::getFromHttpIntoBuffer2_data() +{ + QTest::addColumn<bool>("useDownloadBuffer"); + + QTest::newRow("use-download-buffer") << true; + QTest::newRow("do-not-use-download-buffer") << false; +} + +// This test checks mostly that signal emissions are in correct order +// Please note that the whole "zero copy" download buffer API is private right now. Do not use it. +void tst_QNetworkReply::getFromHttpIntoBuffer2() +{ + QFETCH(bool, useDownloadBuffer); + + // On my Linux Desktop the results are already visible with 128 kB, however we use this to have good results. +#if defined(Q_OS_SYMBIAN) || defined(Q_WS_WINCE_WM) + // Show some mercy to non-desktop platform/s + enum {UploadSize = 4*1024*1024}; // 4 MB +#else + enum {UploadSize = 32*1024*1024}; // 32 MB +#endif + + GetFromHttpIntoBuffer2Server server(UploadSize, true, false); + + QNetworkRequest request(QUrl("http://127.0.0.1:" + QString::number(server.serverPort()) + "/?bare=1")); + if (useDownloadBuffer) + request.setAttribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute, 1024*1024*128); // 128 MB is max allowed + + QNetworkAccessManager manager; + QNetworkReplyPtr reply = manager.get(request); + + GetFromHttpIntoBuffer2Client client(reply, useDownloadBuffer, UploadSize); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); + QTestEventLoop::instance().enterLoop(40); + QCOMPARE(reply->error(), QNetworkReply::NoError); + QVERIFY(!QTestEventLoop::instance().timeout()); +} + + +// Is handled somewhere else too, introduced this special test to have it more accessible +void tst_QNetworkReply::ioGetFromHttpWithoutContentLength() +{ + QByteArray dataToSend("HTTP/1.0 200 OK\r\n\r\nHALLO! 123!"); + MiniHttpServer server(dataToSend); + server.doClose = true; + + QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); + QNetworkReplyPtr reply = manager.get(request); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(reply->url(), request.url()); + QVERIFY(reply->isFinished()); + QVERIFY(reply->error() == QNetworkReply::NoError); +} + +// Is handled somewhere else too, introduced this special test to have it more accessible +void tst_QNetworkReply::ioGetFromHttpBrokenChunkedEncoding() +{ + // This is wrong chunked encoding because of the X. What actually has to follow is \r\n + // and then the declaration of the final 0 chunk + QByteArray dataToSend("HTTP/1.0 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n3\r\nABCX"); + MiniHttpServer server(dataToSend); + server.doClose = false; // FIXME + + QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); + QNetworkReplyPtr reply = manager.get(request); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + + QEXPECT_FAIL(0, "We should close the socket and not just do nothing", Continue); + QVERIFY(!QTestEventLoop::instance().timeout()); + QEXPECT_FAIL(0, "We should close the socket and not just do nothing", Continue); + QVERIFY(reply->isFinished()); + QCOMPARE(reply->error(), QNetworkReply::NoError); +} + // TODO: // Prepare a gzip that has one chunk that expands to the size mentioned in the bugreport. // Then have a custom HTTP server that waits after this chunk so the returning gets @@ -5074,6 +5878,7 @@ void tst_QNetworkReply::qtbug12908compressedHttpReply() // dd if=/dev/zero of=qtbug-12908 bs=16384 count=1 && gzip qtbug-12908 && base64 -w 0 qtbug-12908.gz QString encodedFile("H4sICDdDaUwAA3F0YnVnLTEyOTA4AO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA"); QByteArray decodedFile = QByteArray::fromBase64(encodedFile.toAscii()); + QCOMPARE(decodedFile.size(), 63); MiniHttpServer server(header.toAscii() + decodedFile); server.doClose = true; @@ -5086,6 +5891,31 @@ void tst_QNetworkReply::qtbug12908compressedHttpReply() QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(reply->error(), QNetworkReply::NoError); + QCOMPARE(reply->size(), qint64(16384)); + QCOMPARE(reply->readAll(), QByteArray(16384, '\0')); +} + +void tst_QNetworkReply::compressedHttpReplyBrokenGzip() +{ + QString header("HTTP/1.0 200 OK\r\nContent-Encoding: gzip\r\nContent-Length: 63\r\n\r\n"); + + // dd if=/dev/zero of=qtbug-12908 bs=16384 count=1 && gzip qtbug-12908 && base64 -w 0 qtbug-12908.gz + // Then change "BMQ" to "BMX" + QString encodedFile("H4sICDdDaUwAA3F0YnVnLTEyOTA4AO3BMXEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA"); + QByteArray decodedFile = QByteArray::fromBase64(encodedFile.toAscii()); + QCOMPARE(decodedFile.size(), 63); + + MiniHttpServer server(header.toAscii() + decodedFile); + server.doClose = true; + + QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); + QNetworkReplyPtr reply = manager.get(request); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(reply->error(), QNetworkReply::ProtocolFailure); } // TODO add similar test for FTP @@ -5097,7 +5927,7 @@ void tst_QNetworkReply::getFromUnreachableIp() QNetworkReplyPtr reply = manager.get(request); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(5); + QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(reply->error() != QNetworkReply::NoError); @@ -5163,7 +5993,7 @@ void tst_QNetworkReply::qtbug13431replyThrottling() connect(&nam, SIGNAL(finished(QNetworkReply*)), &helper, SLOT(replyFinished(QNetworkReply*))); // Download a bigger file - QNetworkRequest netRequest(QUrl("http://qt-test-server/qtest/bigfile")); + QNetworkRequest netRequest(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile")); helper.m_reply = nam.get(netRequest); // Set the throttle helper.m_reply->setReadBufferSize(36000); @@ -5283,7 +6113,7 @@ void tst_QNetworkReply::synchronousRequest_data() << QString("text/plain"); QTest::newRow("simple-file") - << QUrl(QString::fromLatin1("file:///" SRCDIR "/rfc3252.txt")) + << QUrl::fromLocalFile(SRCDIR "/rfc3252.txt") << QString("file:" SRCDIR "/rfc3252.txt") << true << QString(); @@ -5313,7 +6143,7 @@ void tst_QNetworkReply::synchronousRequest() #endif request.setAttribute( - static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute), + QNetworkRequest::SynchronousRequestAttribute, true); QNetworkReplyPtr reply; @@ -5344,6 +6174,7 @@ void tst_QNetworkReply::synchronousRequest() reply->deleteLater(); } +#ifndef QT_NO_OPENSSL void tst_QNetworkReply::synchronousRequestSslFailure() { // test that SSL won't be accepted with self-signed certificate, @@ -5353,7 +6184,7 @@ void tst_QNetworkReply::synchronousRequestSslFailure() QUrl url("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"); QNetworkRequest request(url); request.setAttribute( - static_cast<QNetworkRequest::Attribute>(SynchronousRequestAttribute), + QNetworkRequest::SynchronousRequestAttribute, true); QNetworkReplyPtr reply; QSignalSpy sslErrorsSpy(&manager, SIGNAL(sslErrors(QNetworkReply *, const QList<QSslError> &))); @@ -5362,6 +6193,19 @@ void tst_QNetworkReply::synchronousRequestSslFailure() QCOMPARE(reply->error(), QNetworkReply::SslHandshakeFailedError); QCOMPARE(sslErrorsSpy.count(), 0); } +#endif + +void tst_QNetworkReply::httpAbort() +{ + // FIXME: Implement a test that aborts a big HTTP reply + // a) after the first readyRead() + // b) immediatly after the get() + // c) after the finished() + // The goal is no crash and no irrelevant signals after the abort + + // FIXME Also implement one where we do a big upload and then abort(). + // It must not crash either. +} void tst_QNetworkReply::dontInsertPartialContentIntoTheCache() { diff --git a/tests/auto/qnumeric/qnumeric.pro b/tests/auto/qnumeric/qnumeric.pro index 162f980..c0af962 100644 --- a/tests/auto/qnumeric/qnumeric.pro +++ b/tests/auto/qnumeric/qnumeric.pro @@ -4,3 +4,4 @@ QT = core SOURCES += tst_qnumeric.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qobject/qobject.pro b/tests/auto/qobject/qobject.pro index b6b3f20..113e14a 100644 --- a/tests/auto/qobject/qobject.pro +++ b/tests/auto/qobject/qobject.pro @@ -1,2 +1,3 @@ TEMPLATE = subdirs SUBDIRS = tst_qobject.pro signalbug.pro +CONFIG += parallel_test diff --git a/tests/auto/qobject/signalbug.cpp b/tests/auto/qobject/signalbug.cpp index c1f7f51..f81de47 100644 --- a/tests/auto/qobject/signalbug.cpp +++ b/tests/auto/qobject/signalbug.cpp @@ -69,7 +69,8 @@ void Receiver::received () ::Step++; const int stepCopy = ::Step; TRACE (stepCopy, "Receiver::received()"); - Q_ASSERT (::Step == 2 || ::Step == 4); + if (::Step != 2 && ::Step != 4) + qFatal("%s: Incorrect Step: %d (should be 2 or 4)", Q_FUNC_INFO, ::Step); if (::Step == 2) s->fire (); @@ -91,7 +92,8 @@ void Disconnector::received () ::Step++; const int stepCopy = ::Step; TRACE (stepCopy, "Disconnector::received()"); - Q_ASSERT (::Step == 5 || ::Step == 6); + if (::Step != 5 && ::Step != 6) + qFatal("%s: Incorrect Step: %d (should be 5 or 6)", Q_FUNC_INFO, ::Step); fprintf (stderr, "Disconnector<%s>::received() sender=%s\n", (const char *) objectName ().toAscii (), sender ()->metaObject()->className()); @@ -124,7 +126,8 @@ void Sender::fire () ::Step++; const int stepCopy = ::Step; TRACE (stepCopy, "Sender::fire()"); - Q_ASSERT (::Step == 1 || ::Step == 3); + if (::Step != 1 && ::Step != 3) + qFatal("%s: Incorrect Step: %d (should be 1 or 3)", Q_FUNC_INFO, ::Step); emit fired (); TRACE (stepCopy, "ends Sender::fire()"); diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index 6bcb5f7..c7db032 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -129,6 +129,13 @@ private slots: void qMetaObjectConnect(); void qMetaObjectDisconnectOne(); void sameName(); + void connectByMetaMethods(); + void connectByMetaMethodSlotInsteadOfSignal(); + void connectConstructorByMetaMethod(); + void disconnectByMetaMethod(); + void disconnectNotSignalMetaMethod(); + void autoConnectionBehavior(); + void baseDestroyed(); protected: }; @@ -396,6 +403,8 @@ public: } void reset() { + called_slot10 = 0; + called_slot9 = 0; called_slot8 = 0; called_slot7 = 0; called_slot6 = 0; @@ -414,6 +423,8 @@ public: int called_slot6; int called_slot7; int called_slot8; + int called_slot9; + int called_slot10; bool called(int slot) { switch (slot) { @@ -425,6 +436,8 @@ public: case 6: return called_slot6; case 7: return called_slot7; case 8: return called_slot8; + case 9: return called_slot9; + case 10: return called_slot10; default: return false; } } @@ -442,8 +455,8 @@ public slots: void slotLoopBack() { ++called_slot8; } protected slots: - void o() { Q_ASSERT(0); } - void on() { Q_ASSERT(0); } + void o() { ++called_slot9; } + void on() { ++called_slot10; } signals: void on_Sender_signalLoopBack(); @@ -466,6 +479,8 @@ void tst_QObject::connectByName() QCOMPARE(receiver.called(6), false); QCOMPARE(receiver.called(7), false); QCOMPARE(receiver.called(8), false); + QCOMPARE(receiver.called(9), false); + QCOMPARE(receiver.called(10), false); receiver.reset(); sender.emitSignalWithParams(0); @@ -477,6 +492,8 @@ void tst_QObject::connectByName() QCOMPARE(receiver.called(6), false); QCOMPARE(receiver.called(7), false); QCOMPARE(receiver.called(8), false); + QCOMPARE(receiver.called(9), false); + QCOMPARE(receiver.called(10), false); receiver.reset(); sender.emitSignalWithParams(0, "string"); @@ -488,6 +505,8 @@ void tst_QObject::connectByName() QCOMPARE(receiver.called(6), false); QCOMPARE(receiver.called(7), false); QCOMPARE(receiver.called(8), false); + QCOMPARE(receiver.called(9), false); + QCOMPARE(receiver.called(10), false); receiver.reset(); sender.emitSignalManyParams(1, 2, 3, "string", true); @@ -499,6 +518,8 @@ void tst_QObject::connectByName() QCOMPARE(receiver.called(6), false); QCOMPARE(receiver.called(7), false); QCOMPARE(receiver.called(8), false); + QCOMPARE(receiver.called(9), false); + QCOMPARE(receiver.called(10), false); receiver.reset(); sender.emitSignalManyParams2(1, 2, 3, "string", true); @@ -510,6 +531,8 @@ void tst_QObject::connectByName() QCOMPARE(receiver.called(6), false); QCOMPARE(receiver.called(7), true); QCOMPARE(receiver.called(8), false); + QCOMPARE(receiver.called(9), false); + QCOMPARE(receiver.called(10), false); receiver.reset(); sender.emitSignalLoopBack(); @@ -521,6 +544,8 @@ void tst_QObject::connectByName() QCOMPARE(receiver.called(6), false); QCOMPARE(receiver.called(7), false); QCOMPARE(receiver.called(8), true); + QCOMPARE(receiver.called(9), false); + QCOMPARE(receiver.called(10), false); receiver.reset(); } @@ -663,11 +688,9 @@ void tst_QObject::findChildren() l = qFindChildren<QObject*>(&o, "unnamed"); QCOMPARE(l.size(), 0); -#ifndef QT_NO_MEMBER_TEMPLATES tl = o.findChildren<QTimer *>("t1"); QCOMPARE(tl.size(), 1); QCOMPARE(tl.at(0), &t1); -#endif } @@ -727,6 +750,24 @@ void tst_QObject::connectDisconnectNotify() // Test disconnectNotify for a complete disconnect ((SenderObject*)s)->disconnect((ReceiverObject*)r); + // Obtaining meta methods + int signalIndx = ((SenderObject*)s)->metaObject()->indexOfSignal( + QMetaObject::normalizedSignature(a_signal.toLatin1().constData()+1).constData()); + int methodIndx = ((ReceiverObject*)r)->metaObject()->indexOfMethod( + QMetaObject::normalizedSignature(a_slot.toLatin1().constData()+1).constData()); + QMetaMethod signal = ((SenderObject*)s)->metaObject()->method(signalIndx); + QMetaMethod method = ((ReceiverObject*)r)->metaObject()->method(methodIndx); + + // Test connectNotify when connecting by QMetaMethod + connect( (SenderObject*)s, signal, (ReceiverObject*)r, method ); + QCOMPARE( s->org_signal, s->nw_signal ); + QCOMPARE( s->org_signal.toLatin1(), QMetaObject::normalizedSignature(a_signal.toLatin1().constData()) ); + + // Test disconnectNotify when disconnecting by QMetaMethod + QObject::disconnect( (SenderObject*)s, signal, (ReceiverObject*)r, method ); + QCOMPARE( s->org_signal, s->nw_signal ); + QCOMPARE( s->org_signal.toLatin1(), QMetaObject::normalizedSignature(a_signal.toLatin1().constData()) ); + delete s; delete r; } @@ -1289,14 +1330,16 @@ public: void customEvent(QEvent *) { - Q_ASSERT(customEventThread == 0); + if (customEventThread) + qFatal("%s: customEventThread should be null", Q_FUNC_INFO); customEventThread = QThread::currentThread(); emit theSignal(); } void timerEvent(QTimerEvent *) { - Q_ASSERT(timerEventThread == 0); + if (timerEventThread) + qFatal("%s: timerEventThread should be null", Q_FUNC_INFO); timerEventThread = QThread::currentThread(); emit theSignal(); } @@ -1304,7 +1347,8 @@ public: public slots: void theSlot() { - Q_ASSERT(slotThread == 0); + if (slotThread) + qFatal("%s: slotThread should be null", Q_FUNC_INFO); slotThread = QThread::currentThread(); emit theSignal(); } @@ -1760,9 +1804,12 @@ class SuperObject : public QObject Q_OBJECT public: QObject *theSender; + int theSignalId; + SuperObject() { theSender = 0; + theSignalId = 0; } friend class tst_QObject; @@ -1773,16 +1820,17 @@ public slots: void rememberSender() { theSender = sender(); + theSignalId = senderSignalIndex(); } void deleteAndRememberSender() { delete theSender; - theSender = sender(); + rememberSender(); } signals: + void anotherSignal(); void theSignal(); - }; void tst_QObject::sender() @@ -1790,12 +1838,23 @@ void tst_QObject::sender() { SuperObject sender; SuperObject receiver; + connect(&sender, SIGNAL(anotherSignal()), + &receiver, SLOT(rememberSender())); connect(&sender, SIGNAL(theSignal()), &receiver, SLOT(rememberSender())); QCOMPARE(receiver.sender(), (QObject *)0); + QCOMPARE(receiver.senderSignalIndex(), -1); emit sender.theSignal(); QCOMPARE(receiver.theSender, (QObject *)&sender); QCOMPARE(receiver.sender(), (QObject *)0); + QCOMPARE(receiver.theSignalId, + sender.metaObject()->indexOfSignal("theSignal()")); + QCOMPARE(receiver.senderSignalIndex(), -1); + + emit sender.anotherSignal(); + QCOMPARE(receiver.theSignalId, + sender.metaObject()->indexOfSignal("anotherSignal()")); + QCOMPARE(receiver.senderSignalIndex(), -1); } { @@ -1812,11 +1871,16 @@ void tst_QObject::sender() Qt::DirectConnection); QCOMPARE(receiver->sender(), (QObject *)0); + QCOMPARE(receiver->senderSignalIndex(), -1); receiver->theSender = 0; + receiver->theSignalId = -1; thread.start(); emit sender->theSignal(); QCOMPARE(receiver->theSender, (QObject *) sender); QCOMPARE(receiver->sender(), (QObject *)0); + QCOMPARE(receiver->theSignalId, + sender->metaObject()->indexOfSignal("theSignal()")); + QCOMPARE(receiver->senderSignalIndex(), -1); QVERIFY(thread.wait(10000)); delete receiver; @@ -3610,5 +3674,306 @@ void tst_QObject::sameName() QCOMPARE(c1.s, 4); } +void tst_QObject::connectByMetaMethods() +{ + SenderObject s; + ReceiverObject r; + const QMetaObject *smeta = s.metaObject(); + const QMetaObject *rmeta = r.metaObject(); + int sigIndx = smeta->indexOfSignal(QMetaObject::normalizedSignature("signal1()")); + int slotIndx = rmeta->indexOfSlot(QMetaObject::normalizedSignature("slot1()")); + QVERIFY( sigIndx != -1 ); + QVERIFY( slotIndx != -1 ); + QMetaMethod signal = smeta->method(sigIndx); + QMetaMethod slot = rmeta->method(slotIndx); + + QVERIFY(connect(&s,signal, &r,slot)); + + QVERIFY(!r.called(1)); + s.emitSignal1(); + QVERIFY(r.called(1)); +} + +void tst_QObject::connectByMetaMethodSlotInsteadOfSignal() +{ + SenderObject s; + ReceiverObject r; + const QMetaObject *smeta = s.metaObject(); + const QMetaObject *rmeta = r.metaObject(); + int badIndx = smeta->indexOfSlot(QMetaObject::normalizedSignature("aPublicSlot()")); + int slotIndx = rmeta->indexOfSlot(QMetaObject::normalizedSignature("slot1()")); + QVERIFY( badIndx != -1 ); + QVERIFY( slotIndx != -1 ); + QMetaMethod badMethod = smeta->method(badIndx); + QMetaMethod slot = rmeta->method(slotIndx); + + QTest::ignoreMessage(QtWarningMsg,"QObject::connect: Cannot connect SenderObject::aPublicSlot() to ReceiverObject::slot1()"); + QVERIFY(!connect(&s,badMethod, &r,slot)); +} + +class Constructable: public QObject +{ + Q_OBJECT + +public: + Q_INVOKABLE Constructable(){} + +}; + +void tst_QObject::connectConstructorByMetaMethod() +{ + Constructable sc; + Constructable rc; + SenderObject s; + ReceiverObject r; + + const QMetaObject cmeta = Constructable::staticMetaObject; + const QMetaObject *smeta = s.metaObject(); + const QMetaObject *rmeta = r.metaObject(); + int constructorIndx = cmeta.indexOfConstructor(QMetaObject::normalizedSignature("Constructable()")); + int sigIndx = smeta->indexOfSignal(QMetaObject::normalizedSignature("signal1()")); + int slotIndx = rmeta->indexOfSlot(QMetaObject::normalizedSignature("slot1()")); + QVERIFY( constructorIndx != -1 ); + QVERIFY( sigIndx != -1 ); + QVERIFY( slotIndx != -1 ); + + QMetaMethod constructor = cmeta.constructor(constructorIndx); + QMetaMethod signal = smeta->method(sigIndx); + QMetaMethod slot = rmeta->method(slotIndx); + + QTest::ignoreMessage(QtWarningMsg,"QObject::connect: Cannot connect Constructable::Constructable() to ReceiverObject::slot1()"); + QVERIFY(!connect(&sc,constructor, &r,slot)); + QTest::ignoreMessage(QtWarningMsg,"QObject::connect: Cannot connect SenderObject::signal1() to Constructable::Constructable()"); + QVERIFY(!connect(&s,signal, &rc,constructor)); + QTest::ignoreMessage(QtWarningMsg,"QObject::connect: Cannot connect Constructable::Constructable() to Constructable::Constructable()"); + QVERIFY(!connect(&sc,constructor, &rc,constructor)); +} + +void tst_QObject::disconnectByMetaMethod() +{ + SenderObject *s = new SenderObject; + ReceiverObject *r1 = new ReceiverObject; + ReceiverObject *r2 = new ReceiverObject; + + QMetaMethod signal1 = s->metaObject()->method( + s->metaObject()->indexOfMethod("signal1()")); + QMetaMethod signal2 = s->metaObject()->method( + s->metaObject()->indexOfMethod("signal2()")); + QMetaMethod signal3 = s->metaObject()->method( + s->metaObject()->indexOfMethod("signal3()")); + QMetaMethod signal4 = s->metaObject()->method( + s->metaObject()->indexOfMethod("signal4()")); + + QMetaMethod slot1 = r1->metaObject()->method( + r1->metaObject()->indexOfMethod("slot1()")); + QMetaMethod slot2 = r1->metaObject()->method( + r1->metaObject()->indexOfMethod("slot2()")); + QMetaMethod slot3 = r1->metaObject()->method( + r1->metaObject()->indexOfMethod("slot3()")); + QMetaMethod slot4 = r1->metaObject()->method( + r1->metaObject()->indexOfMethod("slot4()")); + + connect(s, signal1, r1, slot1); + + s->emitSignal1(); + + QVERIFY(r1->called(1)); + r1->reset(); + + // usual disconnect with all parameters given + bool ret = QObject::disconnect(s, signal1, r1, slot1); + + s->emitSignal1(); + + QVERIFY(!r1->called(1)); + r1->reset(); + + QVERIFY(ret); + ret = QObject::disconnect(s, signal1, r1, slot1); + QVERIFY(!ret); + + r1->reset(); + + connect( s, signal1, r1, slot1 ); + connect( s, signal1, r1, slot2 ); + connect( s, signal1, r1, slot3 ); + connect( s, signal2, r1, slot4 ); + + // disconnect s's signal1() from all slots of r1 + QObject::disconnect(s, signal1, r1, QMetaMethod()); + + s->emitSignal1(); + s->emitSignal2(); + + QVERIFY(!r1->called(1)); + QVERIFY(!r1->called(2)); + QVERIFY(!r1->called(3)); + QVERIFY(r1->called(4)); + r1->reset(); + // make sure all is disconnected again + QObject::disconnect(s, 0, r1, 0); + + connect(s, signal1, r1, slot1); + connect(s, signal1, r2, slot1); + connect(s, signal2, r1, slot2); + connect(s, signal2, r2, slot2); + connect(s, signal3, r1, slot3); + connect(s, signal3, r2, slot3); + + // disconnect signal1() from all receivers + QObject::disconnect(s, signal1, 0, QMetaMethod()); + s->emitSignal1(); + s->emitSignal2(); + s->emitSignal3(); + + QVERIFY(!r1->called(1)); + QVERIFY(!r2->called(1)); + QVERIFY(r1->called(2)); + QVERIFY(r2->called(2)); + QVERIFY(r1->called(2)); + QVERIFY(r2->called(2)); + + r1->reset(); + r2->reset(); + + // disconnect all signals of s from all receivers + QObject::disconnect( s, 0, 0, 0 ); + + connect( s, signal1, r1, slot1 ); + connect( s, signal1, r2, slot1 ); + + // disconnect all signals from slot1 of r1 + QObject::disconnect(s, QMetaMethod(), r1, slot1); + + s->emitSignal1(); + + QVERIFY(!r1->called(1)); + QVERIFY(r2->called(1)); + + delete r2; + delete r1; + delete s; +} + +void tst_QObject::disconnectNotSignalMetaMethod() +{ + SenderObject s; + ReceiverObject r; + + connect(&s, SIGNAL(signal1()), &r, SLOT(slot1())); + + QMetaMethod slot = s.metaObject()->method( + s.metaObject()->indexOfMethod("aPublicSlot()")); + + QTest::ignoreMessage(QtWarningMsg,"Object::disconnect: Attempt to unbind non-signal SenderObject::aPublicSlot()"); + QVERIFY(!QObject::disconnect(&s, slot, &r, QMetaMethod())); +} + +class ThreadAffinityThread : public QThread +{ +public: + SenderObject *sender; + + ThreadAffinityThread(SenderObject *sender) + : sender(sender) + { } + void run() + { + sender->emitSignal1(); + } +}; + +void tst_QObject::autoConnectionBehavior() +{ + SenderObject *sender = new SenderObject; + ReceiverObject *receiver = new ReceiverObject; + connect(sender, SIGNAL(signal1()), receiver, SLOT(slot1())); + + // at emit, currentThread == sender->thread(), currentThread == receiver->thread(), sender->thread() == receiver->thread() + QVERIFY(!receiver->called(1)); + sender->emitSignal1(); + QVERIFY(receiver->called(1)); + receiver->reset(); + + // at emit, currentThread != sender->thread(), currentThread != receiver->thread(), sender->thread() == receiver->thread() + ThreadAffinityThread emitThread1(sender); + QVERIFY(!receiver->called(1)); + emitThread1.start(); + QVERIFY(emitThread1.wait(30000)); + QVERIFY(!receiver->called(1)); + QCoreApplication::sendPostedEvents(receiver, QEvent::MetaCall); + QVERIFY(receiver->called(1)); + receiver->reset(); + + // at emit, currentThread == sender->thread(), currentThread != receiver->thread(), sender->thread() != receiver->thread() + sender->moveToThread(&emitThread1); + QVERIFY(!receiver->called(1)); + emitThread1.start(); + QVERIFY(emitThread1.wait(30000)); + QVERIFY(!receiver->called(1)); + QCoreApplication::sendPostedEvents(receiver, QEvent::MetaCall); + QVERIFY(receiver->called(1)); + receiver->reset(); + + // at emit, currentThread != sender->thread(), currentThread == receiver->thread(), sender->thread() != receiver->thread() + QVERIFY(!receiver->called(1)); + sender->emitSignal1(); + QVERIFY(receiver->called(1)); + receiver->reset(); + + // at emit, currentThread != sender->thread(), currentThread != receiver->thread(), sender->thread() != receiver->thread() + ThreadAffinityThread emitThread2(sender); + QThread receiverThread; + QTimer *timer = new QTimer; + timer->setSingleShot(true); + timer->setInterval(100); + connect(&receiverThread, SIGNAL(started()), timer, SLOT(start())); + connect(timer, SIGNAL(timeout()), &receiverThread, SLOT(quit()), Qt::DirectConnection); + connect(&receiverThread, SIGNAL(finished()), timer, SLOT(deleteLater())); + timer->moveToThread(&receiverThread); + + receiver->moveToThread(&receiverThread); + QVERIFY(!receiver->called(1)); + emitThread2.start(); + QVERIFY(emitThread2.wait(30000)); + QVERIFY(!receiver->called(1)); + receiverThread.start(); + QVERIFY(receiverThread.wait(30000)); + QVERIFY(receiver->called(1)); + receiver->reset(); + + delete sender; + delete receiver; +} + +class BaseDestroyed : public QObject +{ Q_OBJECT + QList<QString> fooList; + bool destroyed; +public: + BaseDestroyed() : destroyed(false) + { fooList << "a" << "b"; } + ~BaseDestroyed() + { + QVERIFY(!destroyed); + destroyed = true; + } + +public slots: + void slotUseList() + { + QVERIFY(!destroyed); + fooList << "c" << "d"; + } +}; + +void tst_QObject::baseDestroyed() +{ + BaseDestroyed d; + connect(&d, SIGNAL(destroyed()), &d, SLOT(slotUseList())); + //When d goes out of scope, slotUseList should not be called as the BaseDestroyed has + // already been destroyed while ~QObject emit destroyed +} + QTEST_MAIN(tst_QObject) #include "tst_qobject.moc" diff --git a/tests/auto/qobject/tst_qobject.pro b/tests/auto/qobject/tst_qobject.pro index 1d6993a..5745e67 100644 --- a/tests/auto/qobject/tst_qobject.pro +++ b/tests/auto/qobject/tst_qobject.pro @@ -10,12 +10,12 @@ QT = core \ gui contains(QT_CONFIG, qt3support):DEFINES += QT_HAS_QT3SUPPORT wince*: { - addFiles.sources = signalbug.exe + addFiles.files = signalbug.exe addFiles.path = . DEPLOYMENT += addFiles } symbian: { - addFiles.sources = signalbug.exe + addFiles.files = signalbug.exe addFiles.path = \\sys\\bin DEPLOYMENT += addFiles } diff --git a/tests/auto/qobjectrace/qobjectrace.pro b/tests/auto/qobjectrace/qobjectrace.pro index 322adff..526875b 100644 --- a/tests/auto/qobjectrace/qobjectrace.pro +++ b/tests/auto/qobjectrace/qobjectrace.pro @@ -3,3 +3,4 @@ SOURCES += tst_qobjectrace.cpp QT = core TARGET.EPOCHEAPSIZE = 20000000 40000000 +CONFIG += parallel_test diff --git a/tests/auto/qpainter/qpainter.pro b/tests/auto/qpainter/qpainter.pro index 69dc98d..ee624e1 100644 --- a/tests/auto/qpainter/qpainter.pro +++ b/tests/auto/qpainter/qpainter.pro @@ -2,7 +2,7 @@ load(qttest_p4) contains(QT_CONFIG, qt3support): QT += qt3support SOURCES += tst_qpainter.cpp wince*|symbian: { - addFiles.sources = drawEllipse drawLine_rop_bitmap drawPixmap_rop drawPixmap_rop_bitmap task217400.png + addFiles.files = drawEllipse drawLine_rop_bitmap drawPixmap_rop drawPixmap_rop_bitmap task217400.png addFiles.path = . DEPLOYMENT += addFiles } diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index 666cedf..501074f 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -72,11 +72,13 @@ #include <qgraphicsscene.h> #include <qgraphicsproxywidget.h> #include <qlayout.h> +#include <qfontdatabase.h> #if defined(Q_OS_SYMBIAN) # define SRCDIR "." #endif +Q_DECLARE_METATYPE(QGradientStops) Q_DECLARE_METATYPE(QLine) Q_DECLARE_METATYPE(QRect) Q_DECLARE_METATYPE(QSize) @@ -169,6 +171,8 @@ private slots: void clippedText(); + void clipBoundingRect(); + void setOpacity_data(); void setOpacity(); @@ -187,6 +191,7 @@ private slots: void fillRect_stretchToDeviceMode(); void monoImages(); + void linearGradientSymmetry_data(); void linearGradientSymmetry(); void gradientInterpolation(); @@ -220,6 +225,8 @@ private slots: void drawRect_task215378(); void drawRect_task247505(); + void drawText_subPixelPositionsInRaster_qtbug5053(); + void drawImage_data(); void drawImage(); @@ -260,6 +267,8 @@ private slots: void QTBUG17053_zeroDashPattern(); + void drawTextOutsideGuiThread(); + private: void fillData(); void setPenColor(QPainter& p); @@ -1306,7 +1315,7 @@ void tst_QPainter::drawRect2() p.end(); QRect stroke = getPaintedSize(image, Qt::white); - QCOMPARE(stroke.adjusted(1, 1, 0, 0), fill.adjusted(0, 0, 1, 1)); + QCOMPARE(stroke, fill.adjusted(0, 0, 1, 1)); } } @@ -1403,13 +1412,13 @@ void tst_QPainter::drawPath_data() { QPainterPath p; p.addRect(2.25, 2.25, 10, 10); - QTest::newRow("non-aligned rect") << p << QRect(3, 3, 10, 10) << 10 * 10; + QTest::newRow("non-aligned rect") << p << QRect(2, 2, 10, 10) << 10 * 10; } { QPainterPath p; p.addRect(2.25, 2.25, 10.5, 10.5); - QTest::newRow("non-aligned rect 2") << p << QRect(3, 3, 10, 10) << 10 * 10; + QTest::newRow("non-aligned rect 2") << p << QRect(2, 2, 11, 11) << 11 * 11; } { @@ -3513,6 +3522,9 @@ bool verifyOutlineFillConsistency(const QImage &img, QRgb outside, QRgb inside, void tst_QPainter::outlineFillConsistency() { + QSKIP("currently broken...", SkipAll); + return; + QImage dst(256, 256, QImage::Format_ARGB32_Premultiplied); QPolygonF poly; @@ -3976,8 +3988,42 @@ static QLinearGradient inverseGradient(QLinearGradient g) return g2; } +void tst_QPainter::linearGradientSymmetry_data() +{ + QTest::addColumn<QGradientStops>("stops"); + + if (sizeof(qreal) != sizeof(float)) { + QGradientStops stops; + stops << qMakePair(qreal(0.0), QColor(Qt::blue)); + stops << qMakePair(qreal(0.2), QColor(220, 220, 220, 0)); + stops << qMakePair(qreal(0.6), QColor(Qt::red)); + stops << qMakePair(qreal(0.9), QColor(220, 220, 220, 255)); + stops << qMakePair(qreal(1.0), QColor(Qt::black)); + QTest::newRow("multiple stops") << stops; + } + + { + QGradientStops stops; + stops << qMakePair(qreal(0.0), QColor(Qt::blue)); + stops << qMakePair(qreal(1.0), QColor(Qt::black)); + QTest::newRow("two stops") << stops; + } + + if (sizeof(qreal) != sizeof(float)) { + QGradientStops stops; + stops << qMakePair(qreal(0.3), QColor(Qt::blue)); + stops << qMakePair(qreal(0.6), QColor(Qt::black)); + QTest::newRow("two stops 2") << stops; + } +} + void tst_QPainter::linearGradientSymmetry() { +#ifdef Q_WS_QWS + QSKIP("QWS has limited resolution in the gradient color table", SkipAll); +#else + QFETCH(QGradientStops, stops); + QImage a(64, 8, QImage::Format_ARGB32_Premultiplied); QImage b(64, 8, QImage::Format_ARGB32_Premultiplied); @@ -3985,11 +4031,7 @@ void tst_QPainter::linearGradientSymmetry() b.fill(0); QLinearGradient gradient(QRectF(b.rect()).topLeft(), QRectF(b.rect()).topRight()); - gradient.setColorAt(0.0, Qt::blue); - gradient.setColorAt(0.2, QColor(220, 220, 220, 0)); - gradient.setColorAt(0.6, Qt::red); - gradient.setColorAt(0.9, QColor(220, 220, 220, 255)); - gradient.setColorAt(1.0, Qt::black); + gradient.setStops(stops); QPainter pa(&a); pa.fillRect(a.rect(), gradient); @@ -4001,6 +4043,7 @@ void tst_QPainter::linearGradientSymmetry() b = b.mirrored(true); QCOMPARE(a, b); +#endif } void tst_QPainter::gradientInterpolation() @@ -4529,6 +4572,82 @@ void tst_QPainter::QTBUG5939_attachPainterPrivate() QCOMPARE(widget->deviceTransform, proxy->deviceTransform); } +void tst_QPainter::clipBoundingRect() +{ + QPixmap pix(500, 500); + + QPainter p(&pix); + + // Test a basic rectangle + p.setClipRect(100, 100, 200, 100); + QVERIFY(p.clipBoundingRect().contains(QRectF(100, 100, 200, 100))); + QVERIFY(!p.clipBoundingRect().contains(QRectF(50, 50, 300, 200))); + p.setClipRect(120, 120, 20, 20, Qt::IntersectClip); + QVERIFY(p.clipBoundingRect().contains(QRect(120, 120, 20, 20))); + QVERIFY(!p.clipBoundingRect().contains(QRectF(100, 100, 200, 100))); + + // Test a basic float rectangle + p.setClipRect(QRectF(100, 100, 200, 100)); + QVERIFY(p.clipBoundingRect().contains(QRectF(100, 100, 200, 100))); + QVERIFY(!p.clipBoundingRect().contains(QRectF(50, 50, 300, 200))); + p.setClipRect(QRectF(120, 120, 20, 20), Qt::IntersectClip); + QVERIFY(p.clipBoundingRect().contains(QRect(120, 120, 20, 20))); + QVERIFY(!p.clipBoundingRect().contains(QRectF(100, 100, 200, 100))); + + // Test a basic path + region + QPainterPath path; + path.addRect(100, 100, 200, 100); + p.setClipPath(path); + QVERIFY(p.clipBoundingRect().contains(QRectF(100, 100, 200, 100))); + QVERIFY(!p.clipBoundingRect().contains(QRectF(50, 50, 300, 200))); + p.setClipRegion(QRegion(120, 120, 20, 20), Qt::IntersectClip); + QVERIFY(p.clipBoundingRect().contains(QRect(120, 120, 20, 20))); + QVERIFY(!p.clipBoundingRect().contains(QRectF(100, 100, 200, 100))); + + p.setClipRect(0, 0, 500, 500); + p.translate(250, 250); + for (int i=0; i<360; ++i) { + p.rotate(1); + p.setClipRect(-100, -100, 200, 200, Qt::IntersectClip); + } + QVERIFY(p.clipBoundingRect().contains(QRectF(-100, -100, 200, 200))); + QVERIFY(!p.clipBoundingRect().contains(QRectF(-250, -250, 500, 500))); + +} + +void tst_QPainter::drawText_subPixelPositionsInRaster_qtbug5053() +{ +#if !defined(Q_WS_MAC) || !defined(QT_MAC_USE_COCOA) + QSKIP("Only Mac/Cocoa supports sub pixel positions in raster engine currently", SkipAll); +#endif + QFontMetricsF fm(qApp->font()); + + QImage baseLine(fm.width(QChar::fromLatin1('e')), fm.height(), QImage::Format_RGB32); + baseLine.fill(Qt::white); + { + QPainter p(&baseLine); + p.drawText(0, fm.ascent(), QString::fromLatin1("e")); + } + + bool foundDifferentRasterization = false; + for (int i=1; i<12; ++i) { + QImage comparison(baseLine.size(), QImage::Format_RGB32); + comparison.fill(Qt::white); + + { + QPainter p(&comparison); + p.drawText(QPointF(i / 12.0, fm.ascent()), QString::fromLatin1("e")); + } + + if (comparison != baseLine) { + foundDifferentRasterization = true; + break; + } + } + + QVERIFY(foundDifferentRasterization); +} + void tst_QPainter::drawPointScaled() { QImage image(32, 32, QImage::Format_RGB32); @@ -4623,6 +4742,44 @@ void tst_QPainter::QTBUG17053_zeroDashPattern() QCOMPARE(image, original); } +class TextDrawerThread : public QThread +{ +public: + void run(); + QImage rendering; +}; + +void TextDrawerThread::run() +{ + rendering = QImage(100, 100, QImage::Format_ARGB32_Premultiplied); + rendering.fill(0); + QPainter p(&rendering); + p.fillRect(10, 10, 100, 100, Qt::blue); + p.setPen(Qt::green); + p.drawText(20, 20, "some text"); + p.end(); +} + +void tst_QPainter::drawTextOutsideGuiThread() +{ + if (!QFontDatabase::supportsThreadedFontRendering()) + QSKIP("No threaded font rendering", SkipAll); + + QImage referenceRendering(100, 100, QImage::Format_ARGB32_Premultiplied); + referenceRendering.fill(0); + QPainter p(&referenceRendering); + p.fillRect(10, 10, 100, 100, Qt::blue); + p.setPen(Qt::green); + p.drawText(20, 20, "some text"); + p.end(); + + TextDrawerThread t; + t.start(); + t.wait(); + + QCOMPARE(referenceRendering, t.rendering); +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" diff --git a/tests/auto/qpainterpath/tst_qpainterpath.cpp b/tests/auto/qpainterpath/tst_qpainterpath.cpp index 47cd7c6..3941a11 100644 --- a/tests/auto/qpainterpath/tst_qpainterpath.cpp +++ b/tests/auto/qpainterpath/tst_qpainterpath.cpp @@ -60,6 +60,8 @@ public: private slots: void getSetCheck(); + void swap(); + void contains_QPointF_data(); void contains_QPointF(); @@ -142,6 +144,17 @@ void tst_QPainterPath::getSetCheck() QCOMPARE(qreal(1.1), obj1.curveThreshold()); } +void tst_QPainterPath::swap() +{ + QPainterPath p1; + p1.addRect( 0, 0,10,10); + QPainterPath p2; + p2.addRect(10,10,10,10); + p1.swap(p2); + QCOMPARE(p1.boundingRect().toRect(), QRect(10,10,10,10)); + QCOMPARE(p2.boundingRect().toRect(), QRect( 0, 0,10,10)); +} + Q_DECLARE_METATYPE(QPainterPath) Q_DECLARE_METATYPE(QPointF) Q_DECLARE_METATYPE(QRectF) @@ -1040,6 +1053,11 @@ void tst_QPainterPath::pointAtPercent_data() QRectF rect(241, 273, 185, 228); path.addEllipse(rect); QTest::newRow("Case 17") << path << qreal(1.0) << QPointF(rect.right(), qreal(0.5) * (rect.top() + rect.bottom())); + + path = QPainterPath(); + path.moveTo(100, 100); + QTest::newRow("Case 18") << path << qreal(0.0) << QPointF(100, 100); + QTest::newRow("Case 19") << path << qreal(1.0) << QPointF(100, 100); } void tst_QPainterPath::pointAtPercent() diff --git a/tests/auto/qpauseanimation/tst_qpauseanimation.cpp b/tests/auto/qpauseanimation/tst_qpauseanimation.cpp index 502bf39..ea99e19 100644 --- a/tests/auto/qpauseanimation/tst_qpauseanimation.cpp +++ b/tests/auto/qpauseanimation/tst_qpauseanimation.cpp @@ -394,7 +394,10 @@ void tst_QPauseAnimation::multipleSequentialGroups() QVERIFY(subgroup3.state() == QAbstractAnimation::Running); QVERIFY(subgroup4.state() == QAbstractAnimation::Running); - QTest::qWait(group.totalDuration() + 100); + // This is a pretty long animation so it tends to get rather out of sync + // when using the consistent timer, so run for an extra half second for good + // measure... + QTest::qWait(group.totalDuration() + 500); #ifdef Q_OS_WIN if (group.state() != QAbstractAnimation::Stopped) diff --git a/tests/auto/qpen/tst_qpen.cpp b/tests/auto/qpen/tst_qpen.cpp index 4425e30..64d725b 100644 --- a/tests/auto/qpen/tst_qpen.cpp +++ b/tests/auto/qpen/tst_qpen.cpp @@ -59,6 +59,7 @@ public: private slots: void getSetCheck(); + void swap(); void operator_eq_eq(); void operator_eq_eq_data(); @@ -95,6 +96,14 @@ void tst_QPen::getSetCheck() } } +void tst_QPen::swap() +{ + QPen p1(Qt::black), p2(Qt::white); + p1.swap(p2); + QCOMPARE(p1.color(), QColor(Qt::white)); + QCOMPARE(p2.color(), QColor(Qt::black)); +} + Q_DECLARE_METATYPE(QPen) Q_DECLARE_METATYPE(QBrush) diff --git a/tests/auto/qpicture/tst_qpicture.cpp b/tests/auto/qpicture/tst_qpicture.cpp index 3a8285b..b8b10568 100644 --- a/tests/auto/qpicture/tst_qpicture.cpp +++ b/tests/auto/qpicture/tst_qpicture.cpp @@ -64,6 +64,7 @@ private slots: void devType(); void paintingActive(); void boundingRect(); + void swap(); void operator_lt_lt(); void save_restore(); @@ -155,6 +156,18 @@ void tst_QPicture::boundingRect() } } +void tst_QPicture::swap() +{ + QPicture p1, p2; + QPainter(&p1).drawLine(0, 0, 5, 5); + QPainter(&p2).drawLine(0, 3, 3, 0); + QCOMPARE(p1.boundingRect(), QRect(0,0,5,5)); + QCOMPARE(p2.boundingRect(), QRect(0,0,3,3)); + p1.swap(p2); + QCOMPARE(p1.boundingRect(), QRect(0,0,3,3)); + QCOMPARE(p2.boundingRect(), QRect(0,0,5,5)); +} + // operator<< and operator>> void tst_QPicture::operator_lt_lt() { diff --git a/tests/auto/qpixmap/qpixmap.pro b/tests/auto/qpixmap/qpixmap.pro index e6a8257..e73c130 100644 --- a/tests/auto/qpixmap/qpixmap.pro +++ b/tests/auto/qpixmap/qpixmap.pro @@ -3,16 +3,16 @@ SOURCES += tst_qpixmap.cpp contains(QT_CONFIG, qt3support): QT += qt3support wince*|symbian: { - task31722_0.sources = convertFromImage/task31722_0/*.png + task31722_0.files = convertFromImage/task31722_0/*.png task31722_0.path = convertFromImage/task31722_0 - task31722_1.sources = convertFromImage/task31722_1/*.png + task31722_1.files = convertFromImage/task31722_1/*.png task31722_1.path = convertFromImage/task31722_1 - icons.sources = convertFromToHICON/* + icons.files = convertFromToHICON/* icons.path = convertFromToHICON - loadFromData.sources = loadFromData/* + loadFromData.files = loadFromData/* loadFromData.path = loadFromData DEPLOYMENT += task31722_0 task31722_1 icons loadFromData diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 5435a3e..d484b96 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -100,6 +100,8 @@ public slots: void cleanup(); private slots: + void swap(); + void setAlphaChannel_data(); void setAlphaChannel(); @@ -258,6 +260,20 @@ void tst_QPixmap::cleanup() { } +void tst_QPixmap::swap() +{ + QPixmap p1( 16, 16 ), p2( 32, 32 ); + p1.fill( Qt::white ); + p2.fill( Qt::black ); + const qint64 p1k = p1.cacheKey(); + const qint64 p2k = p2.cacheKey(); + p1.swap(p2); + QCOMPARE(p1.cacheKey(), p2k); + QCOMPARE(p1.size(), QSize(32,32)); + QCOMPARE(p2.cacheKey(), p1k); + QCOMPARE(p2.size(), QSize(16,16)); +} + void tst_QPixmap::setAlphaChannel_data() { QTest::addColumn<int>("red"); @@ -1324,7 +1340,7 @@ void tst_QPixmap::toSymbianCFbsBitmap() void tst_QPixmap::onlyNullPixmapsOutsideGuiThread() { -#if !defined(Q_WS_WIN) +#if !defined(Q_WS_WIN) && !defined(Q_WS_MAC) class Thread : public QThread { public: @@ -1357,7 +1373,7 @@ void tst_QPixmap::onlyNullPixmapsOutsideGuiThread() thread.wait(); #endif -#endif // !defined(Q_WS_WIN) +#endif // !defined(Q_WS_WIN) && !defined(Q_WS_MAC) } void tst_QPixmap::refUnref() @@ -1683,8 +1699,8 @@ void tst_QPixmap::fromImageReaderAnimatedGif() QImageReader referenceReader(path); QImageReader pixmapReader(path); - Q_ASSERT(referenceReader.canRead()); - Q_ASSERT(referenceReader.imageCount() > 1); + QVERIFY(referenceReader.canRead()); + QVERIFY(referenceReader.imageCount() > 1); for (int i = 0; i < referenceReader.imageCount(); ++i) { QImage refImage = referenceReader.read(); diff --git a/tests/auto/qpixmapfilter/qpixmapfilter.pro b/tests/auto/qpixmapfilter/qpixmapfilter.pro index e64d68d..964e56d 100644 --- a/tests/auto/qpixmapfilter/qpixmapfilter.pro +++ b/tests/auto/qpixmapfilter/qpixmapfilter.pro @@ -2,7 +2,7 @@ load(qttest_p4) SOURCES += tst_qpixmapfilter.cpp wince*: { - addFiles.sources = noise.png + addFiles.files = noise.png addFiles.path = . DEPLOYMENT += addFiles } diff --git a/tests/auto/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/qplaintextedit/tst_qplaintextedit.cpp index 842c0bb..0802f51 100644 --- a/tests/auto/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/qplaintextedit/tst_qplaintextedit.cpp @@ -150,6 +150,7 @@ private slots: void lineWrapProperty(); void selectionChanged(); void blockCountChanged(); + void insertAndScrollToBottom(); private: void createSelection(); @@ -1504,5 +1505,22 @@ void tst_QPlainTextEdit::blockCountChanged() } +void tst_QPlainTextEdit::insertAndScrollToBottom() +{ + ed->setPlainText("First Line"); + ed->show(); + QString text; + for(int i = 0; i < 2000; ++i) { + text += QLatin1String("this is another line of text to be appended. It is quite long and will probably wrap around, meaning the number of lines is larger than the number of blocks in the text.\n"); + } + QTextCursor cursor = ed->textCursor(); + cursor.beginEditBlock(); + cursor.insertText(text); + cursor.endEditBlock(); + ed->verticalScrollBar()->setValue(ed->verticalScrollBar()->maximum()); + QCOMPARE(ed->verticalScrollBar()->value(), ed->verticalScrollBar()->maximum()); +} + + QTEST_MAIN(tst_QPlainTextEdit) #include "tst_qplaintextedit.moc" diff --git a/tests/auto/qplugin/qplugin.pro b/tests/auto/qplugin/qplugin.pro index aafcb36..37a12da 100644 --- a/tests/auto/qplugin/qplugin.pro +++ b/tests/auto/qplugin/qplugin.pro @@ -25,3 +25,4 @@ mac { SUBDIRS += tst_qplugin.pro +CONFIG += parallel_test diff --git a/tests/auto/qplugin/tst_qplugin.pro b/tests/auto/qplugin/tst_qplugin.pro index 0d9d809..3629fb3 100644 --- a/tests/auto/qplugin/tst_qplugin.pro +++ b/tests/auto/qplugin/tst_qplugin.pro @@ -4,13 +4,13 @@ SOURCES = tst_qplugin.cpp QT = core wince*: { - plugins.sources = plugins/* + plugins.files = plugins/* plugins.path = plugins DEPLOYMENT += plugins } symbian: { - rpDep.sources = releaseplugin.dll debugplugin.dll + rpDep.files = releaseplugin.dll debugplugin.dll rpDep.path = plugins DEPLOYMENT += rpDep dpDep } diff --git a/tests/auto/qpluginloader/elftest/.gitattributes b/tests/auto/qpluginloader/elftest/.gitattributes new file mode 100644 index 0000000..891192c --- /dev/null +++ b/tests/auto/qpluginloader/elftest/.gitattributes @@ -0,0 +1,10 @@ +corrupt1.elf64.so set -crlf -diff +corrupt2.elf64.so set -crlf -diff +corrupt3.elf64.so set -crlf -diff +debugobj.so set -crlf -diff +garbage1.so set -crlf -diff +garbage2.so set -crlf -diff +garbage3.so set -crlf -diff +garbage4.so set -crlf -diff +garbage5.so set -crlf -diff + diff --git a/tests/auto/qpluginloader/elftest/corrupt1.elf64.so b/tests/auto/qpluginloader/elftest/corrupt1.elf64.so Binary files differnew file mode 100755 index 0000000..12ce736 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/corrupt1.elf64.so diff --git a/tests/auto/qpluginloader/elftest/corrupt2.elf64.so b/tests/auto/qpluginloader/elftest/corrupt2.elf64.so Binary files differnew file mode 100755 index 0000000..11fdc2c --- /dev/null +++ b/tests/auto/qpluginloader/elftest/corrupt2.elf64.so diff --git a/tests/auto/qpluginloader/elftest/corrupt3.elf64.so b/tests/auto/qpluginloader/elftest/corrupt3.elf64.so Binary files differnew file mode 100755 index 0000000..94a2bc3 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/corrupt3.elf64.so diff --git a/tests/auto/qpluginloader/elftest/debugobj.so b/tests/auto/qpluginloader/elftest/debugobj.so Binary files differnew file mode 100644 index 0000000..f0ee056 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/debugobj.so diff --git a/tests/auto/qpluginloader/elftest/garbage1.so b/tests/auto/qpluginloader/elftest/garbage1.so new file mode 100644 index 0000000..0c74530 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage1.so @@ -0,0 +1,4 @@ +p¶¤Ðã¨ø±ÕÛcdL+ôúæî&‘¿&÷ýeü¥=კ² +•o°Ã’ÊŽI›§ÙÏmgƒ]!ÀZ +L'Ž)t± +ÙN»¸(e©×P)Y8öG ˆ6ß-yÈÏÀñŸ§÷—“"ô–ZÖÿ›kõ4â?Ë^náÁÇß5$ž’ôY=£ð#y
\ No newline at end of file diff --git a/tests/auto/qpluginloader/elftest/garbage2.so b/tests/auto/qpluginloader/elftest/garbage2.so new file mode 100644 index 0000000..c06338e --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage2.so @@ -0,0 +1 @@ +£Çv.³Y‹¨tKëW3
\ No newline at end of file diff --git a/tests/auto/qpluginloader/elftest/garbage3.so b/tests/auto/qpluginloader/elftest/garbage3.so new file mode 100644 index 0000000..a24c523 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage3.so @@ -0,0 +1 @@ +£ÝÈÈ‚åžT-õ«´ÊôÚ¥ Àä¸ï¨ì¾œÀi8¼_ñxÓõª¾I±Ð×®ÝxÎ=úØ4@þñ[¨—úBàKS$ú
\ No newline at end of file diff --git a/tests/auto/qpluginloader/elftest/garbage4.so b/tests/auto/qpluginloader/elftest/garbage4.so new file mode 100644 index 0000000..4f45cf5 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage4.so @@ -0,0 +1 @@ +¶!¦\~çUu³†:9©ˆ œ§T+91ˆQ¬EøåÇšx¨ng5Óã—zhŒ–…ÿÆ^t™ŠµŽ¦'ÆÎmm*ˈdXH;vw+ªG“²ÃàØ
¨9Lƒ0!
\ No newline at end of file diff --git a/tests/auto/qpluginloader/elftest/garbage5.so b/tests/auto/qpluginloader/elftest/garbage5.so new file mode 100644 index 0000000..f8c0a1d --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage5.so @@ -0,0 +1,2 @@ +ïÌô’Q² +ãµ-¢9Ò
\ No newline at end of file diff --git a/tests/auto/qpluginloader/qpluginloader.pro b/tests/auto/qpluginloader/qpluginloader.pro index 382d6e4..6e41b4c 100644 --- a/tests/auto/qpluginloader/qpluginloader.pro +++ b/tests/auto/qpluginloader/qpluginloader.pro @@ -11,3 +11,4 @@ TARGET = tst_qpluginloader INSTALLS = +CONFIG += parallel_test diff --git a/tests/auto/qpluginloader/tst/tst.pro b/tests/auto/qpluginloader/tst/tst.pro index 2d757e7..be243b8 100644 --- a/tests/auto/qpluginloader/tst/tst.pro +++ b/tests/auto/qpluginloader/tst/tst.pro @@ -14,16 +14,18 @@ win32 { wince*: { - addFiles.sources = $$OUT_PWD/../bin/*.dll + addFiles.files = $$OUT_PWD/../bin/*.dll addFiles.path = bin DEPLOYMENT += addFiles } symbian: { - libDep.sources = tst_qpluginloaderlib.dll + libDep.files = tst_qpluginloaderlib.dll libDep.path = /sys/bin - pluginDep.sources = theplugin.dll + pluginDep.files = theplugin.dll pluginDep.path = bin DEPLOYMENT += libDep pluginDep } + +DEFINES += SRCDIR=\\\"$$PWD/../\\\" diff --git a/tests/auto/qpluginloader/tst_qpluginloader.cpp b/tests/auto/qpluginloader/tst_qpluginloader.cpp index 7ce515c..76dbd48 100644 --- a/tests/auto/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/qpluginloader/tst_qpluginloader.cpp @@ -123,6 +123,9 @@ private slots: void loadHints(); void deleteinstanceOnUnload(); void checkingStubsFromDifferentDrives(); + void loadDebugObj(); + void loadCorruptElf(); + void loadGarbage(); }; tst_QPluginLoader::tst_QPluginLoader() @@ -287,12 +290,14 @@ void tst_QPluginLoader::deleteinstanceOnUnload() QSignalSpy spy1(loader1.instance(), SIGNAL(destroyed())); QSignalSpy spy2(loader2.instance(), SIGNAL(destroyed())); - QCOMPARE(loader1.unload(), false); // refcount not reached 0, not really unloaded - QCOMPARE(spy1.count(), 0); - QCOMPARE(spy2.count(), 0); + if (pass == 0) { + QCOMPARE(loader2.unload(), false); // refcount not reached 0, not really unloaded + QCOMPARE(spy1.count(), 0); + QCOMPARE(spy2.count(), 0); + } QCOMPARE(instance1->pluginName(), QLatin1String("Plugin ok")); QCOMPARE(instance2->pluginName(), QLatin1String("Plugin ok")); - QCOMPARE(loader2.unload(), true); // refcount reached 0, did really unload + QVERIFY(loader1.unload()); // refcount reached 0, did really unload QCOMPARE(spy1.count(), 1); QCOMPARE(spy2.count(), 1); } @@ -348,5 +353,54 @@ void tst_QPluginLoader::checkingStubsFromDifferentDrives() #endif//Q_OS_SYMBIAN } +void tst_QPluginLoader::loadDebugObj() +{ +#if defined (__ELF__) + QVERIFY(QFile::exists(SRCDIR "elftest/debugobj.so")); + QPluginLoader lib1(SRCDIR "elftest/debugobj.so"); + QCOMPARE(lib1.load(), false); +#endif +} + +void tst_QPluginLoader::loadCorruptElf() +{ +#if defined (__ELF__) +if (sizeof(void*) == 8) { + QVERIFY(QFile::exists(SRCDIR "elftest/corrupt1.elf64.so")); + + QPluginLoader lib1(SRCDIR "elftest/corrupt1.elf64.so"); + QCOMPARE(lib1.load(), false); + QVERIFY(lib1.errorString().contains("not a valid Qt plugin")); + + QPluginLoader lib2(SRCDIR "elftest/corrupt2.elf64.so"); + QCOMPARE(lib2.load(), false); + QVERIFY(lib2.errorString().contains("not a valid Qt plugin")); + + QPluginLoader lib3(SRCDIR "elftest/corrupt3.elf64.so"); + QCOMPARE(lib3.load(), false); + QVERIFY(lib3.errorString().contains("not a valid Qt plugin")); +} else if (sizeof(void*) == 4) { + QPluginLoader libW(SRCDIR "elftest/corrupt3.elf64.so"); + QCOMPARE(libW.load(), false); + QVERIFY(libW.errorString().contains("architecture")); +} else { + QFAIL("Please port QElfParser to this platform or blacklist this test."); +} +#endif +} + +void tst_QPluginLoader::loadGarbage() +{ +#if defined (Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) + for (int i=0; i<5; i++) { + QPluginLoader lib(QString(SRCDIR "elftest/garbage%1.so").arg(i)); + QCOMPARE(lib.load(), false); +#ifdef SHOW_ERRORS + qDebug() << lib.errorString(); +#endif + } +#endif +} + QTEST_APPLESS_MAIN(tst_QPluginLoader) #include "tst_qpluginloader.moc" diff --git a/tests/auto/qpoint/qpoint.pro b/tests/auto/qpoint/qpoint.pro index 8b006c2..fd24046 100644 --- a/tests/auto/qpoint/qpoint.pro +++ b/tests/auto/qpoint/qpoint.pro @@ -5,3 +5,4 @@ load(qttest_p4) SOURCES += tst_qpoint.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qpointer/tst_qpointer.cpp b/tests/auto/qpointer/tst_qpointer.cpp index bbc92cf..fed98ec 100644 --- a/tests/auto/qpointer/tst_qpointer.cpp +++ b/tests/auto/qpointer/tst_qpointer.cpp @@ -39,11 +39,8 @@ ** ****************************************************************************/ - #include <QtTest/QtTest> -#include <QApplication> -#include <QDebug> #include <QPointer> #include <QWidget> @@ -51,17 +48,9 @@ class tst_QPointer : public QObject { Q_OBJECT public: - tst_QPointer(); - ~tst_QPointer(); - inline tst_QPointer *me() const { return const_cast<tst_QPointer *>(this); } -public slots: - void initTestCase(); - void cleanupTestCase(); - void init(); - void cleanup(); private slots: void constructors(); void destructor(); @@ -71,28 +60,9 @@ private slots: void dereference_operators(); void disconnect(); void castDuringDestruction(); - void data() const; - void dataSignature() const; + void threadSafety(); }; -tst_QPointer::tst_QPointer() -{ } - -tst_QPointer::~tst_QPointer() -{ } - -void tst_QPointer::initTestCase() -{ } - -void tst_QPointer::cleanupTestCase() -{ } - -void tst_QPointer::init() -{ } - -void tst_QPointer::cleanup() -{ } - void tst_QPointer::constructors() { QPointer<QObject> p1; @@ -105,11 +75,20 @@ void tst_QPointer::constructors() void tst_QPointer::destructor() { + // Make two QPointer's to the same object QObject *object = new QObject; - QPointer<QObject> p = object; - QCOMPARE(p, QPointer<QObject>(object)); + QPointer<QObject> p1 = object; + QPointer<QObject> p2 = object; + // Check that they point to the correct object + QCOMPARE(p1, QPointer<QObject>(object)); + QCOMPARE(p2, QPointer<QObject>(object)); + QCOMPARE(p1, p2); + // Destroy the guarded object delete object; - QCOMPARE(p, QPointer<QObject>(0)); + // Check that both pointers were zeroed + QCOMPARE(p1, QPointer<QObject>(0)); + QCOMPARE(p2, QPointer<QObject>(0)); + QCOMPARE(p1, p2); } void tst_QPointer::assignment_operators() @@ -117,19 +96,21 @@ void tst_QPointer::assignment_operators() QPointer<QObject> p1; QPointer<QObject> p2; + // Test assignment with a QObject-derived object pointer p1 = this; p2 = p1; - QCOMPARE(p1, QPointer<QObject>(this)); QCOMPARE(p2, QPointer<QObject>(this)); QCOMPARE(p1, QPointer<QObject>(p2)); + // Test assignment with a null pointer p1 = 0; p2 = p1; QCOMPARE(p1, QPointer<QObject>(0)); QCOMPARE(p2, QPointer<QObject>(0)); QCOMPARE(p1, QPointer<QObject>(p2)); + // Test assignment with a real QObject pointer QObject *object = new QObject; p1 = object; @@ -138,10 +119,15 @@ void tst_QPointer::assignment_operators() QCOMPARE(p2, QPointer<QObject>(object)); QCOMPARE(p1, QPointer<QObject>(p2)); - delete object; - QCOMPARE(p1, QPointer<QObject>(0)); - QCOMPARE(p2, QPointer<QObject>(0)); + // Test assignment with the same pointer that's already guarded + p1 = object; + p2 = p1; + QCOMPARE(p1, QPointer<QObject>(object)); + QCOMPARE(p2, QPointer<QObject>(object)); QCOMPARE(p1, QPointer<QObject>(p2)); + + // Cleanup + delete object; } void tst_QPointer::equality_operators() @@ -195,19 +181,28 @@ void tst_QPointer::isNull() void tst_QPointer::dereference_operators() { QPointer<tst_QPointer> p1 = this; + QPointer<tst_QPointer> p2; + // operator->() -- only makes sense if not null QObject *object = p1->me(); - QVERIFY(object == this); + QCOMPARE(object, this); + // operator*() -- only makes sense if not null QObject &ref = *p1; - QVERIFY(&ref == this); + QCOMPARE(&ref, this); + + // operator T*() + QCOMPARE(static_cast<QObject *>(p1), this); + QCOMPARE(static_cast<QObject *>(p2), static_cast<QObject *>(0)); - object = static_cast<QObject *>(p1); - QVERIFY(object == this); + // data() + QCOMPARE(p1.data(), this); + QCOMPARE(p2.data(), static_cast<QObject *>(0)); } void tst_QPointer::disconnect() { + // Verify that pointer remains guarded when all signals are disconencted. QPointer<QObject> p1 = new QObject; QVERIFY(!p1.isNull()); p1->disconnect(); @@ -313,37 +308,36 @@ void tst_QPointer::castDuringDestruction() } } -void tst_QPointer::data() const -{ - /* Check value of a default constructed object. */ - { - QPointer<QObject> p; - QCOMPARE(p.data(), static_cast<QObject *>(0)); - } - - /* Check value of a default constructed object. */ - { - QObject *const object = new QObject(); - QPointer<QObject> p(object); - QCOMPARE(p.data(), object); +class TestRunnable : public QObject, public QRunnable { + void run() { + QPointer<QObject> obj1 = new QObject; + QPointer<QObject> obj2 = new QObject; + obj1->moveToThread(thread()); // this is the owner thread + obj1->deleteLater(); // the delete will happen in the owner thread + obj2->moveToThread(thread()); // this is the owner thread + obj2->deleteLater(); // the delete will happen in the owner thread } -} +}; -void tst_QPointer::dataSignature() const +void tst_QPointer::threadSafety() { - /* data() should be const. */ - { - const QPointer<QObject> p; - p.data(); - } - /* The return type should be T. */ - { - const QPointer<QWidget> p; - /* If the types differs, the QCOMPARE will fail to instansiate. */ - QCOMPARE(p.data(), static_cast<QWidget *>(0)); + QThread owner; + owner.start(); + + QThreadPool pool; + for (int i = 0; i < 300; i++) { + QPointer<TestRunnable> task = new TestRunnable; + task->setAutoDelete(true); + task->moveToThread(&owner); + pool.start(task); } + pool.waitForDone(); + + owner.quit(); + owner.wait(); } + QTEST_MAIN(tst_QPointer) #include "tst_qpointer.moc" diff --git a/tests/auto/qpolygon/tst_qpolygon.cpp b/tests/auto/qpolygon/tst_qpolygon.cpp index 77d9328..f47073a 100644 --- a/tests/auto/qpolygon/tst_qpolygon.cpp +++ b/tests/auto/qpolygon/tst_qpolygon.cpp @@ -63,6 +63,7 @@ public: private slots: void makeEllipse(); + void swap(); }; tst_QPolygon::tst_QPolygon() @@ -91,5 +92,14 @@ void tst_QPolygon::makeEllipse() QVERIFY( !err ); } +void tst_QPolygon::swap() +{ + QPolygon p1(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10)); + QPolygon p2(QVector<QPoint>() << QPoint(0,0) << QPoint( 0,10) << QPoint( 10,10) << QPoint(10,0)); + p1.swap(p2); + QCOMPARE(p1.count(),4); + QCOMPARE(p2.count(),3); +} + QTEST_APPLESS_MAIN(tst_QPolygon) #include "tst_qpolygon.moc" diff --git a/tests/auto/qprinterinfo/tst_qprinterinfo.cpp b/tests/auto/qprinterinfo/tst_qprinterinfo.cpp index e207ff5..582fd46 100644 --- a/tests/auto/qprinterinfo/tst_qprinterinfo.cpp +++ b/tests/auto/qprinterinfo/tst_qprinterinfo.cpp @@ -134,7 +134,7 @@ QStringList tst_QPrinterInfo::getPrintersFromSystem() QString output = getOutputFromCommand(command); QStringList list = output.split(QChar::fromLatin1('\n')); - QRegExp reg("^[Pp]rinter ([.a-zA-Z0-9_-]+)"); + QRegExp reg("^[Pp]rinter ([.a-zA-Z0-9-_@]+)"); for (int c = 0; c < list.size(); ++c) { if (reg.indexIn(list[c]) >= 0) { QString printer = reg.cap(1); diff --git a/tests/auto/qprocess/test/test.pro b/tests/auto/qprocess/test/test.pro index d555067..a91cadd 100644 --- a/tests/auto/qprocess/test/test.pro +++ b/tests/auto/qprocess/test/test.pro @@ -27,61 +27,61 @@ embedded: QT += gui wince*: { - addFile_fileWriterProcess.sources = $$OUT_PWD/../fileWriterProcess/fileWriterProcess.exe + addFile_fileWriterProcess.files = $$OUT_PWD/../fileWriterProcess/fileWriterProcess.exe addFile_fileWriterProcess.path = fileWriterProcess - addFile_testBatFiles.sources = $$PWD/../testBatFiles/* + addFile_testBatFiles.files = $$PWD/../testBatFiles/* addFile_testBatFiles.path = testBatFiles - addFile_testDetached.sources = $$OUT_PWD/../testDetached/testDetached.exe + addFile_testDetached.files = $$OUT_PWD/../testDetached/testDetached.exe addFile_testDetached.path = testDetached - addFile_testExitCodes.sources = $$OUT_PWD/../testExitCodes/testExitCodes.exe + addFile_testExitCodes.files = $$OUT_PWD/../testExitCodes/testExitCodes.exe addFile_testExitCodes.path = testExitCodes - addFile_testGuiProcess.sources = $$OUT_PWD/../testGuiProcess/testGuiProcess.exe + addFile_testGuiProcess.files = $$OUT_PWD/../testGuiProcess/testGuiProcess.exe addFile_testGuiProcess.path = testGuiProcess - addFile_testProcessCrash.sources = $$OUT_PWD/../testProcessCrash/testProcessCrash.exe + addFile_testProcessCrash.files = $$OUT_PWD/../testProcessCrash/testProcessCrash.exe addFile_testProcessCrash.path = testProcessCrash - addFile_testProcessDeadWhileReading.sources = $$OUT_PWD/../testProcessDeadWhileReading/testProcessDeadWhileReading.exe + addFile_testProcessDeadWhileReading.files = $$OUT_PWD/../testProcessDeadWhileReading/testProcessDeadWhileReading.exe addFile_testProcessDeadWhileReading.path = testProcessDeadWhileReading - addFile_testProcessEcho.sources = $$OUT_PWD/../testProcessEcho/testProcessEcho.exe + addFile_testProcessEcho.files = $$OUT_PWD/../testProcessEcho/testProcessEcho.exe addFile_testProcessEcho.path = testProcessEcho - addFile_testProcessEcho2.sources = $$OUT_PWD/../testProcessEcho2/testProcessEcho2.exe + addFile_testProcessEcho2.files = $$OUT_PWD/../testProcessEcho2/testProcessEcho2.exe addFile_testProcessEcho2.path = testProcessEcho2 - addFile_testProcessEcho3.sources = $$OUT_PWD/../testProcessEcho3/testProcessEcho3.exe + addFile_testProcessEcho3.files = $$OUT_PWD/../testProcessEcho3/testProcessEcho3.exe addFile_testProcessEcho3.path = testProcessEcho3 - addFile_testProcessEOF.sources = $$OUT_PWD/../testProcessEOF/testProcessEOF.exe + addFile_testProcessEOF.files = $$OUT_PWD/../testProcessEOF/testProcessEOF.exe addFile_testProcessEOF.path = testProcessEOF - addFile_testProcessLoopback.sources = $$OUT_PWD/../testProcessLoopback/testProcessLoopback.exe + addFile_testProcessLoopback.files = $$OUT_PWD/../testProcessLoopback/testProcessLoopback.exe addFile_testProcessLoopback.path = testProcessLoopback - addFile_testProcessNormal.sources = $$OUT_PWD/../testProcessNormal/testProcessNormal.exe + addFile_testProcessNormal.files = $$OUT_PWD/../testProcessNormal/testProcessNormal.exe addFile_testProcessNormal.path = testProcessNormal - addFile_testProcessOutput.sources = $$OUT_PWD/../testProcessOutput/testProcessOutput.exe + addFile_testProcessOutput.files = $$OUT_PWD/../testProcessOutput/testProcessOutput.exe addFile_testProcessOutput.path = testProcessOutput - addFile_testProcessNoSpacesArgs.sources = $$OUT_PWD/../testProcessSpacesArgs/nospace.exe + addFile_testProcessNoSpacesArgs.files = $$OUT_PWD/../testProcessSpacesArgs/nospace.exe addFile_testProcessNoSpacesArgs.path = testProcessSpacesArgs - addFile_testProcessOneSpacesArgs.sources = $$OUT_PWD/../testProcessSpacesArgs/"one space".exe + addFile_testProcessOneSpacesArgs.files = $$OUT_PWD/../testProcessSpacesArgs/"one space".exe addFile_testProcessOneSpacesArgs.path = testProcessSpacesArgs - addFile_testProcessTwoSpacesArgs.sources = $$OUT_PWD/../testProcessSpacesArgs/"two space s".exe + addFile_testProcessTwoSpacesArgs.files = $$OUT_PWD/../testProcessSpacesArgs/"two space s".exe addFile_testProcessTwoSpacesArgs.path = testProcessSpacesArgs - addFile_testSoftExit.sources = $$OUT_PWD/../testSoftExit/testSoftExit.exe + addFile_testSoftExit.files = $$OUT_PWD/../testSoftExit/testSoftExit.exe addFile_testSoftExit.path = testSoftExit - addFile_testSpaceInName.sources = $$OUT_PWD/../"test Space In Name"/testSpaceInName.exe + addFile_testSpaceInName.files = $$OUT_PWD/../"test Space In Name"/testSpaceInName.exe addFile_testSpaceInName.path = "test Space In Name" @@ -108,7 +108,7 @@ wince*: { } symbian: { - binDep.sources = \ + binDep.files = \ fileWriterProcess.exe \ testDetached.exe \ testExitCodes.exe \ diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index a927b81..91e0abe 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -668,7 +668,7 @@ void tst_QProcess::exitStatus() QSKIP("This test opens a crash dialog on Windows", SkipSingle); #endif - Q_ASSERT(processList.count() == exitStatus.count()); + QCOMPARE(exitStatus.count(), processList.count()); for (int i = 0; i < processList.count(); ++i) { process->start(processList.at(i)); QVERIFY(process->waitForStarted(5000)); @@ -1587,6 +1587,7 @@ void tst_QProcess::spaceArgsTest() #if defined(Q_OS_SYMBIAN) // Symbian test outputs to a file, so check that FILE* file = fopen("c:\\logs\\qprocess_args_test.txt","r"); + QVERIFY(file); char buf[256]; fgets(buf, 256, file); fclose(file); @@ -1616,6 +1617,7 @@ void tst_QProcess::spaceArgsTest() #if defined(Q_OS_SYMBIAN) // Symbian test outputs to a file, so check that file = fopen("c:\\logs\\qprocess_args_test.txt","r"); + QVERIFY(file); fgets(buf, 256, file); fclose(file); actual = QString::fromLatin1(buf).split("|"); @@ -1663,6 +1665,7 @@ void tst_QProcess::nativeArguments() # else FILE* file = fopen("\\temp\\qprocess_args_test.txt","r"); # endif + QVERIFY(file); char buf[256]; fgets(buf, 256, file); fclose(file); @@ -2291,7 +2294,9 @@ void tst_QProcess::detachedWorkingDirectoryAndPid() QFileInfo fi(infoFile); fi.setCaching(false); - while (fi.size() == 0) { + //The guard counter ensures the test does not hang if the sub process fails. + //Instead, the test will fail when trying to open & verify the sub process output file. + for (int guard = 0; guard < 100 && fi.size() == 0; guard++) { QTest::qSleep(100); } @@ -2403,6 +2408,7 @@ void tst_QProcess::startFinishStartFinish() #if defined(Q_OS_SYMBIAN) // Symbian test outputs to a file, so check that FILE* file = fopen("c:\\logs\\qprocess_output_test.txt","r"); + QVERIFY(file); char buf[30]; fgets(buf, 30, file); QCOMPARE(QString::fromLatin1(buf), diff --git a/tests/auto/qprocessenvironment/qprocessenvironment.pro b/tests/auto/qprocessenvironment/qprocessenvironment.pro index 398facc..60dba50 100644 --- a/tests/auto/qprocessenvironment/qprocessenvironment.pro +++ b/tests/auto/qprocessenvironment/qprocessenvironment.pro @@ -3,3 +3,4 @@ load(qttest_p4) QT = core SOURCES += tst_qprocessenvironment.cpp +CONFIG += parallel_test diff --git a/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp b/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp index 289ba9d..d88ffde 100644 --- a/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp +++ b/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp @@ -43,10 +43,6 @@ #include <QObject> #include <QProcessEnvironment> -// Note: -// in cross-platform tests, ALWAYS use UPPERCASE variable names -// That's because on Windows, the variables are uppercased - class tst_QProcessEnvironment: public QObject { Q_OBJECT @@ -56,6 +52,8 @@ private slots: void insert(); void emptyNull(); void toStringList(); + void keys(); + void insertEnv(); void caseSensitivity(); void systemEnvironment(); @@ -154,13 +152,65 @@ void tst_QProcessEnvironment::toStringList() QVERIFY(result.contains("HELLO=World")); } +void tst_QProcessEnvironment::keys() +{ + QProcessEnvironment e; + QVERIFY(e.isEmpty()); + QVERIFY(e.keys().isEmpty()); + + e.insert("FOO", "bar"); + QStringList result = e.keys(); + QCOMPARE(result.length(), 1); + QCOMPARE(result.at(0), QString("FOO")); + + e.clear(); + e.insert("BAZ", ""); + result = e.keys(); + QCOMPARE(result.at(0), QString("BAZ")); + + e.insert("FOO", "bar"); + e.insert("A", "bc"); + e.insert("HELLO", "World"); + result = e.keys(); + QCOMPARE(result.length(), 4); + + // order is not specified, so use contains() + QVERIFY(result.contains("FOO")); + QVERIFY(result.contains("BAZ")); + QVERIFY(result.contains("A")); + QVERIFY(result.contains("HELLO")); +} + +void tst_QProcessEnvironment::insertEnv() +{ + QProcessEnvironment e; + e.insert("FOO", "bar"); + e.insert("A", "bc"); + e.insert("Hello", "World"); + + QProcessEnvironment e2; + e2.insert("FOO2", "bar2"); + e2.insert("A2", "bc2"); + e2.insert("Hello", "Another World"); + + e.insert(e2); + QStringList keys = e.keys(); + QCOMPARE(keys.length(), 5); + + QCOMPARE(e.value("FOO"), QString("bar")); + QCOMPARE(e.value("A"), QString("bc")); + QCOMPARE(e.value("Hello"), QString("Another World")); + QCOMPARE(e.value("FOO2"), QString("bar2")); + QCOMPARE(e.value("A2"), QString("bc2")); +} + void tst_QProcessEnvironment::caseSensitivity() { QProcessEnvironment e; e.insert("foo", "bar"); #ifdef Q_OS_WIN - // on Windows, it's uppercased + // Windows is case-insensitive, but case-preserving QVERIFY(e.contains("foo")); QVERIFY(e.contains("FOO")); QVERIFY(e.contains("FoO")); @@ -169,8 +219,12 @@ void tst_QProcessEnvironment::caseSensitivity() QCOMPARE(e.value("FOO"), QString("bar")); QCOMPARE(e.value("FoO"), QString("bar")); + // Per Windows, this overwrites the value, but keeps the name's original capitalization + e.insert("Foo", "Bar"); + QStringList list = e.toStringList(); - QCOMPARE(list.at(0), QString("FOO=bar")); + QCOMPARE(list.length(), 1); + QCOMPARE(list.at(0), QString("foo=Bar")); #else // otherwise, it's case sensitive QVERIFY(e.contains("foo")); @@ -182,6 +236,7 @@ void tst_QProcessEnvironment::caseSensitivity() QCOMPARE(e.value("foo"), QString("bar")); QStringList list = e.toStringList(); + QCOMPARE(list.length(), 2); QVERIFY(list.contains("foo=bar")); QVERIFY(list.contains("FOO=baz")); #endif diff --git a/tests/auto/qprogressbar/tst_qprogressbar.cpp b/tests/auto/qprogressbar/tst_qprogressbar.cpp index 822177d..04b7ce7 100644 --- a/tests/auto/qprogressbar/tst_qprogressbar.cpp +++ b/tests/auto/qprogressbar/tst_qprogressbar.cpp @@ -179,10 +179,15 @@ void tst_QProgressBar::format() bar.repainted = false; bar.setFormat("%v of %m (%p%)"); qApp->processEvents(); + #ifndef Q_WS_MAC - // The Mac scroll bar is animated, which means we get paint events all the time. + // Animated scroll bars get paint events all the time +#ifdef Q_OS_WIN + if (QSysInfo::WindowsVersion < QSysInfo::WV_VISTA) +#endif QVERIFY(!bar.repainted); #endif + QCOMPARE(bar.text(), QString("1 of 10 (10%)")); bar.setRange(5, 5); bar.setValue(5); diff --git a/tests/auto/qqueue/qqueue.pro b/tests/auto/qqueue/qqueue.pro index ed489f9..ce0d8c3 100644 --- a/tests/auto/qqueue/qqueue.pro +++ b/tests/auto/qqueue/qqueue.pro @@ -4,3 +4,4 @@ QT = core SOURCES += tst_qqueue.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qradiobutton/tst_qradiobutton.cpp b/tests/auto/qradiobutton/tst_qradiobutton.cpp index b9a1931..79d3c8e 100644 --- a/tests/auto/qradiobutton/tst_qradiobutton.cpp +++ b/tests/auto/qradiobutton/tst_qradiobutton.cpp @@ -58,6 +58,7 @@ public: private slots: void task190739_focus(); + void minimumSizeHint(); private: }; @@ -96,6 +97,11 @@ void tst_QRadioButton::task190739_focus() } +void tst_QRadioButton::minimumSizeHint() +{ + QRadioButton button(tr("QRadioButtons sizeHint is the same as it's minimumSizeHint")); + QCOMPARE(button.sizeHint(), button.minimumSizeHint()); +} QTEST_MAIN(tst_QRadioButton) diff --git a/tests/auto/qrand/qrand.pro b/tests/auto/qrand/qrand.pro index c868ed4..0db8af8 100644 --- a/tests/auto/qrand/qrand.pro +++ b/tests/auto/qrand/qrand.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qrand.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qrawfont/qrawfont.pro b/tests/auto/qrawfont/qrawfont.pro new file mode 100644 index 0000000..ccdccfb --- /dev/null +++ b/tests/auto/qrawfont/qrawfont.pro @@ -0,0 +1,13 @@ +load(qttest_p4) +QT = core gui + +SOURCES += \ + tst_qrawfont.cpp + +INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src + +wince*|symbian*: { + DEFINES += SRCDIR=\\\"\\\" +} else { + DEFINES += SRCDIR=\\\"$$PWD/\\\" +} diff --git a/tests/auto/qrawfont/testfont.ttf b/tests/auto/qrawfont/testfont.ttf Binary files differnew file mode 100644 index 0000000..d6042d2 --- /dev/null +++ b/tests/auto/qrawfont/testfont.ttf diff --git a/tests/auto/qrawfont/testfont_bold_italic.ttf b/tests/auto/qrawfont/testfont_bold_italic.ttf Binary files differnew file mode 100644 index 0000000..9f65ac8 --- /dev/null +++ b/tests/auto/qrawfont/testfont_bold_italic.ttf diff --git a/tests/auto/qrawfont/tst_qrawfont.cpp b/tests/auto/qrawfont/tst_qrawfont.cpp new file mode 100644 index 0000000..e0680c4 --- /dev/null +++ b/tests/auto/qrawfont/tst_qrawfont.cpp @@ -0,0 +1,850 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <qrawfont.h> +#include <private/qrawfont_p.h> + +class tst_QRawFont: public QObject +{ + Q_OBJECT + +#if !defined(QT_NO_RAWFONT) +private slots: + void invalidRawFont(); + + void explicitRawFontNotLoadedInDatabase_data(); + void explicitRawFontNotLoadedInDatabase(); + + void explicitRawFontNotAvailableInSystem_data(); + void explicitRawFontNotAvailableInSystem(); + + void correctFontData_data(); + void correctFontData(); + + void glyphIndices(); + + void advances_data(); + void advances(); + + void textLayout(); + + void fontTable_data(); + void fontTable(); + + void supportedWritingSystems_data(); + void supportedWritingSystems(); + + void supportsCharacter_data(); + void supportsCharacter(); + + void supportsUcs4Character_data(); + void supportsUcs4Character(); + + void fromFont_data(); + void fromFont(); + + void copyConstructor_data(); + void copyConstructor(); + + void detach_data(); + void detach(); + + void unsupportedWritingSystem_data(); + void unsupportedWritingSystem(); + + void rawFontSetPixelSize_data(); + void rawFontSetPixelSize(); +#endif // QT_NO_RAWFONT +}; + +#if !defined(QT_NO_RAWFONT) +Q_DECLARE_METATYPE(QFont::HintingPreference) +Q_DECLARE_METATYPE(QFont::Style) +Q_DECLARE_METATYPE(QFont::Weight) +Q_DECLARE_METATYPE(QFontDatabase::WritingSystem) + +void tst_QRawFont::invalidRawFont() +{ + QRawFont font; + QVERIFY(!font.isValid()); + QCOMPARE(font.pixelSize(), 0.0); + QVERIFY(font.familyName().isEmpty()); + QCOMPARE(font.style(), QFont::StyleNormal); + QCOMPARE(font.weight(), -1); + QCOMPARE(font.ascent(), 0.0); + QCOMPARE(font.descent(), 0.0); + QVERIFY(font.glyphIndexesForString(QLatin1String("Test")).isEmpty()); +} + +void tst_QRawFont::explicitRawFontNotLoadedInDatabase_data() +{ + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting") << QFont::PreferFullHinting; +} + +void tst_QRawFont::explicitRawFontNotLoadedInDatabase() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + QRawFont font(QLatin1String(SRCDIR "testfont.ttf"), 10, hintingPreference); + QVERIFY(font.isValid()); + + QVERIFY(!QFontDatabase().families().contains(font.familyName())); +} + +void tst_QRawFont::explicitRawFontNotAvailableInSystem_data() +{ + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting") << QFont::PreferFullHinting; +} + +void tst_QRawFont::explicitRawFontNotAvailableInSystem() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + QRawFont rawfont(QLatin1String(SRCDIR "testfont.ttf"), 10, hintingPreference); + + { + QFont font(rawfont.familyName(), 10); + + QVERIFY(!font.exactMatch()); + QVERIFY(font.family() != QFontInfo(font).family()); + } +} + +void tst_QRawFont::correctFontData_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::addColumn<QString>("expectedFamilyName"); + QTest::addColumn<QFont::Style>("style"); + QTest::addColumn<QFont::Weight>("weight"); + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + QTest::addColumn<qreal>("unitsPerEm"); + QTest::addColumn<qreal>("pixelSize"); + + int hintingPreferences[] = { + int(QFont::PreferDefaultHinting), + int(QFont::PreferNoHinting), + int(QFont::PreferVerticalHinting), + int(QFont::PreferFullHinting), + -1 + }; + int *hintingPreference = hintingPreferences; + + while (*hintingPreference >= 0) { + QString fileName = QLatin1String(SRCDIR "testfont.ttf"); + QString title = fileName + + QLatin1String(": hintingPreference=") + + QString::number(*hintingPreference); + + QTest::newRow(qPrintable(title)) + << fileName + << QString::fromLatin1("QtBidiTestFont") + << QFont::StyleNormal + << QFont::Normal + << QFont::HintingPreference(*hintingPreference) + << 1000.0 + << 10.0; + + fileName = QLatin1String(SRCDIR "testfont_bold_italic.ttf"); + title = fileName + + QLatin1String(": hintingPreference=") + + QString::number(*hintingPreference); + + QTest::newRow(qPrintable(title)) + << fileName + << QString::fromLatin1("QtBidiTestFont") + << QFont::StyleItalic + << QFont::Bold + << QFont::HintingPreference(*hintingPreference) + << 1000.0 + << 10.0; + + ++hintingPreference; + } +} + +void tst_QRawFont::correctFontData() +{ + QFETCH(QString, fileName); + QFETCH(QString, expectedFamilyName); + QFETCH(QFont::Style, style); + QFETCH(QFont::Weight, weight); + QFETCH(QFont::HintingPreference, hintingPreference); + QFETCH(qreal, unitsPerEm); + QFETCH(qreal, pixelSize); + + QRawFont font(fileName, 10, hintingPreference); + QVERIFY(font.isValid()); + + QCOMPARE(font.familyName(), expectedFamilyName); + QCOMPARE(font.style(), style); + QCOMPARE(font.weight(), int(weight)); + QCOMPARE(font.hintingPreference(), hintingPreference); + QCOMPARE(font.unitsPerEm(), unitsPerEm); + QCOMPARE(font.pixelSize(), pixelSize); +} + +void tst_QRawFont::glyphIndices() +{ + QRawFont font(QLatin1String(SRCDIR "testfont.ttf"), 10); + QVERIFY(font.isValid()); + + QVector<quint32> glyphIndices = font.glyphIndexesForString(QLatin1String("Foobar")); + QVector<quint32> expectedGlyphIndices; + expectedGlyphIndices << 44 << 83 << 83 << 70 << 69 << 86; + + QCOMPARE(glyphIndices, expectedGlyphIndices); +} + +void tst_QRawFont::advances_data() +{ + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting") << QFont::PreferFullHinting; +} + +void tst_QRawFont::advances() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + QRawFont font(QLatin1String(SRCDIR "testfont.ttf"), 10, hintingPreference); + QVERIFY(font.isValid()); + + QRawFontPrivate *font_d = QRawFontPrivate::get(font); + QVERIFY(font_d->fontEngine != 0); + + QVector<quint32> glyphIndices; + glyphIndices << 44 << 83 << 83 << 70 << 69 << 86; // "Foobar" + + bool supportsSubPixelPositions = font_d->fontEngine->supportsSubPixelPositions(); + QVector<QPointF> advances = font.advancesForGlyphIndexes(glyphIndices); + for (int i=0; i<glyphIndices.size(); ++i) { + QVERIFY(qFuzzyCompare(qRound(advances.at(i).x()), 8.0)); + if (supportsSubPixelPositions) + QVERIFY(advances.at(i).x() > 8.0); + + QVERIFY(qFuzzyIsNull(advances.at(i).y())); + } +} + +void tst_QRawFont::textLayout() +{ + QFontDatabase fontDatabase; + int id = fontDatabase.addApplicationFont(SRCDIR "testfont.ttf"); + QVERIFY(id >= 0); + + QString familyName = QString::fromLatin1("QtBidiTestFont"); + QFont font(familyName); + font.setPixelSize(18.0); + QCOMPARE(QFontInfo(font).family(), familyName); + + QTextLayout layout(QLatin1String("Foobar")); + layout.setFont(font); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 1); + + QGlyphRun glyphs = glyphRuns.at(0); + + QRawFont rawFont = glyphs.rawFont(); + QVERIFY(rawFont.isValid()); + QCOMPARE(rawFont.familyName(), familyName); + QCOMPARE(rawFont.pixelSize(), 18.0); + + QVector<quint32> expectedGlyphIndices; + expectedGlyphIndices << 44 << 83 << 83 << 70 << 69 << 86; + + QCOMPARE(glyphs.glyphIndexes(), expectedGlyphIndices); + + QVERIFY(fontDatabase.removeApplicationFont(id)); +} + +void tst_QRawFont::fontTable_data() +{ + QTest::addColumn<QByteArray>("tagName"); + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + QTest::addColumn<int>("offset"); + QTest::addColumn<quint32>("expectedValue"); + + QTest::newRow("Head table, magic number, default hinting") + << QByteArray("head") + << QFont::PreferDefaultHinting + << 12 + << (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? 0x5F0F3CF5 + : 0xF53C0F5F); + + QTest::newRow("Head table, magic number, no hinting") + << QByteArray("head") + << QFont::PreferNoHinting + << 12 + << (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? 0x5F0F3CF5 + : 0xF53C0F5F); + + QTest::newRow("Head table, magic number, vertical hinting") + << QByteArray("head") + << QFont::PreferVerticalHinting + << 12 + << (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? 0x5F0F3CF5 + : 0xF53C0F5F); + + QTest::newRow("Head table, magic number, full hinting") + << QByteArray("head") + << QFont::PreferFullHinting + << 12 + << (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? 0x5F0F3CF5 + : 0xF53C0F5F); +} + +void tst_QRawFont::fontTable() +{ + QFETCH(QByteArray, tagName); + QFETCH(QFont::HintingPreference, hintingPreference); + QFETCH(int, offset); + QFETCH(quint32, expectedValue); + + QRawFont font(QString::fromLatin1(SRCDIR "testfont.ttf"), 10, hintingPreference); + QVERIFY(font.isValid()); + + QByteArray table = font.fontTable(tagName); + QVERIFY(!table.isEmpty()); + + const quint32 *value = reinterpret_cast<const quint32 *>(table.constData() + offset); + QCOMPARE(*value, expectedValue); +} + +typedef QList<QFontDatabase::WritingSystem> WritingSystemList; +Q_DECLARE_METATYPE(WritingSystemList) + +void tst_QRawFont::supportedWritingSystems_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::addColumn<WritingSystemList>("writingSystems"); + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + + for (int hintingPreference=QFont::PreferDefaultHinting; + hintingPreference<=QFont::PreferFullHinting; + ++hintingPreference) { + + QTest::newRow(qPrintable(QString::fromLatin1("testfont.ttf, hintingPreference=%1") + .arg(hintingPreference))) + << QString::fromLatin1(SRCDIR "testfont.ttf") + << (QList<QFontDatabase::WritingSystem>() + << QFontDatabase::Latin + << QFontDatabase::Hebrew + << QFontDatabase::Vietnamese) // Vietnamese uses same unicode bits as Latin + << QFont::HintingPreference(hintingPreference); + + QTest::newRow(qPrintable(QString::fromLatin1("testfont_bold_italic.ttf, hintingPreference=%1") + .arg(hintingPreference))) + << QString::fromLatin1(SRCDIR "testfont_bold_italic.ttf") + << (QList<QFontDatabase::WritingSystem>() + << QFontDatabase::Latin + << QFontDatabase::Hebrew + << QFontDatabase::Devanagari + << QFontDatabase::Vietnamese) // Vietnamese uses same unicode bits as Latin + << QFont::HintingPreference(hintingPreference); + } +} + +void tst_QRawFont::supportedWritingSystems() +{ + QFETCH(QString, fileName); + QFETCH(WritingSystemList, writingSystems); + QFETCH(QFont::HintingPreference, hintingPreference); + + QRawFont font(fileName, 10, hintingPreference); + QVERIFY(font.isValid()); + + WritingSystemList actualWritingSystems = font.supportedWritingSystems(); + QCOMPARE(actualWritingSystems.size(), writingSystems.size()); + + foreach (QFontDatabase::WritingSystem writingSystem, writingSystems) + QVERIFY(actualWritingSystems.contains(writingSystem)); +} + +void tst_QRawFont::supportsCharacter_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + QTest::addColumn<QChar>("character"); + QTest::addColumn<bool>("shouldBeSupported"); + + const char *fileNames[2] = { + SRCDIR "testfont.ttf", + SRCDIR "testfont_bold_italic.ttf" + }; + + for (int hintingPreference=QFont::PreferDefaultHinting; + hintingPreference<=QFont::PreferFullHinting; + ++hintingPreference) { + + for (int i=0; i<2; ++i) { + QString fileName = QLatin1String(fileNames[i]); + + // Latin text + for (char ch='!'; ch<='~'; ++ch) { + QString title = QString::fromLatin1("%1, character=0x%2, hintingPreference=%3") + .arg(fileName).arg(QString::number(ch, 16)).arg(hintingPreference); + + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(hintingPreference) + << QChar::fromLatin1(ch) + << true; + } + + // Hebrew text + for (quint16 ch=0x05D0; ch<=0x05EA; ++ch) { + QString title = QString::fromLatin1("%1, character=0x%2, hintingPreference=%3") + .arg(fileName).arg(QString::number(ch, 16)).arg(hintingPreference); + + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(hintingPreference) + << QChar(ch) + << true; + } + + QTest::newRow(qPrintable(QString::fromLatin1("Missing character, %1, hintingPreference=%2") + .arg(fileName).arg(hintingPreference))) + << fileName + << QFont::HintingPreference(hintingPreference) + << QChar(0xD8) + << false; + } + } +} + +void tst_QRawFont::supportsCharacter() +{ + QFETCH(QString, fileName); + QFETCH(QFont::HintingPreference, hintingPreference); + QFETCH(QChar, character); + QFETCH(bool, shouldBeSupported); + + QRawFont font(fileName, 10, hintingPreference); + QVERIFY(font.isValid()); + + QCOMPARE(font.supportsCharacter(character), shouldBeSupported); +} + +void tst_QRawFont::supportsUcs4Character_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + QTest::addColumn<quint32>("ucs4"); + QTest::addColumn<bool>("shouldBeSupported"); + + // Gothic text + for (int hintingPreference=QFont::PreferDefaultHinting; + hintingPreference<=QFont::PreferFullHinting; + ++hintingPreference) { + for (quint32 ch=0x10330; ch<=0x1034A; ++ch) { + { + QString fileName = QString::fromLatin1(SRCDIR "testfont.ttf"); + QString title = QString::fromLatin1("%1, character=0x%2, hintingPreference=%3") + .arg(fileName).arg(QString::number(ch, 16)).arg(hintingPreference); + + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(hintingPreference) + << ch + << true; + } + + { + QString fileName = QString::fromLatin1(SRCDIR "testfont_bold_italic.ttf"); + QString title = QString::fromLatin1("%1, character=0x%2, hintingPreference=%3") + .arg(fileName).arg(QString::number(ch, 16)).arg(hintingPreference); + + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(hintingPreference) + << ch + << false; + } + } + } +} + +void tst_QRawFont::supportsUcs4Character() +{ + QFETCH(QString, fileName); + QFETCH(QFont::HintingPreference, hintingPreference); + QFETCH(quint32, ucs4); + QFETCH(bool, shouldBeSupported); + + QRawFont font(fileName, 10, hintingPreference); + QVERIFY(font.isValid()); + + QCOMPARE(font.supportsCharacter(ucs4), shouldBeSupported); +} + +void tst_QRawFont::fromFont_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + QTest::addColumn<QString>("familyName"); + QTest::addColumn<QFontDatabase::WritingSystem>("writingSystem"); + + for (int i=QFont::PreferDefaultHinting; i<=QFont::PreferFullHinting; ++i) { + QString titleBase = QString::fromLatin1("%2, hintingPreference=%1, writingSystem=%3") + .arg(i); + { + QString fileName = QString::fromLatin1(SRCDIR "testfont.ttf"); + QFontDatabase::WritingSystem writingSystem = QFontDatabase::Any; + + QString title = titleBase.arg(fileName).arg(writingSystem); + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(i) + << "QtBidiTestFont" + << writingSystem; + } + + { + QString fileName = QString::fromLatin1(SRCDIR "testfont.ttf"); + QFontDatabase::WritingSystem writingSystem = QFontDatabase::Hebrew; + + QString title = titleBase.arg(fileName).arg(writingSystem); + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(i) + << "QtBidiTestFont" + << writingSystem; + } + + { + QString fileName = QString::fromLatin1(SRCDIR "testfont.ttf"); + QFontDatabase::WritingSystem writingSystem = QFontDatabase::Latin; + + QString title = titleBase.arg(fileName).arg(writingSystem); + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(i) + << "QtBidiTestFont" + << writingSystem; + } + } +} + +void tst_QRawFont::fromFont() +{ + QFETCH(QString, fileName); + QFETCH(QFont::HintingPreference, hintingPreference); + QFETCH(QString, familyName); + QFETCH(QFontDatabase::WritingSystem, writingSystem); + + QFontDatabase fontDatabase; + int id = fontDatabase.addApplicationFont(fileName); + QVERIFY(id >= 0); + + QFont font(familyName); + font.setHintingPreference(hintingPreference); + font.setPixelSize(26.0); + + QRawFont rawFont = QRawFont::fromFont(font, writingSystem); + QVERIFY(rawFont.isValid()); + QCOMPARE(rawFont.familyName(), familyName); + QCOMPARE(rawFont.pixelSize(), 26.0); + + QVERIFY(fontDatabase.removeApplicationFont(id)); +} + +void tst_QRawFont::copyConstructor_data() +{ + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting preference") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting preference") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting preference") << QFont::PreferFullHinting; +} + +void tst_QRawFont::copyConstructor() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + { + QString rawFontFamilyName; + qreal rawFontPixelSize; + qreal rawFontAscent; + qreal rawFontDescent; + int rawFontTableSize; + + QRawFont outerRawFont; + { + QRawFont rawFont(QString::fromLatin1(SRCDIR "testfont.ttf"), 11, hintingPreference); + QVERIFY(rawFont.isValid()); + + rawFontFamilyName = rawFont.familyName(); + rawFontPixelSize = rawFont.pixelSize(); + rawFontAscent = rawFont.ascent(); + rawFontDescent = rawFont.descent(); + rawFontTableSize = rawFont.fontTable("glyf").size(); + QVERIFY(rawFontTableSize > 0); + + { + QRawFont otherRawFont(rawFont); + QVERIFY(otherRawFont.isValid()); + QCOMPARE(otherRawFont.pixelSize(), rawFontPixelSize); + QCOMPARE(otherRawFont.familyName(), rawFontFamilyName); + QCOMPARE(otherRawFont.hintingPreference(), hintingPreference); + QCOMPARE(otherRawFont.ascent(), rawFontAscent); + QCOMPARE(otherRawFont.descent(), rawFontDescent); + QCOMPARE(otherRawFont.fontTable("glyf").size(), rawFontTableSize); + } + + { + QRawFont otherRawFont = rawFont; + QVERIFY(otherRawFont.isValid()); + QCOMPARE(otherRawFont.pixelSize(), rawFontPixelSize); + QCOMPARE(otherRawFont.familyName(), rawFontFamilyName); + QCOMPARE(otherRawFont.hintingPreference(), hintingPreference); + QCOMPARE(otherRawFont.ascent(), rawFontAscent); + QCOMPARE(otherRawFont.descent(), rawFontDescent); + QCOMPARE(otherRawFont.fontTable("glyf").size(), rawFontTableSize); + } + + outerRawFont = rawFont; + } + + QVERIFY(outerRawFont.isValid()); + QCOMPARE(outerRawFont.pixelSize(), rawFontPixelSize); + QCOMPARE(outerRawFont.familyName(), rawFontFamilyName); + QCOMPARE(outerRawFont.hintingPreference(), hintingPreference); + QCOMPARE(outerRawFont.ascent(), rawFontAscent); + QCOMPARE(outerRawFont.descent(), rawFontDescent); + QCOMPARE(outerRawFont.fontTable("glyf").size(), rawFontTableSize); + } +} + +void tst_QRawFont::detach_data() +{ + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting preference") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting preference") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting preference") << QFont::PreferFullHinting; +} + +void tst_QRawFont::detach() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + { + QString rawFontFamilyName; + qreal rawFontPixelSize; + qreal rawFontAscent; + qreal rawFontDescent; + int rawFontTableSize; + + QRawFont outerRawFont; + { + QRawFont rawFont(QString::fromLatin1(SRCDIR "testfont.ttf"), 11, hintingPreference); + QVERIFY(rawFont.isValid()); + + rawFontFamilyName = rawFont.familyName(); + rawFontPixelSize = rawFont.pixelSize(); + rawFontAscent = rawFont.ascent(); + rawFontDescent = rawFont.descent(); + rawFontTableSize = rawFont.fontTable("glyf").size(); + QVERIFY(rawFontTableSize > 0); + + { + QRawFont otherRawFont(rawFont); + + otherRawFont.loadFromFile(QLatin1String(SRCDIR "testfont.ttf"), + rawFontPixelSize, hintingPreference); + + QVERIFY(otherRawFont.isValid()); + QCOMPARE(otherRawFont.pixelSize(), rawFontPixelSize); + QCOMPARE(otherRawFont.familyName(), rawFontFamilyName); + QCOMPARE(otherRawFont.hintingPreference(), hintingPreference); + QCOMPARE(otherRawFont.ascent(), rawFontAscent); + QCOMPARE(otherRawFont.descent(), rawFontDescent); + QCOMPARE(otherRawFont.fontTable("glyf").size(), rawFontTableSize); + } + + { + QRawFont otherRawFont = rawFont; + + otherRawFont.loadFromFile(QLatin1String(SRCDIR "testfont.ttf"), + rawFontPixelSize, hintingPreference); + + QVERIFY(otherRawFont.isValid()); + QCOMPARE(otherRawFont.pixelSize(), rawFontPixelSize); + QCOMPARE(otherRawFont.familyName(), rawFontFamilyName); + QCOMPARE(otherRawFont.hintingPreference(), hintingPreference); + QCOMPARE(otherRawFont.ascent(), rawFontAscent); + QCOMPARE(otherRawFont.descent(), rawFontDescent); + QCOMPARE(otherRawFont.fontTable("glyf").size(), rawFontTableSize); + } + + outerRawFont = rawFont; + + rawFont.loadFromFile(QLatin1String(SRCDIR "testfont.ttf"), rawFontPixelSize, + hintingPreference); + } + + QVERIFY(outerRawFont.isValid()); + QCOMPARE(outerRawFont.pixelSize(), rawFontPixelSize); + QCOMPARE(outerRawFont.familyName(), rawFontFamilyName); + QCOMPARE(outerRawFont.hintingPreference(), hintingPreference); + QCOMPARE(outerRawFont.ascent(), rawFontAscent); + QCOMPARE(outerRawFont.descent(), rawFontDescent); + QCOMPARE(outerRawFont.fontTable("glyf").size(), rawFontTableSize); + } +} + +void tst_QRawFont::unsupportedWritingSystem_data() +{ + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting preference") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting preference") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting preference") << QFont::PreferFullHinting; +} + +void tst_QRawFont::unsupportedWritingSystem() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + QFontDatabase fontDatabase; + int id = fontDatabase.addApplicationFont(QLatin1String(SRCDIR "testfont.ttf")); + + QFont font("QtBidiTestFont"); + font.setHintingPreference(hintingPreference); + font.setPixelSize(12.0); + + QRawFont rawFont = QRawFont::fromFont(font, QFontDatabase::Any); + QCOMPARE(rawFont.familyName(), QString::fromLatin1("QtBidiTestFont")); + QCOMPARE(rawFont.pixelSize(), 12.0); + + rawFont = QRawFont::fromFont(font, QFontDatabase::Hebrew); + QCOMPARE(rawFont.familyName(), QString::fromLatin1("QtBidiTestFont")); + QCOMPARE(rawFont.pixelSize(), 12.0); + + QString arabicText = QFontDatabase::writingSystemSample(QFontDatabase::Arabic); + + QTextLayout layout; + layout.setFont(font); + layout.setText(arabicText); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 1); + + QGlyphRun glyphs = glyphRuns.at(0); + QRawFont layoutFont = glyphs.rawFont(); + QVERIFY(layoutFont.familyName() != QString::fromLatin1("QtBidiTestFont")); + QCOMPARE(layoutFont.pixelSize(), 12.0); + + rawFont = QRawFont::fromFont(font, QFontDatabase::Arabic); + QCOMPARE(rawFont.familyName(), layoutFont.familyName()); + QCOMPARE(rawFont.pixelSize(), 12.0); + + fontDatabase.removeApplicationFont(id); +} + +void tst_QRawFont::rawFontSetPixelSize_data() +{ + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting preference") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting preference") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting preference") << QFont::PreferFullHinting; +} + +void tst_QRawFont::rawFontSetPixelSize() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + QTextLayout layout("Foobar"); + + QFont font = layout.font(); + font.setHintingPreference(hintingPreference); + font.setPixelSize(12); + layout.setFont(font); + + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QGlyphRun glyphs = layout.glyphRuns().at(0); + QRawFont rawFont = glyphs.rawFont(); + QCOMPARE(rawFont.pixelSize(), 12.0); + + rawFont.setPixelSize(24); + QCOMPARE(rawFont.pixelSize(), 24.0); +} + +#endif // QT_NO_RAWFONT + +QTEST_MAIN(tst_QRawFont) +#include "tst_qrawfont.moc" + diff --git a/tests/auto/qreadlocker/qreadlocker.pro b/tests/auto/qreadlocker/qreadlocker.pro index 5919102..ee53307 100644 --- a/tests/auto/qreadlocker/qreadlocker.pro +++ b/tests/auto/qreadlocker/qreadlocker.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qreadlocker.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qreadwritelock/qreadwritelock.pro b/tests/auto/qreadwritelock/qreadwritelock.pro index 4318b18..93f7c68 100644 --- a/tests/auto/qreadwritelock/qreadwritelock.pro +++ b/tests/auto/qreadwritelock/qreadwritelock.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qreadwritelock.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qreadwritelock/tst_qreadwritelock.cpp b/tests/auto/qreadwritelock/tst_qreadwritelock.cpp index 99b6850..720f2b0 100644 --- a/tests/auto/qreadwritelock/tst_qreadwritelock.cpp +++ b/tests/auto/qreadwritelock/tst_qreadwritelock.cpp @@ -362,34 +362,45 @@ void tst_QReadWriteLock::tryWriteLock() class Thread : public QThread { public: + Thread() : failureCount(0) { } void run() { testsTurn.release(); threadsTurn.acquire(); - Q_ASSERT(!readWriteLock.tryLockForWrite()); + if (readWriteLock.tryLockForWrite()) + failureCount++; testsTurn.release(); threadsTurn.acquire(); - Q_ASSERT(readWriteLock.tryLockForWrite()); - Q_ASSERT(lockCount.testAndSetRelaxed(0, 1)); - Q_ASSERT(lockCount.testAndSetRelaxed(1, 0)); + if (!readWriteLock.tryLockForWrite()) + failureCount++; + if (!lockCount.testAndSetRelaxed(0, 1)) + failureCount++; + if (!lockCount.testAndSetRelaxed(1, 0)) + failureCount++; readWriteLock.unlock(); testsTurn.release(); threadsTurn.acquire(); - Q_ASSERT(!readWriteLock.tryLockForWrite(1000)); + if (readWriteLock.tryLockForWrite(1000)) + failureCount++; testsTurn.release(); threadsTurn.acquire(); - Q_ASSERT(readWriteLock.tryLockForWrite(1000)); - Q_ASSERT(lockCount.testAndSetRelaxed(0, 1)); - Q_ASSERT(lockCount.testAndSetRelaxed(1, 0)); + if (!readWriteLock.tryLockForWrite(1000)) + failureCount++; + if (!lockCount.testAndSetRelaxed(0, 1)) + failureCount++; + if (!lockCount.testAndSetRelaxed(1, 0)) + failureCount++; readWriteLock.unlock(); testsTurn.release(); threadsTurn.acquire(); } + + int failureCount; }; Thread thread; @@ -419,6 +430,8 @@ void tst_QReadWriteLock::tryWriteLock() testsTurn.acquire(); threadsTurn.release(); thread.wait(); + + QCOMPARE(thread.failureCount, 0); } } diff --git a/tests/auto/qrect/qrect.pro b/tests/auto/qrect/qrect.pro index 75940b3..f1ad046e 100644 --- a/tests/auto/qrect/qrect.pro +++ b/tests/auto/qrect/qrect.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qrect.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qregexp/qregexp.pro b/tests/auto/qregexp/qregexp.pro index 80b6827..e0fef12 100644 --- a/tests/auto/qregexp/qregexp.pro +++ b/tests/auto/qregexp/qregexp.pro @@ -6,3 +6,4 @@ QT = core QT = core SOURCES += tst_qregexp.cpp +CONFIG += parallel_test diff --git a/tests/auto/qregexp/tst_qregexp.cpp b/tests/auto/qregexp/tst_qregexp.cpp index d448671..65edb56 100644 --- a/tests/auto/qregexp/tst_qregexp.cpp +++ b/tests/auto/qregexp/tst_qregexp.cpp @@ -77,6 +77,7 @@ private slots: void caretAnchoredOptimization(); void isEmpty(); void prepareEngineOptimization(); + void swap(); void operator_eq(); /* @@ -1290,6 +1291,14 @@ void tst_QRegExp::prepareEngineOptimization() QCOMPARE(rx11.matchedLength(), -1); } +void tst_QRegExp::swap() +{ + QRegExp r1(QLatin1String(".*")), r2(QLatin1String("a*")); + r1.swap(r2); + QCOMPARE(r1.pattern(),QLatin1String("a*")); + QCOMPARE(r2.pattern(),QLatin1String(".*")); +} + void tst_QRegExp::operator_eq() { const int I = 2; diff --git a/tests/auto/qregion/tst_qregion.cpp b/tests/auto/qregion/tst_qregion.cpp index fca1ef9..bbc09c9 100644 --- a/tests/auto/qregion/tst_qregion.cpp +++ b/tests/auto/qregion/tst_qregion.cpp @@ -64,6 +64,7 @@ public: private slots: void boundingRect(); void rects(); + void swap(); void setRects(); void ellipseRegion(); void polygonRegion(); @@ -168,6 +169,15 @@ void tst_QRegion::rects() } } +void tst_QRegion::swap() +{ + QRegion r1(QRect( 0, 0,10,10)); + QRegion r2(QRect(10,10,10,10)); + r1.swap(r2); + QCOMPARE(r1.rects().front(), QRect(10,10,10,10)); + QCOMPARE(r2.rects().front(), QRect( 0, 0,10,10)); +} + void tst_QRegion::setRects() { { diff --git a/tests/auto/qresourceengine/qresourceengine.pro b/tests/auto/qresourceengine/qresourceengine.pro index 17e36af..9ca6994 100644 --- a/tests/auto/qresourceengine/qresourceengine.pro +++ b/tests/auto/qresourceengine/qresourceengine.pro @@ -21,25 +21,26 @@ PRE_TARGETDEPS += $${runtime_resource.target} QT = core wince*|symbian:{ - deploy.sources += runtime_resource.rcc parentdir.txt - test.sources = testqrc/* + deploy.files += runtime_resource.rcc parentdir.txt + test.files = testqrc/* test.path = testqrc - alias.sources = testqrc/aliasdir/* + alias.files = testqrc/aliasdir/* alias.path = testqrc/aliasdir - other.sources = testqrc/otherdir/* + other.files = testqrc/otherdir/* other.path = testqrc/otherdir - search1.sources = testqrc/searchpath1/* + search1.files = testqrc/searchpath1/* search1.path = testqrc/searchpath1 - search2.sources = testqrc/searchpath2/* + search2.files = testqrc/searchpath2/* search2.path = testqrc/searchpath2 - sub.sources = testqrc/subdir/* + sub.files = testqrc/subdir/* sub.path = testqrc/subdir - testsub.sources = testqrc/test/* + testsub.files = testqrc/test/* testsub.path = testqrc/test - testsub2.sources = testqrc/test/test/* + testsub2.files = testqrc/test/test/* testsub2.path = testqrc/test/test - DEPLOYMENT = deploy test alias other search1 search2 sub testsub testsub2 + DEPLOYMENT += deploy test alias other search1 search2 sub testsub testsub2 !symbian:DEFINES += SRCDIR=\\\"\\\" } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" } +CONFIG += parallel_test diff --git a/tests/auto/qringbuffer/qringbuffer.pro b/tests/auto/qringbuffer/qringbuffer.pro index 91fb0a0..2e4f166 100644 --- a/tests/auto/qringbuffer/qringbuffer.pro +++ b/tests/auto/qringbuffer/qringbuffer.pro @@ -4,3 +4,4 @@ SOURCES += tst_qringbuffer.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qscopedpointer/qscopedpointer.pro b/tests/auto/qscopedpointer/qscopedpointer.pro index 13d8425..4a3d5b8d 100644 --- a/tests/auto/qscopedpointer/qscopedpointer.pro +++ b/tests/auto/qscopedpointer/qscopedpointer.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qscopedpointer.cpp QT -= gui +CONFIG += parallel_test diff --git a/tests/auto/qscopedvaluerollback/qscopedvaluerollback.pro b/tests/auto/qscopedvaluerollback/qscopedvaluerollback.pro new file mode 100644 index 0000000..f06e21b --- /dev/null +++ b/tests/auto/qscopedvaluerollback/qscopedvaluerollback.pro @@ -0,0 +1,4 @@ +load(qttest_p4) +SOURCES += tst_qscopedvaluerollback.cpp +QT -= gui +CONFIG += parallel_test diff --git a/tests/auto/qscopedvaluerollback/tst_qscopedvaluerollback.cpp b/tests/auto/qscopedvaluerollback/tst_qscopedvaluerollback.cpp new file mode 100644 index 0000000..457733b --- /dev/null +++ b/tests/auto/qscopedvaluerollback/tst_qscopedvaluerollback.cpp @@ -0,0 +1,203 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtCore/QScopedValueRollback> + +/*! + \class tst_QScopedValueRollback + \internal + \since 4.8 + \brief Tests class QScopedValueRollback. + + */ +class tst_QScopedValueRollback : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void leavingScope(); + void leavingScopeAfterCommit(); + void rollbackToPreviousCommit(); + void exceptions(); + void earlyExitScope(); +private: + void earlyExitScope_helper(int exitpoint, int &member); +}; + +void tst_QScopedValueRollback::leavingScope() +{ + int i = 0; + bool b = false; + QString s("This is useful"); + + //test rollback on going out of scope + { + QScopedValueRollback<int> ri(i); + QScopedValueRollback<bool> rb(b); + QScopedValueRollback<QString> rs(s); + QCOMPARE(b, false); + QCOMPARE(i, 0); + QCOMPARE(s, QString("This is useful")); + b = true; + i = 1; + s = "Useless"; + QCOMPARE(b, true); + QCOMPARE(i, 1); + QCOMPARE(s, QString("Useless")); + } + QCOMPARE(b, false); + QCOMPARE(i, 0); + QCOMPARE(s, QString("This is useful")); +} + +void tst_QScopedValueRollback::leavingScopeAfterCommit() +{ + int i = 0; + bool b = false; + QString s("This is useful"); + + //test rollback on going out of scope + { + QScopedValueRollback<int> ri(i); + QScopedValueRollback<bool> rb(b); + QScopedValueRollback<QString> rs(s); + QCOMPARE(b, false); + QCOMPARE(i, 0); + QCOMPARE(s, QString("This is useful")); + b = true; + i = 1; + s = "Useless"; + QCOMPARE(b, true); + QCOMPARE(i, 1); + QCOMPARE(s, QString("Useless")); + ri.commit(); + rb.commit(); + rs.commit(); + } + QCOMPARE(b, true); + QCOMPARE(i, 1); + QCOMPARE(s, QString("Useless")); +} + +void tst_QScopedValueRollback::rollbackToPreviousCommit() +{ + int i=0; + { + QScopedValueRollback<int> ri(i); + i++; + ri.commit(); + i++; + } + QCOMPARE(i,1); + { + QScopedValueRollback<int> ri1(i); + i++; + ri1.commit(); + i++; + ri1.commit(); + i++; + } + QCOMPARE(i,3); +} + +void tst_QScopedValueRollback::exceptions() +{ + bool b = false; + bool caught = false; + QT_TRY + { + QScopedValueRollback<bool> rb(b); + b = true; + QT_THROW(std::bad_alloc()); //if Qt compiled without exceptions this is noop + rb.commit(); //if Qt compiled without exceptions, true is committed + } + QT_CATCH(...) + { + caught = true; + } + QCOMPARE(b, !caught); //expect false if exception was thrown, true otherwise +} + +void tst_QScopedValueRollback::earlyExitScope() +{ + int i=0; + int j=0; + while (true) { + QScopedValueRollback<int> ri(i); + i++; + j=i; + if (i>8) break; + ri.commit(); + } + QCOMPARE(i,8); + QCOMPARE(j,9); + + for (i = 0; i < 5; i++) { + j=1; + earlyExitScope_helper(i,j); + QCOMPARE(j, 1<<i); + } +} + +void tst_QScopedValueRollback::earlyExitScope_helper(int exitpoint, int& member) +{ + QScopedValueRollback<int> r(member); + member *= 2; + if (exitpoint == 0) + return; + r.commit(); + member *= 2; + if (exitpoint == 1) + return; + r.commit(); + member *= 2; + if (exitpoint == 2) + return; + r.commit(); + member *= 2; + if (exitpoint == 3) + return; + r.commit(); +} + +QTEST_MAIN(tst_QScopedValueRollback) +#include "tst_qscopedvaluerollback.moc" diff --git a/tests/auto/qscriptable/tst_qscriptable.cpp b/tests/auto/qscriptable/tst_qscriptable.cpp index 9ab0572..54ffbe9 100644 --- a/tests/auto/qscriptable/tst_qscriptable.cpp +++ b/tests/auto/qscriptable/tst_qscriptable.cpp @@ -131,14 +131,14 @@ QScriptValue MyScriptable::getArguments() int MyScriptable::getArgumentCount() { - return context()->argumentCount(); + return argumentCount(); } void MyScriptable::foo() { m_lastEngine = engine(); - QVERIFY(engine() != 0); - context()->throwError("MyScriptable.foo"); + if (engine()) + context()->throwError("MyScriptable.foo"); } void MyScriptable::evalIsBar() @@ -164,15 +164,15 @@ void MyScriptable::setOtherEngine() void MyScriptable::setX(int x) { m_lastEngine = engine(); - Q_ASSERT(engine()); - thisObject().setProperty("x", QScriptValue(engine(), x)); + if (engine()) + thisObject().setProperty("x", QScriptValue(engine(), x)); } void MyScriptable::setX(const QString &x) { m_lastEngine = engine(); - Q_ASSERT(engine()); - thisObject().setProperty("x", QScriptValue(engine(), x)); + if (engine()) + thisObject().setProperty("x", QScriptValue(engine(), x)); } void MyScriptable::setX2(int) @@ -283,12 +283,15 @@ void tst_QScriptable::engine() void tst_QScriptable::thisObject() { + QVERIFY(!m_scriptable.thisObject().isValid()); + m_engine.evaluate("o = { }"); { QScriptValue ret = m_engine.evaluate("o.__proto__ = scriptable;" "o.setX(123);" "o.__proto__ = Object.prototype;" "o.x"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.strictlyEquals(QScriptValue(&m_engine, 123)), true); } { @@ -296,46 +299,55 @@ void tst_QScriptable::thisObject() "o.setX2(456);" "o.__proto__ = Object.prototype;" "o.x"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.strictlyEquals(QScriptValue(&m_engine, 456)), true); } m_engine.evaluate("o.__proto__ = scriptable"); { QScriptValue ret = m_engine.evaluate("o.isBar()"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.strictlyEquals(QScriptValue(&m_engine, false)), true); } { QScriptValue ret = m_engine.evaluate("o.toString = function() { return 'foo@bar'; }; o.isBar()"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.strictlyEquals(QScriptValue(&m_engine, true)), true); } // property getter { QScriptValue ret = m_engine.evaluate("scriptable.zab"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.isQObject(), true); QCOMPARE(ret.toQObject(), (QObject *)&m_scriptable); } { QScriptValue ret = m_engine.evaluate("scriptable[1]"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.isQObject(), true); QCOMPARE(ret.toQObject(), (QObject *)&m_scriptable); } { QScriptValue ret = m_engine.evaluate("o.zab"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.toQObject(), (QObject *)0); } // property setter { QScriptValue ret = m_engine.evaluate("scriptable.setZab(null)"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.isQObject(), true); QCOMPARE(ret.toQObject(), (QObject *)&m_scriptable); } { QVERIFY(!m_scriptable.oofThisObject().isValid()); m_engine.evaluate("o.oof = 123"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QVERIFY(m_scriptable.oofThisObject().strictlyEquals(m_engine.evaluate("o"))); } { m_engine.evaluate("scriptable.oof = 123"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QVERIFY(m_scriptable.oofThisObject().strictlyEquals(m_engine.evaluate("scriptable"))); } @@ -343,13 +355,17 @@ void tst_QScriptable::thisObject() { { QScriptValue ret = m_engine.evaluate("scriptable.sig.connect(o, scriptable.setX)"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QVERIFY(ret.isUndefined()); } QVERIFY(m_engine.evaluate("o.x").strictlyEquals(QScriptValue(&m_engine, 456))); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); m_scriptable.emitSig(654321); QVERIFY(m_engine.evaluate("o.x").strictlyEquals(QScriptValue(&m_engine, 654321))); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); { QScriptValue ret = m_engine.evaluate("scriptable.sig.disconnect(o, scriptable.setX)"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QVERIFY(ret.isUndefined()); } } @@ -381,6 +397,7 @@ void tst_QScriptable::arguments() void tst_QScriptable::throwError() { QScriptValue ret = m_engine.evaluate("scriptable.foo()"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.isError(), true); QCOMPARE(ret.toString(), QString("Error: MyScriptable.foo")); } diff --git a/tests/auto/qscriptclass/tst_qscriptclass.cpp b/tests/auto/qscriptclass/tst_qscriptclass.cpp index 044ff6b..446c9fd 100644 --- a/tests/auto/qscriptclass/tst_qscriptclass.cpp +++ b/tests/auto/qscriptclass/tst_qscriptclass.cpp @@ -65,10 +65,27 @@ public: private slots: void newInstance(); - void getAndSetProperty(); + void setScriptClassOfExistingObject(); + void setScriptClassOfNonQtScriptObject(); + void getAndSetPropertyFromCpp(); + void getAndSetPropertyFromJS(); + void deleteUndeletableProperty(); + void writeReadOnlyProperty(); + void writePropertyWithoutWriteAccess(); void getProperty_invalidValue(); void enumerate(); - void extension(); + void extension_None(); + void extension_Callable(); + void extension_Callable_construct(); + void extension_HasInstance(); + void originalProperties1(); + void originalProperties2(); + void originalProperties3(); + void originalProperties4(); + void defaultImplementations(); + void scriptClassObjectInPrototype(); + void scriptClassWithNullEngine(); + void scriptClassInOtherEngine(); }; tst_QScriptClass::tst_QScriptClass() @@ -301,7 +318,12 @@ void TestClass::setProperty(QScriptValue &object, const QScriptString &name, CustomProperty *prop = findCustomProperty(name); if (!prop) return; - prop->value = value; + if (prop->pflags & QScriptValue::ReadOnly) + return; + if (!value.isValid()) // deleteProperty() requested + removeCustomProperty(name); + else + prop->value = value; } QScriptValue::PropertyFlags TestClass::propertyFlags( @@ -347,8 +369,7 @@ QVariant TestClass::extension(Extension extension, { m_lastExtensionType = extension; m_lastExtensionArgument = argument; - if (extension == Callable) { - Q_ASSERT(m_callableMode != NotCallable); + if (extension == Callable && m_callableMode != NotCallable) { QScriptContext *ctx = qvariant_cast<QScriptContext*>(argument); if (m_callableMode == CallableReturnsSum) { qsreal sum = 0; @@ -376,8 +397,7 @@ QVariant TestClass::extension(Extension extension, engine()->newQObject(ctx->thisObject(), engine()); return QVariant(); } - } else if (extension == HasInstance) { - Q_ASSERT(m_hasInstance); + } else if (extension == HasInstance && m_hasInstance) { QScriptValueList args = qvariant_cast<QScriptValueList>(argument); QScriptValue obj = args.at(0); QScriptValue value = args.at(1); @@ -595,7 +615,7 @@ void tst_QScriptClass::newInstance() QScriptValue obj1 = eng.newObject(&cls); QVERIFY(!obj1.data().isValid()); QVERIFY(obj1.prototype().strictlyEquals(cls.prototype())); - QEXPECT_FAIL("", "classname is not implemented", Continue); + QEXPECT_FAIL("", "QTBUG-17599: classname is not implemented", Continue); QCOMPARE(obj1.toString(), QString::fromLatin1("[object TestClass]")); QCOMPARE(obj1.scriptClass(), (QScriptClass*)&cls); @@ -604,7 +624,14 @@ void tst_QScriptClass::newInstance() QVERIFY(obj2.data().strictlyEquals(num)); QVERIFY(obj2.prototype().strictlyEquals(cls.prototype())); QCOMPARE(obj2.scriptClass(), (QScriptClass*)&cls); + QVERIFY(!obj2.equals(obj1)); + QVERIFY(!obj2.strictlyEquals(obj1)); +} +void tst_QScriptClass::setScriptClassOfExistingObject() +{ + QScriptEngine eng; + TestClass cls(&eng); QScriptValue obj3 = eng.newObject(); QCOMPARE(obj3.scriptClass(), (QScriptClass*)0); obj3.setScriptClass(&cls); @@ -618,7 +645,12 @@ void tst_QScriptClass::newInstance() TestClass cls2(&eng); obj3.setScriptClass(&cls2); QCOMPARE(obj3.scriptClass(), (QScriptClass*)&cls2); +} +void tst_QScriptClass::setScriptClassOfNonQtScriptObject() +{ + QScriptEngine eng; + TestClass cls(&eng); // undefined behavior really, but shouldn't crash QScriptValue arr = eng.newArray(); QVERIFY(arr.isArray()); @@ -632,7 +664,7 @@ void tst_QScriptClass::newInstance() QVERIFY(arr.isObject()); } -void tst_QScriptClass::getAndSetProperty() +void tst_QScriptClass::getAndSetPropertyFromCpp() { QScriptEngine eng; @@ -644,7 +676,9 @@ void tst_QScriptClass::getAndSetProperty() QScriptString bar = eng.toStringHandle("bar"); QScriptValue num(&eng, 123); - // should behave just like normal + // Initially our TestClass instances have no custom properties, + // and queryProperty() will always return false. + // Hence, the properties will be created as normal JS properties. for (int x = 0; x < 2; ++x) { QScriptValue &o = (x == 0) ? obj1 : obj2; for (int y = 0; y < 2; ++y) { @@ -705,7 +739,7 @@ void tst_QScriptClass::getAndSetProperty() QCOMPARE(obj1.propertyFlags(foo2), foo2Pflags); QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastQueryPropertyName() == foo2); - QEXPECT_FAIL("", "classObject.getOwnPropertyDescriptor() reads the property value", Continue); + QEXPECT_FAIL("", "QTBUG-17601: classObject.getOwnPropertyDescriptor() reads the property value", Continue); QVERIFY(!cls.lastPropertyObject().isValid()); QVERIFY(cls.lastPropertyFlagsObject().strictlyEquals(obj1)); QVERIFY(cls.lastPropertyFlagsName() == foo2); @@ -731,6 +765,14 @@ void tst_QScriptClass::getAndSetProperty() QCOMPARE(cls.lastPropertyId(), foo2Id); } + // attempt to delete custom property + obj1.setProperty(foo2, QScriptValue()); + // delete real property + obj1.setProperty(foo, QScriptValue()); + QVERIFY(!obj1.property(foo).isValid()); + obj1.setProperty(foo, num); + QVERIFY(obj1.property(foo).equals(num)); + // remove script class; normal properties should remain obj1.setScriptClass(0); QCOMPARE(obj1.scriptClass(), (QScriptClass*)0); @@ -742,6 +784,80 @@ void tst_QScriptClass::getAndSetProperty() QVERIFY(!obj1.property(bar).isValid()); } +void tst_QScriptClass::getAndSetPropertyFromJS() +{ + QScriptEngine eng; + TestClass cls(&eng); + cls.addCustomProperty(eng.toStringHandle("x"), + QScriptClass::HandlesReadAccess + | QScriptClass::HandlesWriteAccess, + /*id=*/1, /*flags=*/0, /*value=*/123); + eng.globalObject().setProperty("o", eng.newObject(&cls)); + + // Accessing a custom property + QCOMPARE(eng.evaluate("o.x").toInt32(), 123); + QCOMPARE(eng.evaluate("o.x = 456; o.x").toInt32(), 456); + + // Accessing a new JS property + QVERIFY(eng.evaluate("o.y").isUndefined()); + QCOMPARE(eng.evaluate("o.y = 789; o.y").toInt32(), 789); + + // Deleting custom property + QVERIFY(eng.evaluate("delete o.x").toBool()); + QVERIFY(eng.evaluate("o.x").isUndefined()); + + // Deleting JS property + QVERIFY(eng.evaluate("delete o.y").toBool()); + QVERIFY(eng.evaluate("o.y").isUndefined()); +} + +void tst_QScriptClass::deleteUndeletableProperty() +{ + QScriptEngine eng; + TestClass cls(&eng); + cls.addCustomProperty(eng.toStringHandle("x"), QScriptClass::HandlesWriteAccess, + /*id=*/0, QScriptValue::Undeletable, QScriptValue()); + eng.globalObject().setProperty("o", eng.newObject(&cls)); + QVERIFY(!eng.evaluate("delete o.x").toBool()); +} + +void tst_QScriptClass::writeReadOnlyProperty() +{ + QScriptEngine eng; + TestClass cls(&eng); + cls.addCustomProperty(eng.toStringHandle("x"), + QScriptClass::HandlesReadAccess + | QScriptClass::HandlesWriteAccess, + /*id=*/0, QScriptValue::ReadOnly, 123); + eng.globalObject().setProperty("o", eng.newObject(&cls)); + // Note that if a property is read-only, the setProperty() + // reimplementation will still get called; it's up to that + // function to respect the ReadOnly flag. + QCOMPARE(eng.evaluate("o.x = 456; o.x").toInt32(), 123); +} + +void tst_QScriptClass::writePropertyWithoutWriteAccess() +{ + QScriptEngine eng; + TestClass cls(&eng); + cls.addCustomProperty(eng.toStringHandle("x"), + QScriptClass::HandlesReadAccess, + /*id=*/0, /*flags=*/0, 123); + eng.globalObject().setProperty("o", eng.newObject(&cls)); + QCOMPARE(eng.evaluate("o.x").toInt32(), 123); + + // This will create a JS property on the instance that + // shadows the custom property. + // This behavior is not documented. It might be more + // intuitive to treat a property that only handles read + // access as a read-only, non-shadowable property. + QCOMPARE(eng.evaluate("o.x = 456; o.x").toInt32(), 456); + + QVERIFY(eng.evaluate("delete o.x").toBool()); + // Now the custom property is seen again. + QCOMPARE(eng.evaluate("o.x").toInt32(), 123); +} + void tst_QScriptClass::getProperty_invalidValue() { QScriptEngine eng; @@ -791,10 +907,12 @@ void tst_QScriptClass::enumerate() cls.setIterationEnabled(true); QScriptValueIterator it(obj); + // This test relies on the order in which properties are enumerated, + // which we don't guarantee. However, for compatibility's sake we prefer + // that normal JS properties come before QScriptClass properties. for (int x = 0; x < 2; ++x) { QVERIFY(it.hasNext()); it.next(); - QEXPECT_FAIL("", "", Abort); QVERIFY(it.scriptName() == foo); QVERIFY(it.hasNext()); it.next(); @@ -813,230 +931,571 @@ void tst_QScriptClass::enumerate() } } -void tst_QScriptClass::extension() +void tst_QScriptClass::extension_None() +{ + QScriptEngine eng; + TestClass cls(&eng); + cls.setCallableMode(TestClass::NotCallable); + QVERIFY(!cls.supportsExtension(QScriptClass::Callable)); + QVERIFY(!cls.supportsExtension(QScriptClass::HasInstance)); + QScriptValue obj = eng.newObject(&cls); + QVERIFY(!obj.call().isValid()); + QCOMPARE((int)cls.lastExtensionType(), -1); + QVERIFY(!obj.instanceOf(obj)); + QCOMPARE((int)cls.lastExtensionType(), -1); + QVERIFY(!obj.construct().isValid()); +} + +void tst_QScriptClass::extension_Callable() { QScriptEngine eng; + TestClass cls(&eng); + cls.setCallableMode(TestClass::CallableReturnsSum); + QVERIFY(cls.supportsExtension(QScriptClass::Callable)); + + QScriptValue obj = eng.newObject(&cls); + eng.globalObject().setProperty("obj", obj); + obj.setProperty("one", QScriptValue(&eng, 1)); + obj.setProperty("two", QScriptValue(&eng, 2)); + obj.setProperty("three", QScriptValue(&eng, 3)); + // From C++ + cls.clearReceivedArgs(); { - TestClass cls(&eng); - cls.setCallableMode(TestClass::NotCallable); - QVERIFY(!cls.supportsExtension(QScriptClass::Callable)); - QVERIFY(!cls.supportsExtension(QScriptClass::HasInstance)); - QScriptValue obj = eng.newObject(&cls); - QVERIFY(!obj.call().isValid()); - QCOMPARE((int)cls.lastExtensionType(), -1); - QVERIFY(!obj.instanceOf(obj)); - QCOMPARE((int)cls.lastExtensionType(), -1); + QScriptValueList args; + args << QScriptValue(&eng, 4) << QScriptValue(&eng, 5); + QScriptValue ret = obj.call(obj, args); + QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toNumber(), qsreal(1+2+3+4+5)); } - // Callable + // From JS + cls.clearReceivedArgs(); { - TestClass cls(&eng); - cls.setCallableMode(TestClass::CallableReturnsSum); - QVERIFY(cls.supportsExtension(QScriptClass::Callable)); - - QScriptValue obj = eng.newObject(&cls); - eng.globalObject().setProperty("obj", obj); - obj.setProperty("one", QScriptValue(&eng, 1)); - obj.setProperty("two", QScriptValue(&eng, 2)); - obj.setProperty("three", QScriptValue(&eng, 3)); - // From C++ - cls.clearReceivedArgs(); - { - QScriptValueList args; - args << QScriptValue(&eng, 4) << QScriptValue(&eng, 5); - QScriptValue ret = obj.call(obj, args); - QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); - QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); - QVERIFY(ret.isNumber()); - QCOMPARE(ret.toNumber(), qsreal(15)); - } - // From JS - cls.clearReceivedArgs(); - { - QScriptValue ret = eng.evaluate("obj(4, 5)"); - QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); - QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); - QVERIFY(ret.isNumber()); - QCOMPARE(ret.toNumber(), qsreal(15)); - } + QScriptValue ret = eng.evaluate("obj(4, 5)"); + QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toNumber(), qsreal(1+2+3+4+5)); + } - cls.setCallableMode(TestClass::CallableReturnsArgument); - // From C++ - cls.clearReceivedArgs(); - { - QScriptValue ret = obj.call(obj, QScriptValueList() << 123); - QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); - QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); - QVERIFY(ret.isNumber()); - QCOMPARE(ret.toInt32(), 123); - } - cls.clearReceivedArgs(); - { - QScriptValue ret = obj.call(obj, QScriptValueList() << true); - QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); - QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); - QVERIFY(ret.isBoolean()); - QCOMPARE(ret.toBoolean(), true); - } - { - QScriptValue ret = obj.call(obj, QScriptValueList() << QString::fromLatin1("ciao")); - QVERIFY(ret.isString()); - QCOMPARE(ret.toString(), QString::fromLatin1("ciao")); - } - { - QScriptValue objobj = eng.newObject(); - QScriptValue ret = obj.call(obj, QScriptValueList() << objobj); - QVERIFY(ret.isObject()); - QVERIFY(ret.strictlyEquals(objobj)); - } - { - QScriptValue ret = obj.call(obj, QScriptValueList() << QScriptValue()); - QVERIFY(ret.isUndefined()); - } - // From JS - cls.clearReceivedArgs(); - { - QScriptValue ret = eng.evaluate("obj(123)"); - QVERIFY(ret.isNumber()); - QCOMPARE(ret.toInt32(), 123); - } + cls.setCallableMode(TestClass::CallableReturnsArgument); + // From C++ + cls.clearReceivedArgs(); + { + QScriptValue ret = obj.call(obj, QScriptValueList() << 123); + QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + } + cls.clearReceivedArgs(); + { + QScriptValue ret = obj.call(obj, QScriptValueList() << true); + QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QVERIFY(ret.isBoolean()); + QCOMPARE(ret.toBoolean(), true); + } + { + QScriptValue ret = obj.call(obj, QScriptValueList() << QString::fromLatin1("ciao")); + QVERIFY(ret.isString()); + QCOMPARE(ret.toString(), QString::fromLatin1("ciao")); + } + { + QScriptValue objobj = eng.newObject(); + QScriptValue ret = obj.call(obj, QScriptValueList() << objobj); + QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(objobj)); + } + { + QScriptValue ret = obj.call(obj, QScriptValueList() << QScriptValue()); + QVERIFY(ret.isUndefined()); + } + // From JS + cls.clearReceivedArgs(); + { + QScriptValue ret = eng.evaluate("obj(123)"); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + } - cls.setCallableMode(TestClass::CallableReturnsInvalidVariant); - { - QScriptValue ret = obj.call(obj); - QVERIFY(ret.isUndefined()); - } + cls.setCallableMode(TestClass::CallableReturnsInvalidVariant); + { + QScriptValue ret = obj.call(obj); + QVERIFY(ret.isUndefined()); + } - cls.setCallableMode(TestClass::CallableReturnsThisObject); - // From C++ - { - QScriptValue ret = obj.call(obj); - QVERIFY(ret.isObject()); - QVERIFY(ret.strictlyEquals(obj)); - } - // From JS - { - QScriptValue ret = eng.evaluate("obj()"); - QVERIFY(ret.isObject()); - QVERIFY(ret.strictlyEquals(eng.globalObject())); - } + cls.setCallableMode(TestClass::CallableReturnsThisObject); + // From C++ + { + QScriptValue ret = obj.call(obj); + QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(obj)); + } + // From JS + { + QScriptValue ret = eng.evaluate("obj()"); + QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(eng.globalObject())); + } - cls.setCallableMode(TestClass::CallableReturnsCallee); - // From C++ - { - QScriptValue ret = obj.call(); - QVERIFY(ret.isObject()); - QVERIFY(ret.strictlyEquals(obj)); - } - // From JS - { - QScriptValue ret = eng.evaluate("obj()"); - QVERIFY(ret.isObject()); - QVERIFY(ret.strictlyEquals(obj)); - } + cls.setCallableMode(TestClass::CallableReturnsCallee); + // From C++ + { + QScriptValue ret = obj.call(); + QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(obj)); + } + // From JS + { + QScriptValue ret = eng.evaluate("obj()"); + QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(obj)); + } - cls.setCallableMode(TestClass::CallableReturnsArgumentsObject); - // From C++ - { - QScriptValue ret = obj.call(obj, QScriptValueList() << 123); - QVERIFY(ret.isObject()); - QVERIFY(ret.property("length").isNumber()); - QCOMPARE(ret.property("length").toInt32(), 1); - QVERIFY(ret.property(0).isNumber()); - QCOMPARE(ret.property(0).toInt32(), 123); - } - // From JS - { - QScriptValue ret = eng.evaluate("obj(123)"); - QVERIFY(ret.isObject()); - QVERIFY(ret.property("length").isNumber()); - QCOMPARE(ret.property("length").toInt32(), 1); - QVERIFY(ret.property(0).isNumber()); - QCOMPARE(ret.property(0).toInt32(), 123); - } + cls.setCallableMode(TestClass::CallableReturnsArgumentsObject); + // From C++ + { + QScriptValue ret = obj.call(obj, QScriptValueList() << 123); + QVERIFY(ret.isObject()); + QVERIFY(ret.property("length").isNumber()); + QCOMPARE(ret.property("length").toInt32(), 1); + QVERIFY(ret.property(0).isNumber()); + QCOMPARE(ret.property(0).toInt32(), 123); + } + // From JS + { + QScriptValue ret = eng.evaluate("obj(123)"); + QVERIFY(ret.isObject()); + QVERIFY(ret.property("length").isNumber()); + QCOMPARE(ret.property("length").toInt32(), 1); + QVERIFY(ret.property(0).isNumber()); + QCOMPARE(ret.property(0).toInt32(), 123); + } +} - // construct() - // From C++ - cls.clearReceivedArgs(); - cls.setCallableMode(TestClass::CallableReturnsGlobalObject); - { - QScriptValue ret = obj.construct(); - QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); - QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); - QVERIFY(ret.isObject()); - QVERIFY(ret.strictlyEquals(eng.globalObject())); - } - // From JS - cls.clearReceivedArgs(); - { - QScriptValue ret = eng.evaluate("new obj()"); - QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); - QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); - QVERIFY(ret.isObject()); - QVERIFY(ret.strictlyEquals(eng.globalObject())); - } - // From C++ - cls.clearReceivedArgs(); - cls.setCallableMode(TestClass::CallableInitializesThisObject); - { - QScriptValue ret = obj.construct(); - QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); - QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); - QVERIFY(ret.isQObject()); - QCOMPARE(ret.toQObject(), (QObject*)&eng); - } - // From JS - cls.clearReceivedArgs(); - { - QScriptValue ret = eng.evaluate("new obj()"); - QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); - QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); - QVERIFY(ret.isQObject()); - QCOMPARE(ret.toQObject(), (QObject*)&eng); - } +void tst_QScriptClass::extension_Callable_construct() +{ + QScriptEngine eng; + TestClass cls(&eng); + QScriptValue obj = eng.newObject(&cls); + eng.globalObject().setProperty("obj", obj); + + // From C++ + cls.clearReceivedArgs(); + cls.setCallableMode(TestClass::CallableReturnsGlobalObject); + { + QScriptValue ret = obj.construct(); + QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(eng.globalObject())); } - // HasInstance + // From JS + cls.clearReceivedArgs(); { - TestClass cls(&eng); - cls.setHasInstance(true); - QVERIFY(cls.supportsExtension(QScriptClass::HasInstance)); + QScriptValue ret = eng.evaluate("new obj()"); + QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QVERIFY(ret.isObject()); + QVERIFY(ret.strictlyEquals(eng.globalObject())); + } + // From C++ + cls.clearReceivedArgs(); + cls.setCallableMode(TestClass::CallableInitializesThisObject); + { + QScriptValue ret = obj.construct(); + QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QVERIFY(ret.isQObject()); + QCOMPARE(ret.toQObject(), (QObject*)&eng); + } + // From JS + cls.clearReceivedArgs(); + { + QScriptValue ret = eng.evaluate("new obj()"); + QCOMPARE(cls.lastExtensionType(), QScriptClass::Callable); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptContext*>()); + QVERIFY(ret.isQObject()); + QCOMPARE(ret.toQObject(), (QObject*)&eng); + } +} - QScriptValue obj = eng.newObject(&cls); - obj.setProperty("foo", QScriptValue(&eng, 123)); - QScriptValue plain = eng.newObject(); - QVERIFY(!plain.instanceOf(obj)); +void tst_QScriptClass::extension_HasInstance() +{ + QScriptEngine eng; + TestClass cls(&eng); + cls.setHasInstance(true); + QVERIFY(cls.supportsExtension(QScriptClass::HasInstance)); - eng.globalObject().setProperty("HasInstanceTester", obj); - eng.globalObject().setProperty("hasInstanceValue", plain); - cls.clearReceivedArgs(); - { - QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); - QCOMPARE(cls.lastExtensionType(), QScriptClass::HasInstance); - QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptValueList>()); - QScriptValueList lst = qvariant_cast<QScriptValueList>(cls.lastExtensionArgument()); - QCOMPARE(lst.size(), 2); - QVERIFY(lst.at(0).strictlyEquals(obj)); - QVERIFY(lst.at(1).strictlyEquals(plain)); - QVERIFY(ret.isBoolean()); - QVERIFY(!ret.toBoolean()); - } + QScriptValue obj = eng.newObject(&cls); + obj.setProperty("foo", QScriptValue(&eng, 123)); + QScriptValue plain = eng.newObject(); + QVERIFY(!plain.instanceOf(obj)); - plain.setProperty("foo", QScriptValue(&eng, 456)); - QVERIFY(!plain.instanceOf(obj)); - { - QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); - QVERIFY(ret.isBoolean()); - QVERIFY(!ret.toBoolean()); - } + eng.globalObject().setProperty("HasInstanceTester", obj); + eng.globalObject().setProperty("hasInstanceValue", plain); + cls.clearReceivedArgs(); + { + QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); + QCOMPARE(cls.lastExtensionType(), QScriptClass::HasInstance); + QCOMPARE(cls.lastExtensionArgument().userType(), qMetaTypeId<QScriptValueList>()); + QScriptValueList lst = qvariant_cast<QScriptValueList>(cls.lastExtensionArgument()); + QCOMPARE(lst.size(), 2); + QVERIFY(lst.at(0).strictlyEquals(obj)); + QVERIFY(lst.at(1).strictlyEquals(plain)); + QVERIFY(ret.isBoolean()); + QVERIFY(!ret.toBoolean()); + } - plain.setProperty("foo", obj.property("foo")); - QVERIFY(plain.instanceOf(obj)); - { - QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); - QVERIFY(ret.isBoolean()); - QVERIFY(ret.toBoolean()); - } + plain.setProperty("foo", QScriptValue(&eng, 456)); + QVERIFY(!plain.instanceOf(obj)); + { + QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); + QVERIFY(ret.isBoolean()); + QVERIFY(!ret.toBoolean()); + } + + plain.setProperty("foo", obj.property("foo")); + QVERIFY(plain.instanceOf(obj)); + { + QScriptValue ret = eng.evaluate("hasInstanceValue instanceof HasInstanceTester"); + QVERIFY(ret.isBoolean()); + QVERIFY(ret.toBoolean()); + } +} + +// tests made to match Qt 4.7 (JSC) behaviour +void tst_QScriptClass::originalProperties1() +{ + QScriptEngine eng; + + QScriptString orig1 = eng.toStringHandle("orig1"); + QScriptString orig2 = eng.toStringHandle("orig2"); + QScriptString orig3 = eng.toStringHandle("orig3"); + QScriptString new1 = eng.toStringHandle("new1"); + QScriptString new2 = eng.toStringHandle("new2"); + + { + TestClass cls1(&eng); + cls1.addCustomProperty(orig2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, 89); + cls1.addCustomProperty(new1, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, "hello"); + + TestClass cls2(&eng); + cls2.addCustomProperty(orig2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, 59); + cls2.addCustomProperty(new2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, "world"); + + QScriptValue obj1 = eng.newObject(); + obj1.setProperty(orig1 , 42); + obj1.setProperty(orig2 , "foo"); + obj1.prototype().setProperty(orig3, "bar"); + + QCOMPARE(obj1.property(orig1).toInt32(), 42); + QCOMPARE(obj1.property(orig2).toString(), QString::fromLatin1("foo")); + QCOMPARE(obj1.property(orig3).toString(), QString::fromLatin1("bar")); + QVERIFY(!obj1.property(new1).isValid()); + QVERIFY(!obj1.property(new2).isValid()); + + eng.globalObject().setProperty("obj" , obj1); + + obj1.setScriptClass(&cls1); + QCOMPARE(obj1.property(orig1).toInt32(), 42); + QCOMPARE(obj1.property(orig2).toString(), QString::fromLatin1("foo")); + QCOMPARE(obj1.property(orig3).toString(), QString::fromLatin1("bar")); + QCOMPARE(obj1.property(new1).toString(), QString::fromLatin1("hello")); + QVERIFY(!obj1.property(new2).isValid()); + + QScriptValue obj2 = eng.evaluate("obj"); + QCOMPARE(obj2.scriptClass(), &cls1); + QCOMPARE(obj2.property(orig1).toInt32(), 42); + QCOMPARE(obj2.property(orig2).toString(), QString::fromLatin1("foo")); + QCOMPARE(obj2.property(orig3).toString(), QString::fromLatin1("bar")); + QCOMPARE(obj2.property(new1).toString(), QString::fromLatin1("hello")); + QVERIFY(!obj2.property(new2).isValid()); + + obj1.setScriptClass(&cls2); + QCOMPARE(obj1.property(orig1).toInt32(), 42); + QCOMPARE(obj1.property(orig2).toString(), QString::fromLatin1("foo")); + QCOMPARE(obj1.property(orig3).toString(), QString::fromLatin1("bar")); + QVERIFY(!obj1.property(new1).isValid()); + QCOMPARE(obj1.property(new2).toString(), QString::fromLatin1("world")); + + QCOMPARE(obj2.scriptClass(), &cls2); + QCOMPARE(obj2.property(orig1).toInt32(), 42); + QCOMPARE(obj2.property(orig2).toString(), QString::fromLatin1("foo")); + QCOMPARE(obj2.property(orig3).toString(), QString::fromLatin1("bar")); + QVERIFY(!obj2.property(new1).isValid()); + QCOMPARE(obj2.property(new2).toString(), QString::fromLatin1("world")); + + obj1.setScriptClass(0); + QCOMPARE(obj1.property(orig1).toInt32(), 42); + QCOMPARE(obj1.property(orig2).toString(), QString::fromLatin1("foo")); + QCOMPARE(obj1.property(orig3).toString(), QString::fromLatin1("bar")); + QVERIFY(!obj1.property(new1).isValid()); + QVERIFY(!obj1.property(new2).isValid()); + } +} + +void tst_QScriptClass::originalProperties2() +{ + QScriptEngine eng; + + QScriptString orig1 = eng.toStringHandle("orig1"); + QScriptString orig2 = eng.toStringHandle("orig2"); + QScriptString orig3 = eng.toStringHandle("orig3"); + QScriptString new1 = eng.toStringHandle("new1"); + QScriptString new2 = eng.toStringHandle("new2"); + + { + TestClass cls1(&eng); + cls1.addCustomProperty(orig2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, 89); + cls1.addCustomProperty(new1, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, "hello"); + + TestClass cls2(&eng); + cls2.addCustomProperty(orig2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, 59); + cls2.addCustomProperty(new2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, "world"); + + QScriptValue obj1 = eng.newObject(); + obj1.setProperty(orig1 , 42); + obj1.setProperty(orig2 , "foo"); + obj1.prototype().setProperty(orig3, "bar"); + + QCOMPARE(obj1.property(orig1).toInt32(), 42); + QCOMPARE(obj1.property(orig2).toString(), QString::fromLatin1("foo")); + QCOMPARE(obj1.property(orig3).toString(), QString::fromLatin1("bar")); + QVERIFY(!obj1.property(new1).isValid()); + QVERIFY(!obj1.property(new2).isValid()); + + obj1.setScriptClass(&cls1); + obj1.setProperty(orig1 , QScriptValue(&eng, 852)); + obj1.setProperty(orig2 , "oli"); + obj1.setProperty(orig3 , "fu*c"); + obj1.setProperty(new1 , "moo"); + obj1.setProperty(new2 , "allo?"); + QCOMPARE(obj1.property(orig1).toInt32(), 852); + QCOMPARE(obj1.property(orig2).toString(), QString::fromLatin1("foo")); + QCOMPARE(obj1.property(orig3).toString(), QString::fromLatin1("fu*c")); + QCOMPARE(obj1.property(new1).toString(), QString::fromLatin1("moo")); + QCOMPARE(obj1.property(new2).toString(), QString::fromLatin1("allo?")); + + obj1.setScriptClass(&cls2); + QCOMPARE(obj1.property(orig1).toInt32(), 852); + QCOMPARE(obj1.property(orig2).toString(), QString::fromLatin1("foo")); + QCOMPARE(obj1.property(orig3).toString(), QString::fromLatin1("fu*c")); + QVERIFY(!obj1.property(new1).isValid()); + QCOMPARE(obj1.property(new2).toString(), QString::fromLatin1("allo?")); + + obj1.setScriptClass(0); + QCOMPARE(obj1.property(orig1).toInt32(), 852); + QCOMPARE(obj1.property(orig2).toString(), QString::fromLatin1("foo")); + QCOMPARE(obj1.property(orig3).toString(), QString::fromLatin1("fu*c")); + QVERIFY(!obj1.property(new1).isValid()); + QCOMPARE(obj1.property(new2).toString(), QString::fromLatin1("allo?")); + } +} + +void tst_QScriptClass::originalProperties3() +{ + QScriptEngine eng; + + QScriptString orig1 = eng.toStringHandle("orig1"); + QScriptString orig2 = eng.toStringHandle("orig2"); + QScriptString orig3 = eng.toStringHandle("orig3"); + QScriptString new1 = eng.toStringHandle("new1"); + QScriptString new2 = eng.toStringHandle("new2"); + + { + TestClass cls1(&eng); + cls1.addCustomProperty(orig2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, 89); + cls1.addCustomProperty(new1, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, "hello"); + + TestClass cls2(&eng); + cls2.addCustomProperty(orig2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, 59); + cls2.addCustomProperty(new2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, "world"); + + QScriptValue obj1 = eng.newObject(&cls1); + QVERIFY(!obj1.property(orig1).isValid()); + QCOMPARE(obj1.property(orig2).toInt32(), 89); + QCOMPARE(obj1.property(new1).toString(), QString::fromLatin1("hello")); + QVERIFY(!obj1.property(new2).isValid()); + obj1.setProperty(orig1, 42); + QCOMPARE(obj1.property(orig1).toInt32(), 42); + + eng.globalObject().setProperty("obj" , obj1); + obj1.setScriptClass(&cls2); + QCOMPARE(obj1.property(orig1).toInt32(), 42); + QCOMPARE(obj1.property(orig2).toInt32(), 59); + QVERIFY(!obj1.property(new1).isValid()); + QCOMPARE(obj1.property(new2).toString(), QString::fromLatin1("world")); + + QScriptValue obj2 = eng.evaluate("obj"); + QCOMPARE(obj2.scriptClass(), &cls2); + QCOMPARE(obj2.property(orig1).toInt32(), 42); + QCOMPARE(obj2.property(orig2).toInt32(), 59); + QVERIFY(!obj2.property(new1).isValid()); + QCOMPARE(obj2.property(new2).toString(), QString::fromLatin1("world")); + + obj1.setScriptClass(0); + QCOMPARE(obj1.property(orig1).toInt32(), 42); + QVERIFY(!obj1.property(orig2).isValid()); + QVERIFY(!obj1.property(new1).isValid()); + QVERIFY(!obj1.property(new2).isValid()); + + QCOMPARE(obj2.scriptClass(), (QScriptClass *)0); + QCOMPARE(obj2.property(orig1).toInt32(), 42); + QVERIFY(!obj2.property(orig2).isValid()); + QVERIFY(!obj2.property(new1).isValid()); + QVERIFY(!obj2.property(new2).isValid()); } } +void tst_QScriptClass::originalProperties4() +{ + QScriptEngine eng; + + QScriptString orig1 = eng.toStringHandle("orig1"); + QScriptString orig2 = eng.toStringHandle("orig2"); + QScriptString orig3 = eng.toStringHandle("orig3"); + QScriptString new1 = eng.toStringHandle("new1"); + QScriptString new2 = eng.toStringHandle("new2"); + + { + TestClass cls1(&eng); + cls1.addCustomProperty(orig2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, 89); + cls1.addCustomProperty(new1, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, "hello"); + + TestClass cls2(&eng); + cls2.addCustomProperty(orig2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, 59); + cls2.addCustomProperty(new2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, 1, 0, "world"); + + QScriptValue obj1 = eng.newObject(&cls1); + QVERIFY(!obj1.property(orig1).isValid()); + QCOMPARE(obj1.property(orig2).toInt32(), 89); + QCOMPARE(obj1.property(new1).toString(), QString::fromLatin1("hello")); + QVERIFY(!obj1.property(new2).isValid()); + + eng.globalObject().setProperty("obj" , obj1); + + obj1.setScriptClass(0); + QVERIFY(obj1.isObject()); + QVERIFY(!obj1.property(orig1).isValid()); + QVERIFY(!obj1.property(orig2).isValid()); + QVERIFY(!obj1.property(new1).isValid()); + QVERIFY(!obj1.property(new2).isValid()); + obj1.setProperty(orig1, 42); + QCOMPARE(obj1.property(orig1).toInt32(), 42); + + QScriptValue obj2 = eng.evaluate("obj"); + QCOMPARE(obj2.scriptClass(), (QScriptClass *)0); + QVERIFY(obj2.isObject()); + QCOMPARE(obj2.property(orig1).toInt32(), 42); + QVERIFY(!obj2.property(orig2).isValid()); + QVERIFY(!obj2.property(new1).isValid()); + QVERIFY(!obj2.property(new2).isValid()); + + obj1.setScriptClass(&cls2); + QCOMPARE(obj1.property(orig1).toInt32(), 42); + QCOMPARE(obj1.property(orig2).toInt32(), 59); + QVERIFY(!obj1.property(new1).isValid()); + QCOMPARE(obj1.property(new2).toString(), QString::fromLatin1("world")); + + QCOMPARE(obj2.scriptClass(), (QScriptClass *)(&cls2)); + QCOMPARE(obj2.property(orig1).toInt32(), 42); + QCOMPARE(obj2.property(orig2).toInt32(), 59); + QVERIFY(!obj2.property(new1).isValid()); + QCOMPARE(obj2.property(new2).toString(), QString::fromLatin1("world")); + } +} + +void tst_QScriptClass::defaultImplementations() +{ + QScriptEngine eng; + + QScriptClass defaultClass(&eng); + QCOMPARE(defaultClass.engine(), &eng); + QVERIFY(!defaultClass.prototype().isValid()); + QCOMPARE(defaultClass.name(), QString()); + + QScriptValue obj = eng.newObject(&defaultClass); + QCOMPARE(obj.scriptClass(), &defaultClass); + + QScriptString name = eng.toStringHandle("foo"); + uint id = -1; + QCOMPARE(defaultClass.queryProperty(obj, name, QScriptClass::HandlesReadAccess, &id), QScriptClass::QueryFlags(0)); + QVERIFY(!defaultClass.property(obj, name, id).isValid()); + QCOMPARE(defaultClass.propertyFlags(obj, name, id), QScriptValue::PropertyFlags(0)); + defaultClass.setProperty(obj, name, id, 123); + QVERIFY(!obj.property(name).isValid()); + + QCOMPARE(defaultClass.newIterator(obj), (QScriptClassPropertyIterator*)0); + + QVERIFY(!defaultClass.supportsExtension(QScriptClass::Callable)); + QVERIFY(!defaultClass.supportsExtension(QScriptClass::HasInstance)); + QVERIFY(!defaultClass.extension(QScriptClass::Callable).isValid()); + QVERIFY(!defaultClass.extension(QScriptClass::HasInstance).isValid()); +} + +void tst_QScriptClass::scriptClassObjectInPrototype() +{ + QScriptEngine eng; + TestClass cls(&eng); + QScriptValue plainObject = eng.newObject(); + QScriptValue classObject = eng.newObject(&cls); + plainObject.setPrototype(classObject); + QVERIFY(plainObject.prototype().equals(classObject)); + eng.globalObject().setProperty("plainObject", plainObject); + eng.globalObject().setProperty("classObject", classObject); + + QScriptString name = eng.toStringHandle("x"); + cls.addCustomProperty(name, QScriptClass::HandlesReadAccess, /*id=*/1, /*flags=*/0, /*value=*/123); + QVERIFY(plainObject.property(name).equals(classObject.property(name))); + QVERIFY(eng.evaluate("plainObject.x == classObject.x").toBool()); + + // Add a property that shadows the one in the script class. + plainObject.setProperty(name, 456); + QVERIFY(!plainObject.property(name).equals(classObject.property(name))); + QVERIFY(eng.evaluate("plainObject.x != classObject.x").toBool()); + + QVERIFY(eng.evaluate("delete plainObject.x").toBool()); + QVERIFY(eng.evaluate("plainObject.x == classObject.x").toBool()); +} + +void tst_QScriptClass::scriptClassWithNullEngine() +{ + QScriptClass cls(0); + QCOMPARE(cls.engine(), (QScriptEngine*)0); + QScriptEngine eng; + QScriptValue obj = eng.newObject(&cls); + QVERIFY(obj.isObject()); + QCOMPARE(obj.scriptClass(), &cls); + // The class could have been "bound" to the engine at this point, + // but it's currently not. + // This behavior is not documented and is subject to change. + QCOMPARE(cls.engine(), (QScriptEngine*)0); + // The engine pointer stored in the QScriptClass is not actually used + // during property access, so this still works. + obj.setProperty("x", 123); + QVERIFY(obj.property("x").isNumber()); +} + +void tst_QScriptClass::scriptClassInOtherEngine() +{ + QScriptEngine eng; + TestClass cls(&eng); + QScriptEngine eng2; + // We don't check that the class is associated with another engine, so + // we only get a warning when trying to set the prototype of the new + // instance. + // This behavior is not documented and is subject to change. + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cannot set a prototype created in a different engine"); + QScriptValue obj = eng2.newObject(&cls); + QVERIFY(obj.isObject()); + QCOMPARE(obj.scriptClass(), &cls); + + obj.setProperty("x", 123); + QVERIFY(obj.property("x").isNumber()); +} + QTEST_MAIN(tst_QScriptClass) #include "tst_qscriptclass.moc" diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp index 522af03..14c204e 100644 --- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp +++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp @@ -44,11 +44,13 @@ #include <QtScript/qscriptcontext.h> #include <QtScript/qscriptengine.h> +#include <QtScript/qscriptvalueiterator.h> //TESTED_CLASS= //TESTED_FILES= Q_DECLARE_METATYPE(QScriptValueList) +Q_DECLARE_METATYPE(QScriptContext::Error) QT_BEGIN_NAMESPACE extern bool qt_script_isJITEnabled(); @@ -64,27 +66,51 @@ public: private slots: void callee(); + void callee_implicitCall(); void arguments(); + void argumentsInJS(); void thisObject(); void returnValue(); - void throwError(); + void throwError_data(); + void throwError_fromEvaluate_data(); + void throwError_fromEvaluate(); + void throwError_fromCpp_data(); + void throwError_fromCpp(); void throwValue(); void evaluateInFunction(); void pushAndPopContext(); + void pushAndPopContext_variablesInActivation(); + void pushAndPopContext_setThisObject(); + void pushAndPopContext_throwException(); void lineNumber(); void backtrace_data(); void backtrace(); - void scopeChain(); - void pushAndPopScope(); - void getSetActivationObject(); + void scopeChain_globalContext(); + void scopeChain_closure(); + void scopeChain_withStatement(); + void pushAndPopScope_globalContext(); + void pushAndPopScope_globalContext2(); + void getSetActivationObject_globalContext(); + void pushScopeEvaluate(); + void pushScopeCall(); + void popScopeSimple(); + void pushAndPopGlobalObjectSimple(); + void pushAndPopIterative(); + void getSetActivationObject_customContext(); void inheritActivationAndThisObject(); void toString(); - void calledAsConstructor(); + void calledAsConstructor_fromCpp(); + void calledAsConstructor_fromJS(); + void calledAsConstructor_parentContext(); void argumentsObjectInNative(); void jsActivationObject(); void qobjectAsActivationObject(); void parentContextCallee_QT2270(); void popNativeContextScope(); + void throwErrorInGlobalContext(); + void throwErrorWithTypeInGlobalContext_data(); + void throwErrorWithTypeInGlobalContext(); + void throwValueInGlobalContext(); }; tst_QScriptContext::tst_QScriptContext() @@ -110,33 +136,33 @@ void tst_QScriptContext::callee() { QScriptEngine eng; - { - QScriptValue fun = eng.newFunction(get_callee); - fun.setProperty("foo", QScriptValue(&eng, "bar")); - eng.globalObject().setProperty("get_callee", fun); + QScriptValue fun = eng.newFunction(get_callee); + fun.setProperty("foo", QScriptValue(&eng, "bar")); + eng.globalObject().setProperty("get_callee", fun); - QScriptValue result = eng.evaluate("get_callee()"); - QCOMPARE(result.isFunction(), true); - QCOMPARE(result.property("foo").toString(), QString("bar")); - } + QScriptValue result = eng.evaluate("get_callee()"); + QCOMPARE(result.isFunction(), true); + QCOMPARE(result.property("foo").toString(), QString("bar")); +} +void tst_QScriptContext::callee_implicitCall() +{ + QScriptEngine eng; // callee when toPrimitive() is called internally - { - QScriptValue fun = eng.newFunction(store_callee_and_return_primitive); - QScriptValue obj = eng.newObject(); - obj.setProperty("toString", fun); - QVERIFY(!obj.property("callee").isValid()); - (void)obj.toString(); - QVERIFY(obj.property("callee").isFunction()); - QVERIFY(obj.property("callee").strictlyEquals(fun)); - - obj.setProperty("callee", QScriptValue()); - QVERIFY(!obj.property("callee").isValid()); - obj.setProperty("valueOf", fun); - (void)obj.toNumber(); - QVERIFY(obj.property("callee").isFunction()); - QVERIFY(obj.property("callee").strictlyEquals(fun)); - } + QScriptValue fun = eng.newFunction(store_callee_and_return_primitive); + QScriptValue obj = eng.newObject(); + obj.setProperty("toString", fun); + QVERIFY(!obj.property("callee").isValid()); + (void)obj.toString(); + QVERIFY(obj.property("callee").isFunction()); + QVERIFY(obj.property("callee").strictlyEquals(fun)); + + obj.setProperty("callee", QScriptValue()); + QVERIFY(!obj.property("callee").isValid()); + obj.setProperty("valueOf", fun); + (void)obj.toNumber(); + QVERIFY(obj.property("callee").isFunction()); + QVERIFY(obj.property("callee").strictlyEquals(fun)); } static QScriptValue get_arguments(QScriptContext *ctx, QScriptEngine *eng) @@ -156,6 +182,8 @@ void tst_QScriptContext::arguments() { QScriptEngine eng; + // See section 10.6 ("Arguments Object") of ECMA-262. + { QScriptValue args = eng.currentContext()->argumentsObject(); QVERIFY(args.isObject()); @@ -167,6 +195,8 @@ void tst_QScriptContext::arguments() } for (int x = 0; x < 2; ++x) { + // The expected arguments array should be the same regardless of + // whether get_arguments() is called as a constructor. QString prefix; if (x == 0) prefix = ""; @@ -213,11 +243,15 @@ void tst_QScriptContext::arguments() QCOMPARE(result.propertyFlags("length"), QScriptValue::SkipInEnumeration); QCOMPARE(result.property("callee").strictlyEquals(fun), true); QCOMPARE(result.propertyFlags("callee"), QScriptValue::SkipInEnumeration); + + // callee and length properties should be writable. QScriptValue replacedCallee(&eng, 123); result.setProperty("callee", replacedCallee); QVERIFY(result.property("callee").equals(replacedCallee)); QScriptValue replacedLength(&eng, 456); result.setProperty("length", replacedLength); + + // callee and length properties should be deletable. QVERIFY(result.property("length").equals(replacedLength)); result.setProperty("callee", QScriptValue()); QVERIFY(!result.property("callee").isValid()); @@ -251,28 +285,31 @@ void tst_QScriptContext::arguments() QCOMPARE(result.property("2").toBoolean(), true); QCOMPARE(result.property("3").isUndefined(), true); } + } +} - // arguments object returned from script - { - QScriptValue result = eng.evaluate("(function() { return arguments; })(123)"); - QCOMPARE(result.isArray(), false); - QVERIFY(result.isObject()); - QCOMPARE(result.property("length").toUInt32(), quint32(1)); - QCOMPARE(result.property("0").isNumber(), true); - QCOMPARE(result.property("0").toNumber(), 123.0); - } +void tst_QScriptContext::argumentsInJS() +{ + QScriptEngine eng; + { + QScriptValue result = eng.evaluate("(function() { return arguments; })(123)"); + QCOMPARE(result.isArray(), false); + QVERIFY(result.isObject()); + QCOMPARE(result.property("length").toUInt32(), quint32(1)); + QCOMPARE(result.property("0").isNumber(), true); + QCOMPARE(result.property("0").toNumber(), 123.0); + } - { - QScriptValue result = eng.evaluate("(function() { return arguments; })('ciao', null, true, undefined)"); - QCOMPARE(result.isArray(), false); - QCOMPARE(result.property("length").toUInt32(), quint32(4)); - QCOMPARE(result.property("0").isString(), true); - QCOMPARE(result.property("0").toString(), QString("ciao")); - QCOMPARE(result.property("1").isNull(), true); - QCOMPARE(result.property("2").isBoolean(), true); - QCOMPARE(result.property("2").toBoolean(), true); - QCOMPARE(result.property("3").isUndefined(), true); - } + { + QScriptValue result = eng.evaluate("(function() { return arguments; })('ciao', null, true, undefined)"); + QCOMPARE(result.isArray(), false); + QCOMPARE(result.property("length").toUInt32(), quint32(4)); + QCOMPARE(result.property("0").isString(), true); + QCOMPARE(result.property("0").toString(), QString("ciao")); + QCOMPARE(result.property("1").isNull(), true); + QCOMPARE(result.property("2").isBoolean(), true); + QCOMPARE(result.property("2").toBoolean(), true); + QCOMPARE(result.property("3").isUndefined(), true); } } @@ -360,73 +397,71 @@ static QScriptValue throw_ErrorAndReturnUndefined(QScriptContext *ctx, QScriptEn return eng->undefinedValue(); } -void tst_QScriptContext::throwError() +static QScriptValue throw_ErrorAndReturnString(QScriptContext *ctx, QScriptEngine *) { - QScriptEngine eng; + return ctx->throwError(QScriptContext::UnknownError, "foo").toString(); +} - { - QScriptValue fun = eng.newFunction(throw_Error); - eng.globalObject().setProperty("throw_Error", fun); - QScriptValue result = eng.evaluate("throw_Error()"); - QCOMPARE(eng.hasUncaughtException(), true); - QCOMPARE(result.isError(), true); - QCOMPARE(result.toString(), QString("Error: foo")); - } +static QScriptValue throw_ErrorAndReturnObject(QScriptContext *ctx, QScriptEngine *eng) +{ + ctx->throwError(QScriptContext::UnknownError, "foo"); + return eng->newObject(); +} - { - QScriptValue fun = eng.newFunction(throw_TypeError); - eng.globalObject().setProperty("throw_TypeError", fun); - QScriptValue result = eng.evaluate("throw_TypeError()"); - QCOMPARE(eng.hasUncaughtException(), true); - QCOMPARE(result.isError(), true); - QCOMPARE(result.toString(), QString("TypeError: foo")); - } +void tst_QScriptContext::throwError_data() +{ + QTest::addColumn<void*>("nativeFunctionPtr"); + QTest::addColumn<QString>("stringRepresentation"); + + QTest::newRow("Error") << reinterpret_cast<void*>(throw_Error) << QString("Error: foo"); + QTest::newRow("TypeError") << reinterpret_cast<void*>(throw_TypeError) << QString("TypeError: foo"); + QTest::newRow("ReferenceError") << reinterpret_cast<void*>(throw_ReferenceError) << QString("ReferenceError: foo"); + QTest::newRow("SyntaxError") << reinterpret_cast<void*>(throw_SyntaxError) << QString("SyntaxError: foo"); + QTest::newRow("RangeError") << reinterpret_cast<void*>(throw_RangeError) << QString("RangeError: foo"); + QTest::newRow("URIError") << reinterpret_cast<void*>(throw_URIError) << QString("URIError: foo"); + QTest::newRow("ErrorAndReturnUndefined") << reinterpret_cast<void*>(throw_ErrorAndReturnUndefined) << QString("Error: foo"); + QTest::newRow("ErrorAndReturnString") << reinterpret_cast<void*>(throw_ErrorAndReturnString) << QString("Error: foo"); + QTest::newRow("ErrorAndReturnObject") << reinterpret_cast<void*>(throw_ErrorAndReturnObject) << QString("Error: foo"); +} - { - QScriptValue fun = eng.newFunction(throw_ReferenceError); - eng.globalObject().setProperty("throw_ReferenceError", fun); - QScriptValue result = eng.evaluate("throw_ReferenceError()"); - QCOMPARE(eng.hasUncaughtException(), true); - QCOMPARE(result.isError(), true); - QCOMPARE(result.toString(), QString("ReferenceError: foo")); - } +void tst_QScriptContext::throwError_fromEvaluate_data() +{ + throwError_data(); +} - { - QScriptValue fun = eng.newFunction(throw_SyntaxError); - eng.globalObject().setProperty("throw_SyntaxError", fun); - QScriptValue result = eng.evaluate("throw_SyntaxError()"); - QCOMPARE(eng.hasUncaughtException(), true); - QCOMPARE(result.isError(), true); - QCOMPARE(result.toString(), QString("SyntaxError: foo")); - } +void tst_QScriptContext::throwError_fromEvaluate() +{ + QFETCH(void*, nativeFunctionPtr); + QScriptEngine::FunctionSignature nativeFunction = reinterpret_cast<QScriptEngine::FunctionSignature>(nativeFunctionPtr); + QFETCH(QString, stringRepresentation); + QScriptEngine engine; - { - QScriptValue fun = eng.newFunction(throw_RangeError); - eng.globalObject().setProperty("throw_RangeError", fun); - QScriptValue result = eng.evaluate("throw_RangeError()"); - QCOMPARE(eng.hasUncaughtException(), true); - QCOMPARE(result.isError(), true); - QCOMPARE(result.toString(), QString("RangeError: foo")); - } + QScriptValue fun = engine.newFunction(nativeFunction); + engine.globalObject().setProperty("throw_Error", fun); + QScriptValue result = engine.evaluate("throw_Error()"); + QCOMPARE(engine.hasUncaughtException(), true); + QCOMPARE(result.isError(), true); + QCOMPARE(result.toString(), stringRepresentation); +} - { - QScriptValue fun = eng.newFunction(throw_URIError); - eng.globalObject().setProperty("throw_URIError", fun); - QScriptValue result = eng.evaluate("throw_URIError()"); - QCOMPARE(eng.hasUncaughtException(), true); - QCOMPARE(result.isError(), true); - QCOMPARE(result.toString(), QString("URIError: foo")); - } +void tst_QScriptContext::throwError_fromCpp_data() +{ + throwError_data(); +} - { - QScriptValue fun = eng.newFunction(throw_ErrorAndReturnUndefined); - eng.globalObject().setProperty("throw_ErrorAndReturnUndefined", fun); - QScriptValue result = eng.evaluate("throw_ErrorAndReturnUndefined()"); - QVERIFY(eng.hasUncaughtException()); - QVERIFY(result.isError()); - QCOMPARE(result.toString(), QString("Error: foo")); - } +void tst_QScriptContext::throwError_fromCpp() +{ + QFETCH(void*, nativeFunctionPtr); + QScriptEngine::FunctionSignature nativeFunction = reinterpret_cast<QScriptEngine::FunctionSignature>(nativeFunctionPtr); + QFETCH(QString, stringRepresentation); + QScriptEngine engine; + QScriptValue fun = engine.newFunction(nativeFunction); + engine.globalObject().setProperty("throw_Error", fun); + QScriptValue result = fun.call(); + QCOMPARE(engine.hasUncaughtException(), true); + QCOMPARE(result.isError(), true); + QCOMPARE(result.toString(), stringRepresentation); } static QScriptValue throw_value(QScriptContext *ctx, QScriptEngine *) @@ -508,36 +543,65 @@ void tst_QScriptContext::pushAndPopContext() QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::popContext() doesn't match with pushContext()"); eng.popContext(); QCOMPARE(eng.currentContext(), topLevel); +} - { - QScriptContext *ctx3 = eng.pushContext(); - ctx3->activationObject().setProperty("foo", QScriptValue(&eng, 123)); - QVERIFY(eng.evaluate("foo").strictlyEquals(QScriptValue(&eng, 123))); - eng.evaluate("var bar = 'ciao'"); - QVERIFY(ctx3->activationObject().property("bar", QScriptValue::ResolveLocal).strictlyEquals(QScriptValue(&eng, "ciao"))); - eng.popContext(); +void tst_QScriptContext::pushAndPopContext_variablesInActivation() +{ + QScriptEngine eng; + QScriptContext *ctx = eng.pushContext(); + ctx->activationObject().setProperty("foo", QScriptValue(&eng, 123)); + // evaluate() should use the current context. + QVERIFY(eng.evaluate("foo").strictlyEquals(QScriptValue(&eng, 123))); + QCOMPARE(ctx->activationObject().propertyFlags("foo"), QScriptValue::PropertyFlags(0)); + + ctx->activationObject().setProperty(4, 456); + QVERIFY(ctx->activationObject().property(4, QScriptValue::ResolveLocal).equals(456)); + + // New JS variables should become properties of the current context's activation. + eng.evaluate("var bar = 'ciao'"); + QVERIFY(ctx->activationObject().property("bar", QScriptValue::ResolveLocal).strictlyEquals(QScriptValue(&eng, "ciao"))); + + ctx->activationObject().setProperty("baz", 789, QScriptValue::ReadOnly); + QVERIFY(eng.evaluate("baz").equals(789)); + QCOMPARE(ctx->activationObject().propertyFlags("baz"), QScriptValue::ReadOnly); + + QSet<QString> activationPropertyNames; + QScriptValueIterator it(ctx->activationObject()); + while (it.hasNext()) { + it.next(); + activationPropertyNames.insert(it.name()); } + QCOMPARE(activationPropertyNames.size(), 4); + QVERIFY(activationPropertyNames.contains("foo")); + QVERIFY(activationPropertyNames.contains("4")); + QVERIFY(activationPropertyNames.contains("bar")); + QVERIFY(activationPropertyNames.contains("baz")); - { - QScriptContext *ctx4 = eng.pushContext(); - QScriptValue obj = eng.newObject(); - obj.setProperty("prop", QScriptValue(&eng, 456)); - ctx4->setThisObject(obj); - QScriptValue ret = eng.evaluate("var tmp = this.prop; tmp + 1"); - QCOMPARE(eng.currentContext(), ctx4); - QVERIFY(ret.strictlyEquals(QScriptValue(&eng, 457))); - eng.popContext(); - } + eng.popContext(); +} - // throwing an exception - { - QScriptContext *ctx5 = eng.pushContext(); - QScriptValue ret = eng.evaluate("throw new Error('oops')"); - QVERIFY(ret.isError()); - QVERIFY(eng.hasUncaughtException()); - QCOMPARE(eng.currentContext(), ctx5); - eng.popContext(); - } +void tst_QScriptContext::pushAndPopContext_setThisObject() +{ + QScriptEngine eng; + QScriptContext *ctx = eng.pushContext(); + QScriptValue obj = eng.newObject(); + obj.setProperty("prop", QScriptValue(&eng, 456)); + ctx->setThisObject(obj); + QScriptValue ret = eng.evaluate("var tmp = this.prop; tmp + 1"); + QCOMPARE(eng.currentContext(), ctx); + QVERIFY(ret.strictlyEquals(QScriptValue(&eng, 457))); + eng.popContext(); +} + +void tst_QScriptContext::pushAndPopContext_throwException() +{ + QScriptEngine eng; + QScriptContext *ctx = eng.pushContext(); + QScriptValue ret = eng.evaluate("throw new Error('oops')"); + QVERIFY(ret.isError()); + QVERIFY(eng.hasUncaughtException()); + QCOMPARE(eng.currentContext(), ctx); + eng.popContext(); } void tst_QScriptContext::popNativeContextScope() @@ -565,7 +629,7 @@ void tst_QScriptContext::popNativeContextScope() QVERIFY(ctx->activationObject().strictlyEquals(customScope)); QCOMPARE(ctx->scopeChain().size(), 2); QVERIFY(ctx->scopeChain().at(0).strictlyEquals(customScope)); - QEXPECT_FAIL("", "QTBUG-11012", Continue); + QEXPECT_FAIL("", "QTBUG-11012: Global object is replaced in scope chain", Continue); QVERIFY(ctx->scopeChain().at(1).strictlyEquals(eng.globalObject())); QVERIFY(!eng.evaluate("baz = 456; var foo = 789; function barbar() {}").isError()); @@ -661,10 +725,7 @@ void tst_QScriptContext::backtrace_data() expected << "<native>('hey') at -1" << "<eval>() at 3" - << QString::fromLatin1("foo(arg1 = 'hello', arg2 = 456) at testfile:%0") - // interpreter unfortunately doesn't provide line number for eval() - .arg(qt_script_isJITEnabled() ? 2 : -1); - expected + << "foo(arg1 = 'hello', arg2 = 456) at testfile:2" << "<global>() at testfile:4"; QTest::newRow("eval") << source << expected; @@ -723,10 +784,7 @@ void tst_QScriptContext::backtrace_data() expected << "<native>('hey') at -1" << "<eval>() at 3" - << QString::fromLatin1("plop('hello', 456) at testfile:%0") - // interpreter unfortunately doesn't provide line number for eval() - .arg(qt_script_isJITEnabled() ? 3 : -1); - expected + << "plop('hello', 456) at testfile:3" << "<global>() at testfile:5"; QTest::newRow("eval in member") << source << expected; @@ -923,6 +981,8 @@ void tst_QScriptContext::backtrace() QVERIFY(!eng.hasUncaughtException()); QVERIFY(ret.isArray()); QStringList slist = qscriptvalue_cast<QStringList>(ret); + QEXPECT_FAIL("eval", "QTBUG-17842: Missing line number in backtrace when function calls eval()", Continue); + QEXPECT_FAIL("eval in member", "QTBUG-17842: Missing line number in backtrace when function calls eval()", Continue); QCOMPARE(slist, expectedbacktrace); } @@ -931,7 +991,7 @@ static QScriptValue getScopeChain(QScriptContext *ctx, QScriptEngine *eng) return qScriptValueFromValue(eng, ctx->parentContext()->scopeChain()); } -void tst_QScriptContext::scopeChain() +void tst_QScriptContext::scopeChain_globalContext() { QScriptEngine eng; { @@ -945,19 +1005,35 @@ void tst_QScriptContext::scopeChain() QCOMPARE(ret.size(), 1); QVERIFY(ret.at(0).strictlyEquals(eng.globalObject())); } - { - eng.evaluate("function foo() { function bar() { return getScopeChain(); } return bar() }"); - QScriptValueList ret = qscriptvalue_cast<QScriptValueList>(eng.evaluate("foo()")); - QEXPECT_FAIL("", "Number of items in returned scope chain is incorrect", Abort); - QCOMPARE(ret.size(), 3); - QVERIFY(ret.at(2).strictlyEquals(eng.globalObject())); - QCOMPARE(ret.at(1).toString(), QString::fromLatin1("activation")); - QVERIFY(ret.at(1).property("arguments").isObject()); - QCOMPARE(ret.at(0).toString(), QString::fromLatin1("activation")); - QVERIFY(ret.at(0).property("arguments").isObject()); - } +} + +void tst_QScriptContext::scopeChain_closure() +{ + QScriptEngine eng; + eng.globalObject().setProperty("getScopeChain", eng.newFunction(getScopeChain)); + + eng.evaluate("function foo() { function bar() { return getScopeChain(); } return bar() }"); + QScriptValueList ret = qscriptvalue_cast<QScriptValueList>(eng.evaluate("foo()")); + // JSC will not create an activation for bar() unless we insert a call + // to eval() in the function body; JSC has no way of knowing that the + // native function will be asking for the activation, and we don't want + // to needlessly create it. + QEXPECT_FAIL("", "QTBUG-10313: JSC optimizes away the activation object", Abort); + QCOMPARE(ret.size(), 3); + QVERIFY(ret.at(2).strictlyEquals(eng.globalObject())); + QCOMPARE(ret.at(1).toString(), QString::fromLatin1("activation")); + QVERIFY(ret.at(1).property("arguments").isObject()); + QCOMPARE(ret.at(0).toString(), QString::fromLatin1("activation")); + QVERIFY(ret.at(0).property("arguments").isObject()); +} + +void tst_QScriptContext::scopeChain_withStatement() +{ + QScriptEngine eng; + eng.globalObject().setProperty("getScopeChain", eng.newFunction(getScopeChain)); { QScriptValueList ret = qscriptvalue_cast<QScriptValueList>(eng.evaluate("o = { x: 123 }; with(o) getScopeChain();")); + QEXPECT_FAIL("", "QTBUG-17131: with-scope isn't reflected by QScriptContext", Abort); QCOMPARE(ret.size(), 2); QVERIFY(ret.at(1).strictlyEquals(eng.globalObject())); QVERIFY(ret.at(0).isObject()); @@ -975,7 +1051,73 @@ void tst_QScriptContext::scopeChain() } } -void tst_QScriptContext::pushAndPopScope() +void tst_QScriptContext::pushScopeEvaluate() +{ + QScriptEngine engine; + QScriptValue object = engine.newObject(); + object.setProperty("foo", 1234); + object.setProperty(1, 1234); + engine.currentContext()->pushScope(object); + object.setProperty("bar", 4321); + object.setProperty(2, 4321); + QVERIFY(engine.evaluate("foo").equals(1234)); + QVERIFY(engine.evaluate("bar").equals(4321)); +} + +void tst_QScriptContext::pushScopeCall() +{ + QScriptEngine engine; + QScriptValue object = engine.globalObject(); + QScriptValue thisObject = engine.newObject(); + QScriptValue function = engine.evaluate("(function(property){return this[property]; })"); + QVERIFY(function.isFunction()); + object.setProperty("foo", 1234); + thisObject.setProperty("foo", "foo"); + engine.currentContext()->pushScope(object); + object.setProperty("bar", 4321); + thisObject.setProperty("bar", "bar"); + QVERIFY(function.call(QScriptValue(), QScriptValueList() << "foo").equals(1234)); + QVERIFY(function.call(QScriptValue(), QScriptValueList() << "bar").equals(4321)); + QVERIFY(function.call(thisObject, QScriptValueList() << "foo").equals("foo")); + QVERIFY(function.call(thisObject, QScriptValueList() << "bar").equals("bar")); +} + +void tst_QScriptContext::popScopeSimple() +{ + QScriptEngine engine; + QScriptValue object = engine.newObject(); + QScriptValue globalObject = engine.globalObject(); + engine.currentContext()->pushScope(object); + QVERIFY(engine.currentContext()->popScope().strictlyEquals(object)); + QVERIFY(engine.globalObject().strictlyEquals(globalObject)); +} + +void tst_QScriptContext::pushAndPopGlobalObjectSimple() +{ + QScriptEngine engine; + QScriptValue globalObject = engine.globalObject(); + engine.currentContext()->pushScope(globalObject); + QVERIFY(engine.currentContext()->popScope().strictlyEquals(globalObject)); + QVERIFY(engine.globalObject().strictlyEquals(globalObject)); +} + +void tst_QScriptContext::pushAndPopIterative() +{ + QScriptEngine engine; + for (uint repeat = 0; repeat < 2; ++repeat) { + for (uint i = 1; i < 11; ++i) { + QScriptValue object = engine.newObject(); + object.setProperty("x", i + 10 * repeat); + engine.currentContext()->pushScope(object); + } + for (uint i = 10; i > 0; --i) { + QScriptValue object = engine.currentContext()->popScope(); + QVERIFY(object.property("x").equals(i + 10 * repeat)); + } + } +} + +void tst_QScriptContext::pushAndPopScope_globalContext() { QScriptEngine eng; QScriptContext *ctx = eng.currentContext(); @@ -1032,14 +1174,19 @@ void tst_QScriptContext::pushAndPopScope() ctx->pushScope(QScriptValue()); QCOMPARE(ctx->scopeChain().size(), 1); +} +void tst_QScriptContext::pushAndPopScope_globalContext2() +{ + QScriptEngine eng; + QScriptContext *ctx = eng.currentContext(); QVERIFY(ctx->popScope().strictlyEquals(eng.globalObject())); QVERIFY(ctx->scopeChain().isEmpty()); // Used to work with old back-end, doesn't with new one because JSC requires that the last object in // a scope chain is the Global Object. QTest::ignoreMessage(QtWarningMsg, "QScriptContext::pushScope() failed: initial object in scope chain has to be the Global Object"); - ctx->pushScope(obj); + ctx->pushScope(eng.newObject()); QCOMPARE(ctx->scopeChain().size(), 0); QScriptEngine eng2; @@ -1056,7 +1203,7 @@ static QScriptValue get_activationObject(QScriptContext *ctx, QScriptEngine *) return ctx->activationObject(); } -void tst_QScriptContext::getSetActivationObject() +void tst_QScriptContext::getSetActivationObject_globalContext() { QScriptEngine eng; QScriptContext *ctx = eng.currentContext(); @@ -1089,7 +1236,7 @@ void tst_QScriptContext::getSetActivationObject() QScriptValue ret = eng.evaluate("get_activationObject(1, 2, 3)"); QVERIFY(ret.isObject()); QScriptValue arguments = ret.property("arguments"); - QEXPECT_FAIL("", "Getting arguments property of activation object doesn't work", Abort); + QEXPECT_FAIL("", "QTBUG-17136: arguments property of activation object is missing", Abort); QVERIFY(arguments.isObject()); QCOMPARE(arguments.property("length").toInt32(), 3); QCOMPARE(arguments.property("0").toInt32(), 1); @@ -1098,6 +1245,22 @@ void tst_QScriptContext::getSetActivationObject() } } +void tst_QScriptContext::getSetActivationObject_customContext() +{ + QScriptEngine eng; + QScriptContext *ctx = eng.pushContext(); + QVERIFY(ctx->activationObject().isObject()); + QScriptValue act = eng.newObject(); + ctx->setActivationObject(act); + QVERIFY(ctx->activationObject().equals(act)); + eng.evaluate("var foo = 123"); + QCOMPARE(act.property("foo").toInt32(), 123); + eng.popContext(); + QCOMPARE(act.property("foo").toInt32(), 123); +} + +// Helper function that's intended to have the same behavior +// as the built-in eval() function. static QScriptValue myEval(QScriptContext *ctx, QScriptEngine *eng) { QString code = ctx->argument(0).toString(); @@ -1126,13 +1289,14 @@ void tst_QScriptContext::inheritActivationAndThisObject() QCOMPARE(ret.toInt32(), 123); } - // QT-2219 { eng.globalObject().setProperty("a", 123); QScriptValue ret = eng.evaluate("(function() { myEval('var a = 456'); return a; })()"); QVERIFY(ret.isNumber()); QCOMPARE(ret.toInt32(), 456); - QEXPECT_FAIL("", "QT-2219: Wrong activation object is returned from native function's parent context", Continue); + // Since JSC doesn't create an activation object for the anonymous function call, + // myEval() will use the global object as the activation, which is wrong. + QEXPECT_FAIL("", "QTBUG-10313: Wrong activation object is returned from native function's parent context", Continue); QVERIFY(eng.globalObject().property("a").strictlyEquals(123)); } } @@ -1171,11 +1335,11 @@ static QScriptValue storeCalledAsConstructorV3(QScriptContext *ctx, QScriptEngin return eng->undefinedValue(); } -void tst_QScriptContext::calledAsConstructor() +void tst_QScriptContext::calledAsConstructor_fromCpp() { QScriptEngine eng; - QScriptValue fun1 = eng.newFunction(storeCalledAsConstructor); { + QScriptValue fun1 = eng.newFunction(storeCalledAsConstructor); fun1.call(); QVERIFY(!fun1.property("calledAsConstructor").toBool()); fun1.construct(); @@ -1188,25 +1352,31 @@ void tst_QScriptContext::calledAsConstructor() fun.construct(); QVERIFY(fun.property("calledAsConstructor").toBool()); } - { - eng.globalObject().setProperty("fun1", fun1); - eng.evaluate("fun1();"); - QVERIFY(!fun1.property("calledAsConstructor").toBool()); - eng.evaluate("new fun1();"); - QVERIFY(fun1.property("calledAsConstructor").toBool()); - } - { - QScriptValue fun3 = eng.newFunction(storeCalledAsConstructorV3); - eng.globalObject().setProperty("fun3", fun3); - eng.evaluate("function test() { fun3() }"); - eng.evaluate("test();"); - QVERIFY(!fun3.property("calledAsConstructor").toBool()); - eng.evaluate("new test();"); - if (qt_script_isJITEnabled()) - QEXPECT_FAIL("", "QTBUG-6132: calledAsConstructor is not correctly set for JS functions when JIT is enabled", Continue); - QVERIFY(fun3.property("calledAsConstructor").toBool()); - } +} + +void tst_QScriptContext::calledAsConstructor_fromJS() +{ + QScriptEngine eng; + QScriptValue fun1 = eng.newFunction(storeCalledAsConstructor); + eng.globalObject().setProperty("fun1", fun1); + eng.evaluate("fun1();"); + QVERIFY(!fun1.property("calledAsConstructor").toBool()); + eng.evaluate("new fun1();"); + QVERIFY(fun1.property("calledAsConstructor").toBool()); +} +void tst_QScriptContext::calledAsConstructor_parentContext() +{ + QScriptEngine eng; + QScriptValue fun3 = eng.newFunction(storeCalledAsConstructorV3); + eng.globalObject().setProperty("fun3", fun3); + eng.evaluate("function test() { fun3() }"); + eng.evaluate("test();"); + QVERIFY(!fun3.property("calledAsConstructor").toBool()); + eng.evaluate("new test();"); + if (qt_script_isJITEnabled()) + QEXPECT_FAIL("", "QTBUG-6132: calledAsConstructor is not correctly set for JS functions when JIT is enabled", Continue); + QVERIFY(fun3.property("calledAsConstructor").toBool()); } static QScriptValue argumentsObjectInNative_test1(QScriptContext *ctx, QScriptEngine *eng) @@ -1268,7 +1438,7 @@ void tst_QScriptContext::jsActivationObject() QScriptValue result1 = eng.evaluate("f2('hello', 'useless', 'world')"); QScriptValue result2 = eng.evaluate("f3()"); QVERIFY(result1.isObject()); - QEXPECT_FAIL("", "JSC optimize away the activation object", Abort); + QEXPECT_FAIL("", "QTBUG-10313: JSC optimizes away the activation object", Abort); QCOMPARE(result1.property("v1").toInt32() , 42); QCOMPARE(result1.property("arguments").property(1).toString() , QString::fromLatin1("useless")); QVERIFY(result2.isObject()); @@ -1327,5 +1497,49 @@ void tst_QScriptContext::parentContextCallee_QT2270() QVERIFY(callee.equals(fun)); } +void tst_QScriptContext::throwErrorInGlobalContext() +{ + QScriptEngine eng; + QScriptValue ret = eng.currentContext()->throwError("foo"); + QVERIFY(ret.isError()); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(eng.uncaughtException().strictlyEquals(ret)); + QCOMPARE(ret.toString(), QString::fromLatin1("Error: foo")); +} + +void tst_QScriptContext::throwErrorWithTypeInGlobalContext_data() +{ + QTest::addColumn<QScriptContext::Error>("error"); + QTest::addColumn<QString>("stringRepresentation"); + QTest::newRow("ReferenceError") << QScriptContext::ReferenceError << QString::fromLatin1("ReferenceError: foo"); + QTest::newRow("SyntaxError") << QScriptContext::SyntaxError << QString::fromLatin1("SyntaxError: foo"); + QTest::newRow("TypeError") << QScriptContext::TypeError << QString::fromLatin1("TypeError: foo"); + QTest::newRow("RangeError") << QScriptContext::RangeError << QString::fromLatin1("RangeError: foo"); + QTest::newRow("URIError") << QScriptContext::URIError << QString::fromLatin1("URIError: foo"); + QTest::newRow("UnknownError") << QScriptContext::UnknownError << QString::fromLatin1("Error: foo"); +} + +void tst_QScriptContext::throwErrorWithTypeInGlobalContext() +{ + QFETCH(QScriptContext::Error, error); + QFETCH(QString, stringRepresentation); + QScriptEngine eng; + QScriptValue ret = eng.currentContext()->throwError(error, "foo"); + QVERIFY(ret.isError()); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(eng.uncaughtException().strictlyEquals(ret)); + QCOMPARE(ret.toString(), stringRepresentation); +} + +void tst_QScriptContext::throwValueInGlobalContext() +{ + QScriptEngine eng; + QScriptValue val(&eng, 123); + QScriptValue ret = eng.currentContext()->throwValue(val); + QVERIFY(ret.strictlyEquals(val)); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(eng.uncaughtException().strictlyEquals(val)); +} + QTEST_MAIN(tst_QScriptContext) #include "tst_qscriptcontext.moc" diff --git a/tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp b/tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp index 9e80fde..e0ce20b 100644 --- a/tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp +++ b/tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp @@ -93,6 +93,7 @@ private slots: void qtPropertyFunction(); void nullContext(); void streaming(); + void comparison_null(); void assignmentAndComparison(); }; @@ -150,7 +151,7 @@ void tst_QScriptContextInfo::nativeFunction() QVERIFY(info.scriptId() != -1); QCOMPARE(info.fileName(), fileName); QCOMPARE(info.lineNumber(), lineNumber); - QEXPECT_FAIL("", "columnNumber doesn't work", Continue); + QEXPECT_FAIL("", "QTBUG-17602: columnNumber doesn't work", Continue); QCOMPARE(info.columnNumber(), 1); QCOMPARE(info.functionName(), QString()); QCOMPARE(info.functionEndLineNumber(), -1); @@ -182,7 +183,7 @@ void tst_QScriptContextInfo::scriptFunction() QVERIFY(info.scriptId() != -1); QCOMPARE(info.fileName(), fileName); QCOMPARE(info.lineNumber(), lineNumber + 1); - QEXPECT_FAIL("", "columnNumber doesn't work", Continue); + QEXPECT_FAIL("", "QTBUG-17602: columnNumber doesn't work", Continue); QCOMPARE(info.columnNumber(), 2); QCOMPARE(info.functionName(), QString::fromLatin1("bar")); QCOMPARE(info.functionStartLineNumber(), lineNumber); @@ -201,7 +202,7 @@ void tst_QScriptContextInfo::scriptFunction() QVERIFY(info.scriptId() != -1); QCOMPARE(info.fileName(), fileName); QCOMPARE(info.lineNumber(), lineNumber + 3); - QEXPECT_FAIL("", "columnNumber doesn't work", Continue); + QEXPECT_FAIL("", "QTBUG-17602: columnNumber doesn't work", Continue); QCOMPARE(info.columnNumber(), 1); QCOMPARE(info.functionName(), QString()); QCOMPARE(info.functionEndLineNumber(), -1); @@ -366,6 +367,13 @@ void tst_QScriptContextInfo::streaming() } } +void tst_QScriptContextInfo::comparison_null() +{ + QScriptContextInfo info1, info2, info3(0); + QCOMPARE(info1, info2); + QCOMPARE(info1, info3); +} + void tst_QScriptContextInfo::assignmentAndComparison() { QScriptEngine eng; diff --git a/tests/auto/qscriptengine/idtranslatable-unicode.js b/tests/auto/qscriptengine/idtranslatable-unicode.js new file mode 100644 index 0000000..e17d617 --- /dev/null +++ b/tests/auto/qscriptengine/idtranslatable-unicode.js @@ -0,0 +1,5 @@ +qsTrId('\u01F8\u01D2\u0199\u01D0\u01E1'); + +QT_TRID_NOOP("\u0191\u01CE\u0211\u0229\u019C\u018E\u019A\u01D0"); + +qsTrId("\u0181\u01A1\u0213\u018F\u018C", 10); diff --git a/tests/auto/qscriptengine/qscriptengine.pro b/tests/auto/qscriptengine/qscriptengine.pro index fc35f66..c5c2861 100644 --- a/tests/auto/qscriptengine/qscriptengine.pro +++ b/tests/auto/qscriptengine/qscriptengine.pro @@ -10,7 +10,7 @@ wince* { } wince*|symbian: { - addFiles.sources = script + addFiles.files = script addFiles.path = . DEPLOYMENT += addFiles } diff --git a/tests/auto/qscriptengine/qscriptengine.qrc b/tests/auto/qscriptengine/qscriptengine.qrc index fa55a5b..d05d115 100644 --- a/tests/auto/qscriptengine/qscriptengine.qrc +++ b/tests/auto/qscriptengine/qscriptengine.qrc @@ -2,5 +2,7 @@ <qresource> <file>translations/translatable_la.qm</file> <file>translations/idtranslatable_la.qm</file> + <file>translations/translatable-unicode.qm</file> + <file>translations/idtranslatable-unicode.qm</file> </qresource> </RCC> diff --git a/tests/auto/qscriptengine/translatable-unicode.js b/tests/auto/qscriptengine/translatable-unicode.js new file mode 100644 index 0000000..afe2aff --- /dev/null +++ b/tests/auto/qscriptengine/translatable-unicode.js @@ -0,0 +1,9 @@ +qsTr("H\u2082O"); +qsTranslate("\u010C\u0101\u011F\u0115", "CO\u2082"); + +var unicode_strings = [ + QT_TR_NOOP("\u0391\u0392\u0393"), + QT_TRANSLATE_NOOP("\u010C\u0101\u011F\u0115", "\u0414\u0415\u0416") +]; + +qsTr("H\u2082O", "not the same H\u2082O"); diff --git a/tests/auto/qscriptengine/translatable.js b/tests/auto/qscriptengine/translatable.js index 30e139a..c0d7ed0 100644 --- a/tests/auto/qscriptengine/translatable.js +++ b/tests/auto/qscriptengine/translatable.js @@ -7,3 +7,6 @@ var greeting_strings = [ ]; qsTr("One", "not the same one"); + +qsTr("%n message(s) saved", "", 10); +qsTranslate("FooContext", "%n fooish bar(s) found", "", "UnicodeUTF8", 10); diff --git a/tests/auto/qscriptengine/translations/idtranslatable-unicode.qm b/tests/auto/qscriptengine/translations/idtranslatable-unicode.qm Binary files differnew file mode 100644 index 0000000..8c5fb91 --- /dev/null +++ b/tests/auto/qscriptengine/translations/idtranslatable-unicode.qm diff --git a/tests/auto/qscriptengine/translations/idtranslatable-unicode.ts b/tests/auto/qscriptengine/translations/idtranslatable-unicode.ts new file mode 100644 index 0000000..74ebf43 --- /dev/null +++ b/tests/auto/qscriptengine/translations/idtranslatable-unicode.ts @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="nb_NO"> +<defaultcodec>UTF-8</defaultcodec> +<context> + <name></name> + <message id="ǸǒƙÇÇ¡"> + <location filename="idtranslatable-unicode.js" line="1"/> + <source></source> + <translation>ƧưƈȼÈÈ¿È™</translation> + </message> + <message id="ƑǎȑȩƜƎƚÇ"> + <location filename="idtranslatable-unicode.js" line="3"/> + <source></source> + <translation>Ç È¡È‹È…È•</translation> + </message> + <message id="ÆÆ¡È“ÆÆŒ" numerus="yes"> + <location filename="idtranslatable-unicode.js" line="5"/> + <source></source> + <translation> + <numerusform>Ƒưǹ</numerusform> + <numerusform>%n Æ’Æ¡Ç’(È™)</numerusform> + </translation> + </message> +</context> +</TS> diff --git a/tests/auto/qscriptengine/translations/translatable-unicode.qm b/tests/auto/qscriptengine/translations/translatable-unicode.qm Binary files differnew file mode 100644 index 0000000..aa75ce6 --- /dev/null +++ b/tests/auto/qscriptengine/translations/translatable-unicode.qm diff --git a/tests/auto/qscriptengine/translations/translatable-unicode.ts b/tests/auto/qscriptengine/translations/translatable-unicode.ts new file mode 100644 index 0000000..1b8b4d2 --- /dev/null +++ b/tests/auto/qscriptengine/translations/translatable-unicode.ts @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0"> +<defaultcodec>UTF-8</defaultcodec> +<context> + <name>translatable-unicode</name> + <message> + <location filename="translatable-unicode.js" line="1"/> + <source>Hâ‚‚O</source> + <translation>ͻͼͽ</translation> + </message> + <message> + <location filename="translatable-unicode.js" line="5"/> + <source>ΑΒΓ</source> + <translation>ӜҴѼ</translation> + </message> + <message> + <location filename="translatable-unicode.js" line="9"/> + <source>Hâ‚‚O</source> + <comment>not the same Hâ‚‚O</comment> + <translation>Ô¶ÕŠÕ’</translation> + </message> +</context> +<context> + <name>ÄŒÄÄŸÄ•</name> + <message> + <location filename="translatable-unicode.js" line="2"/> + <source>COâ‚‚</source> + <translation>בךע</translation> + </message> + <message> + <location filename="translatable-unicode.js" line="6"/> + <source>ДЕЖ</source> + <translation>خسس</translation> + </message> +</context> +</TS> diff --git a/tests/auto/qscriptengine/translations/translatable_la.qm b/tests/auto/qscriptengine/translations/translatable_la.qm Binary files differindex 703d0f1..d76b1ca 100644 --- a/tests/auto/qscriptengine/translations/translatable_la.qm +++ b/tests/auto/qscriptengine/translations/translatable_la.qm diff --git a/tests/auto/qscriptengine/translations/translatable_la.ts b/tests/auto/qscriptengine/translations/translatable_la.ts index 1598f39..36271c9 100644 --- a/tests/auto/qscriptengine/translations/translatable_la.ts +++ b/tests/auto/qscriptengine/translations/translatable_la.ts @@ -26,6 +26,14 @@ <source>Goodbye</source> <translation>Farvel</translation> </message> + <message numerus="yes"> + <location filename="translatable.js" line="12"/> + <source>%n fooish bar(s) found</source> + <translation> + <numerusform>%n fooaktig bar funnet</numerusform> + <numerusform>%n fooaktige barer funnet</numerusform> + </translation> + </message> </context> <context> <name>translatable</name> @@ -45,6 +53,14 @@ <comment>not the same one</comment> <translation>Enda en</translation> </message> + <message numerus="yes"> + <location filename="translatable.js" line="11"/> + <source>%n message(s) saved</source> + <translation> + <numerusform>%n melding lagret</numerusform> + <numerusform>%n meldinger lagret</numerusform> + </translation> + </message> <message> <source>Goodbye</source> <translation type="obsolete">Farvel</translation> diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index 5028b47..b92cd29 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -93,18 +93,39 @@ private slots: void constructWithParent(); void currentContext(); void pushPopContext(); - void getSetDefaultPrototype(); + void getSetDefaultPrototype_int(); + void getSetDefaultPrototype_customType(); void newFunction(); + void newFunctionWithArg(); + void newFunctionWithProto(); void newObject(); void newArray(); + void newArray_HooliganTask218092(); + void newArray_HooliganTask233836(); void newVariant(); + void newVariant_defaultPrototype(); + void newVariant_promoteObject(); + void newVariant_replaceValue(); + void newVariant_valueOfToString(); + void newVariant_promoteNonObject(); + void newVariant_promoteNonQScriptObject(); void newRegExp(); + void jsRegExp(); void newDate(); + void jsParseDate(); void newQObject(); + void newQObject_ownership(); + void newQObject_promoteObject(); + void newQObject_sameQObject(); + void newQObject_defaultPrototype(); + void newQObject_promoteNonObject(); + void newQObject_promoteNonQScriptObject(); void newQMetaObject(); void newActivationObject(); void getSetGlobalObject(); void globalObjectProperties(); + void globalObjectProperties_enumerate(); + void createGlobalObjectProperty(); void globalObjectGetterSetterProperty(); void customGlobalObjectWithPrototype(); void globalObjectWithCustomPrototype(); @@ -119,7 +140,15 @@ private slots: void nestedEvaluate(); void uncaughtException(); void errorMessage_QT679(); - void valueConversion(); + void valueConversion_basic(); + void valueConversion_customType(); + void valueConversion_sequence(); + void valueConversion_QVariant(); + void valueConversion_hooliganTask248802(); + void valueConversion_basic2(); + void valueConversion_dateTime(); + void valueConversion_regExp(); + void qScriptValueFromValue_noEngine(); void importExtension(); void infiniteRecursion(); void castWithPrototypeChain(); @@ -128,49 +157,89 @@ private slots: void reportAdditionalMemoryCost(); void gcWithNestedDataStructure(); void processEventsWhileRunning(); + void throwErrorFromProcessEvents_data(); void throwErrorFromProcessEvents(); + void disableProcessEventsInterval(); void stacktrace(); void numberParsing_data(); void numberParsing(); void automaticSemicolonInsertion(); + void abortEvaluation_notEvaluating(); + void abortEvaluation_data(); void abortEvaluation(); + void abortEvaluation_tryCatch(); + void abortEvaluation_fromNative(); void abortEvaluation_QTBUG9433(); - void isEvaluating(); + void isEvaluating_notEvaluating(); + void isEvaluating_fromNative(); + void isEvaluating_fromEvent(); void printFunctionWithCustomHandler(); void printThrowsException(); void errorConstructors(); - void argumentsProperty(); - void numberClass(); - void forInStatement(); - void functionExpression(); + void argumentsProperty_globalContext(); + void argumentsProperty_JS(); + void argumentsProperty_evaluateInNativeFunction(); + void jsNumberClass(); + void jsForInStatement_simple(); + void jsForInStatement_prototypeProperties(); + void jsForInStatement_mutateWhileIterating(); + void jsForInStatement_arrays(); + void jsForInStatement_nullAndUndefined(); + void jsFunctionDeclarationAsStatement(); void stringObjects(); - void getterSetterThisObject(); - void continueInSwitch(); - void readOnlyPrototypeProperty(); + void jsStringPrototypeReplaceBugs(); + void getterSetterThisObject_global(); + void getterSetterThisObject_plain(); + void getterSetterThisObject_prototypeChain(); + void getterSetterThisObject_activation(); + void jsContinueInSwitch(); + void jsShadowReadOnlyPrototypeProperty(); void toObject(); - void reservedWords_data(); - void reservedWords(); - void futureReservedWords_data(); - void futureReservedWords(); - void throwInsideWithStatement(); - void getSetAgent(); - void reentrancy(); - void incDecNonObjectProperty(); + void jsReservedWords_data(); + void jsReservedWords(); + void jsFutureReservedWords_data(); + void jsFutureReservedWords(); + void jsThrowInsideWithStatement(); + void getSetAgent_ownership(); + void getSetAgent_deleteAgent(); + void getSetAgent_differentEngine(); + void reentrancy_stringHandles(); + void reentrancy_processEventsInterval(); + void reentrancy_typeConversion(); + void reentrancy_globalObjectProperties(); + void reentrancy_Array(); + void reentrancy_objectCreation(); + void jsIncDecNonObjectProperty(); void installTranslatorFunctions_data(); void installTranslatorFunctions(); + void translateScript_data(); void translateScript(); + void translateScript_crossScript(); + void translateScript_callQsTrFromNative(); + void translateScript_trNoOp(); + void translateScript_callQsTrFromCpp(); void translateWithInvalidArgs_data(); void translateWithInvalidArgs(); void translationContext_data(); void translationContext(); void translateScriptIdBased(); + void translateScriptUnicode_data(); + void translateScriptUnicode(); + void translateScriptUnicodeIdBased_data(); + void translateScriptUnicodeIdBased(); void translateFromBuiltinCallback(); void functionScopes(); void nativeFunctionScopes(); void evaluateProgram(); + void evaluateProgram_customScope(); + void evaluateProgram_closure(); + void evaluateProgram_executeLater(); + void evaluateProgram_multipleEngines(); + void evaluateProgram_empty(); void collectGarbageAfterConnect(); void collectGarbageAfterNativeArguments(); void promoteThisObjectToQObjectInConstructor(); + void scriptValueFromQMetaObject(); void qRegExpInport_data(); void qRegExpInport(); @@ -279,8 +348,8 @@ void tst_QScriptEngine::newFunction() QScriptValue prot = fun.property("prototype", QScriptValue::ResolveLocal); QVERIFY(prot.isObject()); QVERIFY(prot.property("constructor").strictlyEquals(fun)); - QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable); - QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); + QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); + QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::SkipInEnumeration); } // prototype should be Function.prototype QCOMPARE(fun.prototype().isValid(), true); @@ -290,8 +359,11 @@ void tst_QScriptEngine::newFunction() QCOMPARE(fun.call().isNull(), true); QCOMPARE(fun.construct().isObject(), true); } +} - // the overload that takes a void* +void tst_QScriptEngine::newFunctionWithArg() +{ + QScriptEngine eng; { QScriptValue fun = eng.newFunction(myFunctionWithVoidArg, (void*)this); QVERIFY(fun.isFunction()); @@ -301,8 +373,8 @@ void tst_QScriptEngine::newFunction() QScriptValue prot = fun.property("prototype", QScriptValue::ResolveLocal); QVERIFY(prot.isObject()); QVERIFY(prot.property("constructor").strictlyEquals(fun)); - QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable); - QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); + QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); + QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::SkipInEnumeration); } // prototype should be Function.prototype QCOMPARE(fun.prototype().isValid(), true); @@ -312,8 +384,11 @@ void tst_QScriptEngine::newFunction() QCOMPARE(fun.call().isNull(), true); QCOMPARE(fun.construct().isObject(), true); } +} - // the overload that takes a prototype +void tst_QScriptEngine::newFunctionWithProto() +{ + QScriptEngine eng; { QScriptValue proto = eng.newObject(); QScriptValue fun = eng.newFunction(myFunction, proto); @@ -326,10 +401,9 @@ void tst_QScriptEngine::newFunction() QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true); // public prototype should be the one we passed QCOMPARE(fun.property("prototype").strictlyEquals(proto), true); - QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable); + QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); QCOMPARE(proto.property("constructor").strictlyEquals(fun), true); - QCOMPARE(proto.propertyFlags("constructor"), - QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); + QCOMPARE(proto.propertyFlags("constructor"), QScriptValue::SkipInEnumeration); QCOMPARE(fun.call().isNull(), true); QCOMPARE(fun.construct().isObject(), true); @@ -363,8 +437,11 @@ void tst_QScriptEngine::newArray() QCOMPARE(array.prototype().isValid(), true); QCOMPARE(array.prototype().isArray(), true); QCOMPARE(array.prototype().strictlyEquals(eng.evaluate("Array.prototype")), true); +} - // task 218092 +void tst_QScriptEngine::newArray_HooliganTask218092() +{ + QScriptEngine eng; { QScriptValue ret = eng.evaluate("[].splice(0, 0, 'a')"); QVERIFY(ret.isArray()); @@ -390,13 +467,16 @@ void tst_QScriptEngine::newArray() QVERIFY(ret.isArray()); QCOMPARE(ret.property("length").toInt32(), 2); } +} - // task 233836 +void tst_QScriptEngine::newArray_HooliganTask233836() +{ + QScriptEngine eng; { + // According to ECMA-262, this should cause a RangeError. QScriptValue ret = eng.evaluate("a = new Array(4294967295); a.push('foo')"); - QVERIFY(ret.isNumber()); - QCOMPARE(ret.toInt32(), 0); - QCOMPARE(eng.evaluate("a[4294967295]").toString(), QString::fromLatin1("foo")); + QEXPECT_FAIL("", "ECMA compliance bug in Array.prototype.push: https://bugs.webkit.org/show_bug.cgi?id=55033", Continue); + QVERIFY(ret.isError() && ret.toString().contains(QLatin1String("RangeError"))); } { QScriptValue ret = eng.newArray(0xFFFFFFFF); @@ -425,7 +505,12 @@ void tst_QScriptEngine::newVariant() QCOMPARE(opaque.prototype().isVariant(), true); QVERIFY(opaque.property("valueOf").call(opaque).isUndefined()); } +} + +void tst_QScriptEngine::newVariant_defaultPrototype() +{ // default prototype should be set automatically + QScriptEngine eng; { QScriptValue proto = eng.newObject(); eng.setDefaultPrototype(qMetaTypeId<QString>(), proto); @@ -438,7 +523,12 @@ void tst_QScriptEngine::newVariant() QVERIFY(ret2.isVariant()); QVERIFY(!ret2.prototype().strictlyEquals(proto)); } +} + +void tst_QScriptEngine::newVariant_promoteObject() +{ // "promote" plain object to variant + QScriptEngine eng; { QScriptValue object = eng.newObject(); object.setProperty("foo", eng.newObject()); @@ -455,17 +545,28 @@ void tst_QScriptEngine::newVariant() QCOMPARE(ret.toVariant(), QVariant(123)); QVERIFY(ret.prototype().strictlyEquals(originalProto)); } +} + +void tst_QScriptEngine::newVariant_replaceValue() +{ // replace value of existing object + QScriptEngine eng; { QScriptValue object = eng.newVariant(QVariant(123)); - QScriptValue ret = eng.newVariant(object, QVariant(456)); - QVERIFY(ret.isValid()); - QVERIFY(ret.strictlyEquals(object)); - QVERIFY(ret.isVariant()); - QCOMPARE(ret.toVariant(), QVariant(456)); + for (int x = 0; x < 2; ++x) { + QScriptValue ret = eng.newVariant(object, QVariant(456)); + QVERIFY(ret.isValid()); + QVERIFY(ret.strictlyEquals(object)); + QVERIFY(ret.isVariant()); + QCOMPARE(ret.toVariant(), QVariant(456)); + } } +} +void tst_QScriptEngine::newVariant_valueOfToString() +{ // valueOf() and toString() + QScriptEngine eng; { QScriptValue object = eng.newVariant(QVariant(123)); QScriptValue value = object.property("valueOf").call(object); @@ -499,6 +600,27 @@ void tst_QScriptEngine::newVariant() } } +void tst_QScriptEngine::newVariant_promoteNonObject() +{ + QScriptEngine eng; + { + QVariant var(456); + QScriptValue ret = eng.newVariant(123, var); + QVERIFY(ret.isVariant()); + QCOMPARE(ret.toVariant(), var); + } +} + +void tst_QScriptEngine::newVariant_promoteNonQScriptObject() +{ + QScriptEngine eng; + { + QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::newVariant(): changing class of non-QScriptObject not supported"); + QScriptValue ret = eng.newVariant(eng.newArray(), 123); + QVERIFY(!ret.isValid()); + } +} + void tst_QScriptEngine::newRegExp() { QScriptEngine eng; @@ -520,54 +642,66 @@ void tst_QScriptEngine::newRegExp() QCOMPARE(rexp.toRegExp().pattern(), QRegExp("foo").pattern()); } - { - QScriptValue r = eng.evaluate("/foo/gim"); - QVERIFY(r.isRegExp()); - QCOMPARE(r.toString(), QString::fromLatin1("/foo/gim")); - - QScriptValue rxCtor = eng.globalObject().property("RegExp"); - QScriptValue r2 = rxCtor.call(QScriptValue(), QScriptValueList() << r); - QVERIFY(r2.isRegExp()); - QVERIFY(r2.strictlyEquals(r)); - - QScriptValue r3 = rxCtor.call(QScriptValue(), QScriptValueList() << r << "gim"); - QVERIFY(r3.isError()); - QCOMPARE(r3.toString(), QString::fromLatin1("TypeError: Cannot supply flags when constructing one RegExp from another.")); - - QScriptValue r4 = rxCtor.call(QScriptValue(), QScriptValueList() << "foo" << "gim"); - QVERIFY(r4.isRegExp()); - - QScriptValue r5 = rxCtor.construct(QScriptValueList() << r); - QVERIFY(r5.isRegExp()); - QCOMPARE(r5.toString(), QString::fromLatin1("/foo/gim")); - // In JSC, constructing a RegExp from another produces the same identical object. - // This is different from SpiderMonkey and old back-end. - QVERIFY(r5.strictlyEquals(r)); - - QScriptValue r6 = rxCtor.construct(QScriptValueList() << "foo" << "bar"); - QVERIFY(r6.isError()); - QCOMPARE(r6.toString(), QString::fromLatin1("SyntaxError: Invalid regular expression: invalid regular expression flag")); - - QScriptValue r7 = eng.evaluate("/foo/gimp"); - QVERIFY(r7.isError()); - QCOMPARE(r7.toString(), QString::fromLatin1("SyntaxError: Invalid regular expression: invalid regular expression flag")); - - QScriptValue r8 = eng.evaluate("/foo/migmigmig"); - QVERIFY(r8.isRegExp()); - QCOMPARE(r8.toString(), QString::fromLatin1("/foo/gim")); - - QScriptValue r9 = rxCtor.construct(); - QVERIFY(r9.isRegExp()); - QCOMPARE(r9.toString(), QString::fromLatin1("/(?:)/")); +} - QScriptValue r10 = rxCtor.construct(QScriptValueList() << "" << "gim"); - QVERIFY(r10.isRegExp()); - QCOMPARE(r10.toString(), QString::fromLatin1("/(?:)/gim")); +void tst_QScriptEngine::jsRegExp() +{ + // See ECMA-262 Section 15.10, "RegExp Objects". + // These should really be JS-only tests, as they test the implementation's + // ECMA-compliance, not the C++ API. Compliance should already be covered + // by the Mozilla tests (qscriptjstestsuite). + // We can consider updating the expected results of this test if the + // RegExp implementation changes. - QScriptValue r11 = rxCtor.construct(QScriptValueList() << "{1.*}" << "g"); - QVERIFY(r11.isRegExp()); - QCOMPARE(r11.toString(), QString::fromLatin1("/{1.*}/g")); - } + QScriptEngine eng; + QScriptValue r = eng.evaluate("/foo/gim"); + QVERIFY(r.isRegExp()); + QCOMPARE(r.toString(), QString::fromLatin1("/foo/gim")); + + QScriptValue rxCtor = eng.globalObject().property("RegExp"); + QScriptValue r2 = rxCtor.call(QScriptValue(), QScriptValueList() << r); + QVERIFY(r2.isRegExp()); + QVERIFY(r2.strictlyEquals(r)); + + QScriptValue r3 = rxCtor.call(QScriptValue(), QScriptValueList() << r << "gim"); + QVERIFY(r3.isError()); + QVERIFY(r3.toString().contains(QString::fromLatin1("TypeError"))); // Cannot supply flags when constructing one RegExp from another + + QScriptValue r4 = rxCtor.call(QScriptValue(), QScriptValueList() << "foo" << "gim"); + QVERIFY(r4.isRegExp()); + + QScriptValue r5 = rxCtor.construct(QScriptValueList() << r); + QVERIFY(r5.isRegExp()); + QCOMPARE(r5.toString(), QString::fromLatin1("/foo/gim")); + // In JSC, constructing a RegExp from another produces the same identical object. + // This is different from SpiderMonkey and old back-end. + QEXPECT_FAIL("", "RegExp copy-constructor should return a new object: https://bugs.webkit.org/show_bug.cgi?id=55040", Continue); + QVERIFY(!r5.strictlyEquals(r)); + + QScriptValue r6 = rxCtor.construct(QScriptValueList() << "foo" << "bar"); + QVERIFY(r6.isError()); + QVERIFY(r6.toString().contains(QString::fromLatin1("SyntaxError"))); // Invalid regular expression flag + + QScriptValue r7 = eng.evaluate("/foo/gimp"); + QVERIFY(r7.isError()); + QVERIFY(r7.toString().contains(QString::fromLatin1("SyntaxError"))); // Invalid regular expression flag + + // JSC doesn't complain about duplicate flags. + QScriptValue r8 = eng.evaluate("/foo/migmigmig"); + QVERIFY(r8.isRegExp()); + QCOMPARE(r8.toString(), QString::fromLatin1("/foo/gim")); + + QScriptValue r9 = rxCtor.construct(); + QVERIFY(r9.isRegExp()); + QCOMPARE(r9.toString(), QString::fromLatin1("/(?:)/")); + + QScriptValue r10 = rxCtor.construct(QScriptValueList() << "" << "gim"); + QVERIFY(r10.isRegExp()); + QCOMPARE(r10.toString(), QString::fromLatin1("/(?:)/gim")); + + QScriptValue r11 = rxCtor.construct(QScriptValueList() << "{1.*}" << "g"); + QVERIFY(r11.isRegExp()); + QCOMPARE(r11.toString(), QString::fromLatin1("/{1.*}/g")); } void tst_QScriptEngine::newDate() @@ -606,7 +740,11 @@ void tst_QScriptEngine::newDate() // toDateTime() result should be in local time QCOMPARE(date.toDateTime(), dt.toLocalTime()); } +} +void tst_QScriptEngine::jsParseDate() +{ + QScriptEngine eng; // Date.parse() should return NaN when it fails { QScriptValue ret = eng.evaluate("Date.parse()"); @@ -647,8 +785,11 @@ void tst_QScriptEngine::newQObject() QCOMPARE(qobject.prototype().isQObject(), true); QCOMPARE(qobject.scriptClass(), (QScriptClass*)0); } +} - // test ownership +void tst_QScriptEngine::newQObject_ownership() +{ + QScriptEngine eng; { QPointer<QObject> ptr = new QObject(); QVERIFY(ptr != 0); @@ -703,7 +844,11 @@ void tst_QScriptEngine::newQObject() QVERIFY(child != 0); delete parent; } +} +void tst_QScriptEngine::newQObject_promoteObject() +{ + QScriptEngine eng; // "promote" plain object to QObject { QScriptValue obj = eng.newObject(); @@ -735,14 +880,20 @@ void tst_QScriptEngine::newQObject() QScriptValue object = eng.newVariant(123); QScriptValue originalProto = object.prototype(); QObject otherQObject; - QScriptValue ret = eng.newQObject(object, &otherQObject); - QVERIFY(ret.isValid()); - QVERIFY(ret.isQObject()); - QVERIFY(ret.strictlyEquals(object)); - QCOMPARE(ret.toQObject(), (QObject *)&otherQObject); - QVERIFY(ret.prototype().strictlyEquals(originalProto)); + for (int x = 0; x < 2; ++x) { + QScriptValue ret = eng.newQObject(object, &otherQObject); + QVERIFY(ret.isValid()); + QVERIFY(ret.isQObject()); + QVERIFY(ret.strictlyEquals(object)); + QCOMPARE(ret.toQObject(), (QObject *)&otherQObject); + QVERIFY(ret.prototype().strictlyEquals(originalProto)); + } } +} +void tst_QScriptEngine::newQObject_sameQObject() +{ + QScriptEngine eng; // calling newQObject() several times with same object for (int x = 0; x < 2; ++x) { QObject qobj; @@ -773,7 +924,11 @@ void tst_QScriptEngine::newQObject() QScriptEngine::ExcludeSuperClassMethods | opt); QCOMPARE(obj8.strictlyEquals(obj7), preferExisting); } +} +void tst_QScriptEngine::newQObject_defaultPrototype() +{ + QScriptEngine eng; // newQObject() should set the default prototype, if one has been registered { QScriptValue oldQObjectProto = eng.defaultPrototype(qMetaTypeId<QObject*>()); @@ -797,6 +952,26 @@ void tst_QScriptEngine::newQObject() } } +void tst_QScriptEngine::newQObject_promoteNonObject() +{ + QScriptEngine eng; + { + QScriptValue ret = eng.newQObject(123, this); + QVERIFY(ret.isQObject()); + QCOMPARE(ret.toQObject(), this); + } +} + +void tst_QScriptEngine::newQObject_promoteNonQScriptObject() +{ + QScriptEngine eng; + { + QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::newQObject(): changing class of non-QScriptObject not supported"); + QScriptValue ret = eng.newQObject(eng.newArray(), this); + QVERIFY(!ret.isValid()); + } +} + QT_BEGIN_NAMESPACE Q_SCRIPT_DECLARE_QMETAOBJECT(QObject, QObject*) Q_SCRIPT_DECLARE_QMETAOBJECT(QWidget, QWidget*) @@ -983,6 +1158,11 @@ void tst_QScriptEngine::getSetGlobalObject() QCOMPARE(glob.prototype().isObject(), true); QCOMPARE(glob.prototype().strictlyEquals(eng.evaluate("Object.prototype")), true); + eng.setGlobalObject(glob); + QVERIFY(eng.globalObject().equals(glob)); + eng.setGlobalObject(123); + QVERIFY(eng.globalObject().equals(glob)); + QScriptValue obj = eng.newObject(); eng.setGlobalObject(obj); QVERIFY(eng.globalObject().strictlyEquals(obj)); @@ -1032,6 +1212,28 @@ void tst_QScriptEngine::getSetGlobalObject() QScriptValue ret = eng.evaluate("(function() { return this; })()"); QVERIFY(ret.strictlyEquals(obj)); } + + // Delete property. + { + QScriptValue ret = eng.evaluate("delete foo"); + QVERIFY(ret.isBool()); + QVERIFY(ret.toBool()); + QVERIFY(!obj.property("foo").isValid()); + } + + // Getter/setter property. + QVERIFY(eng.evaluate("this.__defineGetter__('oof', function() { return this.bar; })").isUndefined()); + QVERIFY(eng.evaluate("this.__defineSetter__('oof', function(v) { this.bar = v; })").isUndefined()); + QVERIFY(eng.evaluate("this.__lookupGetter__('oof')").isFunction()); + QVERIFY(eng.evaluate("this.__lookupSetter__('oof')").isFunction()); + eng.evaluate("oof = 123"); + QVERIFY(eng.evaluate("oof").equals(obj.property("bar"))); + + // Enumeration. + { + QScriptValue ret = eng.evaluate("a = []; for (var p in this) a.push(p); a"); + QCOMPARE(ret.toString(), QString::fromLatin1("bar,baz,oof,p,a")); + } } static QScriptValue getSetFoo(QScriptContext *ctx, QScriptEngine *) @@ -1043,6 +1245,8 @@ static QScriptValue getSetFoo(QScriptContext *ctx, QScriptEngine *) void tst_QScriptEngine::globalObjectProperties() { + // See ECMA-262 Section 15.1, "The Global Object". + QScriptEngine eng; QScriptValue global = eng.globalObject(); @@ -1116,10 +1320,15 @@ void tst_QScriptEngine::globalObjectProperties() QCOMPARE(global.propertyFlags("URIError"), QScriptValue::SkipInEnumeration); QVERIFY(global.property("Math").isObject()); QVERIFY(!global.property("Math").isFunction()); - QEXPECT_FAIL("", "[ECMA compliance] JSC sets DontDelete flag for Math object", Continue); + QEXPECT_FAIL("", "[ECMA compliance] JSC sets DontDelete flag for Math object: https://bugs.webkit.org/show_bug.cgi?id=55034", Continue); QCOMPARE(global.propertyFlags("Math"), QScriptValue::SkipInEnumeration); +} + +void tst_QScriptEngine::globalObjectProperties_enumerate() +{ + QScriptEngine eng; + QScriptValue global = eng.globalObject(); - // enumeration QSet<QString> expectedNames; expectedNames << "isNaN" @@ -1178,7 +1387,12 @@ void tst_QScriptEngine::globalObjectProperties() } } QVERIFY(remainingNames.isEmpty()); +} +void tst_QScriptEngine::createGlobalObjectProperty() +{ + QScriptEngine eng; + QScriptValue global = eng.globalObject(); // create property with no attributes { QString name = QString::fromLatin1("foo"); @@ -1342,7 +1556,7 @@ void tst_QScriptEngine::globalObjectWithCustomPrototype() { QScriptValue ret = engine.evaluate("this.__proto__ = { 'a': 123 }; a"); QVERIFY(ret.isNumber()); - QEXPECT_FAIL("", "QTBUG-9737", Continue); + QEXPECT_FAIL("", "QTBUG-9737: Prototype change in JS not reflected on C++ side", Continue); QVERIFY(ret.strictlyEquals(global.property("a"))); } } @@ -1352,7 +1566,9 @@ void tst_QScriptEngine::builtinFunctionNames_data() QTest::addColumn<QString>("expression"); QTest::addColumn<QString>("expectedName"); - QTest::newRow("print") << QString("print") << QString("print"); + // See ECMA-262 Chapter 15, "Standard Built-in ECMAScript Objects". + + QTest::newRow("print") << QString("print") << QString("print"); // QtScript extension. QTest::newRow("parseInt") << QString("parseInt") << QString("parseInt"); QTest::newRow("parseFloat") << QString("parseFloat") << QString("parseFloat"); QTest::newRow("isNaN") << QString("isNaN") << QString("isNaN"); @@ -1363,8 +1579,8 @@ void tst_QScriptEngine::builtinFunctionNames_data() QTest::newRow("encodeURIComponent") << QString("encodeURIComponent") << QString("encodeURIComponent"); QTest::newRow("escape") << QString("escape") << QString("escape"); QTest::newRow("unescape") << QString("unescape") << QString("unescape"); - QTest::newRow("version") << QString("version") << QString("version"); - QTest::newRow("gc") << QString("gc") << QString("gc"); + QTest::newRow("version") << QString("version") << QString("version"); // QtScript extension. + QTest::newRow("gc") << QString("gc") << QString("gc"); // QtScript extension. QTest::newRow("Array") << QString("Array") << QString("Array"); QTest::newRow("Array.prototype.toString") << QString("Array.prototype.toString") << QString("toString"); @@ -1515,6 +1731,7 @@ void tst_QScriptEngine::builtinFunctionNames() QFETCH(QString, expression); QFETCH(QString, expectedName); QScriptEngine eng; + // The "name" property is actually non-standard, but JSC supports it. QScriptValue ret = eng.evaluate(QString::fromLatin1("%0.name").arg(expression)); QVERIFY(ret.isString()); QCOMPARE(ret.toString(), expectedName); @@ -1736,22 +1953,24 @@ static QScriptValue eval_nested(QScriptContext *ctx, QScriptEngine *eng) return result; } +// Tests that nested evaluate uses the "this" that was passed. void tst_QScriptEngine::nestedEvaluate() { QScriptEngine eng; QScriptValue fun = eng.newFunction(eval_nested); eng.globalObject().setProperty("fun", fun); + // From JS function call { QScriptValue result = eng.evaluate("o = { id:'foo'}; o.fun = fun; o.fun()"); QCOMPARE(result.property("local_bar").toString(), QString("local")); QCOMPARE(result.property("thisObjectIdBefore").toString(), QString("foo")); QCOMPARE(result.property("thisObjectIdAfter").toString(), QString("foo")); QCOMPARE(result.property("evaluatedThisObjectId").toString(), QString("foo")); - QScriptValue bar = eng.evaluate("bar"); + QScriptValue bar = eng.evaluate("bar"); // Was introduced in local scope. QVERIFY(bar.isError()); - QCOMPARE(bar.toString(), QString::fromLatin1("ReferenceError: Can't find variable: bar")); + QVERIFY(bar.toString().contains(QString::fromLatin1("ReferenceError"))); } - + // From QScriptValue::call() { QScriptValue result = fun.call(eng.evaluate("p = { id:'foo' }") , QScriptValueList() ); QCOMPARE(result.property("local_bar").toString(), QString("local")); @@ -1760,7 +1979,7 @@ void tst_QScriptEngine::nestedEvaluate() QCOMPARE(result.property("evaluatedThisObjectId").toString(), QString("foo")); QScriptValue bar = eng.evaluate("bar"); QVERIFY(bar.isError()); - QCOMPARE(bar.toString(), QString::fromLatin1("ReferenceError: Can't find variable: bar")); + QVERIFY(bar.toString().contains(QString::fromLatin1("ReferenceError"))); } } @@ -1827,6 +2046,7 @@ void tst_QScriptEngine::errorMessage_QT679() engine.globalObject().setProperty("foo", 15); QScriptValue error = engine.evaluate("'hello world';\nfoo.bar.blah"); QVERIFY(error.isError()); + // The exact message is back-end specific and subject to change. QCOMPARE(error.toString(), QString::fromLatin1("TypeError: Result of expression 'foo.bar' [undefined] is not an object.")); } @@ -1839,37 +2059,40 @@ public: Q_DECLARE_METATYPE(Foo) Q_DECLARE_METATYPE(Foo*) -void tst_QScriptEngine::getSetDefaultPrototype() +void tst_QScriptEngine::getSetDefaultPrototype_int() { QScriptEngine eng; - { - QScriptValue object = eng.newObject(); - QCOMPARE(eng.defaultPrototype(qMetaTypeId<int>()).isValid(), false); - eng.setDefaultPrototype(qMetaTypeId<int>(), object); - QCOMPARE(eng.defaultPrototype(qMetaTypeId<int>()).strictlyEquals(object), true); - QScriptValue value = eng.newVariant(int(123)); - QCOMPARE(value.prototype().isObject(), true); - QCOMPARE(value.prototype().strictlyEquals(object), true); - eng.setDefaultPrototype(qMetaTypeId<int>(), QScriptValue()); - QCOMPARE(eng.defaultPrototype(qMetaTypeId<int>()).isValid(), false); - QScriptValue value2 = eng.newVariant(int(123)); - QCOMPARE(value2.prototype().strictlyEquals(object), false); - } - { - QScriptValue object = eng.newObject(); - QCOMPARE(eng.defaultPrototype(qMetaTypeId<Foo>()).isValid(), false); - eng.setDefaultPrototype(qMetaTypeId<Foo>(), object); - QCOMPARE(eng.defaultPrototype(qMetaTypeId<Foo>()).strictlyEquals(object), true); - QScriptValue value = eng.newVariant(qVariantFromValue(Foo())); - QCOMPARE(value.prototype().isObject(), true); - QCOMPARE(value.prototype().strictlyEquals(object), true); + QScriptValue object = eng.newObject(); + QCOMPARE(eng.defaultPrototype(qMetaTypeId<int>()).isValid(), false); + eng.setDefaultPrototype(qMetaTypeId<int>(), object); + QCOMPARE(eng.defaultPrototype(qMetaTypeId<int>()).strictlyEquals(object), true); + QScriptValue value = eng.newVariant(int(123)); + QCOMPARE(value.prototype().isObject(), true); + QCOMPARE(value.prototype().strictlyEquals(object), true); + + eng.setDefaultPrototype(qMetaTypeId<int>(), QScriptValue()); + QCOMPARE(eng.defaultPrototype(qMetaTypeId<int>()).isValid(), false); + QScriptValue value2 = eng.newVariant(int(123)); + QCOMPARE(value2.prototype().strictlyEquals(object), false); +} - eng.setDefaultPrototype(qMetaTypeId<Foo>(), QScriptValue()); - QCOMPARE(eng.defaultPrototype(qMetaTypeId<Foo>()).isValid(), false); - QScriptValue value2 = eng.newVariant(qVariantFromValue(Foo())); - QCOMPARE(value2.prototype().strictlyEquals(object), false); - } +void tst_QScriptEngine::getSetDefaultPrototype_customType() +{ + QScriptEngine eng; + + QScriptValue object = eng.newObject(); + QCOMPARE(eng.defaultPrototype(qMetaTypeId<Foo>()).isValid(), false); + eng.setDefaultPrototype(qMetaTypeId<Foo>(), object); + QCOMPARE(eng.defaultPrototype(qMetaTypeId<Foo>()).strictlyEquals(object), true); + QScriptValue value = eng.newVariant(qVariantFromValue(Foo())); + QCOMPARE(value.prototype().isObject(), true); + QCOMPARE(value.prototype().strictlyEquals(object), true); + + eng.setDefaultPrototype(qMetaTypeId<Foo>(), QScriptValue()); + QCOMPARE(eng.defaultPrototype(qMetaTypeId<Foo>()).isValid(), false); + QScriptValue value2 = eng.newVariant(qVariantFromValue(Foo())); + QCOMPARE(value2.prototype().strictlyEquals(object), false); } static QScriptValue fooToScriptValue(QScriptEngine *eng, const Foo &foo) @@ -1903,7 +2126,7 @@ Q_DECLARE_METATYPE(QStack<int>) Q_DECLARE_METATYPE(QQueue<char>) Q_DECLARE_METATYPE(QLinkedList<QStack<int> >) -void tst_QScriptEngine::valueConversion() +void tst_QScriptEngine::valueConversion_basic() { QScriptEngine eng; { @@ -1917,7 +2140,6 @@ void tst_QScriptEngine::valueConversion() QString snum = qScriptValueToValue<QString>(num); QCOMPARE(snum, QLatin1String("123")); } -#ifndef QT_NO_MEMBER_TEMPLATES { QScriptValue num = eng.toScriptValue(123); QCOMPARE(num.isNumber(), true); @@ -1929,7 +2151,6 @@ void tst_QScriptEngine::valueConversion() QString snum = eng.fromScriptValue<QString>(num); QCOMPARE(snum, QLatin1String("123")); } -#endif { QScriptValue num(&eng, 123); QCOMPARE(qScriptValueToValue<char>(num), char(123)); @@ -1967,7 +2188,11 @@ void tst_QScriptEngine::valueConversion() QCOMPARE(qScriptValueToValue<QChar>(code), c); QCOMPARE(qScriptValueToValue<QChar>(qScriptValueFromValue(&eng, c)), c); } +} +void tst_QScriptEngine::valueConversion_customType() +{ + QScriptEngine eng; { // a type that we don't have built-in conversion of // (it's stored as a variant) @@ -2013,7 +2238,11 @@ void tst_QScriptEngine::valueConversion() QVERIFY(fooVal2.property("x").strictlyEquals(QScriptValue(&eng, 56))); QVERIFY(fooVal2.property("y").strictlyEquals(QScriptValue(&eng, 78))); } +} +void tst_QScriptEngine::valueConversion_sequence() +{ + QScriptEngine eng; qScriptRegisterSequenceMetaType<QLinkedList<QString> >(&eng); { @@ -2092,13 +2321,49 @@ void tst_QScriptEngine::valueConversion() QCOMPARE(qscriptvalue_cast<QObjectList>(val), lst); } +} +void tst_QScriptEngine::valueConversion_QVariant() +{ + QScriptEngine eng; // qScriptValueFromValue() should be "smart" when the argument is a QVariant { QScriptValue val = qScriptValueFromValue(&eng, QVariant()); QVERIFY(!val.isVariant()); QVERIFY(val.isUndefined()); } + // Checking nested QVariants + { + QVariant tmp1; + QVariant tmp2(QMetaType::QVariant, &tmp1); + QVERIFY(QMetaType::Type(tmp2.type()) == QMetaType::QVariant); + + QScriptValue val1 = qScriptValueFromValue(&eng, tmp1); + QScriptValue val2 = qScriptValueFromValue(&eng, tmp2); + QVERIFY(val1.isValid()); + QVERIFY(val2.isValid()); + QVERIFY(val1.isUndefined()); + QVERIFY(!val2.isUndefined()); + QVERIFY(!val1.isVariant()); + QVERIFY(val2.isVariant()); + } + { + QVariant tmp1(123); + QVariant tmp2(QMetaType::QVariant, &tmp1); + QVariant tmp3(QMetaType::QVariant, &tmp2); + QVERIFY(QMetaType::Type(tmp1.type()) == QMetaType::Int); + QVERIFY(QMetaType::Type(tmp2.type()) == QMetaType::QVariant); + QVERIFY(QMetaType::Type(tmp3.type()) == QMetaType::QVariant); + + QScriptValue val1 = qScriptValueFromValue(&eng, tmp2); + QScriptValue val2 = qScriptValueFromValue(&eng, tmp3); + QVERIFY(val1.isValid()); + QVERIFY(val2.isValid()); + QVERIFY(val1.isVariant()); + QVERIFY(val2.isVariant()); + QVERIFY(val1.toVariant().toInt() == 123); + QVERIFY(qScriptValueFromValue(&eng, val2.toVariant()).toVariant().toInt() == 123); + } { QScriptValue val = qScriptValueFromValue(&eng, QVariant(true)); QVERIFY(!val.isVariant()); @@ -2137,7 +2402,12 @@ void tst_QScriptEngine::valueConversion() QCOMPARE(val.toVariant(), var); } - // task 248802 + QCOMPARE(qscriptvalue_cast<QVariant>(QScriptValue(123)), QVariant(123)); +} + +void tst_QScriptEngine::valueConversion_hooliganTask248802() +{ + QScriptEngine eng; qScriptRegisterMetaType<Foo>(&eng, fooToScriptValueV2, fooFromScriptValueV2); { QScriptValue num(&eng, 123); @@ -2155,6 +2425,11 @@ void tst_QScriptEngine::valueConversion() QCOMPARE(foo.x, 123); } +} + +void tst_QScriptEngine::valueConversion_basic2() +{ + QScriptEngine eng; // more built-in types { QScriptValue val = qScriptValueFromValue(&eng, uint(123)); @@ -2191,6 +2466,11 @@ void tst_QScriptEngine::valueConversion() QVERIFY(val.isNumber()); QCOMPARE(val.toInt32(), 123); } +} + +void tst_QScriptEngine::valueConversion_dateTime() +{ + QScriptEngine eng; { QDateTime in = QDateTime::currentDateTime(); QScriptValue val = qScriptValueFromValue(&eng, in); @@ -2203,6 +2483,11 @@ void tst_QScriptEngine::valueConversion() QVERIFY(val.isDate()); QCOMPARE(val.toDateTime().date(), in); } +} + +void tst_QScriptEngine::valueConversion_regExp() +{ + QScriptEngine eng; { QRegExp in = QRegExp("foo"); QScriptValue val = qScriptValueFromValue(&eng, in); @@ -2230,6 +2515,12 @@ void tst_QScriptEngine::valueConversion() } } +void tst_QScriptEngine::qScriptValueFromValue_noEngine() +{ + QVERIFY(!qScriptValueFromValue(0, 123).isValid()); + QVERIFY(!qScriptValueFromValue(0, QVariant(123)).isValid()); +} + static QScriptValue __import__(QScriptContext *ctx, QScriptEngine *eng) { return eng->importExtension(ctx->argument(0).toString()); @@ -2326,7 +2617,7 @@ void tst_QScriptEngine::importExtension() QEXPECT_FAIL("", "JSC throws syntax error eagerly", Continue); QCOMPARE(eng.uncaughtExceptionLineNumber(), 4); QVERIFY(ret.isError()); - QCOMPARE(ret.property("message").toString(), QLatin1String("Parse error")); + QVERIFY(ret.toString().contains(QLatin1String("SyntaxError"))); } QStringList imp = eng.importedExtensions(); QCOMPARE(imp.size(), 2); @@ -2352,6 +2643,9 @@ static QScriptValue recurse2(QScriptContext *ctx, QScriptEngine *eng) void tst_QScriptEngine::infiniteRecursion() { + // Infinite recursion in JS should cause the VM to throw an error + // when the JS stack is exhausted. + // The exact error is back-end specific and subject to change. const QString stackOverflowError = QString::fromLatin1("RangeError: Maximum call stack size exceeded."); QScriptEngine eng; { @@ -2414,6 +2708,8 @@ void tst_QScriptEngine::castWithPrototypeChain() baz2.b = 456; QScriptValue baz2Value = qScriptValueFromValue(&eng, &baz2); { + // qscriptvalue_cast() does magic; if the QScriptValue contains + // t of type T, and the target type is T*, &t is returned. Baz *pbaz = qscriptvalue_cast<Baz*>(baz2Value); QVERIFY(pbaz != 0); QCOMPARE(pbaz->b, baz2.b); @@ -2436,6 +2732,13 @@ void tst_QScriptEngine::castWithPrototypeChain() } // establish chain -- now casting should work + // Why? because qscriptvalue_cast() does magic again. + // It the instance itself is not of type T, qscriptvalue_cast() + // searches the prototype chain for T, and if it finds one, it infers + // that the instance can also be casted to that type. This cast is + // _not_ safe and thus relies on the developer doing the right thing. + // This is an undocumented feature to enable qscriptvalue_cast() to + // be used by prototype functions to cast the JS this-object to C++. bazProto.setPrototype(barProto); { @@ -2544,6 +2847,9 @@ void tst_QScriptEngine::collectGarbage() void tst_QScriptEngine::reportAdditionalMemoryCost() { QScriptEngine eng; + // There isn't any reliable way to test whether calling + // this function affects garbage collection responsiveness; + // the best we can do is call it with a few different values. for (int x = 0; x < 1000; ++x) { eng.reportAdditionalMemoryCost(0); eng.reportAdditionalMemoryCost(10); @@ -2561,6 +2867,8 @@ void tst_QScriptEngine::reportAdditionalMemoryCost() void tst_QScriptEngine::gcWithNestedDataStructure() { + // The GC must be able to traverse deeply nested objects, otherwise this + // test would crash. QScriptEngine eng; eng.evaluate( "function makeList(size)" @@ -2582,6 +2890,7 @@ void tst_QScriptEngine::gcWithNestedDataStructure() if (x == 1) eng.evaluate("gc()"); QScriptValue l = head; + // Make sure all the nodes are still alive. for (int i = 0; i < 200; ++i) { QCOMPARE(l.property("data").toString(), QString::number(i)); l = l.property("next"); @@ -2611,6 +2920,8 @@ void tst_QScriptEngine::processEventsWhileRunning() if (x == 0) eng.pushContext(); + // This is running for a silly amount of time just to make sure + // the script doesn't finish before event processing is triggered. QString script = QString::fromLatin1( "var end = Number(new Date()) + 2000;" "var x = 0;" @@ -2653,17 +2964,55 @@ public: QScriptEngine *engine; }; +void tst_QScriptEngine::throwErrorFromProcessEvents_data() +{ + QTest::addColumn<QString>("script"); + QTest::addColumn<QString>("error"); + + QTest::newRow("while (1)") + << QString::fromLatin1("while (1) { }") + << QString::fromLatin1("Error: Killed"); + QTest::newRow("while (1) i++") + << QString::fromLatin1("i = 0; while (1) { i++; }") + << QString::fromLatin1("Error: Killed"); + // Unlike abortEvaluation(), scripts should be able to catch the + // exception. + QTest::newRow("try catch") + << QString::fromLatin1("try {" + " while (1) { }" + "} catch(e) {" + " throw new Error('Caught');" + "}") + << QString::fromLatin1("Error: Caught"); +} + void tst_QScriptEngine::throwErrorFromProcessEvents() { + QFETCH(QString, script); + QFETCH(QString, error); + QScriptEngine eng; EventReceiver2 receiver(&eng); QCoreApplication::postEvent(&receiver, new QEvent(QEvent::Type(QEvent::User+1))); eng.setProcessEventsInterval(100); - QScriptValue ret = eng.evaluate(QString::fromLatin1("while (1) { }")); + QScriptValue ret = eng.evaluate(script); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("Error: Killed")); + QCOMPARE(ret.toString(), error); +} + +void tst_QScriptEngine::disableProcessEventsInterval() +{ + QScriptEngine eng; + eng.setProcessEventsInterval(100); + QCOMPARE(eng.processEventsInterval(), 100); + eng.setProcessEventsInterval(0); + QCOMPARE(eng.processEventsInterval(), 0); + eng.setProcessEventsInterval(-1); + QCOMPARE(eng.processEventsInterval(), -1); + eng.setProcessEventsInterval(-100); + QCOMPARE(eng.processEventsInterval(), -100); } void tst_QScriptEngine::stacktrace() @@ -2803,13 +3152,15 @@ void tst_QScriptEngine::numberParsing() } // see ECMA-262, section 7.9 +// This is testing ECMA compliance, not our C++ API, but it's important that +// the back-end is conformant in this regard. void tst_QScriptEngine::automaticSemicolonInsertion() { QScriptEngine eng; { QScriptValue ret = eng.evaluate("{ 1 2 } 3"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("SyntaxError: Parse error")); + QVERIFY(ret.toString().contains("SyntaxError")); } { QScriptValue ret = eng.evaluate("{ 1\n2 } 3"); @@ -2819,7 +3170,7 @@ void tst_QScriptEngine::automaticSemicolonInsertion() { QScriptValue ret = eng.evaluate("for (a; b\n)"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("SyntaxError: Parse error")); + QVERIFY(ret.toString().contains("SyntaxError")); } { QScriptValue ret = eng.evaluate("(function() { return\n1 + 2 })()"); @@ -2834,7 +3185,7 @@ void tst_QScriptEngine::automaticSemicolonInsertion() { QScriptValue ret = eng.evaluate("if (a > b)\nelse c = d"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("SyntaxError: Parse error")); + QVERIFY(ret.toString().contains("SyntaxError")); } { eng.evaluate("function c() { return { foo: function() { return 5; } } }"); @@ -2846,7 +3197,7 @@ void tst_QScriptEngine::automaticSemicolonInsertion() { QScriptValue ret = eng.evaluate("throw\n1"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("SyntaxError: Parse error")); + QVERIFY(ret.toString().contains("SyntaxError")); } { QScriptValue ret = eng.evaluate("a = Number(1)\n++a"); @@ -3048,7 +3399,7 @@ static QScriptValue myFunctionAbortingEvaluation(QScriptContext *, QScriptEngine return eng->nullValue(); // should be ignored } -void tst_QScriptEngine::abortEvaluation() +void tst_QScriptEngine::abortEvaluation_notEvaluating() { QScriptEngine eng; @@ -3061,14 +3412,36 @@ void tst_QScriptEngine::abortEvaluation() QVERIFY(ret.isString()); QCOMPARE(ret.toString(), QString::fromLatin1("ciao")); } +} + +void tst_QScriptEngine::abortEvaluation_data() +{ + QTest::addColumn<QString>("script"); + + QTest::newRow("while (1)") + << QString::fromLatin1("while (1) { }"); + QTest::newRow("while (1) i++") + << QString::fromLatin1("i = 0; while (1) { i++; }"); + QTest::newRow("try catch") + << QString::fromLatin1("try {" + " while (1) { }" + "} catch(e) {" + " throw new Error('Caught');" + "}"); +} +void tst_QScriptEngine::abortEvaluation() +{ + QFETCH(QString, script); + + QScriptEngine eng; EventReceiver3 receiver(&eng); eng.setProcessEventsInterval(100); for (int x = 0; x < 4; ++x) { QCoreApplication::postEvent(&receiver, new QEvent(QEvent::Type(QEvent::User+1))); receiver.resultType = EventReceiver3::AbortionResult(x); - QScriptValue ret = eng.evaluate(QString::fromLatin1("while (1) { }")); + QScriptValue ret = eng.evaluate(script); switch (receiver.resultType) { case EventReceiver3::None: QVERIFY(!eng.hasUncaughtException()); @@ -3092,6 +3465,13 @@ void tst_QScriptEngine::abortEvaluation() } } +} + +void tst_QScriptEngine::abortEvaluation_tryCatch() +{ + QScriptEngine eng; + EventReceiver3 receiver(&eng); + eng.setProcessEventsInterval(100); // scripts cannot intercept the abortion with try/catch for (int y = 0; y < 4; ++y) { QCoreApplication::postEvent(&receiver, new QEvent(QEvent::Type(QEvent::User+1))); @@ -3125,13 +3505,15 @@ void tst_QScriptEngine::abortEvaluation() break; } } +} - { - QScriptValue fun = eng.newFunction(myFunctionAbortingEvaluation); - eng.globalObject().setProperty("myFunctionAbortingEvaluation", fun); - QScriptValue ret = eng.evaluate("myFunctionAbortingEvaluation()"); - QVERIFY(!ret.isValid()); - } +void tst_QScriptEngine::abortEvaluation_fromNative() +{ + QScriptEngine eng; + QScriptValue fun = eng.newFunction(myFunctionAbortingEvaluation); + eng.globalObject().setProperty("myFunctionAbortingEvaluation", fun); + QScriptValue ret = eng.evaluate("myFunctionAbortingEvaluation()"); + QVERIFY(!ret.isValid()); } class ThreadedEngine : public QThread { @@ -3198,7 +3580,7 @@ public: bool wasEvaluating; }; -void tst_QScriptEngine::isEvaluating() +void tst_QScriptEngine::isEvaluating_notEvaluating() { QScriptEngine eng; @@ -3210,30 +3592,34 @@ void tst_QScriptEngine::isEvaluating() QVERIFY(!eng.isEvaluating()); eng.evaluate("0 = 0"); QVERIFY(!eng.isEvaluating()); +} - { - QScriptValue fun = eng.newFunction(myFunctionReturningIsEvaluating); - eng.globalObject().setProperty("myFunctionReturningIsEvaluating", fun); - QScriptValue ret = eng.evaluate("myFunctionReturningIsEvaluating()"); - QVERIFY(ret.isBoolean()); - QVERIFY(ret.toBoolean()); - } +void tst_QScriptEngine::isEvaluating_fromNative() +{ + QScriptEngine eng; + QScriptValue fun = eng.newFunction(myFunctionReturningIsEvaluating); + eng.globalObject().setProperty("myFunctionReturningIsEvaluating", fun); + QScriptValue ret = eng.evaluate("myFunctionReturningIsEvaluating()"); + QVERIFY(ret.isBoolean()); + QVERIFY(ret.toBoolean()); +} - { - EventReceiver4 receiver(&eng); - QCoreApplication::postEvent(&receiver, new QEvent(QEvent::Type(QEvent::User+1))); +void tst_QScriptEngine::isEvaluating_fromEvent() +{ + QScriptEngine eng; + EventReceiver4 receiver(&eng); + QCoreApplication::postEvent(&receiver, new QEvent(QEvent::Type(QEvent::User+1))); - QString script = QString::fromLatin1( - "var end = Number(new Date()) + 1000;" - "var x = 0;" - "while (Number(new Date()) < end) {" - " ++x;" - "}"); + QString script = QString::fromLatin1( + "var end = Number(new Date()) + 1000;" + "var x = 0;" + "while (Number(new Date()) < end) {" + " ++x;" + "}"); - eng.setProcessEventsInterval(100); - eng.evaluate(script); - QVERIFY(receiver.wasEvaluating); - } + eng.setProcessEventsInterval(100); + eng.evaluate(script); + QVERIFY(receiver.wasEvaluating); } static QtMsgType theMessageType; @@ -3247,24 +3633,33 @@ static void myMsgHandler(QtMsgType type, const char *msg) void tst_QScriptEngine::printFunctionWithCustomHandler() { + // The built-in print() function passes the output to Qt's message + // handler. By installing a custom message handler, the output can be + // redirected without changing the print() function itself. + // This behavior is not documented. QScriptEngine eng; QtMsgHandler oldHandler = qInstallMsgHandler(myMsgHandler); QVERIFY(eng.globalObject().property("print").isFunction()); + theMessageType = QtSystemMsg; QVERIFY(theMessage.isEmpty()); QVERIFY(eng.evaluate("print('test')").isUndefined()); QCOMPARE(theMessageType, QtDebugMsg); QCOMPARE(theMessage, QString::fromLatin1("test")); + theMessageType = QtSystemMsg; theMessage.clear(); QVERIFY(eng.evaluate("print(3, true, 'little pigs')").isUndefined()); QCOMPARE(theMessageType, QtDebugMsg); QCOMPARE(theMessage, QString::fromLatin1("3 true little pigs")); + qInstallMsgHandler(oldHandler); } void tst_QScriptEngine::printThrowsException() { + // If an argument to print() causes an exception to be thrown when + // it's converted to a string, print() should propagate the exception. QScriptEngine eng; QScriptValue ret = eng.evaluate("print({ toString: function() { throw 'foo'; } });"); QVERIFY(eng.hasUncaughtException()); @@ -3297,34 +3692,30 @@ void tst_QScriptEngine::errorConstructors() } } -static QScriptValue argumentsProperty_fun(QScriptContext *, QScriptEngine *eng) +void tst_QScriptEngine::argumentsProperty_globalContext() { - eng->evaluate("var a = arguments[0];"); - eng->evaluate("arguments[0] = 200;"); - return eng->evaluate("a + arguments[0]"); + QScriptEngine eng; + { + // Unlike function calls, the global context doesn't have an + // arguments property. + QScriptValue ret = eng.evaluate("arguments"); + QVERIFY(ret.isError()); + QVERIFY(ret.toString().contains(QString::fromLatin1("ReferenceError"))); + } + eng.evaluate("arguments = 10"); + { + QScriptValue ret = eng.evaluate("arguments"); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 10); + } + QVERIFY(eng.evaluate("delete arguments").toBoolean()); + QVERIFY(!eng.globalObject().property("arguments").isValid()); } - -void tst_QScriptEngine::argumentsProperty() +void tst_QScriptEngine::argumentsProperty_JS() { { QScriptEngine eng; - { - QScriptValue ret = eng.evaluate("arguments"); - QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("ReferenceError: Can't find variable: arguments")); - } - eng.evaluate("arguments = 10"); - { - QScriptValue ret = eng.evaluate("arguments"); - QVERIFY(ret.isNumber()); - QCOMPARE(ret.toInt32(), 10); - } - QVERIFY(eng.evaluate("delete arguments").toBoolean()); - QVERIFY(!eng.globalObject().property("arguments").isValid()); - } - { - QScriptEngine eng; eng.evaluate("o = { arguments: 123 }"); QScriptValue ret = eng.evaluate("with (o) { arguments; }"); QVERIFY(ret.isNumber()); @@ -3333,24 +3724,39 @@ void tst_QScriptEngine::argumentsProperty() { QScriptEngine eng; QVERIFY(!eng.globalObject().property("arguments").isValid()); + // This is testing ECMA-262 compliance. In function calls, "arguments" + // appears like a local variable, and it can be replaced. QScriptValue ret = eng.evaluate("(function() { arguments = 456; return arguments; })()"); QVERIFY(ret.isNumber()); QCOMPARE(ret.toInt32(), 456); QVERIFY(!eng.globalObject().property("arguments").isValid()); } +} - { - QScriptEngine eng; - QScriptValue fun = eng.newFunction(argumentsProperty_fun); - eng.globalObject().setProperty("fun", eng.newFunction(argumentsProperty_fun)); - QScriptValue result = eng.evaluate("fun(18)"); - QVERIFY(result.isNumber()); - QCOMPARE(result.toInt32(), 218); - } +static QScriptValue argumentsProperty_fun(QScriptContext *, QScriptEngine *eng) +{ + // Since evaluate() is done in the current context, "arguments" should + // refer to currentContext()->argumentsObject(). + // This is for consistency with the built-in JS eval() function. + eng->evaluate("var a = arguments[0];"); + eng->evaluate("arguments[0] = 200;"); + return eng->evaluate("a + arguments[0]"); +} + +void tst_QScriptEngine::argumentsProperty_evaluateInNativeFunction() +{ + QScriptEngine eng; + QScriptValue fun = eng.newFunction(argumentsProperty_fun); + eng.globalObject().setProperty("fun", eng.newFunction(argumentsProperty_fun)); + QScriptValue result = eng.evaluate("fun(18)"); + QVERIFY(result.isNumber()); + QCOMPARE(result.toInt32(), 200+18); } -void tst_QScriptEngine::numberClass() +void tst_QScriptEngine::jsNumberClass() { + // See ECMA-262 Section 15.7, "Number Objects". + QScriptEngine eng; QScriptValue ctor = eng.globalObject().property("Number"); @@ -3460,7 +3866,7 @@ void tst_QScriptEngine::numberClass() } } -void tst_QScriptEngine::forInStatement() +void tst_QScriptEngine::jsForInStatement_simple() { QScriptEngine eng; { @@ -3483,8 +3889,11 @@ void tst_QScriptEngine::forInStatement() QCOMPARE(lst.at(0), QString::fromLatin1("p")); QCOMPARE(lst.at(1), QString::fromLatin1("q")); } +} - // properties in prototype +void tst_QScriptEngine::jsForInStatement_prototypeProperties() +{ + QScriptEngine eng; { QScriptValue ret = eng.evaluate("o = { }; o.__proto__ = { p: 123 }; r = [];" "for (var p in o) r[r.length] = p; r"); @@ -3509,6 +3918,11 @@ void tst_QScriptEngine::forInStatement() QCOMPARE(lst.at(0), QString::fromLatin1("p")); } +} + +void tst_QScriptEngine::jsForInStatement_mutateWhileIterating() +{ + QScriptEngine eng; // deleting property during enumeration { QScriptValue ret = eng.evaluate("o = { p: 123 }; r = [];" @@ -3534,7 +3948,11 @@ void tst_QScriptEngine::forInStatement() QCOMPARE(lst.at(0), QString::fromLatin1("p")); } - // arrays +} + +void tst_QScriptEngine::jsForInStatement_arrays() +{ + QScriptEngine eng; { QScriptValue ret = eng.evaluate("a = [123, 456]; r = [];" "for (var p in a) r[r.length] = p; r"); @@ -3565,10 +3983,11 @@ void tst_QScriptEngine::forInStatement() QCOMPARE(lst.at(3), QString::fromLatin1("2")); QCOMPARE(lst.at(4), QString::fromLatin1("bar")); } +} - // null and undefined - // according to the spec, we should throw an exception; however, for - // compability with the real world, we don't +void tst_QScriptEngine::jsForInStatement_nullAndUndefined() +{ + QScriptEngine eng; { QScriptValue ret = eng.evaluate("r = true; for (var p in undefined) r = false; r"); QVERIFY(ret.isBool()); @@ -3581,9 +4000,17 @@ void tst_QScriptEngine::forInStatement() } } -void tst_QScriptEngine::functionExpression() +void tst_QScriptEngine::jsFunctionDeclarationAsStatement() { - // task 175679 + // ECMA-262 does not allow function declarations to be used as statements, + // but several popular implementations (including JSC) do. See the NOTE + // at the beginning of chapter 12 in ECMA-262 5th edition, where it's + // recommended that implementations either disallow this usage or issue + // a warning. + // Since we had a bug report long ago about QtScript not supporting this + // "feature" (and thus deviating from other implementations), we still + // check this behavior. + QScriptEngine eng; QVERIFY(!eng.globalObject().property("bar").isValid()); eng.evaluate("function foo(arg) {\n" @@ -3616,6 +4043,8 @@ void tst_QScriptEngine::functionExpression() void tst_QScriptEngine::stringObjects() { + // See ECMA-262 Section 15.5, "String Objects". + QScriptEngine eng; QString str("ciao"); // in C++ @@ -3677,7 +4106,11 @@ void tst_QScriptEngine::stringObjects() QVERIFY(ret7.isBoolean()); QVERIFY(ret7.toBoolean()); } +} +void tst_QScriptEngine::jsStringPrototypeReplaceBugs() +{ + QScriptEngine eng; // task 212440 { QScriptValue ret = eng.evaluate("replace_args = []; \"a a a\".replace(/(a)/g, function() { replace_args.push(arguments); }); replace_args"); @@ -3702,9 +4135,8 @@ void tst_QScriptEngine::stringObjects() } } -void tst_QScriptEngine::getterSetterThisObject() +void tst_QScriptEngine::getterSetterThisObject_global() { - // Global Object { QScriptEngine eng; // read @@ -3762,8 +4194,10 @@ void tst_QScriptEngine::getterSetterThisObject() QCOMPARE(ret.toString(), QString::fromLatin1("foo")); } } +} - // other object +void tst_QScriptEngine::getterSetterThisObject_plain() +{ { QScriptEngine eng; eng.evaluate("o = {}"); @@ -3780,8 +4214,10 @@ void tst_QScriptEngine::getterSetterThisObject() QVERIFY(eng.evaluate("with (o) x = 'foo'").equals("foo")); QVERIFY(eng.evaluate("with (o) with (q) x = 'foo'").equals("foo")); } +} - // getter+setter in prototype chain +void tst_QScriptEngine::getterSetterThisObject_prototypeChain() +{ { QScriptEngine eng; eng.evaluate("o = {}; p = {}; o.__proto__ = p"); @@ -3799,8 +4235,10 @@ void tst_QScriptEngine::getterSetterThisObject() QVERIFY(eng.evaluate("with (o) x = 'foo'").equals("foo")); QVERIFY(eng.evaluate("with (o) with (q) x = 'foo'").equals("foo")); } +} - // getter+setter in activation +void tst_QScriptEngine::getterSetterThisObject_activation() +{ { QScriptEngine eng; QScriptContext *ctx = eng.pushContext(); @@ -3810,7 +4248,8 @@ void tst_QScriptEngine::getterSetterThisObject() // read eng.evaluate("act.__defineGetter__('x', function() { return this; })"); QVERIFY(eng.evaluate("x === act").toBoolean()); - QEXPECT_FAIL("", "Exotic overload (don't care for now)", Continue); + QEXPECT_FAIL("", "QTBUG-17605: Not possible to implement local variables as getter/setter properties", Abort); + QVERIFY(!eng.hasUncaughtException()); QVERIFY(eng.evaluate("with (act) x").equals("foo")); QVERIFY(eng.evaluate("(function() { with (act) return x; })() === act").toBoolean()); eng.evaluate("q = {}; with (act) with (q) x").equals(eng.evaluate("act")); @@ -3824,8 +4263,10 @@ void tst_QScriptEngine::getterSetterThisObject() } } -void tst_QScriptEngine::continueInSwitch() +void tst_QScriptEngine::jsContinueInSwitch() { + // This is testing ECMA-262 compliance, not C++ API. + QScriptEngine eng; // switch - continue { @@ -3902,35 +4343,17 @@ void tst_QScriptEngine::continueInSwitch() } } -void tst_QScriptEngine::readOnlyPrototypeProperty() +void tst_QScriptEngine::jsShadowReadOnlyPrototypeProperty() { - QSKIP("JSC semantics differ from old back-end and SpiderMonkey", SkipAll); + // SpiderMonkey has different behavior than JSC and V8; it disallows + // creating a property on the instance if there's a property with the + // same name in the prototype, and that property is read-only. We + // adopted that behavior in the old (4.5) QtScript back-end, but it + // just seems weird -- and non-compliant. Adopt the JSC behavior instead. QScriptEngine eng; - QCOMPARE(eng.evaluate("o = {}; o.__proto__ = parseInt; o.length").toInt32(), 2); - QCOMPARE(eng.evaluate("o.length = 4; o.length").toInt32(), 2); - QVERIFY(!eng.evaluate("o.hasOwnProperty('length')").toBoolean()); - QCOMPARE(eng.evaluate("o.length *= 2; o.length").toInt32(), 2); - QCOMPARE(eng.evaluate("o.length /= 2; o.length").toInt32(), 2); - QCOMPARE(eng.evaluate("o.length %= 2; o.length").toInt32(), 2); - QCOMPARE(eng.evaluate("o.length += 2; o.length").toInt32(), 2); - QCOMPARE(eng.evaluate("o.length -= 2; o.length").toInt32(), 2); - QCOMPARE(eng.evaluate("o.length <<= 2; o.length").toInt32(), 2); - QCOMPARE(eng.evaluate("o.length >>= 2; o.length").toInt32(), 2); - QCOMPARE(eng.evaluate("o.length >>>= 2; o.length").toInt32(), 2); - QCOMPARE(eng.evaluate("o.length &= 0; o.length").toInt32(), 2); - QCOMPARE(eng.evaluate("o.length ^= 255; o.length").toInt32(), 2); - QCOMPARE(eng.evaluate("o.length |= 255; o.length").toInt32(), 2); - - { - QScriptValue ret = eng.evaluate("o.__defineGetter__('length', function() {})"); - QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("Error: cannot redefine read-only property")); - } - { - QScriptValue ret = eng.evaluate("o.__defineSetter__('length', function() {})"); - QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("Error: cannot redefine read-only property")); - } + QVERIFY(eng.evaluate("o = {}; o.__proto__ = parseInt; o.length").isNumber()); + QCOMPARE(eng.evaluate("o.length = 123; o.length").toInt32(), 123); + QVERIFY(eng.evaluate("o.hasOwnProperty('length')").toBoolean()); } void tst_QScriptEngine::toObject() @@ -4012,7 +4435,7 @@ void tst_QScriptEngine::toObject() QVERIFY(stringValue.isString()); } -void tst_QScriptEngine::reservedWords_data() +void tst_QScriptEngine::jsReservedWords_data() { QTest::addColumn<QString>("word"); QTest::newRow("break") << QString("break"); @@ -4045,8 +4468,13 @@ void tst_QScriptEngine::reservedWords_data() QTest::newRow("with") << QString("with"); } -void tst_QScriptEngine::reservedWords() +void tst_QScriptEngine::jsReservedWords() { + // See ECMA-262 Section 7.6.1, "Reserved Words". + // We prefer that the implementation is less strict than the spec; e.g. + // it's good to allow reserved words as identifiers in object literals, + // and when accessing properties using dot notation. + QFETCH(QString, word); { QScriptEngine eng; @@ -4084,7 +4512,7 @@ void tst_QScriptEngine::reservedWords() } } -void tst_QScriptEngine::futureReservedWords_data() +void tst_QScriptEngine::jsFutureReservedWords_data() { QTest::addColumn<QString>("word"); QTest::addColumn<bool>("allowed"); @@ -4121,8 +4549,12 @@ void tst_QScriptEngine::futureReservedWords_data() QTest::newRow("volatile") << QString("volatile") << true; } -void tst_QScriptEngine::futureReservedWords() +void tst_QScriptEngine::jsFutureReservedWords() { + // See ECMA-262 Section 7.6.1.2, "Future Reserved Words". + // In real-world implementations, most of these words are + // actually allowed as normal identifiers. + QFETCH(QString, word); QFETCH(bool, allowed); { @@ -4150,8 +4582,10 @@ void tst_QScriptEngine::futureReservedWords() } } -void tst_QScriptEngine::throwInsideWithStatement() +void tst_QScriptEngine::jsThrowInsideWithStatement() { + // This is testing ECMA-262 compliance, not C++ API. + // task 209988 QScriptEngine eng; { @@ -4165,7 +4599,7 @@ void tst_QScriptEngine::throwInsideWithStatement() " bad;" "}"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("ReferenceError: Can't find variable: bad")); + QVERIFY(ret.toString().contains(QString::fromLatin1("ReferenceError"))); } { QScriptValue ret = eng.evaluate( @@ -4178,7 +4612,7 @@ void tst_QScriptEngine::throwInsideWithStatement() " bad;" "}"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("ReferenceError: Can't find variable: bad")); + QVERIFY(ret.toString().contains(QString::fromLatin1("ReferenceError"))); } { eng.clearExceptions(); @@ -4205,7 +4639,7 @@ void tst_QScriptEngine::throwInsideWithStatement() QVERIFY(ret.isNumber()); QScriptValue ret2 = eng.evaluate("bug"); QVERIFY(ret2.isError()); - QCOMPARE(ret2.toString(), QString::fromLatin1("ReferenceError: Can't find variable: bug")); + QVERIFY(ret2.toString().contains(QString::fromLatin1("ReferenceError"))); } } @@ -4215,106 +4649,116 @@ public: TestAgent(QScriptEngine *engine) : QScriptEngineAgent(engine) {} }; -void tst_QScriptEngine::getSetAgent() +void tst_QScriptEngine::getSetAgent_ownership() { - // case 1: engine deleted before agent --> agent deleted too - { - QScriptEngine *eng = new QScriptEngine; - QCOMPARE(eng->agent(), (QScriptEngineAgent*)0); - TestAgent *agent = new TestAgent(eng); - eng->setAgent(agent); - QCOMPARE(eng->agent(), (QScriptEngineAgent*)agent); - eng->setAgent(0); // the engine maintains ownership of the old agent - QCOMPARE(eng->agent(), (QScriptEngineAgent*)0); - delete eng; - } - // case 2: agent deleted before engine --> engine's agent should become 0 - { - QScriptEngine *eng = new QScriptEngine; - TestAgent *agent = new TestAgent(eng); - eng->setAgent(agent); - QCOMPARE(eng->agent(), (QScriptEngineAgent*)agent); - delete agent; - QCOMPARE(eng->agent(), (QScriptEngineAgent*)0); - eng->evaluate("(function(){ return 123; })()"); - delete eng; - } - { - QScriptEngine eng; - QScriptEngine eng2; - TestAgent *agent = new TestAgent(&eng); - QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::setAgent(): cannot set agent belonging to different engine"); - eng2.setAgent(agent); - QCOMPARE(eng2.agent(), (QScriptEngineAgent*)0); - } + // engine deleted before agent --> agent deleted too + QScriptEngine *eng = new QScriptEngine; + QCOMPARE(eng->agent(), (QScriptEngineAgent*)0); + TestAgent *agent = new TestAgent(eng); + eng->setAgent(agent); + QCOMPARE(eng->agent(), (QScriptEngineAgent*)agent); + eng->setAgent(0); // the engine maintains ownership of the old agent + QCOMPARE(eng->agent(), (QScriptEngineAgent*)0); + delete eng; } -void tst_QScriptEngine::reentrancy() +void tst_QScriptEngine::getSetAgent_deleteAgent() { - { - QScriptEngine eng1; - QScriptEngine eng2; - QScriptString s1 = eng1.toStringHandle("foo"); - QScriptString s2 = eng2.toStringHandle("foo"); - QVERIFY(s1 != s2); - } - { - QScriptEngine eng1; - QScriptEngine eng2; - eng1.setProcessEventsInterval(123); - QCOMPARE(eng2.processEventsInterval(), -1); - eng2.setProcessEventsInterval(456); - QCOMPARE(eng1.processEventsInterval(), 123); + // agent deleted before engine --> engine's agent should become 0 + QScriptEngine *eng = new QScriptEngine; + TestAgent *agent = new TestAgent(eng); + eng->setAgent(agent); + QCOMPARE(eng->agent(), (QScriptEngineAgent*)agent); + delete agent; + QCOMPARE(eng->agent(), (QScriptEngineAgent*)0); + eng->evaluate("(function(){ return 123; })()"); + delete eng; +} + +void tst_QScriptEngine::getSetAgent_differentEngine() +{ + QScriptEngine eng; + QScriptEngine eng2; + TestAgent *agent = new TestAgent(&eng); + QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::setAgent(): cannot set agent belonging to different engine"); + eng2.setAgent(agent); + QCOMPARE(eng2.agent(), (QScriptEngineAgent*)0); +} + +void tst_QScriptEngine::reentrancy_stringHandles() +{ + QScriptEngine eng1; + QScriptEngine eng2; + QScriptString s1 = eng1.toStringHandle("foo"); + QScriptString s2 = eng2.toStringHandle("foo"); + QVERIFY(s1 != s2); +} + +void tst_QScriptEngine::reentrancy_processEventsInterval() +{ + QScriptEngine eng1; + QScriptEngine eng2; + eng1.setProcessEventsInterval(123); + QCOMPARE(eng2.processEventsInterval(), -1); + eng2.setProcessEventsInterval(456); + QCOMPARE(eng1.processEventsInterval(), 123); +} + +void tst_QScriptEngine::reentrancy_typeConversion() +{ + QScriptEngine eng1; + QScriptEngine eng2; + qScriptRegisterMetaType<Foo>(&eng1, fooToScriptValue, fooFromScriptValue); + Foo foo; + foo.x = 12; + foo.y = 34; + { + QScriptValue fooVal = qScriptValueFromValue(&eng1, foo); + QVERIFY(fooVal.isObject()); + QVERIFY(!fooVal.isVariant()); + QCOMPARE(fooVal.property("x").toInt32(), 12); + QCOMPARE(fooVal.property("y").toInt32(), 34); + fooVal.setProperty("x", 56); + fooVal.setProperty("y", 78); + + Foo foo2 = qScriptValueToValue<Foo>(fooVal); + QCOMPARE(foo2.x, 56); + QCOMPARE(foo2.y, 78); } { - QScriptEngine eng1; - QScriptEngine eng2; - qScriptRegisterMetaType<Foo>(&eng1, fooToScriptValue, fooFromScriptValue); - Foo foo; - foo.x = 12; - foo.y = 34; - { - QScriptValue fooVal = qScriptValueFromValue(&eng1, foo); - QVERIFY(fooVal.isObject()); - QVERIFY(!fooVal.isVariant()); - QCOMPARE(fooVal.property("x").toInt32(), 12); - QCOMPARE(fooVal.property("y").toInt32(), 34); - fooVal.setProperty("x", 56); - fooVal.setProperty("y", 78); - - Foo foo2 = qScriptValueToValue<Foo>(fooVal); - QCOMPARE(foo2.x, 56); - QCOMPARE(foo2.y, 78); - } - { - QScriptValue fooVal = qScriptValueFromValue(&eng2, foo); - QVERIFY(fooVal.isVariant()); + QScriptValue fooVal = qScriptValueFromValue(&eng2, foo); + QVERIFY(fooVal.isVariant()); - Foo foo2 = qScriptValueToValue<Foo>(fooVal); - QCOMPARE(foo2.x, 12); - QCOMPARE(foo2.y, 34); - } - QVERIFY(!eng1.defaultPrototype(qMetaTypeId<Foo>()).isValid()); - QVERIFY(!eng2.defaultPrototype(qMetaTypeId<Foo>()).isValid()); - QScriptValue proto1 = eng1.newObject(); - eng1.setDefaultPrototype(qMetaTypeId<Foo>(), proto1); - QVERIFY(!eng2.defaultPrototype(qMetaTypeId<Foo>()).isValid()); - QScriptValue proto2 = eng2.newObject(); - eng2.setDefaultPrototype(qMetaTypeId<Foo>(), proto2); - QVERIFY(eng2.defaultPrototype(qMetaTypeId<Foo>()).isValid()); - QVERIFY(eng1.defaultPrototype(qMetaTypeId<Foo>()).strictlyEquals(proto1)); - } - { - QScriptEngine eng1; - QScriptEngine eng2; - QVERIFY(!eng2.globalObject().property("a").isValid()); - eng1.evaluate("a = 10"); - QVERIFY(eng1.globalObject().property("a").isNumber()); - QVERIFY(!eng2.globalObject().property("a").isValid()); - eng2.evaluate("a = 20"); - QVERIFY(eng2.globalObject().property("a").isNumber()); - QCOMPARE(eng1.globalObject().property("a").toInt32(), 10); - } + Foo foo2 = qScriptValueToValue<Foo>(fooVal); + QCOMPARE(foo2.x, 12); + QCOMPARE(foo2.y, 34); + } + QVERIFY(!eng1.defaultPrototype(qMetaTypeId<Foo>()).isValid()); + QVERIFY(!eng2.defaultPrototype(qMetaTypeId<Foo>()).isValid()); + QScriptValue proto1 = eng1.newObject(); + eng1.setDefaultPrototype(qMetaTypeId<Foo>(), proto1); + QVERIFY(!eng2.defaultPrototype(qMetaTypeId<Foo>()).isValid()); + QScriptValue proto2 = eng2.newObject(); + eng2.setDefaultPrototype(qMetaTypeId<Foo>(), proto2); + QVERIFY(eng2.defaultPrototype(qMetaTypeId<Foo>()).isValid()); + QVERIFY(eng1.defaultPrototype(qMetaTypeId<Foo>()).strictlyEquals(proto1)); +} + +void tst_QScriptEngine::reentrancy_globalObjectProperties() +{ + QScriptEngine eng1; + QScriptEngine eng2; + QVERIFY(!eng2.globalObject().property("a").isValid()); + eng1.evaluate("a = 10"); + QVERIFY(eng1.globalObject().property("a").isNumber()); + QVERIFY(!eng2.globalObject().property("a").isValid()); + eng2.evaluate("a = 20"); + QVERIFY(eng2.globalObject().property("a").isNumber()); + QCOMPARE(eng1.globalObject().property("a").toInt32(), 10); +} + +void tst_QScriptEngine::reentrancy_Array() +{ // weird bug with JSC backend { QScriptEngine eng; @@ -4326,79 +4770,82 @@ void tst_QScriptEngine::reentrancy() QScriptEngine eng; QCOMPARE(eng.evaluate("Array()").toString(), QString()); } +} +void tst_QScriptEngine::reentrancy_objectCreation() +{ + QScriptEngine eng1; + QScriptEngine eng2; { - QScriptEngine eng1; - QScriptEngine eng2; - { - QScriptValue d1 = eng1.newDate(0); - QScriptValue d2 = eng2.newDate(0); - QCOMPARE(d1.toDateTime(), d2.toDateTime()); - QCOMPARE(d2.toDateTime(), d1.toDateTime()); - } - { - QScriptValue r1 = eng1.newRegExp("foo", "gim"); - QScriptValue r2 = eng2.newRegExp("foo", "gim"); - QCOMPARE(r1.toRegExp(), r2.toRegExp()); - QCOMPARE(r2.toRegExp(), r1.toRegExp()); - } - { - QScriptValue o1 = eng1.newQObject(this); - QScriptValue o2 = eng2.newQObject(this); - QCOMPARE(o1.toQObject(), o2.toQObject()); - QCOMPARE(o2.toQObject(), o1.toQObject()); - } - { - QScriptValue mo1 = eng1.newQMetaObject(&staticMetaObject); - QScriptValue mo2 = eng2.newQMetaObject(&staticMetaObject); - QCOMPARE(mo1.toQMetaObject(), mo2.toQMetaObject()); - QCOMPARE(mo2.toQMetaObject(), mo1.toQMetaObject()); - } + QScriptValue d1 = eng1.newDate(0); + QScriptValue d2 = eng2.newDate(0); + QCOMPARE(d1.toDateTime(), d2.toDateTime()); + QCOMPARE(d2.toDateTime(), d1.toDateTime()); + } + { + QScriptValue r1 = eng1.newRegExp("foo", "gim"); + QScriptValue r2 = eng2.newRegExp("foo", "gim"); + QCOMPARE(r1.toRegExp(), r2.toRegExp()); + QCOMPARE(r2.toRegExp(), r1.toRegExp()); + } + { + QScriptValue o1 = eng1.newQObject(this); + QScriptValue o2 = eng2.newQObject(this); + QCOMPARE(o1.toQObject(), o2.toQObject()); + QCOMPARE(o2.toQObject(), o1.toQObject()); + } + { + QScriptValue mo1 = eng1.newQMetaObject(&staticMetaObject); + QScriptValue mo2 = eng2.newQMetaObject(&staticMetaObject); + QCOMPARE(mo1.toQMetaObject(), mo2.toQMetaObject()); + QCOMPARE(mo2.toQMetaObject(), mo1.toQMetaObject()); } } -void tst_QScriptEngine:: incDecNonObjectProperty() +void tst_QScriptEngine::jsIncDecNonObjectProperty() { + // This is testing ECMA-262 compliance, not C++ API. + QScriptEngine eng; { QScriptValue ret = eng.evaluate("var a; a.n++"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'a' [undefined] is not an object.")); + QVERIFY(ret.toString().contains(QString::fromLatin1("TypeError"))); } { QScriptValue ret = eng.evaluate("var a; a.n--"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'a' [undefined] is not an object.")); + QVERIFY(ret.toString().contains(QString::fromLatin1("TypeError"))); } { QScriptValue ret = eng.evaluate("var a = null; a.n++"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'a' [null] is not an object.")); + QVERIFY(ret.toString().contains(QString::fromLatin1("TypeError"))); } { QScriptValue ret = eng.evaluate("var a = null; a.n--"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'a' [null] is not an object.")); + QVERIFY(ret.toString().contains(QString::fromLatin1("TypeError"))); } { QScriptValue ret = eng.evaluate("var a; ++a.n"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'a' [null] is not an object.")); + QVERIFY(ret.toString().contains(QString::fromLatin1("TypeError"))); } { QScriptValue ret = eng.evaluate("var a; --a.n"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'a' [null] is not an object.")); + QVERIFY(ret.toString().contains(QString::fromLatin1("TypeError"))); } { QScriptValue ret = eng.evaluate("var a; a.n += 1"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'a' [null] is not an object.")); + QVERIFY(ret.toString().contains(QString::fromLatin1("TypeError"))); } { QScriptValue ret = eng.evaluate("var a; a.n -= 1"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'a' [null] is not an object.")); + QVERIFY(ret.toString().contains(QString::fromLatin1("TypeError"))); } { QScriptValue ret = eng.evaluate("var a = 'ciao'; a.length++"); @@ -4494,6 +4941,17 @@ void tst_QScriptEngine::installTranslatorFunctions() QVERIFY(ret.isString()); QCOMPARE(ret.toString(), QString::fromLatin1("foobar")); } + { + QScriptValue ret = eng.evaluate("'foo%0'.arg(123)"); + QVERIFY(ret.isString()); + QCOMPARE(ret.toString(), QString::fromLatin1("foo123")); + } + { + // Maybe this should throw an error? + QScriptValue ret = eng.evaluate("'foo%0'.arg()"); + QVERIFY(ret.isString()); + QCOMPARE(ret.toString(), QString()); + } { QScriptValue ret = eng.evaluate("qsTrId('foo')"); @@ -4505,75 +4963,137 @@ void tst_QScriptEngine::installTranslatorFunctions() QVERIFY(ret.isString()); QCOMPARE(ret.toString(), QString::fromLatin1("foo")); } + QVERIFY(eng.evaluate("QT_TRID_NOOP()").isUndefined()); } -static QScriptValue callQsTr(QScriptContext *ctx, QScriptEngine *eng) +class TranslationScope { - return eng->globalObject().property("qsTr").call(ctx->thisObject(), ctx->argumentsObject()); -} - -void tst_QScriptEngine::translateScript() -{ - QScriptEngine engine; +public: + TranslationScope(const QString &fileName) + { + translator.load(fileName); + QCoreApplication::instance()->installTranslator(&translator); + } + ~TranslationScope() + { + QCoreApplication::instance()->removeTranslator(&translator); + } +private: QTranslator translator; - translator.load(":/translations/translatable_la"); - QCoreApplication::instance()->installTranslator(&translator); - engine.installTranslatorFunctions(); +}; + +void tst_QScriptEngine::translateScript_data() +{ + QTest::addColumn<QString>("expression"); + QTest::addColumn<QString>("fileName"); + QTest::addColumn<QString>("expectedTranslation"); QString fileName = QString::fromLatin1("translatable.js"); // Top-level - QCOMPARE(engine.evaluate("qsTr('One')", fileName).toString(), QString::fromLatin1("En")); - QCOMPARE(engine.evaluate("qsTr('Hello')", fileName).toString(), QString::fromLatin1("Hallo")); + QTest::newRow("qsTr('One')@translatable.js") + << QString::fromLatin1("qsTr('One')") << fileName << QString::fromLatin1("En"); + QTest::newRow("qsTr('Hello')@translatable.js") + << QString::fromLatin1("qsTr('Hello')") << fileName << QString::fromLatin1("Hallo"); // From function - QCOMPARE(engine.evaluate("(function() { return qsTr('One'); })()", fileName).toString(), QString::fromLatin1("En")); - QCOMPARE(engine.evaluate("(function() { return qsTr('Hello'); })()", fileName).toString(), QString::fromLatin1("Hallo")); + QTest::newRow("(function() { return qsTr('One'); })()@translatable.js") + << QString::fromLatin1("(function() { return qsTr('One'); })()") << fileName << QString::fromLatin1("En"); + QTest::newRow("(function() { return qsTr('Hello'); })()@translatable.js") + << QString::fromLatin1("(function() { return qsTr('Hello'); })()") << fileName << QString::fromLatin1("Hallo"); // From eval - QCOMPARE(engine.evaluate("eval('qsTr(\\'One\\')')", fileName).toString(), QString::fromLatin1("En")); - QCOMPARE(engine.evaluate("eval('qsTr(\\'Hello\\')')", fileName).toString(), QString::fromLatin1("Hallo")); + QTest::newRow("eval('qsTr(\\'One\\')')@translatable.js") + << QString::fromLatin1("eval('qsTr(\\'One\\')')") << fileName << QString::fromLatin1("En"); + QTest::newRow("eval('qsTr(\\'Hello\\')')@translatable.js") + << QString::fromLatin1("eval('qsTr(\\'Hello\\')')") << fileName << QString::fromLatin1("Hallo"); + // Plural + QTest::newRow("qsTr('%n message(s) saved', '', 1)@translatable.js") + << QString::fromLatin1("qsTr('%n message(s) saved', '', 1)") << fileName << QString::fromLatin1("1 melding lagret"); + QTest::newRow("qsTr('%n message(s) saved', '', 3).arg@translatable.js") + << QString::fromLatin1("qsTr('%n message(s) saved', '', 3)") << fileName << QString::fromLatin1("3 meldinger lagret"); - QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Two')", fileName).toString(), QString::fromLatin1("To")); - QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Goodbye')", fileName).toString(), QString::fromLatin1("Farvel")); + // Top-level + QTest::newRow("qsTranslate('FooContext', 'Two')@translatable.js") + << QString::fromLatin1("qsTranslate('FooContext', 'Two')") << fileName << QString::fromLatin1("To"); + QTest::newRow("qsTranslate('FooContext', 'Goodbye')@translatable.js") + << QString::fromLatin1("qsTranslate('FooContext', 'Goodbye')") << fileName << QString::fromLatin1("Farvel"); // From eval - QCOMPARE(engine.evaluate("eval('qsTranslate(\\'FooContext\\', \\'Two\\')')", fileName).toString(), QString::fromLatin1("To")); - QCOMPARE(engine.evaluate("eval('qsTranslate(\\'FooContext\\', \\'Goodbye\\')')", fileName).toString(), QString::fromLatin1("Farvel")); + QTest::newRow("eval('qsTranslate(\\'FooContext\\', \\'Two\\')')@translatable.js") + << QString::fromLatin1("eval('qsTranslate(\\'FooContext\\', \\'Two\\')')") << fileName << QString::fromLatin1("To"); + QTest::newRow("eval('qsTranslate(\\'FooContext\\', \\'Goodbye\\')')@translatable.js") + << QString::fromLatin1("eval('qsTranslate(\\'FooContext\\', \\'Goodbye\\')')") << fileName << QString::fromLatin1("Farvel"); - QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8')", fileName).toString(), QString::fromLatin1("Farvel")); + QTest::newRow("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8')@translatable.js") + << QString::fromLatin1("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8')") << fileName << QString::fromLatin1("Farvel"); + QTest::newRow("qsTranslate('FooContext', 'Goodbye', '', 'CodecForTr')@translatable.js") + << QString::fromLatin1("qsTranslate('FooContext', 'Goodbye', '', 'CodecForTr')") << fileName << QString::fromLatin1("Farvel"); - QCOMPARE(engine.evaluate("qsTr('One', 'not the same one')", fileName).toString(), QString::fromLatin1("Enda en")); + QTest::newRow("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8', 42)@translatable.js") + << QString::fromLatin1("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8', 42)") << fileName << QString::fromLatin1("Goodbye"); - QVERIFY(engine.evaluate("QT_TR_NOOP()").isUndefined()); - QCOMPARE(engine.evaluate("QT_TR_NOOP('One')").toString(), QString::fromLatin1("One")); + QTest::newRow("qsTr('One', 'not the same one')@translatable.js") + << QString::fromLatin1("qsTr('One', 'not the same one')") << fileName << QString::fromLatin1("Enda en"); - QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP()").isUndefined()); - QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP('FooContext')").isUndefined()); - QCOMPARE(engine.evaluate("QT_TRANSLATE_NOOP('FooContext', 'Two')").toString(), QString::fromLatin1("Two")); + QTest::newRow("qsTr('One', 'not the same one', 42)@translatable.js") + << QString::fromLatin1("qsTr('One', 'not the same one', 42)") << fileName << QString::fromLatin1("One"); - // Don't exist in translation - QCOMPARE(engine.evaluate("qsTr('Three')", fileName).toString(), QString::fromLatin1("Three")); - QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'So long')", fileName).toString(), QString::fromLatin1("So long")); - QCOMPARE(engine.evaluate("qsTranslate('BarContext', 'Goodbye')", fileName).toString(), QString::fromLatin1("Goodbye")); + // Plural + QTest::newRow("qsTranslate('FooContext', '%n fooish bar(s) found', '', 'UnicodeUTF8', 1)@translatable.js") + << QString::fromLatin1("qsTranslate('FooContext', '%n fooish bar(s) found', '', 'UnicodeUTF8', 1)") << fileName << QString::fromLatin1("1 fooaktig bar funnet"); + QTest::newRow("qsTranslate('FooContext', '%n fooish bar(s) found', '', 'UnicodeUTF8', 2)@translatable.js") + << QString::fromLatin1("qsTranslate('FooContext', '%n fooish bar(s) found', '', 'UnicodeUTF8', 2)") << fileName << QString::fromLatin1("2 fooaktige barer funnet"); - // From C++ - // There is no context, but it shouldn't crash - QCOMPARE(engine.globalObject().property("qsTr").call( - QScriptValue(), QScriptValueList() << "One").toString(), QString::fromLatin1("One")); + // Don't exist in translation + QTest::newRow("qsTr('Three')@translatable.js") + << QString::fromLatin1("qsTr('Three')") << fileName << QString::fromLatin1("Three"); + QTest::newRow("qsTranslate('FooContext', 'So long')@translatable.js") + << QString::fromLatin1("qsTranslate('FooContext', 'So long')") << fileName << QString::fromLatin1("So long"); + QTest::newRow("qsTranslate('BarContext', 'Goodbye')@translatable.js") + << QString::fromLatin1("qsTranslate('BarContext', 'Goodbye')") << fileName << QString::fromLatin1("Goodbye"); // Translate strings from the second script (translatable2.js) QString fileName2 = QString::fromLatin1("translatable2.js"); - - QCOMPARE(engine.evaluate("qsTr('Three')", fileName2).toString(), QString::fromLatin1("Tre")); - QCOMPARE(engine.evaluate("qsTr('Happy birthday!')", fileName2).toString(), QString::fromLatin1("Gratulerer med dagen!")); + QTest::newRow("qsTr('Three')@translatable2.js") + << QString::fromLatin1("qsTr('Three')") << fileName2 << QString::fromLatin1("Tre"); + QTest::newRow("qsTr('Happy birthday!')@translatable2.js") + << QString::fromLatin1("qsTr('Happy birthday!')") << fileName2 << QString::fromLatin1("Gratulerer med dagen!"); // Not translated because translation is only in translatable.js - QCOMPARE(engine.evaluate("qsTr('One')", fileName2).toString(), QString::fromLatin1("One")); - QCOMPARE(engine.evaluate("(function() { return qsTr('One'); })()", fileName2).toString(), QString::fromLatin1("One")); + QTest::newRow("qsTr('One')@translatable2.js") + << QString::fromLatin1("qsTr('One')") << fileName2 << QString::fromLatin1("One"); + QTest::newRow("(function() { return qsTr('One'); })()@translatable2.js") + << QString::fromLatin1("(function() { return qsTr('One'); })()") << fileName2 << QString::fromLatin1("One"); // For qsTranslate() the filename shouldn't matter - QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Two')", fileName2).toString(), QString::fromLatin1("To")); - QCOMPARE(engine.evaluate("qsTranslate('BarContext', 'Congratulations!')", fileName).toString(), QString::fromLatin1("Gratulerer!")); + QTest::newRow("qsTranslate('FooContext', 'Two')@translatable2.js") + << QString::fromLatin1("qsTranslate('FooContext', 'Two')") << fileName2 << QString::fromLatin1("To"); + QTest::newRow("qsTranslate('BarContext', 'Congratulations!')@translatable.js") + << QString::fromLatin1("qsTranslate('BarContext', 'Congratulations!')") << fileName << QString::fromLatin1("Gratulerer!"); +} + +void tst_QScriptEngine::translateScript() +{ + QFETCH(QString, expression); + QFETCH(QString, fileName); + QFETCH(QString, expectedTranslation); + + QScriptEngine engine; + + TranslationScope tranScope(":/translations/translatable_la"); + engine.installTranslatorFunctions(); + + QCOMPARE(engine.evaluate(expression, fileName).toString(), expectedTranslation); + QVERIFY(!engine.hasUncaughtException()); +} + +void tst_QScriptEngine::translateScript_crossScript() +{ + QScriptEngine engine; + TranslationScope tranScope(":/translations/translatable_la"); + engine.installTranslatorFunctions(); + QString fileName = QString::fromLatin1("translatable.js"); + QString fileName2 = QString::fromLatin1("translatable2.js"); // qsTr() should use the innermost filename as context engine.evaluate("function foo(s) { return bar(s); }", fileName); engine.evaluate("function bar(s) { return qsTr(s); }", fileName2); @@ -4586,15 +5106,52 @@ void tst_QScriptEngine::translateScript() QCOMPARE(engine.evaluate("bar('Three')", fileName2).toString(), QString::fromLatin1("Three")); QCOMPARE(engine.evaluate("bar('One')", fileName).toString(), QString::fromLatin1("En")); QCOMPARE(engine.evaluate("bar('One')", fileName2).toString(), QString::fromLatin1("En")); +} +static QScriptValue callQsTr(QScriptContext *ctx, QScriptEngine *eng) +{ + return eng->globalObject().property("qsTr").call(ctx->thisObject(), ctx->argumentsObject()); +} + +void tst_QScriptEngine::translateScript_callQsTrFromNative() +{ + QScriptEngine engine; + TranslationScope tranScope(":/translations/translatable_la"); + engine.installTranslatorFunctions(); + + QString fileName = QString::fromLatin1("translatable.js"); + QString fileName2 = QString::fromLatin1("translatable2.js"); // Calling qsTr() from a native function engine.globalObject().setProperty("qsTrProxy", engine.newFunction(callQsTr)); QCOMPARE(engine.evaluate("qsTrProxy('One')", fileName).toString(), QString::fromLatin1("En")); QCOMPARE(engine.evaluate("qsTrProxy('One')", fileName2).toString(), QString::fromLatin1("One")); QCOMPARE(engine.evaluate("qsTrProxy('Three')", fileName).toString(), QString::fromLatin1("Three")); QCOMPARE(engine.evaluate("qsTrProxy('Three')", fileName2).toString(), QString::fromLatin1("Tre")); +} + +void tst_QScriptEngine::translateScript_trNoOp() +{ + QScriptEngine engine; + TranslationScope tranScope(":/translations/translatable_la"); + engine.installTranslatorFunctions(); - QCoreApplication::instance()->removeTranslator(&translator); + QVERIFY(engine.evaluate("QT_TR_NOOP()").isUndefined()); + QCOMPARE(engine.evaluate("QT_TR_NOOP('One')").toString(), QString::fromLatin1("One")); + + QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP()").isUndefined()); + QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP('FooContext')").isUndefined()); + QCOMPARE(engine.evaluate("QT_TRANSLATE_NOOP('FooContext', 'Two')").toString(), QString::fromLatin1("Two")); +} + +void tst_QScriptEngine::translateScript_callQsTrFromCpp() +{ + QScriptEngine engine; + TranslationScope tranScope(":/translations/translatable_la"); + engine.installTranslatorFunctions(); + + // There is no context, but it shouldn't crash + QCOMPARE(engine.globalObject().property("qsTr").call( + QScriptValue(), QScriptValueList() << "One").toString(), QString::fromLatin1("One")); } void tst_QScriptEngine::translateWithInvalidArgs_data() @@ -4610,6 +5167,7 @@ void tst_QScriptEngine::translateWithInvalidArgs_data() QTest::newRow("qsTranslate()") << "qsTranslate()" << "Error: qsTranslate() requires at least two arguments"; QTest::newRow("qsTranslate('foo')") << "qsTranslate('foo')" << "Error: qsTranslate() requires at least two arguments"; + QTest::newRow("qsTranslate(123, 'foo')") << "qsTranslate(123, 'foo')" << "Error: qsTranslate(): first argument (context) must be a string"; QTest::newRow("qsTranslate('foo', 123)") << "qsTranslate('foo', 123)" << "Error: qsTranslate(): second argument (text) must be a string"; QTest::newRow("qsTranslate('foo', 'bar', 123)") << "qsTranslate('foo', 'bar', 123)" << "Error: qsTranslate(): third argument (comment) must be a string"; QTest::newRow("qsTranslate('foo', 'bar', 'baz', 123)") << "qsTranslate('foo', 'bar', 'baz', 123)" << "Error: qsTranslate(): fourth argument (encoding) must be a string"; @@ -4663,9 +5221,7 @@ void tst_QScriptEngine::translationContext_data() void tst_QScriptEngine::translationContext() { - QTranslator translator; - translator.load(":/translations/translatable_la"); - QCoreApplication::instance()->installTranslator(&translator); + TranslationScope tranScope(":/translations/translatable_la"); QScriptEngine engine; engine.installTranslatorFunctions(); @@ -4676,17 +5232,13 @@ void tst_QScriptEngine::translationContext() QScriptValue ret = engine.evaluate(QString::fromLatin1("qsTr('%0')").arg(text), path); QVERIFY(ret.isString()); QCOMPARE(ret.toString(), expectedTranslation); - - QCoreApplication::instance()->removeTranslator(&translator); } void tst_QScriptEngine::translateScriptIdBased() { QScriptEngine engine; - QTranslator translator; - translator.load(":/translations/idtranslatable_la"); - QCoreApplication::instance()->installTranslator(&translator); + TranslationScope tranScope(":/translations/idtranslatable_la"); engine.installTranslatorFunctions(); QString fileName = QString::fromLatin1("idtranslatable.js"); @@ -4727,6 +5279,85 @@ void tst_QScriptEngine::translateScriptIdBased() QString::fromLatin1("qtn_foo_bar")); // Doesn't have plural } +// How to add a new test row: +// - Find a nice list of Unicode characters to choose from +// - Write source string/context/comment in .js using Unicode escape sequences (\uABCD) +// - Update corresponding .ts file (e.g. lupdate foo.js -ts foo.ts -codecfortr UTF-8) +// - Enter translation in Linguist +// - Update corresponding .qm file (e.g. lrelease foo.ts) +// - Evaluate script that performs translation; make sure the correct result is returned +// (e.g. by setting the resulting string as the text of a QLabel and visually verifying +// that it looks the same as what you entered in Linguist :-) ) +// - Generate the expectedTranslation column data using toUtf8().toHex() +void tst_QScriptEngine::translateScriptUnicode_data() +{ + QTest::addColumn<QString>("expression"); + QTest::addColumn<QString>("fileName"); + QTest::addColumn<QString>("expectedTranslation"); + + QString fileName = QString::fromLatin1("translatable-unicode.js"); + QTest::newRow("qsTr('H\\u2082O')@translatable-unicode.js") + << QString::fromLatin1("qsTr('H\\u2082O')") << fileName << QString::fromUtf8("\xcd\xbb\xcd\xbc\xcd\xbd"); + QTest::newRow("qsTranslate('\\u010C\\u0101\\u011F\\u0115', 'CO\\u2082')@translatable-unicode.js") + << QString::fromLatin1("qsTranslate('\\u010C\\u0101\\u011F\\u0115', 'CO\\u2082')") << fileName << QString::fromUtf8("\xd7\x91\xd7\x9a\xd7\xa2"); + QTest::newRow("qsTr('\\u0391\\u0392\\u0393')@translatable-unicode.js") + << QString::fromLatin1("qsTr('\\u0391\\u0392\\u0393')") << fileName << QString::fromUtf8("\xd3\x9c\xd2\xb4\xd1\xbc"); + QTest::newRow("qsTranslate('\\u010C\\u0101\\u011F\\u0115', '\\u0414\\u0415\\u0416')@translatable-unicode.js") + << QString::fromLatin1("qsTranslate('\\u010C\\u0101\\u011F\\u0115', '\\u0414\\u0415\\u0416')") << fileName << QString::fromUtf8("\xd8\xae\xd8\xb3\xd8\xb3"); + QTest::newRow("qsTr('H\\u2082O', 'not the same H\\u2082O')@translatable-unicode.js") + << QString::fromLatin1("qsTr('H\\u2082O', 'not the same H\\u2082O')") << fileName << QString::fromUtf8("\xd4\xb6\xd5\x8a\xd5\x92"); + QTest::newRow("qsTr('H\\u2082O')") + << QString::fromLatin1("qsTr('H\\u2082O')") << QString() << QString::fromUtf8("\x48\xe2\x82\x82\x4f"); + QTest::newRow("qsTranslate('\\u010C\\u0101\\u011F\\u0115', 'CO\\u2082')") + << QString::fromLatin1("qsTranslate('\\u010C\\u0101\\u011F\\u0115', 'CO\\u2082')") << QString() << QString::fromUtf8("\xd7\x91\xd7\x9a\xd7\xa2"); +} + +void tst_QScriptEngine::translateScriptUnicode() +{ + QFETCH(QString, expression); + QFETCH(QString, fileName); + QFETCH(QString, expectedTranslation); + + QScriptEngine engine; + + TranslationScope tranScope(":/translations/translatable-unicode"); + engine.installTranslatorFunctions(); + + QCOMPARE(engine.evaluate(expression, fileName).toString(), expectedTranslation); + QVERIFY(!engine.hasUncaughtException()); +} + +void tst_QScriptEngine::translateScriptUnicodeIdBased_data() +{ + QTest::addColumn<QString>("expression"); + QTest::addColumn<QString>("expectedTranslation"); + + QTest::newRow("qsTrId('\\u01F8\\u01D2\\u0199\\u01D0\\u01E1'')") + << QString::fromLatin1("qsTrId('\\u01F8\\u01D2\\u0199\\u01D0\\u01E1')") << QString::fromUtf8("\xc6\xa7\xc6\xb0\xc6\x88\xc8\xbc\xc8\x9d\xc8\xbf\xc8\x99"); + QTest::newRow("qsTrId('\\u0191\\u01CE\\u0211\\u0229\\u019C\\u018E\\u019A\\u01D0')") + << QString::fromLatin1("qsTrId('\\u0191\\u01CE\\u0211\\u0229\\u019C\\u018E\\u019A\\u01D0')") << QString::fromUtf8("\xc7\xa0\xc8\xa1\xc8\x8b\xc8\x85\xc8\x95"); + QTest::newRow("qsTrId('\\u0181\\u01A1\\u0213\\u018F\\u018C', 10)") + << QString::fromLatin1("qsTrId('\\u0181\\u01A1\\u0213\\u018F\\u018C', 10)") << QString::fromUtf8("\x31\x30\x20\xc6\x92\xc6\xa1\xc7\x92\x28\xc8\x99\x29"); + QTest::newRow("qsTrId('\\u0181\\u01A1\\u0213\\u018F\\u018C')") + << QString::fromLatin1("qsTrId('\\u0181\\u01A1\\u0213\\u018F\\u018C')") << QString::fromUtf8("\xc6\x91\xc6\xb0\xc7\xb9"); + QTest::newRow("qsTrId('\\u01CD\\u0180\\u01A8\\u0190\\u019E\\u01AB')") + << QString::fromLatin1("qsTrId('\\u01CD\\u0180\\u01A8\\u0190\\u019E\\u01AB')") << QString::fromUtf8("\xc7\x8d\xc6\x80\xc6\xa8\xc6\x90\xc6\x9e\xc6\xab"); +} + +void tst_QScriptEngine::translateScriptUnicodeIdBased() +{ + QFETCH(QString, expression); + QFETCH(QString, expectedTranslation); + + QScriptEngine engine; + + TranslationScope tranScope(":/translations/idtranslatable-unicode"); + engine.installTranslatorFunctions(); + + QCOMPARE(engine.evaluate(expression).toString(), expectedTranslation); + QVERIFY(!engine.hasUncaughtException()); +} + void tst_QScriptEngine::translateFromBuiltinCallback() { QScriptEngine eng; @@ -4749,7 +5380,7 @@ void tst_QScriptEngine::functionScopes() // top-level functions have only the global object in their scope QScriptValue fun = eng.evaluate("(function() {})"); QVERIFY(fun.isFunction()); - QEXPECT_FAIL("", "Function scope proxying is not implemented", Abort); + QEXPECT_FAIL("", "QScriptValue::scope() is internal, not implemented", Abort); QVERIFY(fun.scope().isObject()); QVERIFY(fun.scope().strictlyEquals(eng.globalObject())); QVERIFY(!eng.globalObject().scope().isValid()); @@ -4919,8 +5550,11 @@ void tst_QScriptEngine::evaluateProgram() QVERIFY(differentProgram != program); QVERIFY(!eng.evaluate(differentProgram).equals(expected)); } +} - // Program that accesses variable in the scope +void tst_QScriptEngine::evaluateProgram_customScope() +{ + QScriptEngine eng; { QScriptProgram program("a"); QVERIFY(!program.isNull()); @@ -4957,8 +5591,11 @@ void tst_QScriptEngine::evaluateProgram() ctx->popScope(); } +} - // Program that creates closure +void tst_QScriptEngine::evaluateProgram_closure() +{ + QScriptEngine eng; { QScriptProgram program("(function() { var count = 0; return function() { return count++; }; })"); QVERIFY(!program.isNull()); @@ -4978,7 +5615,11 @@ void tst_QScriptEngine::evaluateProgram() QVERIFY(ret.isNumber()); } } +} +void tst_QScriptEngine::evaluateProgram_executeLater() +{ + QScriptEngine eng; // Program created in a function call, then executed later { QScriptValue fun = eng.newFunction(createProgram); @@ -4999,8 +5640,11 @@ void tst_QScriptEngine::evaluateProgram() QCOMPARE(ret.toInt32(), 123); } } +} - // Same program run in different engines +void tst_QScriptEngine::evaluateProgram_multipleEngines() +{ + QScriptEngine eng; { QString code("1 + 2"); QScriptProgram program(code); @@ -5014,8 +5658,11 @@ void tst_QScriptEngine::evaluateProgram() } } } +} - // No program +void tst_QScriptEngine::evaluateProgram_empty() +{ + QScriptEngine eng; { QScriptProgram program; QVERIFY(program.isNull()); @@ -5037,6 +5684,7 @@ void tst_QScriptEngine::collectGarbageAfterConnect() .isUndefined()); QVERIFY(widget != 0); engine.evaluate("widget = null;"); + // The connection should not keep the widget alive. collectGarbage_helper(engine); QVERIFY(widget == 0); } @@ -5053,7 +5701,10 @@ void tst_QScriptEngine::collectGarbageAfterNativeArguments() static QScriptValue constructQObjectFromThisObject(QScriptContext *ctx, QScriptEngine *eng) { - Q_ASSERT(ctx->isCalledAsConstructor()); + if (!ctx->isCalledAsConstructor()) { + qWarning("%s: ctx->isCalledAsConstructor() returned false", Q_FUNC_INFO); + return QScriptValue(); + } return eng->newQObject(ctx->thisObject(), new QObject, QScriptEngine::ScriptOwnership); } @@ -5098,6 +5749,10 @@ void tst_QScriptEngine::qRegExpInport_data() QTest::newRow("aaa") << QRegExp("a{2,5}") << "aAaAaaaaaAa"; QTest::newRow("aaa minimal") << minimal(QRegExp("a{2,5}")) << "aAaAaaaaaAa"; QTest::newRow("minimal") << minimal(QRegExp(".*\\} [*8]")) << "}?} ?} *"; + QTest::newRow(".? minimal") << minimal(QRegExp(".?")) << ".?"; + QTest::newRow(".+ minimal") << minimal(QRegExp(".+")) << ".+"; + QTest::newRow("[.?] minimal") << minimal(QRegExp("[.?]")) << ".?"; + QTest::newRow("[.+] minimal") << minimal(QRegExp("[.+]")) << ".+"; } void tst_QScriptEngine::qRegExpInport() @@ -5163,6 +5818,7 @@ void tst_QScriptEngine::dateConversionJSQt() QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate); QString jsUTCDateStr = jsDate.property("toISOString").call(jsDate).toString(); jsUTCDateStr.chop(5); // get rid of milliseconds (".000Z") + jsUTCDateStr.append("Z"); // append the timezone specifier again if (qtUTCDateStr != jsUTCDateStr) QFAIL(qPrintable(jsDate.toString())); secs += 2*60*60; @@ -5177,6 +5833,7 @@ void tst_QScriptEngine::dateConversionQtJS() QScriptValue jsDate = eng.newDate(qtDate); QString jsUTCDateStr = jsDate.property("toISOString").call(jsDate).toString(); jsUTCDateStr.chop(5); // get rid of milliseconds (".000Z") + jsUTCDateStr.append("Z"); // append the timezone specifier again QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate); if (jsUTCDateStr != qtUTCDateStr) QFAIL(qPrintable(qtDate.toString())); @@ -5206,6 +5863,17 @@ void tst_QScriptEngine::reentrency() void tst_QScriptEngine::newFixedStaticScopeObject() { + // "Static scope objects" is an optimization we do for QML. + // It enables the creation of JS objects that can guarantee to the + // compiler that no properties will be added or removed. This enables + // the compiler to generate a very simple (fast) property access, as + // opposed to a full virtual lookup. Due to the inherent use of scope + // chains in QML, this can make a huge difference (10x improvement for + // benchmark in QTBUG-8576). + // Ideally we would not need a special object type for this, and the + // VM would dynamically optimize it to be fast... + // See also QScriptEngine benchmark. + QScriptEngine eng; static const int propertyCount = 4; QString names[] = { "foo", "bar", "baz", "Math" }; @@ -5346,6 +6014,11 @@ void tst_QScriptEngine::newFixedStaticScopeObject() void tst_QScriptEngine::newGrowingStaticScopeObject() { + // The main use case for a growing static scope object is to set it as + // the activation object of a QScriptContext, so that all JS variable + // declarations end up in that object. It needs to be "growable" since + // we don't know in advance how many variables a script will declare. + QScriptEngine eng; QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(&eng); @@ -5433,14 +6106,40 @@ void tst_QScriptEngine::newGrowingStaticScopeObject() { QScriptValue fun = eng.evaluate("(function() { return futureProperty; })"); QVERIFY(fun.isFunction()); - QCOMPARE(fun.call().toString(), QString::fromLatin1("ReferenceError: Can't find variable: futureProperty")); + QVERIFY(fun.call().toString().contains(QString::fromLatin1("ReferenceError"))); scope.setProperty("futureProperty", "added after the function was compiled"); // If scope were dynamic, this would return the new property. - QCOMPARE(fun.call().toString(), QString::fromLatin1("ReferenceError: Can't find variable: futureProperty")); + QVERIFY(fun.call().toString().contains(QString::fromLatin1("ReferenceError"))); } eng.popContext(); } +QT_BEGIN_NAMESPACE +Q_SCRIPT_DECLARE_QMETAOBJECT(QStandardItemModel, QObject*) +QT_END_NAMESPACE + +void tst_QScriptEngine::scriptValueFromQMetaObject() +{ + QScriptEngine eng; + { + QScriptValue meta = eng.scriptValueFromQMetaObject<QScriptEngine>(); + QVERIFY(meta.isQMetaObject()); + QCOMPARE(meta.toQMetaObject(), &QScriptEngine::staticMetaObject); + // Because of missing Q_SCRIPT_DECLARE_QMETAOBJECT() for QScriptEngine. + QVERIFY(!meta.construct().isValid()); + } + { + QScriptValue meta = eng.scriptValueFromQMetaObject<QStandardItemModel>(); + QVERIFY(meta.isQMetaObject()); + QCOMPARE(meta.toQMetaObject(), &QStandardItemModel::staticMetaObject); + QScriptValue obj = meta.construct(QScriptValueList() << eng.newQObject(&eng)); + QVERIFY(obj.isQObject()); + QStandardItemModel *model = qobject_cast<QStandardItemModel*>(obj.toQObject()); + QVERIFY(model != 0); + QCOMPARE(model->parent(), (QObject*)&eng); + } +} + QTEST_MAIN(tst_QScriptEngine) #include "tst_qscriptengine.moc" diff --git a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp index 4bb9564..2390f19 100644 --- a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp +++ b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp @@ -73,6 +73,7 @@ signals: void testSignal(double arg); private slots: + void unloadRecursion(); void scriptLoadAndUnload_statement(); void scriptLoadAndUnload(); void scriptLoadAndUnload_eval(); @@ -345,6 +346,46 @@ QVariant ScriptEngineSpy::extension(Extension ext, const QVariant &arg) return QVariant(); } +static void collectScriptObjects(QScriptEngine *engine) +{ + // We call garbage collection few times to collect objects that + // are unreferenced after first gc. We try to force full gc. + engine->collectGarbage(); + engine->collectGarbage(); + engine->collectGarbage(); +} + +class EvaluatingAgent : public QScriptEngineAgent { +public: + EvaluatingAgent(QScriptEngine *engine) + : QScriptEngineAgent(engine) + , count(0) + {} + + virtual void scriptUnload(qint64) + { + if (++count > 10) // recursion breaker. + return; + // check if recursive evaluation works + engine()->evaluate(";"); + collectScriptObjects(engine()); + } + + bool isOk() const { return count > 10; } +private: + int count; +}; + +void tst_QScriptEngineAgent::unloadRecursion() +{ + QScriptEngine engine; + EvaluatingAgent *agent = new EvaluatingAgent(&engine); + engine.setAgent(agent); + engine.evaluate(";"); + collectScriptObjects(&engine); + QVERIFY(agent->isOk()); +} + void tst_QScriptEngineAgent::scriptLoadAndUnload_statement() { QScriptEngine eng; @@ -358,6 +399,8 @@ void tst_QScriptEngineAgent::scriptLoadAndUnload_statement() int lineNumber = 123; eng.evaluate(code, fileName, lineNumber); + // Script object have to be garbage collected first. + collectScriptObjects(&eng); QCOMPARE(spy->count(), 2); QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); @@ -377,6 +420,8 @@ void tst_QScriptEngineAgent::scriptLoadAndUnload_statement() int lineNumber = 456; eng.evaluate(code, fileName, lineNumber); + // Script object have to be garbage collected first. + collectScriptObjects(&eng); QCOMPARE(spy->count(), 2); QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); @@ -414,7 +459,8 @@ void tst_QScriptEngineAgent::scriptLoadAndUnload() code = "foo = null"; eng.evaluate(code); - QCOMPARE(spy->count(), 3); + collectScriptObjects(&eng); // foo() is GC'ed + QCOMPARE(spy->count(), 4); QCOMPARE(spy->at(1).type, ScriptEngineEvent::ScriptLoad); QVERIFY(spy->at(1).scriptId != -1); @@ -425,8 +471,6 @@ void tst_QScriptEngineAgent::scriptLoadAndUnload() QCOMPARE(spy->at(2).type, ScriptEngineEvent::ScriptUnload); QCOMPARE(spy->at(2).scriptId, spy->at(1).scriptId); - eng.collectGarbage(); // foo() is GC'ed - QCOMPARE(spy->count(), 4); QCOMPARE(spy->at(3).type, ScriptEngineEvent::ScriptUnload); QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); } @@ -448,6 +492,7 @@ void tst_QScriptEngineAgent::scriptLoadAndUnload() code = "bar = foo(); foo = null"; eng.evaluate(code); + collectScriptObjects(&eng); QCOMPARE(spy->count(), 3); QCOMPARE(spy->at(1).type, ScriptEngineEvent::ScriptLoad); @@ -458,14 +503,12 @@ void tst_QScriptEngineAgent::scriptLoadAndUnload() QCOMPARE(spy->at(2).type, ScriptEngineEvent::ScriptUnload); QCOMPARE(spy->at(2).scriptId, spy->at(1).scriptId); - eng.collectGarbage(); // foo() is not GC'ed + collectScriptObjects(&eng); // foo() is not GC'ed QCOMPARE(spy->count(), 3); code = "bar = null"; eng.evaluate(code); - QCOMPARE(spy->count(), 5); - - eng.collectGarbage(); // foo() is GC'ed + collectScriptObjects(&eng); // foo() is GC'ed QCOMPARE(spy->count(), 6); } delete spy; @@ -1248,7 +1291,7 @@ void tst_QScriptEngineAgent::positionChange_1() QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, lineNumber); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 8); // 5 + 6 @@ -1283,7 +1326,7 @@ void tst_QScriptEngineAgent::positionChange_2() QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QVERIFY(spy->at(1).scriptId != spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, lineNumber); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 18); } @@ -1302,7 +1345,7 @@ void tst_QScriptEngineAgent::positionChange_2() QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 11); } @@ -1333,14 +1376,14 @@ void tst_QScriptEngineAgent::positionChange_2() QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 31); // void(i) QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(2).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(2).columnNumber, 31); } @@ -1359,21 +1402,21 @@ void tst_QScriptEngineAgent::positionChange_2() QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 12); // ++i QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(2).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(2).columnNumber, 28); // ++i QCOMPARE(spy->at(3).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(3).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(3).columnNumber, 28); } @@ -1392,28 +1435,28 @@ void tst_QScriptEngineAgent::positionChange_2() QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 12); // ++i QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(2).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(2).columnNumber, 17); // do QCOMPARE(spy->at(3).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(3).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(3).columnNumber, 12); // ++i QCOMPARE(spy->at(4).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(4).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(4).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(4).columnNumber, 17); } @@ -1444,7 +1487,7 @@ void tst_QScriptEngineAgent::positionChange_2() QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 15); } @@ -1463,14 +1506,14 @@ void tst_QScriptEngineAgent::positionChange_2() QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 32); // continue QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(2).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(2).columnNumber, 32); } @@ -1513,7 +1556,7 @@ void tst_QScriptEngineAgent::positionChange_2() QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 31); } @@ -1532,14 +1575,14 @@ void tst_QScriptEngineAgent::positionChange_2() QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 38); // break QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(2).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(2).columnNumber, 45); } @@ -1564,21 +1607,21 @@ void tst_QScriptEngineAgent::positionChange_2() QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); QVERIFY(spy->at(0).scriptId != -1); QCOMPARE(spy->at(0).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(0).columnNumber, 7); // i = e QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 29); // i = 2 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(2).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(2).columnNumber, 48); } @@ -1591,14 +1634,14 @@ void tst_QScriptEngineAgent::positionChange_2() QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); QVERIFY(spy->at(0).scriptId != -1); QCOMPARE(spy->at(0).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(0).columnNumber, 7); // i = 3 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 46); } @@ -1620,7 +1663,7 @@ void tst_QScriptEngineAgent::positionChange_2() QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); QCOMPARE(spy->at(1).lineNumber, 1); - QEXPECT_FAIL("", "With JSC-based back-end, column number is always reported as 1", Continue); + QEXPECT_FAIL("", "QTBUG-17609: With JSC-based back-end, column number is always reported as 1", Continue); QCOMPARE(spy->at(1).columnNumber, 20); } delete spy; @@ -2204,8 +2247,7 @@ void tst_QScriptEngineAgent::syntaxError() QCOMPARE(spy->at(i).scriptId, spy->at(0).scriptId); QVERIFY(!spy->at(i).hasExceptionHandler); QVERIFY(spy->at(i).value.isError()); - QEXPECT_FAIL("","QTBUG-6137 There are other messages in JSC",Continue); - QCOMPARE(spy->at(i).value.toString(), QString("SyntaxError: Expected `}'")); + QVERIFY(spy->at(i).value.toString().contains(QLatin1String("SyntaxError"))); QCOMPARE(spy->at(i).scriptId, spy->at(0).scriptId); i = 7; //exit script diff --git a/tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp b/tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp index 1563e7e..142b0b7 100644 --- a/tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp +++ b/tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp @@ -50,24 +50,11 @@ #include <qmenu.h> #include <qplaintextedit.h> #include <qtoolbar.h> +#include "../../shared/util.h" //TESTED_CLASS= //TESTED_FILES= -// Will try to wait for the condition while allowing event processing -#define QTRY_COMPARE(__expr, __expected) \ - do { \ - const int __step = 50; \ - const int __timeout = 5000; \ - if ((__expr) != (__expected)) { \ - QTest::qWait(0); \ - } \ - for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \ - QTest::qWait(__step); \ - } \ - QCOMPARE(__expr, __expected); \ - } while(0) - // Can't use QTest::qWait() because it causes event loop to hang on some platforms static void qsWait(int ms) { @@ -97,6 +84,8 @@ private slots: void debuggerSignals(); void consoleCommands(); void multithreadedDebugging(); + void autoShowStandardWindow(); + void standardWindowOwnership(); }; tst_QScriptEngineDebugger::tst_QScriptEngineDebugger() @@ -784,5 +773,68 @@ void tst_QScriptEngineDebugger::multithreadedDebugging() QTRY_COMPARE(threadFinishedSpy.count(), 1); } +void tst_QScriptEngineDebugger::autoShowStandardWindow() +{ + { + QScriptEngine engine; + QScriptEngineDebugger debugger; + QCOMPARE(debugger.autoShowStandardWindow(), true); + debugger.attachTo(&engine); + QObject::connect(&debugger, SIGNAL(evaluationSuspended()), + debugger.action(QScriptEngineDebugger::ContinueAction), + SLOT(trigger())); + engine.evaluate("debugger"); + QTRY_VERIFY(debugger.standardWindow()->isVisible()); + + debugger.setAutoShowStandardWindow(true); + QCOMPARE(debugger.autoShowStandardWindow(), true); + + debugger.setAutoShowStandardWindow(false); + QCOMPARE(debugger.autoShowStandardWindow(), false); + + debugger.setAutoShowStandardWindow(true); + QCOMPARE(debugger.autoShowStandardWindow(), true); + + debugger.standardWindow()->hide(); + + engine.evaluate("debugger"); + QTRY_VERIFY(debugger.standardWindow()->isVisible()); + } + + { + QScriptEngine engine; + QScriptEngineDebugger debugger; + debugger.setAutoShowStandardWindow(false); + debugger.attachTo(&engine); + QObject::connect(&debugger, SIGNAL(evaluationSuspended()), + debugger.action(QScriptEngineDebugger::ContinueAction), + SLOT(trigger())); + QSignalSpy evaluationResumedSpy(&debugger, SIGNAL(evaluationResumed())); + engine.evaluate("debugger"); + QTRY_COMPARE(evaluationResumedSpy.count(), 1); + QVERIFY(!debugger.standardWindow()->isVisible()); + } +} + +void tst_QScriptEngineDebugger::standardWindowOwnership() +{ + QScriptEngine engine; + QPointer<QMainWindow> win; + { + QScriptEngineDebugger debugger; + win = debugger.standardWindow(); + } + QVERIFY(win == 0); + + // Reparent the window. + QWidget widget; + { + QScriptEngineDebugger debugger; + win = debugger.standardWindow(); + win->setParent(&widget); + } + QVERIFY(win != 0); +} + QTEST_MAIN(tst_QScriptEngineDebugger) #include "tst_qscriptenginedebugger.moc" diff --git a/tests/auto/qscriptextensionplugin/qscriptextensionplugin.pro b/tests/auto/qscriptextensionplugin/qscriptextensionplugin.pro new file mode 100644 index 0000000..d4671c8 --- /dev/null +++ b/tests/auto/qscriptextensionplugin/qscriptextensionplugin.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +CONFIG -= app_bundle +SUBDIRS = simpleplugin staticplugin test diff --git a/tests/auto/qscriptextensionplugin/simpleplugin/simpleplugin.cpp b/tests/auto/qscriptextensionplugin/simpleplugin/simpleplugin.cpp new file mode 100644 index 0000000..333406b --- /dev/null +++ b/tests/auto/qscriptextensionplugin/simpleplugin/simpleplugin.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtScript/qscriptextensionplugin.h> +#include <QtScript/qscriptengine.h> +#include <qdebug.h> + +class SimplePlugin : public QScriptExtensionPlugin +{ +public: + SimplePlugin(QObject *parent = 0); + ~SimplePlugin(); + + virtual QStringList keys() const; + virtual void initialize(const QString &key, QScriptEngine *engine); +}; + +SimplePlugin::SimplePlugin(QObject *parent) + : QScriptExtensionPlugin(parent) +{ +} + +SimplePlugin::~SimplePlugin() +{ +} + +QStringList SimplePlugin::keys() const +{ + return QStringList() << "simple" + << "simple.foo" + << "simple.foo.bar"; +} + +void SimplePlugin::initialize(const QString &key, QScriptEngine *engine) +{ + engine->globalObject().setProperty("pluginKey", key); + QScriptValue package = setupPackage(key, engine); + engine->globalObject().setProperty("package", package); +} + +Q_EXPORT_PLUGIN2(simpleplugin, SimplePlugin) diff --git a/tests/auto/qscriptextensionplugin/simpleplugin/simpleplugin.pro b/tests/auto/qscriptextensionplugin/simpleplugin/simpleplugin.pro new file mode 100644 index 0000000..e184ca4 --- /dev/null +++ b/tests/auto/qscriptextensionplugin/simpleplugin/simpleplugin.pro @@ -0,0 +1,10 @@ +TEMPLATE = lib +CONFIG += plugin +SOURCES = simpleplugin.cpp +QT = core script +TARGET = simpleplugin +DESTDIR = ../plugins/script + +symbian { + TARGET.EPOCALLOWDLLDATA=1 +} diff --git a/tests/auto/qscriptextensionplugin/staticplugin/__init__.js b/tests/auto/qscriptextensionplugin/staticplugin/__init__.js new file mode 100644 index 0000000..4e462ae --- /dev/null +++ b/tests/auto/qscriptextensionplugin/staticplugin/__init__.js @@ -0,0 +1,6 @@ +spy = { + extension: __extension__, + setupPackage: __setupPackage__, + postInit: __postInit__ +}; +__postInit__ = function() { postInitWasCalled = true; }; diff --git a/tests/auto/qscriptextensionplugin/staticplugin/staticplugin.cpp b/tests/auto/qscriptextensionplugin/staticplugin/staticplugin.cpp new file mode 100644 index 0000000..19b90d4 --- /dev/null +++ b/tests/auto/qscriptextensionplugin/staticplugin/staticplugin.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtScript/qscriptextensionplugin.h> +#include <QtScript/qscriptengine.h> +#include <qdebug.h> + +class StaticPlugin : public QScriptExtensionPlugin +{ +public: + StaticPlugin(QObject *parent = 0); + ~StaticPlugin(); + + virtual QStringList keys() const; + virtual void initialize(const QString &key, QScriptEngine *engine); +}; + +StaticPlugin::StaticPlugin(QObject *parent) + : QScriptExtensionPlugin(parent) +{ +} + +StaticPlugin::~StaticPlugin() +{ +} + +QStringList StaticPlugin::keys() const +{ + return QStringList() << "static"; +} + +void StaticPlugin::initialize(const QString &key, QScriptEngine *engine) +{ + engine->globalObject().setProperty("pluginKey", key); +} + +Q_EXPORT_PLUGIN2(staticplugin, StaticPlugin) diff --git a/tests/auto/qscriptextensionplugin/staticplugin/staticplugin.pro b/tests/auto/qscriptextensionplugin/staticplugin/staticplugin.pro new file mode 100644 index 0000000..a003338 --- /dev/null +++ b/tests/auto/qscriptextensionplugin/staticplugin/staticplugin.pro @@ -0,0 +1,7 @@ +TEMPLATE = lib +CONFIG += static plugin +SOURCES = staticplugin.cpp +RESOURCES = staticplugin.qrc +QT = core script +TARGET = staticplugin +DESTDIR = ../plugins/script diff --git a/tests/auto/qscriptextensionplugin/staticplugin/staticplugin.qrc b/tests/auto/qscriptextensionplugin/staticplugin/staticplugin.qrc new file mode 100644 index 0000000..293bf0e --- /dev/null +++ b/tests/auto/qscriptextensionplugin/staticplugin/staticplugin.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/qtscriptextension/static/"> +<file>__init__.js</file> +</qresource> +</RCC> + diff --git a/tests/auto/qscriptextensionplugin/test/test.pro b/tests/auto/qscriptextensionplugin/test/test.pro new file mode 100644 index 0000000..549bac2 --- /dev/null +++ b/tests/auto/qscriptextensionplugin/test/test.pro @@ -0,0 +1,18 @@ +load(qttest_p4) + +QT = core script +SOURCES = ../tst_qscriptextensionplugin.cpp +CONFIG -= app_bundle +LIBS += -L../plugins/script -lstaticplugin + +TARGET = tst_qscriptextensionplugin +CONFIG(debug_and_release) { + CONFIG(debug, debug|release) { + DESTDIR = ../debug + } else { + DESTDIR = ../release + } +} else { + DESTDIR = .. +} + diff --git a/tests/auto/qscriptextensionplugin/tst_qscriptextensionplugin.cpp b/tests/auto/qscriptextensionplugin/tst_qscriptextensionplugin.cpp new file mode 100644 index 0000000..ee840a8 --- /dev/null +++ b/tests/auto/qscriptextensionplugin/tst_qscriptextensionplugin.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + +#include <QtScript/qscriptengine.h> + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QScriptExtensionPlugin : public QObject +{ + Q_OBJECT + +public: + tst_QScriptExtensionPlugin(); + virtual ~tst_QScriptExtensionPlugin(); + +private slots: + void importSimplePlugin(); + void importStaticPlugin(); +}; + +tst_QScriptExtensionPlugin::tst_QScriptExtensionPlugin() +{ +} + +tst_QScriptExtensionPlugin::~tst_QScriptExtensionPlugin() +{ +} + +void tst_QScriptExtensionPlugin::importSimplePlugin() +{ + QScriptEngine eng; + QCoreApplication::addLibraryPath("plugins"); + + QVERIFY(eng.importedExtensions().isEmpty()); + + QStringList available = eng.availableExtensions(); + QVERIFY(available.contains("simple")); + QVERIFY(available.contains("simple.foo")); + QVERIFY(available.contains("simple.foo.bar")); + + QScriptValue extensionObject; + { + QVERIFY(eng.importExtension("simple").isUndefined()); + QCOMPARE(eng.importedExtensions().size(), 1); + QCOMPARE(eng.importedExtensions().at(0), QString::fromLatin1("simple")); + QVERIFY(eng.availableExtensions().contains("simple")); + QVERIFY(eng.globalObject().property("pluginKey").equals("simple")); + QVERIFY(eng.globalObject().property("package").isObject()); + extensionObject = eng.globalObject().property("simple"); + QVERIFY(extensionObject.isObject()); + QVERIFY(extensionObject.equals(eng.globalObject().property("package"))); + } + + { + QVERIFY(eng.importExtension("simple.foo").isUndefined()); + QCOMPARE(eng.importedExtensions().size(), 2); + QCOMPARE(eng.importedExtensions().at(1), QString::fromLatin1("simple.foo")); + QVERIFY(eng.availableExtensions().contains("simple.foo")); + QVERIFY(eng.globalObject().property("pluginKey").equals("simple.foo")); + QVERIFY(eng.globalObject().property("package").isObject()); + QVERIFY(!extensionObject.equals(eng.globalObject().property("package"))); + QVERIFY(extensionObject.equals(eng.globalObject().property("simple"))); + QVERIFY(extensionObject.property("foo").isObject()); + QVERIFY(extensionObject.property("foo").equals(eng.globalObject().property("package"))); + } + + { + QVERIFY(eng.importExtension("simple.foo.bar").isUndefined()); + QCOMPARE(eng.importedExtensions().size(), 3); + QCOMPARE(eng.importedExtensions().at(2), QString::fromLatin1("simple.foo.bar")); + QVERIFY(eng.availableExtensions().contains("simple.foo.bar")); + QVERIFY(eng.globalObject().property("pluginKey").equals("simple.foo.bar")); + QVERIFY(eng.globalObject().property("package").isObject()); + QVERIFY(!extensionObject.equals(eng.globalObject().property("package"))); + QVERIFY(extensionObject.equals(eng.globalObject().property("simple"))); + QVERIFY(extensionObject.property("foo").property("bar").isObject()); + QVERIFY(extensionObject.property("foo").property("bar").equals(eng.globalObject().property("package"))); + } + + // Extensions can't be imported multiple times. + eng.globalObject().setProperty("pluginKey", QScriptValue()); + QVERIFY(eng.importExtension("simple").isUndefined()); + QCOMPARE(eng.importedExtensions().size(), 3); + QVERIFY(!eng.globalObject().property("pluginKey").isValid()); + + QVERIFY(eng.importExtension("simple.foo").isUndefined()); + QCOMPARE(eng.importedExtensions().size(), 3); + QVERIFY(!eng.globalObject().property("pluginKey").isValid()); + + QVERIFY(eng.importExtension("simple.foo.bar").isUndefined()); + QCOMPARE(eng.importedExtensions().size(), 3); + QVERIFY(!eng.globalObject().property("pluginKey").isValid()); +} + +void tst_QScriptExtensionPlugin::importStaticPlugin() +{ + Q_INIT_RESOURCE(staticplugin); + QScriptEngine eng; + QVERIFY(eng.availableExtensions().contains("static")); + QVERIFY(eng.importExtension("static").isUndefined()); + QCOMPARE(eng.importedExtensions().size(), 1); + QCOMPARE(eng.importedExtensions().at(0), QString::fromLatin1("static")); + QVERIFY(eng.availableExtensions().contains("static")); + QVERIFY(eng.globalObject().property("pluginKey").equals("static")); + + // Verify that :/qtscriptextension/static/__init__.js was evaluated. + QVERIFY(eng.evaluate("spy").isObject()); + QVERIFY(eng.evaluate("spy.extension").equals("static")); + QVERIFY(eng.evaluate("spy.setupPackage").isFunction()); + QVERIFY(eng.evaluate("spy.postInit").isUndefined()); + + QVERIFY(eng.evaluate("postInitWasCalled").isBool()); + QVERIFY(eng.evaluate("postInitWasCalled").toBool()); + + // Extensions can't be imported multiple times. + eng.globalObject().setProperty("pluginKey", QScriptValue()); + QVERIFY(eng.importExtension("static").isUndefined()); + QCOMPARE(eng.importedExtensions().size(), 1); + QVERIFY(!eng.globalObject().property("pluginKey").isValid()); +} + +Q_IMPORT_PLUGIN(staticplugin) + +QTEST_MAIN(tst_QScriptExtensionPlugin) +#include "tst_qscriptextensionplugin.moc" diff --git a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp index 8e120b0..815c522 100644 --- a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp +++ b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp @@ -329,6 +329,18 @@ public: { m_qtFunctionInvoked = 58; m_actuals << int(arg); return arg; } Q_INVOKABLE MyQObject::Ability myInvokableWithQualifiedFlagsArg(MyQObject::Ability arg) { m_qtFunctionInvoked = 59; m_actuals << int(arg); return arg; } + Q_INVOKABLE QWidget *myInvokableWithQWidgetStarArg(QWidget *arg) + { m_qtFunctionInvoked = 63; m_actuals << qVariantFromValue((QWidget*)arg); return arg; } + Q_INVOKABLE short myInvokableWithShortArg(short arg) + { m_qtFunctionInvoked = 64; m_actuals << qVariantFromValue(arg); return arg; } + Q_INVOKABLE unsigned short myInvokableWithUShortArg(unsigned short arg) + { m_qtFunctionInvoked = 65; m_actuals << qVariantFromValue(arg); return arg; } + Q_INVOKABLE char myInvokableWithCharArg(char arg) + { m_qtFunctionInvoked = 66; m_actuals << qVariantFromValue(arg); return arg; } + Q_INVOKABLE unsigned char myInvokableWithUCharArg(unsigned char arg) + { m_qtFunctionInvoked = 67; m_actuals << qVariantFromValue(arg); return arg; } + Q_INVOKABLE qulonglong myInvokableWithULonglongArg(qulonglong arg) + { m_qtFunctionInvoked = 68; m_actuals << qVariantFromValue(arg); return arg; } Q_INVOKABLE QObjectList findObjects() const { return findChildren<QObject *>(); } @@ -394,6 +406,8 @@ public Q_SLOTS: { m_qtFunctionInvoked = 32; m_actuals << arg; } void myOverloadedSlot(const QDate &arg) { m_qtFunctionInvoked = 33; m_actuals << arg; } + void myOverloadedSlot(const QTime &arg) + { m_qtFunctionInvoked = 69; m_actuals << arg; } void myOverloadedSlot(const QRegExp &arg) { m_qtFunctionInvoked = 34; m_actuals << arg; } void myOverloadedSlot(const QVariant &arg) @@ -514,18 +528,47 @@ protected slots: private slots: void registeredTypes(); void getSetStaticProperty(); + void getSetStaticProperty_propertyFlags(); + void getSetStaticProperty_changeInCpp(); + void getSetStaticProperty_changeInJS(); + void getSetStaticProperty_compatibleVariantTypes(); + void getSetStaticProperty_conversion(); + void getSetStaticProperty_delete(); + void getSetStaticProperty_nonScriptable(); + void getSetStaticProperty_writeOnly(); + void getSetStaticProperty_readOnly(); + void getSetStaticProperty_enum(); + void getSetStaticProperty_qflags(); + void getSetStaticProperty_pointerDeref(); + void getSetStaticProperty_customGetterSetter(); + void getSetStaticProperty_methodPersistence(); void getSetDynamicProperty(); + void getSetDynamicProperty_deleteFromCpp(); + void getSetDynamicProperty_hideChildObject(); + void getSetDynamicProperty_setBeforeGet(); + void getSetDynamicProperty_doNotHideJSProperty(); void getSetChildren(); void callQtInvokable(); + void callQtInvokable2(); + void callQtInvokable3(); + void callQtInvokable4(); + void callQtInvokable5(); + void callQtInvokable6(); + void callQtInvokable7(); void connectAndDisconnect(); + void connectAndDisconnect_emitFromJS(); + void connectAndDisconnect_senderWrapperCollected(); void connectAndDisconnectWithBadArgs(); + void connectAndDisconnect_senderDeleted(); void cppConnectAndDisconnect(); + void cppConnectAndDisconnect2(); void classEnums(); void classConstructor(); void overrideInvokable(); void transferInvokable(); void findChild(); void findChildren(); + void childObjects(); void overloadedSlots(); void enumerate_data(); void enumerate(); @@ -640,7 +683,10 @@ void tst_QScriptExtQObject::getSetStaticProperty() QCOMPARE(m_engine->evaluate("myObject.stringListProperty[1]").isString(), true); QCOMPARE(m_engine->evaluate("myObject.stringListProperty[1]").toString(), QLatin1String("zag")); +} +void tst_QScriptExtQObject::getSetStaticProperty_propertyFlags() +{ // default flags for "normal" properties { QScriptValue mobj = m_engine->globalObject().property("myObject"); @@ -662,7 +708,10 @@ void tst_QScriptExtQObject::getSetStaticProperty() QVERIFY(!(mobj.propertyFlags("mySlot()") & QScriptValue::SkipInEnumeration)); QVERIFY(mobj.propertyFlags("mySlot()") & QScriptValue::QObjectMember); } +} +void tst_QScriptExtQObject::getSetStaticProperty_changeInCpp() +{ // property change in C++ should be reflected in script m_myObject->setIntProperty(456); QCOMPARE(m_engine->evaluate("myObject.intProperty") @@ -686,7 +735,10 @@ void tst_QScriptExtQObject::getSetStaticProperty() m_myObject->setStringProperty(QLatin1String("zab")); QCOMPARE(m_engine->evaluate("myObject.stringProperty") .equals(QScriptValue(m_engine, QLatin1String("zab"))), true); +} +void tst_QScriptExtQObject::getSetStaticProperty_changeInJS() +{ // property change in script should be reflected in C++ QCOMPARE(m_engine->evaluate("myObject.intProperty = 123") .strictlyEquals(QScriptValue(m_engine, 123)), true); @@ -769,7 +821,10 @@ void tst_QScriptExtQObject::getSetStaticProperty() << QLatin1String("two") << QLatin1String("true")); } +} +void tst_QScriptExtQObject::getSetStaticProperty_compatibleVariantTypes() +{ // test setting properties where we can't convert the type natively but where the // types happen to be compatible variant types already { @@ -788,7 +843,10 @@ void tst_QScriptExtQObject::getSetStaticProperty() mobj.setProperty("propWithCustomType", m_engine->newVariant(qVariantFromValue(t))); QVERIFY(m_myObject->propWithCustomType().string == t.string); } +} +void tst_QScriptExtQObject::getSetStaticProperty_conversion() +{ // test that we do value conversion if necessary when setting properties { QScriptValue br = m_engine->evaluate("myObject.brushProperty"); @@ -808,28 +866,41 @@ void tst_QScriptExtQObject::getSetStaticProperty() m_engine->globalObject().setProperty("myColor", QScriptValue()); } +} +void tst_QScriptExtQObject::getSetStaticProperty_delete() +{ // try to delete QCOMPARE(m_engine->evaluate("delete myObject.intProperty").toBoolean(), false); QCOMPARE(m_engine->evaluate("myObject.intProperty").toNumber(), 123.0); + m_myObject->setVariantProperty(42); QCOMPARE(m_engine->evaluate("delete myObject.variantProperty").toBoolean(), false); QCOMPARE(m_engine->evaluate("myObject.variantProperty").toNumber(), 42.0); +} +void tst_QScriptExtQObject::getSetStaticProperty_nonScriptable() +{ // non-scriptable property QCOMPARE(m_myObject->hiddenProperty(), 456.0); QCOMPARE(m_engine->evaluate("myObject.hiddenProperty").isUndefined(), true); QCOMPARE(m_engine->evaluate("myObject.hiddenProperty = 123;" "myObject.hiddenProperty").toInt32(), 123); QCOMPARE(m_myObject->hiddenProperty(), 456.0); +} +void tst_QScriptExtQObject::getSetStaticProperty_writeOnly() +{ // write-only property QCOMPARE(m_myObject->writeOnlyProperty(), 789); QCOMPARE(m_engine->evaluate("myObject.writeOnlyProperty").isUndefined(), true); QCOMPARE(m_engine->evaluate("myObject.writeOnlyProperty = 123;" "myObject.writeOnlyProperty").isUndefined(), true); QCOMPARE(m_myObject->writeOnlyProperty(), 123); +} +void tst_QScriptExtQObject::getSetStaticProperty_readOnly() +{ // read-only property QCOMPARE(m_myObject->readOnlyProperty(), 987); QCOMPARE(m_engine->evaluate("myObject.readOnlyProperty").toInt32(), 987); @@ -841,7 +912,10 @@ void tst_QScriptExtQObject::getSetStaticProperty() QCOMPARE(mobj.propertyFlags("readOnlyProperty") & QScriptValue::ReadOnly, QScriptValue::ReadOnly); } +} +void tst_QScriptExtQObject::getSetStaticProperty_enum() +{ // enum property QCOMPARE(m_myObject->enumProperty(), MyQObject::BarPolicy); { @@ -866,7 +940,10 @@ void tst_QScriptExtQObject::getSetStaticProperty() QCOMPARE(m_myObject->enumProperty(), MyQObject::BazPolicy); m_engine->evaluate("myObject.enumProperty = 'nada'"); QCOMPARE(m_myObject->enumProperty(), (MyQObject::Policy)-1); +} +void tst_QScriptExtQObject::getSetStaticProperty_qflags() +{ // flags property QCOMPARE(m_myObject->flagsProperty(), MyQObject::FooAbility); { @@ -885,7 +962,10 @@ void tst_QScriptExtQObject::getSetStaticProperty() m_engine->evaluate("myObject.flagsProperty = 'ScoobyDoo'"); // ### ouch! Shouldn't QMetaProperty::write() rather not change the value...? QCOMPARE(m_myObject->flagsProperty(), (MyQObject::Ability)-1); +} +void tst_QScriptExtQObject::getSetStaticProperty_pointerDeref() +{ // auto-dereferencing of pointers { QBrush b = QColor(0xCA, 0xFE, 0xBA, 0xBE); @@ -905,7 +985,10 @@ void tst_QScriptExtQObject::getSetStaticProperty() } m_engine->globalObject().setProperty("brushPointer", QScriptValue()); } +} +void tst_QScriptExtQObject::getSetStaticProperty_customGetterSetter() +{ // install custom property getter+setter { QScriptValue mobj = m_engine->globalObject().property("myObject"); @@ -915,15 +998,19 @@ void tst_QScriptExtQObject::getSetStaticProperty() mobj.setProperty("intProperty", 321); QCOMPARE(mobj.property("intProperty").toInt32(), 321); } +} +void tst_QScriptExtQObject::getSetStaticProperty_methodPersistence() +{ // method properties are persistent { QScriptValue slot = m_engine->evaluate("myObject.mySlot"); QVERIFY(slot.isFunction()); QScriptValue sameSlot = m_engine->evaluate("myObject.mySlot"); QVERIFY(sameSlot.strictlyEquals(slot)); - sameSlot = m_engine->evaluate("myObject[mySlot()]"); - QEXPECT_FAIL("", "Signature-based method lookup creates new function wrapper object", Continue); + sameSlot = m_engine->evaluate("myObject['mySlot()']"); + QVERIFY(sameSlot.isFunction()); + QEXPECT_FAIL("", "QTBUG-17611: Signature-based method lookup creates new function wrapper object", Continue); QVERIFY(sameSlot.strictlyEquals(slot)); } } @@ -963,6 +1050,69 @@ void tst_QScriptExtQObject::getSetDynamicProperty() QCOMPARE(m_engine->evaluate("myObject.hasOwnProperty('dynamicProperty')").toBoolean(), false); } +void tst_QScriptExtQObject::getSetDynamicProperty_deleteFromCpp() +{ + QScriptValue val = m_engine->newQObject(m_myObject); + + m_myObject->setProperty("dynamicFromCpp", 1234); + QVERIFY(val.property("dynamicFromCpp").strictlyEquals(QScriptValue(m_engine, 1234))); + + m_myObject->setProperty("dynamicFromCpp", 4321); + QVERIFY(val.property("dynamicFromCpp").strictlyEquals(QScriptValue(m_engine, 4321))); + QCOMPARE(m_myObject->property("dynamicFromCpp").toInt(), 4321); + + // In this case we delete the property from C++ + m_myObject->setProperty("dynamicFromCpp", QVariant()); + QVERIFY(!m_myObject->property("dynamicFromCpp").isValid()); + QVERIFY(!val.property("dynamicFromCpp").isValid()); +} + +void tst_QScriptExtQObject::getSetDynamicProperty_hideChildObject() +{ + QScriptValue val = m_engine->newQObject(m_myObject); + + // Add our named child and access it + QObject *child = new QObject(m_myObject); + child->setObjectName("testName"); + QCOMPARE(val.property("testName").toQObject(), child); + + // Dynamic properties have precedence, hiding the child object + m_myObject->setProperty("testName", 42); + QVERIFY(val.property("testName").strictlyEquals(QScriptValue(m_engine, 42))); + + // Remove dynamic property + m_myObject->setProperty("testName", QVariant()); + QCOMPARE(val.property("testName").toQObject(), child); +} + +void tst_QScriptExtQObject::getSetDynamicProperty_setBeforeGet() +{ + QScriptValue val = m_engine->newQObject(m_myObject); + + m_myObject->setProperty("dynamic", 1111); + val.setProperty("dynamic", 42); + + QVERIFY(val.property("dynamic").strictlyEquals(QScriptValue(m_engine, 42))); + QCOMPARE(m_myObject->property("dynamic").toInt(), 42); +} + +void tst_QScriptExtQObject::getSetDynamicProperty_doNotHideJSProperty() +{ + QScriptValue val = m_engine->newQObject(m_myObject); + + // Set property on JS and dynamically on our QObject + val.setProperty("x", 42); + m_myObject->setProperty("x", 2222); + + QEXPECT_FAIL("", "QTBUG-17612: Dynamic C++ property overrides JS property", Continue); + + // JS should see the original JS value + QVERIFY(val.property("x").strictlyEquals(QScriptValue(m_engine, 42))); + + // The dynamic property is intact + QCOMPARE(m_myObject->property("x").toInt(), 2222); +} + void tst_QScriptExtQObject::getSetChildren() { QScriptValue mobj = m_engine->evaluate("myObject"); @@ -1130,7 +1280,10 @@ void tst_QScriptExtQObject::callQtInvokable() QCOMPARE(m_myObject->qtFunctionActuals().size(), 2); QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 123); QCOMPARE(m_myObject->qtFunctionActuals().at(1).toInt(), 456); +} +void tst_QScriptExtQObject::callQtInvokable2() +{ m_myObject->resetQtFunctionInvoked(); QVERIFY(m_engine->evaluate("myObject.myInvokableWithVoidStarArg(null)").isUndefined()); QCOMPARE(m_myObject->qtFunctionInvoked(), 44); @@ -1219,7 +1372,10 @@ void tst_QScriptExtQObject::callQtInvokable() QCOMPARE(ret.isArray(), true); QCOMPARE(m_myObject->qtFunctionInvoked(), 11); } +} +void tst_QScriptExtQObject::callQtInvokable3() +{ { QScriptValue ret = m_engine->evaluate("myObject.myInvokableWithVectorOfIntArg(myObject.myInvokableReturningVectorOfInt())"); QCOMPARE(ret.isUndefined(), true); @@ -1345,7 +1501,10 @@ void tst_QScriptExtQObject::callQtInvokable() QCOMPARE(ret.property("0").strictlyEquals(QScriptValue(m_engine, 1)), true); QCOMPARE(ret.property("1").strictlyEquals(QScriptValue(m_engine, 5)), true); } +} +void tst_QScriptExtQObject::callQtInvokable4() +{ m_myObject->resetQtFunctionInvoked(); { QScriptValue ret = m_engine->evaluate("myObject.myInvokableWithQObjectStarArg(myObject)"); @@ -1361,6 +1520,17 @@ void tst_QScriptExtQObject::callQtInvokable() m_myObject->resetQtFunctionInvoked(); { + QScriptValue ret = m_engine->evaluate("myObject.myInvokableWithQWidgetStarArg(null)"); + QVERIFY(ret.isNull()); + QCOMPARE(m_myObject->qtFunctionInvoked(), 63); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QVariant v = m_myObject->qtFunctionActuals().at(0); + QCOMPARE(v.userType(), int(QMetaType::QWidgetStar)); + QCOMPARE(qvariant_cast<QWidget*>(v), (QObject *)0); + } + + m_myObject->resetQtFunctionInvoked(); + { // no implicit conversion from integer to QObject* QScriptValue ret = m_engine->evaluate("myObject.myInvokableWithQObjectStarArg(123)"); QCOMPARE(ret.isError(), true); @@ -1368,6 +1538,64 @@ void tst_QScriptExtQObject::callQtInvokable() m_myObject->resetQtFunctionInvoked(); { + QScriptValue ret = m_engine->evaluate("myObject.myInvokableWithShortArg(123)"); + QVERIFY(ret.isNumber()); + QCOMPARE(m_myObject->qtFunctionInvoked(), 64); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QVariant v = m_myObject->qtFunctionActuals().at(0); + QCOMPARE(v.userType(), int(QMetaType::Short)); + QCOMPARE(qvariant_cast<short>(v), short(123)); + } + + m_myObject->resetQtFunctionInvoked(); + { + QScriptValue ret = m_engine->evaluate("myObject.myInvokableWithUShortArg(123)"); + QVERIFY(ret.isNumber()); + QCOMPARE(m_myObject->qtFunctionInvoked(), 65); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QVariant v = m_myObject->qtFunctionActuals().at(0); + QCOMPARE(v.userType(), int(QMetaType::UShort)); + QCOMPARE(qvariant_cast<ushort>(v), ushort(123)); + } + + m_myObject->resetQtFunctionInvoked(); + { + QScriptValue ret = m_engine->evaluate("myObject.myInvokableWithCharArg(123)"); + QVERIFY(ret.isNumber()); + QCOMPARE(m_myObject->qtFunctionInvoked(), 66); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QVariant v = m_myObject->qtFunctionActuals().at(0); + QCOMPARE(v.userType(), int(QMetaType::Char)); + QCOMPARE(qvariant_cast<char>(v), char(123)); + } + + m_myObject->resetQtFunctionInvoked(); + { + QScriptValue ret = m_engine->evaluate("myObject.myInvokableWithUCharArg(123)"); + QVERIFY(ret.isNumber()); + QCOMPARE(m_myObject->qtFunctionInvoked(), 67); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QVariant v = m_myObject->qtFunctionActuals().at(0); + QCOMPARE(v.userType(), int(QMetaType::UChar)); + QCOMPARE(qvariant_cast<uchar>(v), uchar(123)); + } + + m_myObject->resetQtFunctionInvoked(); + { + QScriptValue ret = m_engine->evaluate("myObject.myInvokableWithULonglongArg(123)"); + QVERIFY(ret.isNumber()); + QCOMPARE(m_myObject->qtFunctionInvoked(), 68); + QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); + QVariant v = m_myObject->qtFunctionActuals().at(0); + QCOMPARE(v.userType(), int(QMetaType::ULongLong)); + QCOMPARE(qvariant_cast<qulonglong>(v), qulonglong(123)); + } +} + +void tst_QScriptExtQObject::callQtInvokable5() +{ + m_myObject->resetQtFunctionInvoked(); + { QScriptValue fun = m_engine->evaluate("myObject.myInvokableWithQBrushArg"); QVERIFY(fun.isFunction()); QColor color(10, 20, 30, 40); @@ -1453,7 +1681,10 @@ void tst_QScriptExtQObject::callQtInvokable() QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); QCOMPARE(qvariant_cast<QObject*>(m_myObject->qtFunctionActuals().at(0)), (QObject*)m_myObject); } +} +void tst_QScriptExtQObject::callQtInvokable6() +{ // QScriptValue arguments should be passed on without conversion m_myObject->resetQtFunctionInvoked(); { @@ -1517,18 +1748,21 @@ void tst_QScriptExtQObject::callQtInvokable() QCOMPARE(m_myObject->qtFunctionInvoked(), 55); } } +} +void tst_QScriptExtQObject::callQtInvokable7() +{ // qscript_call() { m_myObject->resetQtFunctionInvoked(); QScriptValue ret = m_engine->evaluate("new myObject(123)"); QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'myObject' [MyQObject(name = \"\")] is not a constructor.")); + QVERIFY(ret.toString().contains(QString::fromLatin1("TypeError"))); } { m_myObject->resetQtFunctionInvoked(); QScriptValue ret = m_engine->evaluate("myObject(123)"); - QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'myObject' [MyQObject(name = \"\")] is not a function.")); + QVERIFY(ret.toString().contains(QString::fromLatin1("TypeError"))); } // task 233624 @@ -1670,6 +1904,7 @@ void tst_QScriptExtQObject::connectAndDisconnect() m_myObject->emitMySignalWithVariantArg(123); QCOMPARE(m_engine->evaluate("gotSignal").toBoolean(), true); QCOMPARE(m_engine->evaluate("signalArgs.length").toNumber(), 1.0); + QVERIFY(m_engine->evaluate("signalArgs[0]").isNumber()); QCOMPARE(m_engine->evaluate("signalArgs[0]").toNumber(), 123.0); QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.disconnect(myHandler)").isUndefined()); @@ -1685,16 +1920,29 @@ void tst_QScriptExtQObject::connectAndDisconnect() QVERIFY(m_engine->evaluate("signalArgs[0]").isUndefined()); QVERIFY(m_engine->evaluate("myObject.mySignalWithScriptEngineArg.disconnect(myHandler)").isUndefined()); - // signal with QVariant arg: argument conversion should work + // signal with QVariant arg: QVariant should be unwrapped only once m_myObject->clearConnectedSignal(); QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.connect(myHandler)").isUndefined()); QCOMPARE(m_myObject->connectedSignal().constData(), SIGNAL(mySignalWithVariantArg(QVariant))); m_engine->evaluate("gotSignal = false"); - m_myObject->emitMySignalWithVariantArg(123); + QVariant tmp(123); + QVariant signalArg(QMetaType::QVariant, &tmp); + m_myObject->emitMySignalWithVariantArg(signalArg); QCOMPARE(m_engine->evaluate("gotSignal").toBoolean(), true); QCOMPARE(m_engine->evaluate("signalArgs.length").toNumber(), 1.0); - QVERIFY(m_engine->evaluate("signalArgs[0]").isNumber()); - QCOMPARE(m_engine->evaluate("signalArgs[0]").toNumber(), 123.0); + QVERIFY(m_engine->evaluate("signalArgs[0]").isVariant()); + QCOMPARE(m_engine->evaluate("signalArgs[0]").toVariant().toDouble(), 123.0); + QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.disconnect(myHandler)").isUndefined()); + + // signal with QVariant arg: with an invalid QVariant + m_myObject->clearConnectedSignal(); + QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.connect(myHandler)").isUndefined()); + QCOMPARE(m_myObject->connectedSignal().constData(), SIGNAL(mySignalWithVariantArg(QVariant))); + m_engine->evaluate("gotSignal = false"); + m_myObject->emitMySignalWithVariantArg(QVariant()); + QCOMPARE(m_engine->evaluate("gotSignal").toBoolean(), true); + QCOMPARE(m_engine->evaluate("signalArgs.length").toNumber(), 1.0); + QVERIFY(m_engine->evaluate("signalArgs[0]").isUndefined()); QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.disconnect(myHandler)").isUndefined()); // signal with argument type that's unknown to the meta-type system @@ -1751,9 +1999,10 @@ void tst_QScriptExtQObject::connectAndDisconnect() QVERIFY(m_engine->evaluate("myObject.mySignal.connect(myObject, 'mySlot')").isUndefined()); QVERIFY(m_engine->evaluate("myObject.mySignal.disconnect(yetAnotherObject, 'func')").isUndefined()); QVERIFY(m_engine->evaluate("myObject.mySignal.disconnect(myObject, 'mySlot')").isUndefined()); +} - // check that emitting signals from script works - +void tst_QScriptExtQObject::connectAndDisconnect_emitFromJS() +{ // no arguments QVERIFY(m_engine->evaluate("myObject.mySignal.connect(myObject.mySlot)").isUndefined()); m_myObject->resetQtFunctionInvoked(); @@ -1802,7 +2051,10 @@ void tst_QScriptExtQObject::connectAndDisconnect() QCOMPARE(m_myObject->qtFunctionActuals().size(), 1); QCOMPARE(m_myObject->qtFunctionActuals().at(0).toInt(), 456); QVERIFY(m_engine->evaluate("myObject.mySignalWithIntArg.disconnect(myObject['myOverloadedSlot(int)'])").isUndefined()); +} +void tst_QScriptExtQObject::connectAndDisconnect_senderWrapperCollected() +{ // when the wrapper dies, the connection stays alive QVERIFY(m_engine->evaluate("myObject.mySignal.connect(myObject.mySlot)").isUndefined()); m_myObject->resetQtFunctionInvoked(); @@ -1902,6 +2154,25 @@ void tst_QScriptExtQObject::connectAndDisconnectWithBadArgs() } } +void tst_QScriptExtQObject::connectAndDisconnect_senderDeleted() +{ + QScriptEngine eng; + QObject *obj = new QObject; + eng.globalObject().setProperty("obj", eng.newQObject(obj)); + eng.evaluate("signal = obj.destroyed"); + delete obj; + { + QScriptValue ret = eng.evaluate("signal.connect(function(){})"); + QVERIFY(ret.isError()); + QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Function.prototype.connect: cannot connect to deleted QObject")); + } + { + QScriptValue ret = eng.evaluate("signal.disconnect(function(){})"); + QVERIFY(ret.isError()); + QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Function.prototype.discconnect: cannot disconnect from deleted QObject")); + } +} + void tst_QScriptExtQObject::cppConnectAndDisconnect() { QScriptEngine eng; @@ -1971,7 +2242,14 @@ void tst_QScriptExtQObject::cppConnectAndDisconnect() QVERIFY(!qScriptDisconnect(&edit2, SIGNAL(textChanged(const QString &)), receiver, fun)); } } +} +void tst_QScriptExtQObject::cppConnectAndDisconnect2() +{ + QScriptEngine eng; + QLineEdit edit; + QLineEdit edit2; + QScriptValue fun = eng.evaluate("function fun(text) { signalObject = this; signalArg = text; }; fun"); // make sure we don't crash when engine is deleted { QScriptEngine *eng2 = new QScriptEngine; @@ -2490,6 +2768,49 @@ void tst_QScriptExtQObject::findChildren() delete child; } +void tst_QScriptExtQObject::childObjects() +{ + QObject *child1 = new QObject(m_myObject); + child1->setObjectName("child1"); + QObject *child2 = new QObject(m_myObject); + QScriptValue wrapped = m_engine->newQObject(m_myObject); + + QVERIFY(wrapped.property("child1").isQObject()); + QCOMPARE(wrapped.property("child1").toQObject(), child1); + QVERIFY(!wrapped.property("child2").isQObject()); + QVERIFY(!wrapped.property("child2").isValid()); + + // Setting the name later + child2->setObjectName("child2"); + + QVERIFY(wrapped.property("child1").isQObject()); + QCOMPARE(wrapped.property("child1").toQObject(), child1); + QVERIFY(wrapped.property("child2").isQObject()); + QCOMPARE(wrapped.property("child2").toQObject(), child2); + + // Adding a child later + QObject *child3 = new QObject(m_myObject); + child3->setObjectName("child3"); + + QVERIFY(wrapped.property("child3").isQObject()); + QCOMPARE(wrapped.property("child3").toQObject(), child3); + + // Changing a child name + child1->setObjectName("anotherName"); + + QVERIFY(!wrapped.property("child1").isValid()); + QVERIFY(wrapped.property("anotherName").isQObject()); + QCOMPARE(wrapped.property("anotherName").toQObject(), child1); + + // Creating another object wrapper excluding child from + // properties. + QScriptValue wrapped2 = m_engine->newQObject(m_myObject, QScriptEngine::QtOwnership, QScriptEngine::ExcludeChildObjects); + + QVERIFY(!wrapped2.property("anotherName").isValid()); + QVERIFY(!wrapped2.property("child2").isValid()); + QVERIFY(!wrapped2.property("child3").isValid()); +} + void tst_QScriptExtQObject::overloadedSlots() { // should pick myOverloadedSlot(double) diff --git a/tests/auto/qscriptjstestsuite/expect_fail.txt b/tests/auto/qscriptjstestsuite/expect_fail.txt new file mode 100644 index 0000000..7f93378 --- /dev/null +++ b/tests/auto/qscriptjstestsuite/expect_fail.txt @@ -0,0 +1,198 @@ +ecma/Array/15.4.3.1-2.js | var props = ''; for ( p in Array ) { props += p } props + +ecma/Boolean/15.6.3.1-1.js | var str='';for ( p in Boolean ) { str += p } str; + +ecma/Expressions/11.4.1.js | var abc; delete(abc) + +ecma/FunctionObjects/15.3.3.1-2.js | var str='';for (prop in Function ) str += prop; str; + +ecma/ObjectObjects/15.2.3.1-1.js | var str = '';for ( p in Object ) { str += p; }; str + +ecma/Statements/12.6.3-11.js | result = ""; for ( p in Number ) { result += String(p) }; +ecma/Statements/12.6.3-2.js | Boolean.prototype.foo = 34; for ( j in Boolean ) Boolean[j] + +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4256) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4257) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4258) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4259) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4260) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4261) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4262) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4263) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4264) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4265) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4266) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4267) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4268) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4269) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4270) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4271) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4272) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4273) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4274) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4275) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4276) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4277) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4278) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4279) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4280) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4281) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4282) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4283) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4284) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4285) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4286) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4287) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4288) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4289) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4290) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4291) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4292) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-2.js | var s = new String( String.fromCharCode(4293) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-5.js | var s = new String( String.fromCharCode(1024) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.11-5.js | var s = new String( String.fromCharCode(1037) ); s.toLowerCase().charCodeAt(0) +ecma/String/15.5.4.12-1.js | var s = new String( String.fromCharCode(181) ); s.toUpperCase().charCodeAt(0) +ecma/String/15.5.4.12-1.js | var s = new String( String.fromCharCode(329) ); s.toUpperCase().charCodeAt(0) +ecma/String/15.5.4.12-4.js | var s = new String( String.fromCharCode(1104) ); s.toUpperCase().charCodeAt(0) +ecma/String/15.5.4.12-4.js | var s = new String( String.fromCharCode(1117) ); s.toUpperCase().charCodeAt(0) +ecma/String/15.5.4.12-5.js | var s = new String( String.fromCharCode(1415) ); s.toUpperCase().charCodeAt(0) + +ecma/TypeConversion/9.3.1-3.js | -"\u20001234\u2001" +ecma/TypeConversion/9.3.1-3.js | - "-0x123456789abcde8" + +ecma/extensions/15.1.2.1-1.js | var PROPS = ''; for ( p in eval ) { PROPS += p }; PROPS + +ecma/GlobalObject/15.1.2.2-1.js | var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS +ecma/GlobalObject/15.1.2.3-1.js | var MYPROPS=''; for ( var p in parseFloat ) { MYPROPS += p }; MYPROPS +ecma/GlobalObject/15.1.2.4.js | var MYPROPS=''; for ( var p in escape ) { MYPROPS+= p}; MYPROPS +ecma/GlobalObject/15.1.2.5-1.js | var MYPROPS=''; for ( var p in unescape ) { MYPROPS+= p }; MYPROPS +ecma/GlobalObject/15.1.2.6.js | var MYPROPS=''; for ( var p in isNaN ) { MYPROPS+= p }; MYPROPS +ecma/GlobalObject/15.1.2.7.js | var MYPROPS=''; for ( p in isFinite ) { MYPROPS+= p }; MYPROPS + +ecma_3/Array/15.4.5.1-01.js | 15.4.5.1 - array.length coverage + +ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 0 +ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 1 +ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 2 +ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 3 +ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 4 +ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 5 +ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 6 +ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 7 +ecma_3/extensions/regress-274152.js | Do not ignore unicode format-control characters: 8 +ecma_3/extensions/regress-368516.js | Treat unicode BOM characters as whitespace: 0 +ecma_3/extensions/regress-368516.js | Treat unicode BOM characters as whitespace: 1 + +ecma_3/Date/15.9.4.3.js | 15.9.4.3 - Date.UTC edge-case arguments.: date Infinity +ecma_3/Date/15.9.4.3.js | 15.9.4.3 - Date.UTC edge-case arguments.: hours Infinity +ecma_3/Date/15.9.4.3.js | 15.9.4.3 - Date.UTC edge-case arguments.: minutes Infinity +ecma_3/Date/15.9.4.3.js | 15.9.4.3 - Date.UTC edge-case arguments.: seconds Infinity +ecma_3/Function/regress-131964.js | Section 1 of test - +ecma_3/Function/regress-313570.js | length of objects whose prototype chain includes a function: immutable +ecma_3/FunExpr/fe-001.js | Both functions were defined. + +ecma_3/LexicalConventions/7.9.1.js | Automatic Semicolon insertion in postfix expressions: expr\n++ +ecma_3/LexicalConventions/7.9.1.js | Automatic Semicolon insertion in postfix expressions: expr\n-- +ecma_3/LexicalConventions/7.9.1.js | Automatic Semicolon insertion in postfix expressions: (x\n)-- y +ecma_3/LexicalConventions/7.9.1.js | Automatic Semicolon insertion in postfix expressions: (x)-- y + +ecma_3/Object/8.6.1-01.js | In strict mode, setting a read-only property should generate a warning: Throw if STRICT and WERROR is enabled + +ecma_3/Operators/order-01.js | operator evaluation order: 11.8.2 > +ecma_3/Operators/order-01.js | operator evaluation order: 11.8.4 >= + +ecma_3/RegExp/15.10.2-1.js | Section 7 of test - \nregexp = /(z)((a+)?(b+)?(c))*/\nstring = 'zaacbbbcac'\nERROR !!! regexp failed to give expected match array:\nExpect: ["zaacbbbcac", "z", "ac", "a", , "c"]\nActual: ["zaacbbbcac", "z", "ac", "a", "bbb", "c"]\n +ecma_3/RegExp/15.10.2-1.js | Section 8 of test - \nregexp = /(a*)*/\nstring = 'b'\nERROR !!! regexp failed to give expected match array:\nExpect: ["", , ]\nActual: ["", ""]\n +ecma_3/RegExp/15.10.2-1.js | Section 12 of test - \nregexp = /(.*?)a(?!(a+)b\2c)\2(.*)/\nstring = 'baaabaac'\nERROR !!! regexp failed to give expected match array:\nExpect: ["baaabaac", "ba", , "abaac"]\nActual: ["baaabaac", "ba", "aa", "abaac"]\n +ecma_3/RegExp/perlstress-001.js | Section 218 of test - \nregexp = /((foo)|(bar))*/\nstring = 'foobar'\nERROR !!! regexp failed to give expected match array:\nExpect: ["foobar", "bar", , "bar"]\nActual: ["foobar", "bar", "foo", "bar"]\n +ecma_3/RegExp/perlstress-001.js | Section 234 of test - \nregexp = /(?:(f)(o)(o)|(b)(a)(r))*/\nstring = 'foobar'\nERROR !!! regexp failed to give expected match array:\nExpect: ["foobar", , , , "b", "a", "r"]\nActual: ["foobar", "f", "o", "o", "b", "a", "r"]\n +ecma_3/RegExp/perlstress-001.js | Section 241 of test - \nregexp = /^(?:b|a(?=(.)))*\1/\nstring = 'abc'\nERROR !!! regexp failed to give expected match array:\nExpect: ["ab", , ]\nActual: ["ab", "b"]\n +ecma_3/RegExp/perlstress-001.js | Section 412 of test - \nregexp = /^(a(b)?)+$/\nstring = 'aba'\nERROR !!! regexp failed to give expected match array:\nExpect: ["aba", "a", , ]\nActual: ["aba", "a", "b"]\n +ecma_3/RegExp/perlstress-001.js | Section 413 of test - \nregexp = /^(aa(bb)?)+$/\nstring = 'aabbaa'\nERROR !!! regexp failed to give expected match array:\nExpect: ["aabbaa", "aa", , ]\nActual: ["aabbaa", "aa", "bb"]\n + +ecma_3/RegExp/regress-209919.js | Section 1 of test - \nregexp = /(a|b*)*/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: ["a", "a"]\nActual: ["a", ""]\n +ecma_3/RegExp/regress-209919.js | Section 3 of test - \nregexp = /(b*)*/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: ["", , ]\nActual: ["", ""]\n +ecma_3/RegExp/regress-209919.js | Section 5 of test - \nregexp = /^\-?(\d{1,}|\.{0,})*(\,\d{1,})?$/\nstring = '100.00'\nERROR !!! regexp failed to give expected match array:\nExpect: ["100.00", "00", , ]\nActual: ["100.00", "", , ]\n +ecma_3/RegExp/regress-209919.js | Section 6 of test - \nregexp = /^\-?(\d{1,}|\.{0,})*(\,\d{1,})?$/\nstring = '100,00'\nERROR !!! regexp failed to give expected match array:\nExpect: ["100,00", "100", ",00"]\nActual: ["100,00", "", ",00"]\n +ecma_3/RegExp/regress-209919.js | Section 7 of test - \nregexp = /^\-?(\d{1,}|\.{0,})*(\,\d{1,})?$/\nstring = '1.000,00'\nERROR !!! regexp failed to give expected match array:\nExpect: ["1.000,00", "000", ",00"]\nActual: ["1.000,00", "", ",00"]\n + +ecma_3/String/15.5.4.11.js | Section 7 +ecma_3/String/15.5.4.11.js | Section 24 +ecma_3/String/15.5.4.11.js | Section 26 +ecma_3/String/15.5.4.11.js | Section 28 +ecma_3/String/15.5.4.11.js | Section 30 +ecma_3/String/15.5.4.14.js | 15.5.4.14 - String.prototype.split(/()/) + +ecma_3/Unicode/regress-352044-01.js | issues with Unicode escape sequences in JavaScript source code +ecma_3/Unicode/uc-001.js | Unicode format-control character test (Category Cf.) + +ecma_2/RegExp/exec-001.js | NO TESTS EXIST +ecma_2/String/replace-001.js | NO TESTS EXIST + +[Q_CC_MSVC] +ecma_3/Expressions/11.7.3-01.js | 11.7.3 - >>> should evaluate operands in order: order | QTBUG-8056 +ecma_3/Operators/order-01.js | operator evaluation order: 11.7.3 >>> | QTBUG-8056 +ecma_3/Operators/order-01.js | operator evaluation order: 11.13.2 >>>= | QTBUG-8056 + +[Q_CC_MINGW] +ecma/Math/15.8.2.13.js | Math.pow(NaN,0) +ecma/Math/15.8.2.13.js | Math.pow(NaN,-0) +ecma/Math/15.8.2.5.js | Math.atan2(Infinity, Infinity) +ecma/Math/15.8.2.5.js | Math.atan2(Infinity, -Infinity) +ecma/Math/15.8.2.5.js | Math.atan2(-Infinity, Infinity) +ecma/Math/15.8.2.5.js | Math.atan2(-Infinity, -Infinity) + +[Q_OS_SOLARIS] +ecma/Expressions/11.13.2-2.js | VAR1 = -0; VAR2= Infinity; VAR2 /= VAR1 +ecma/Expressions/11.13.2-2.js | VAR1 = -0; VAR2= -Infinity; VAR2 /= VAR1 +ecma/Expressions/11.13.2-2.js | VAR1 = 1; VAR2= -0; VAR1 /= VAR2 +ecma/Expressions/11.13.2-2.js | VAR1 = -1; VAR2= -0; VAR1 /= VAR2 +ecma/Expressions/11.5.2.js | Number.POSITIVE_INFINITY / -0 +ecma/Expressions/11.5.2.js | Number.NEGATIVE_INFINITY / -0 +ecma/Expressions/11.5.2.js | 1 / -0 +ecma/Expressions/11.5.2.js | -1 / -0 +ecma/Math/15.8.2.10.js | Math.log(-0.0000001) +ecma/Math/15.8.2.10.js | Math.log(-1) +ecma/Math/15.8.2.11.js | Infinity/Math.max(-0,-0) +ecma/Math/15.8.2.12.js | Infinity/Math.min(0,-0) +ecma/Math/15.8.2.12.js | Infinity/Math.min(-0,-0) +ecma/Math/15.8.2.13.js | Math.pow(NaN,0) +ecma/Math/15.8.2.13.js | Math.pow(NaN,-0) +ecma/Math/15.8.2.13.js | Infinity/Math.pow(-Infinity, -1) +ecma/Math/15.8.2.13.js | Math.pow(0, -1) +ecma/Math/15.8.2.13.js | Math.pow(0, -0.5) +ecma/Math/15.8.2.13.js | Math.pow(0, -1000) +ecma/Math/15.8.2.13.js | Infinity/Math.pow(-0, 1) +ecma/Math/15.8.2.13.js | Infinity/Math.pow(-0, 3) +ecma/Math/15.8.2.13.js | Math.pow(-0, -2) +ecma/Math/15.8.2.15.js | Infinity/Math.round(-0) +ecma/Math/15.8.2.15.js | Infinity/Math.round(-0.49) +ecma/Math/15.8.2.15.js | Infinity/Math.round(-0.5) +ecma/Math/15.8.2.17.js | Infinity/Math.sqrt(-0) +ecma/Math/15.8.2.18.js | Infinity/Math.tan(-0) +ecma/Math/15.8.2.2.js | Math.acos(1.00000001) +ecma/Math/15.8.2.2.js | Math.acos(11.00000001) +ecma/Math/15.8.2.3.js | Math.asin(1.000001) +ecma/Math/15.8.2.3.js | Math.asin(-1.000001) +ecma/Math/15.8.2.3.js | Infinity/Math.asin(-0) +ecma/Math/15.8.2.4.js | Infinity/Math.atan(-0) +ecma/Math/15.8.2.5.js | Math.atan2(0, -0) +ecma/Math/15.8.2.5.js | Infinity/Math.atan2(-0, 1) +ecma/Math/15.8.2.5.js | Math.atan2(-0,\t-0) +ecma/Math/15.8.2.5.js | Math.atan2(-0,\t-1) +ecma/Math/15.8.2.6.js | Infinity/Math.ceil('-0') +ecma/Math/15.8.2.6.js | Infinity/Math.ceil(-0) +ecma/Math/15.8.2.6.js | Infinity/Math.ceil(-Number.MIN_VALUE) +ecma/Math/15.8.2.6.js | Infinity/Math.ceil(-0.9) +ecma/Math/15.8.2.9.js | Infinity/Math.floor(-0) +ecma/TypeConversion/9.3.1-3.js | var z = 0; print(1/-z) +ecma/TypeConversion/9.3.1-3.js | 1/-1e-2000 + +[Q_OS_SYMBIAN] +ecma/Math/15.8.2.13.js | Math.pow(-1, 0.5) +ecma/Math/15.8.2.13.js | Math.pow(-1, -0.5) +ecma_3/Operators/order-01.js | operator evaluation order: 11.5.1 * +ecma_3/Operators/order-01.js | operator evaluation order: 11.5.2 / +ecma_3/Operators/order-01.js | operator evaluation order: 11.6.2 - +ecma_3/Operators/order-01.js | operator evaluation order: 11.13.2 *= +ecma_3/Operators/order-01.js | operator evaluation order: 11.13.2 /= diff --git a/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro b/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro index 07a4672..471aa02 100644 --- a/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro +++ b/tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro @@ -1,11 +1,13 @@ load(qttest_p4) QT = core script SOURCES += tst_qscriptjstestsuite.cpp +RESOURCES += qscriptjstestsuite.qrc +include(../qscriptv8testsuite/abstracttestsuite.pri) !symbian: DEFINES += SRCDIR=\\\"$$PWD\\\" wince*|symbian: { -testFiles.sources = tests +testFiles.files = tests testFiles.path = . DEPLOYMENT += testFiles } diff --git a/tests/auto/qscriptjstestsuite/qscriptjstestsuite.qrc b/tests/auto/qscriptjstestsuite/qscriptjstestsuite.qrc new file mode 100644 index 0000000..4a4eb60 --- /dev/null +++ b/tests/auto/qscriptjstestsuite/qscriptjstestsuite.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>expect_fail.txt</file> + <file>skip.txt</file> +</qresource> +</RCC> diff --git a/tests/auto/qscriptjstestsuite/skip.txt b/tests/auto/qscriptjstestsuite/skip.txt new file mode 100644 index 0000000..2dc0ccb --- /dev/null +++ b/tests/auto/qscriptjstestsuite/skip.txt @@ -0,0 +1,9 @@ +.+/15\.9\.2\..+ | unstable on slow machines +.+/15\.9\.5\..+ | too slooow +regress-130451.js | asserts +regress-322135-01.js | asserts +regress-322135-02.js | asserts +regress-322135-03.js | takes forever +regress-322135-04.js | takes forever +ecma_3/RegExp/regress-375715-04.js | bug +ecma_3/RegExp/regress-289669.js | Can fail due to relying on wall-clock time diff --git a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp index 36df805..0e4f5b9 100644 --- a/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp +++ b/tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp @@ -40,44 +40,18 @@ ****************************************************************************/ +#include "abstracttestsuite.h" #include <QtTest/QtTest> #include <QtScript> #if defined(Q_OS_SYMBIAN) -# define SRCDIR "" +# define SRCDIR "." #endif //TESTED_CLASS= //TESTED_FILES= -// Uncomment the following define to have the autotest generate -// addExpectedFailure() code for all the tests that fail. -// This is useful when a whole new test (sub)suite is added. -// The code is stored in addexpectedfailures.cpp. -// Paste the contents into this file after the existing -// addExpectedFailure() calls. - -//#define GENERATE_ADDEXPECTEDFAILURE_CODE - -static QString readFile(const QString &filename) -{ - QFile file(filename); - if (!file.open(QFile::ReadOnly)) - return QString(); - QTextStream stream(&file); - return stream.readAll(); -} - -static void appendCString(QVector<char> *v, const char *s) -{ - char c; - do { - c = *(s++); - *v << c; - } while (c != '\0'); -} - struct TestRecord { TestRecord() : lineNumber(-1) { } @@ -120,17 +94,18 @@ struct FailureItem QString message; }; -class tst_Suite : public QObject +class tst_QScriptJSTestSuite : public AbstractTestSuite { public: - tst_Suite(); - virtual ~tst_Suite(); + tst_QScriptJSTestSuite(); + virtual ~tst_QScriptJSTestSuite(); - static QMetaObject staticMetaObject; - virtual const QMetaObject *metaObject() const; - virtual void *qt_metacast(const char *); - virtual int qt_metacall(QMetaObject::Call, int, void **argv); +protected: + virtual void configData(TestConfig::Mode mode, const QStringList &parts); + virtual void writeSkipConfigFile(QTextStream &); + virtual void writeExpectFailConfigFile(QTextStream &); + virtual void runTestFunction(int testIndex); private: void addExpectedFailure(const QString &fileName, const QString &description, const QString &message); @@ -143,33 +118,11 @@ private: void addFileExclusion(const QRegExp &rx, const QString &message); bool isExcludedFile(const QString &fileName, QString *message) const; - QDir testsDir; QList<QString> subSuitePaths; QList<FailureItem> expectedFailures; QList<QPair<QRegExp, QString> > fileExclusions; -#ifdef GENERATE_ADDEXPECTEDFAILURE_CODE - QString generatedAddExpectedFailureCode; -#endif }; -QMetaObject tst_Suite::staticMetaObject; - -Q_GLOBAL_STATIC(QVector<uint>, qt_meta_data_tst_Suite) -Q_GLOBAL_STATIC(QVector<char>, qt_meta_stringdata_tst_Suite) - -const QMetaObject *tst_Suite::metaObject() const -{ - return &staticMetaObject; -} - -void *tst_Suite::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_tst_Suite()->constData())) - return static_cast<void*>(const_cast<tst_Suite*>(this)); - return QObject::qt_metacast(_clname); -} - static QScriptValue qscript_void(QScriptContext *, QScriptEngine *eng) { return eng->undefinedValue(); @@ -222,625 +175,245 @@ static QScriptValue qscript_TestCase(QScriptContext *ctx, QScriptEngine *eng) return ret; } -int tst_Suite::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +void tst_QScriptJSTestSuite::runTestFunction(int testIndex) { - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (!(_id & 1)) { - // data - QTest::addColumn<TestRecord>("record"); - bool hasData = false; - - QString testsShellPath = testsDir.absoluteFilePath("shell.js"); - QString testsShellContents = readFile(testsShellPath); - - QDir subSuiteDir(subSuitePaths.at(_id / 2)); - QString subSuiteShellPath = subSuiteDir.absoluteFilePath("shell.js"); - QString subSuiteShellContents = readFile(subSuiteShellPath); - - QDir testSuiteDir(subSuiteDir); - testSuiteDir.cdUp(); - QString suiteJsrefPath = testSuiteDir.absoluteFilePath("jsref.js"); - QString suiteJsrefContents = readFile(suiteJsrefPath); - QString suiteShellPath = testSuiteDir.absoluteFilePath("shell.js"); - QString suiteShellContents = readFile(suiteShellPath); - - QFileInfoList testFileInfos = subSuiteDir.entryInfoList(QStringList() << "*.js", QDir::Files); - foreach (QFileInfo tfi, testFileInfos) { - if ((tfi.fileName() == "shell.js") || (tfi.fileName() == "browser.js")) - continue; - - QString abspath = tfi.absoluteFilePath(); - QString relpath = testsDir.relativeFilePath(abspath); - QString excludeMessage; - if (isExcludedFile(relpath, &excludeMessage)) { - QTest::newRow(relpath.toLatin1()) << TestRecord(excludeMessage, relpath); - continue; - } + if (!(testIndex & 1)) { + // data + QTest::addColumn<TestRecord>("record"); + bool hasData = false; + + QString testsShellPath = testsDir.absoluteFilePath("shell.js"); + QString testsShellContents = readFile(testsShellPath); + + QDir subSuiteDir(subSuitePaths.at(testIndex / 2)); + QString subSuiteShellPath = subSuiteDir.absoluteFilePath("shell.js"); + QString subSuiteShellContents = readFile(subSuiteShellPath); + + QDir testSuiteDir(subSuiteDir); + testSuiteDir.cdUp(); + QString suiteJsrefPath = testSuiteDir.absoluteFilePath("jsref.js"); + QString suiteJsrefContents = readFile(suiteJsrefPath); + QString suiteShellPath = testSuiteDir.absoluteFilePath("shell.js"); + QString suiteShellContents = readFile(suiteShellPath); + + QFileInfoList testFileInfos = subSuiteDir.entryInfoList(QStringList() << "*.js", QDir::Files); + foreach (QFileInfo tfi, testFileInfos) { + if ((tfi.fileName() == "shell.js") || (tfi.fileName() == "browser.js")) + continue; + + QString abspath = tfi.absoluteFilePath(); + QString relpath = testsDir.relativeFilePath(abspath); + QString excludeMessage; + if (isExcludedFile(relpath, &excludeMessage)) { + QTest::newRow(relpath.toLatin1()) << TestRecord(excludeMessage, relpath); + continue; + } - QScriptEngine eng; - QScriptValue global = eng.globalObject(); - global.setProperty("print", eng.newFunction(qscript_void)); - global.setProperty("quit", eng.newFunction(qscript_quit)); - global.setProperty("options", eng.newFunction(qscript_options)); - - eng.evaluate(testsShellContents, testsShellPath); - if (eng.hasUncaughtException()) { - QStringList bt = eng.uncaughtExceptionBacktrace(); - QString err = eng.uncaughtException().toString(); - qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); - break; - } + QScriptEngine eng; + QScriptValue global = eng.globalObject(); + global.setProperty("print", eng.newFunction(qscript_void)); + global.setProperty("quit", eng.newFunction(qscript_quit)); + global.setProperty("options", eng.newFunction(qscript_options)); + + eng.evaluate(testsShellContents, testsShellPath); + if (eng.hasUncaughtException()) { + QStringList bt = eng.uncaughtExceptionBacktrace(); + QString err = eng.uncaughtException().toString(); + qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); + break; + } - eng.evaluate(suiteJsrefContents, suiteJsrefPath); - if (eng.hasUncaughtException()) { - QStringList bt = eng.uncaughtExceptionBacktrace(); - QString err = eng.uncaughtException().toString(); - qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); - break; - } + eng.evaluate(suiteJsrefContents, suiteJsrefPath); + if (eng.hasUncaughtException()) { + QStringList bt = eng.uncaughtExceptionBacktrace(); + QString err = eng.uncaughtException().toString(); + qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); + break; + } - eng.evaluate(suiteShellContents, suiteShellPath); - if (eng.hasUncaughtException()) { - QStringList bt = eng.uncaughtExceptionBacktrace(); - QString err = eng.uncaughtException().toString(); - qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); - break; - } + eng.evaluate(suiteShellContents, suiteShellPath); + if (eng.hasUncaughtException()) { + QStringList bt = eng.uncaughtExceptionBacktrace(); + QString err = eng.uncaughtException().toString(); + qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); + break; + } - eng.evaluate(subSuiteShellContents, subSuiteShellPath); - if (eng.hasUncaughtException()) { - QStringList bt = eng.uncaughtExceptionBacktrace(); - QString err = eng.uncaughtException().toString(); - qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); - break; - } + eng.evaluate(subSuiteShellContents, subSuiteShellPath); + if (eng.hasUncaughtException()) { + QStringList bt = eng.uncaughtExceptionBacktrace(); + QString err = eng.uncaughtException().toString(); + qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); + break; + } - QScriptValue origTestCaseCtor = global.property("TestCase"); - QScriptValue myTestCaseCtor = eng.newFunction(qscript_TestCase); - myTestCaseCtor.setData(origTestCaseCtor); - global.setProperty("TestCase", myTestCaseCtor); + QScriptValue origTestCaseCtor = global.property("TestCase"); + QScriptValue myTestCaseCtor = eng.newFunction(qscript_TestCase); + myTestCaseCtor.setData(origTestCaseCtor); + global.setProperty("TestCase", myTestCaseCtor); - global.setProperty("gTestfile", tfi.fileName()); - global.setProperty("gTestsuite", testSuiteDir.dirName()); - global.setProperty("gTestsubsuite", subSuiteDir.dirName()); - QString testFileContents = readFile(abspath); + global.setProperty("gTestfile", tfi.fileName()); + global.setProperty("gTestsuite", testSuiteDir.dirName()); + global.setProperty("gTestsubsuite", subSuiteDir.dirName()); + QString testFileContents = readFile(abspath); // qDebug() << relpath; - eng.evaluate(testFileContents, abspath); - if (eng.hasUncaughtException() && !relpath.endsWith("-n.js")) { - QStringList bt = eng.uncaughtExceptionBacktrace(); - QString err = eng.uncaughtException().toString(); - qWarning("%s\n%s\n", qPrintable(err), qPrintable(bt.join("\n"))); - continue; - } + eng.evaluate(testFileContents, abspath); + if (eng.hasUncaughtException() && !relpath.endsWith("-n.js")) { + QStringList bt = eng.uncaughtExceptionBacktrace(); + QString err = eng.uncaughtException().toString(); + qWarning("%s\n%s\n", qPrintable(err), qPrintable(bt.join("\n"))); + continue; + } - QScriptValue testcases = global.property("testcases"); - if (!testcases.isArray()) - testcases = global.property("gTestcases"); - int count = testcases.property("length").toInt32(); - if (count == 0) - continue; - - hasData = true; - QString title = global.property("TITLE").toString(); - for (int i = 0; i < count; ++i) { - QScriptValue kase = testcases.property(i); - QString description = kase.property("description").toString(); - QScriptValue expect = kase.property("expect"); - QScriptValue actual = kase.property("actual"); - bool passed = kase.property("passed").toBoolean(); - int lineNumber = kase.property("__lineNumber__").toInt32(); - - TestRecord rec(description, passed, - actual.toString(), expect.toString(), - relpath, lineNumber); - - QTest::newRow(description.toLatin1()) << rec; - } + QScriptValue testcases = global.property("testcases"); + if (!testcases.isArray()) + testcases = global.property("gTestcases"); + int count = testcases.property("length").toInt32(); + if (count == 0) + continue; + + hasData = true; + QString title = global.property("TITLE").toString(); + for (int i = 0; i < count; ++i) { + QScriptValue kase = testcases.property(i); + QString description = kase.property("description").toString(); + QScriptValue expect = kase.property("expect"); + QScriptValue actual = kase.property("actual"); + bool passed = kase.property("passed").toBoolean(); + int lineNumber = kase.property("__lineNumber__").toInt32(); + + TestRecord rec(description, passed, + actual.toString(), expect.toString(), + relpath, lineNumber); + + QTest::newRow(description.toLatin1()) << rec; } - if (!hasData) - QTest::newRow("") << TestRecord(); // dummy + } + if (!hasData) + QTest::newRow("") << TestRecord(); // dummy + } else { + QFETCH(TestRecord, record); + if ((record.lineNumber == -1) && (record.actual == "QSKIP")) { + QTest::qSkip(record.description.toLatin1(), QTest::SkipAll, record.fileName.toLatin1(), -1); } else { - QFETCH(TestRecord, record); - if ((record.lineNumber == -1) && (record.actual == "QSKIP")) { - QTest::qSkip(record.description.toLatin1(), QTest::SkipAll, record.fileName.toLatin1(), -1); - } else { - QString msg; - FailureItem::Action failAct; - bool expectFail = isExpectedFailure(record.fileName, record.description, &msg, &failAct); - if (expectFail) { - switch (failAct) { - case FailureItem::ExpectFail: - QTest::qExpectFail("", msg.toLatin1(), - QTest::Continue, record.fileName.toLatin1(), - record.lineNumber); - break; - case FailureItem::Skip: - QTest::qSkip(msg.toLatin1(), QTest::SkipSingle, - record.fileName.toLatin1(), record.lineNumber); - break; - } + QString msg; + FailureItem::Action failAct; + bool expectFail = isExpectedFailure(record.fileName, record.description, &msg, &failAct); + if (expectFail) { + switch (failAct) { + case FailureItem::ExpectFail: + QTest::qExpectFail("", msg.toLatin1(), + QTest::Continue, record.fileName.toLatin1(), + record.lineNumber); + break; + case FailureItem::Skip: + QTest::qSkip(msg.toLatin1(), QTest::SkipSingle, + record.fileName.toLatin1(), record.lineNumber); + break; } - if (!expectFail || (failAct == FailureItem::ExpectFail)) { - if (!record.passed) { -#ifdef GENERATE_ADDEXPECTEDFAILURE_CODE - if (!expectFail) { - QString escapedDescription = record.description; - escapedDescription.replace("\\", "\\\\"); - escapedDescription.replace("\n", "\\n"); - escapedDescription.replace("\"", "\\\""); - generatedAddExpectedFailureCode.append( - " addExpectedFailure(\"" + record.fileName - + "\", \"" + escapedDescription + - "\", willFixInNextReleaseMessage);\n"); - } -#endif - QTest::qCompare(record.actual, record.expected, "actual", "expect", - record.fileName.toLatin1(), record.lineNumber); - } else { - QTest::qCompare(record.actual, record.actual, "actual", "expect", - record.fileName.toLatin1(), record.lineNumber); + } + if (!expectFail || (failAct == FailureItem::ExpectFail)) { + if (!record.passed) { + if (!expectFail && shouldGenerateExpectedFailures) { + addExpectedFailure(record.fileName, + record.description, + QString()); } + QTest::qCompare(record.actual, record.expected, "actual", "expect", + record.fileName.toLatin1(), record.lineNumber); + } else { + QTest::qCompare(record.actual, record.actual, "actual", "expect", + record.fileName.toLatin1(), record.lineNumber); } } } - _id -= subSuitePaths.size()*2; } - return _id; } -tst_Suite::tst_Suite() +tst_QScriptJSTestSuite::tst_QScriptJSTestSuite() + : AbstractTestSuite("tst_QScriptJsTestSuite", + QString::fromLatin1("%0/tests").arg(SRCDIR), + ":/") { - testsDir = QDir(SRCDIR); - bool testsFound = testsDir.cd("tests"); - if (!testsFound) { - qWarning("*** no tests/ dir!"); - } - - QString willFixInNextReleaseMessage = QString::fromLatin1("Will fix in next release"); - QString fromCharCodeMessage = QString::fromLatin1("Test is wrong?"); - for (int i = 4256; i < 4294; ++i) { - addExpectedFailure("ecma/String/15.5.4.11-2.js", QString::fromLatin1("var s = new String( String.fromCharCode(%0) ); s.toLowerCase().charCodeAt(0)").arg(i), fromCharCodeMessage); - } - addExpectedFailure("ecma/String/15.5.4.11-5.js", "var s = new String( String.fromCharCode(1024) ); s.toLowerCase().charCodeAt(0)", fromCharCodeMessage); - addExpectedFailure("ecma/String/15.5.4.11-5.js", "var s = new String( String.fromCharCode(1037) ); s.toLowerCase().charCodeAt(0)", fromCharCodeMessage); - addExpectedFailure("ecma/String/15.5.4.12-1.js", "var s = new String( String.fromCharCode(181) ); s.toUpperCase().charCodeAt(0)", fromCharCodeMessage); - addExpectedFailure("ecma/String/15.5.4.12-1.js", "var s = new String( String.fromCharCode(329) ); s.toUpperCase().charCodeAt(0)", fromCharCodeMessage); - addExpectedFailure("ecma/String/15.5.4.12-4.js", "var s = new String( String.fromCharCode(1104) ); s.toUpperCase().charCodeAt(0)", fromCharCodeMessage); - addExpectedFailure("ecma/String/15.5.4.12-4.js", "var s = new String( String.fromCharCode(1117) ); s.toUpperCase().charCodeAt(0)", fromCharCodeMessage); - addExpectedFailure("ecma/String/15.5.4.12-5.js", "var s = new String( String.fromCharCode(1415) ); s.toUpperCase().charCodeAt(0)", fromCharCodeMessage); - - addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "- \"-0x123456789abcde8\"", willFixInNextReleaseMessage); - - addExpectedFailure("ecma/extensions/15.1.2.1-1.js", "var PROPS = ''; for ( p in eval ) { PROPS += p }; PROPS", willFixInNextReleaseMessage); - addExpectedFailure("ecma/GlobalObject/15.1.2.2-1.js", "var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS", willFixInNextReleaseMessage); - - addExpectedFailure("ecma/GlobalObject/15.1.2.3-1.js", "var MYPROPS=''; for ( var p in parseFloat ) { MYPROPS += p }; MYPROPS", willFixInNextReleaseMessage); - addExpectedFailure("ecma/GlobalObject/15.1.2.4.js", "var MYPROPS=''; for ( var p in escape ) { MYPROPS+= p}; MYPROPS", willFixInNextReleaseMessage); - addExpectedFailure("ecma/GlobalObject/15.1.2.5-1.js", "var MYPROPS=''; for ( var p in unescape ) { MYPROPS+= p }; MYPROPS", willFixInNextReleaseMessage); - addExpectedFailure("ecma/GlobalObject/15.1.2.6.js", "var MYPROPS=''; for ( var p in isNaN ) { MYPROPS+= p }; MYPROPS", willFixInNextReleaseMessage); - addExpectedFailure("ecma/GlobalObject/15.1.2.7.js", "var MYPROPS=''; for ( p in isFinite ) { MYPROPS+= p }; MYPROPS", willFixInNextReleaseMessage); - - addExpectedFailure(QRegExp(), "NO TESTS EXIST", willFixInNextReleaseMessage); - - addExpectedFailure("ecma_3/Array/15.4.5.1-01.js", "15.4.5.1 - array.length coverage", willFixInNextReleaseMessage); - - addExpectedFailure("ecma_3/extensions/regress-228087-002.js", - "Section 1 of test - \nregexp = /{1.*}/g\n" - "string = 'foo {1} foo {2} foo'\n" - "ERROR !!! match arrays have different lengths:\n" - "Expect: [\"{1} foo {2}\"]\n" - "Actual: []", willFixInNextReleaseMessage); - - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", - "Section 1 of test - \n" - "regexp = /a|ab/\n" - "string = 'abc'\n" - "ERROR !!! regexp failed to give expected match array:\n" - "Expect: [\"a\"]\n" - "Actual: [\"ab\"]\n", willFixInNextReleaseMessage); - - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", - "Section 2 of test - \n" - "regexp = /((a)|(ab))((c)|(bc))/\n" - "string = 'abc'\n" - "ERROR !!! regexp failed to give expected match array:\n" - "Expect: [\"abc\", \"a\", \"a\", , \"bc\", , \"bc\"]\n" - "Actual: [\"abc\", \"ab\", \"\", \"ab\", \"c\", \"c\", \"\"]\n", willFixInNextReleaseMessage); - - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", - "Section 4 of test - \n" - "regexp = /a[a-z]{2,4}?/\n" - "string = 'abcdefghi'\n" - "ERROR !!! regexp FAILED to match anything !!!\n" - "Expect: abc\n" - "Actual: null\n", willFixInNextReleaseMessage); - - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js(317)", - "Section 5 of test - \n" - "regexp = /(aa|aabaac|ba|b|c)*/\n" - "string = 'aabaac'\n" - "ERROR !!! regexp failed to give expected match array:\n" - "Expect: [\"aaba\", \"ba\"]\n" - "Actual: [\"aabaac\", \"aabaac\"]\n", willFixInNextReleaseMessage); - - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 1 of test - \nregexp = /{1.*}/g\nstring = 'foo {1} foo {2} foo'\nERROR !!! match arrays have different lengths:\nExpect: [\"{1} foo {2}\"]\nActual: []\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 2 of test - \nregexp = /{1.*}/g\nstring = 'foo {1} foo {2} foo'\nERROR !!! match arrays have different lengths:\nExpect: [\"{1} foo {2}\"]\nActual: []\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 3 of test - \nregexp = /{1[.!}]*}/g\nstring = 'foo {1} foo {2} foo'\nERROR !!! match arrays have different lengths:\nExpect: [\"{1}\"]\nActual: []\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 4 of test - \nregexp = /{1[.!}]*}/g\nstring = 'foo {1} foo {2} foo'\nERROR !!! match arrays have different lengths:\nExpect: [\"{1}\"]\nActual: []\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 6 of test - \nregexp = /c{3 }/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3 }\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 7 of test - \nregexp = /c{3.}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3 }\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 8 of test - \nregexp = /c{3\\s}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3 }\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 9 of test - \nregexp = /c{3[ ]}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3 }\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 10 of test - \nregexp = /c{ 3}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{ 3}\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 12 of test - \nregexp = /c{3, }/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3, }\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 13 of test - \nregexp = /c{3 ,}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3 ,}\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 15 of test - \nregexp = /c{3 ,4}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3 ,4}\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 16 of test - \nregexp = /c{3, 4}/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3, 4}\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-228087.js", "Section 17 of test - \nregexp = /c{3,4 }/\nstring = 'abccccc{3 }c{ 3}c{3, }c{3 ,}c{3 ,4}c{3, 4}c{3,4 }de'\nERROR !!! regexp FAILED to match anything !!!\nExpect: c{3,4 }\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 0", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 1", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 2", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 3", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 4", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 5", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 6", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 7", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-274152.js", "Do not ignore unicode format-control characters: 8", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-368516.js", "Treat unicode BOM characters as whitespace: 0", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/extensions/regress-368516.js", "Treat unicode BOM characters as whitespace: 1", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/FunExpr/fe-001-n.js", "Previous statement should have thrown a ReferenceError", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/LexicalConventions/7.9.1.js", "Automatic Semicolon insertion in postfix expressions: expr\n++", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/LexicalConventions/7.9.1.js", "Automatic Semicolon insertion in postfix expressions: expr\n--", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/LexicalConventions/7.9.1.js", "Automatic Semicolon insertion in postfix expressions: (x\n)-- y", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/LexicalConventions/7.9.1.js", "Automatic Semicolon insertion in postfix expressions: (x)-- y", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Object/8.6.1-01.js", "In strict mode, setting a read-only property should generate a warning: Throw if STRICT and WERROR is enabled", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.8.2 >", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.8.4 >=", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 5 of test - \nregexp = /(aa|aabaac|ba|b|c)*/\nstring = 'aabaac'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"aaba\", \"ba\"]\nActual: [\"aabaac\", \"aabaac\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 6 of test - \nregexp = /^(a+)\\1*,\\1+$/\nstring = 'aaaaaaaaaa,aaaaaaaaaaaaaaa'\nERROR !!! regexp FAILED to match anything !!!\nExpect: aaaaaaaaaa,aaaaaaaaaaaaaaa,aaaaa\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 7 of test - \nregexp = /(z)((a+)?(b+)?(c))*/\nstring = 'zaacbbbcac'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"zaacbbbcac\", \"z\", \"ac\", \"a\", , \"c\"]\nActual: [\"zaacbbbcac\", \"z\", \"ac\", \"a\", \"\", \"c\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 8 of test - \nregexp = /(a*)*/\nstring = 'b'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\", , ]\nActual: [\"\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 10 of test - \nregexp = /(?=(a+))/\nstring = 'baaabac'\nERROR !!! match arrays have different lengths:\nExpect: [\"\", \"aaa\"]\nActual: [\"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 11 of test - \nregexp = /(?=(a+))a*b\\1/\nstring = 'baaabac'\nERROR !!! match arrays have different lengths:\nExpect: [\"aba\", \"a\"]\nActual: [\"aaab\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 12 of test - \nregexp = /(.*?)a(?!(a+)b\\2c)\\2(.*)/\nstring = 'baaabaac'\nERROR !!! regexp FAILED to match anything !!!\nExpect: baaabaac,ba,,abaac\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 13 of test - \nregexp = /(?=(a+))/\nstring = 'baaabac'\nERROR !!! match arrays have different lengths:\nExpect: [\"\", \"aaa\"]\nActual: [\"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 34 of test - \nregexp = /a]/\nstring = 'a]'\nERROR !!! regexp FAILED to match anything !!!\nExpect: a]\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 66 of test - \nregexp = /a.+?c/\nstring = 'abcabc'\nERROR !!! regexp FAILED to match anything !!!\nExpect: abc\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 94 of test - \nregexp = /^a(bc+|b[eh])g|.h$/\nstring = 'abh'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"bh\", , ]\nActual: [\"bh\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 95 of test - \nregexp = /(bc+d$|ef*g.|h?i(j|k))/\nstring = 'effgz'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"effgz\", \"effgz\", , ]\nActual: [\"effgz\", \"effgz\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 97 of test - \nregexp = /(bc+d$|ef*g.|h?i(j|k))/\nstring = 'reffgz'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"effgz\", \"effgz\", , ]\nActual: [\"effgz\", \"effgz\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 109 of test - \nregexp = /(([a-c])b*?\\2)*/\nstring = 'ababbbcbc'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ababb,bb,b\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 110 of test - \nregexp = /(([a-c])b*?\\2){3}/\nstring = 'ababbbcbc'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ababbbcbc,cbc,c\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 119 of test - \nregexp = /ab*?bc/i\nstring = 'ABBBBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBBBC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 120 of test - \nregexp = /ab{0,}?bc/i\nstring = 'ABBBBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBBBC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 121 of test - \nregexp = /ab+?bc/i\nstring = 'ABBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 123 of test - \nregexp = /ab{1,}?bc/i\nstring = 'ABBBBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBBBC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 124 of test - \nregexp = /ab{1,3}?bc/i\nstring = 'ABBBBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBBBC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 125 of test - \nregexp = /ab{3,4}?bc/i\nstring = 'ABBBBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBBBC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 126 of test - \nregexp = /ab??bc/i\nstring = 'ABBC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABBC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 127 of test - \nregexp = /ab??bc/i\nstring = 'ABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 128 of test - \nregexp = /ab{0,1}?bc/i\nstring = 'ABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 129 of test - \nregexp = /ab??c/i\nstring = 'ABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 130 of test - \nregexp = /ab{0,1}?c/i\nstring = 'ABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 138 of test - \nregexp = /a.*?c/i\nstring = 'AXYZC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: AXYZC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 144 of test - \nregexp = /a]/i\nstring = 'A]'\nERROR !!! regexp FAILED to match anything !!!\nExpect: A]\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 160 of test - \nregexp = /a.+?c/i\nstring = 'ABCABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 161 of test - \nregexp = /a.*?c/i\nstring = 'ABCABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 162 of test - \nregexp = /a.{0,5}?c/i\nstring = 'ABCABC'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ABC\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 169 of test - \nregexp = /(a+|b){0,1}?/i\nstring = 'AB'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ,\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 191 of test - \nregexp = /^a(bc+|b[eh])g|.h$/i\nstring = 'ABH'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"BH\", , ]\nActual: [\"BH\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 192 of test - \nregexp = /(bc+d$|ef*g.|h?i(j|k))/i\nstring = 'EFFGZ'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"EFFGZ\", \"EFFGZ\", , ]\nActual: [\"EFFGZ\", \"EFFGZ\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 194 of test - \nregexp = /(bc+d$|ef*g.|h?i(j|k))/i\nstring = 'REFFGZ'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"EFFGZ\", \"EFFGZ\", , ]\nActual: [\"EFFGZ\", \"EFFGZ\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 212 of test - \nregexp = /a(?:b|c|d)+?(.)/\nstring = 'ace'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ace,e\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 213 of test - \nregexp = /a(?:b|c|d)+?(.)/\nstring = 'acdbcdbe'\nERROR !!! regexp FAILED to match anything !!!\nExpect: acd,d\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 217 of test - \nregexp = /a(?:b|c|d){4,5}?(.)/\nstring = 'acdbcdbe'\nERROR !!! regexp FAILED to match anything !!!\nExpect: acdbcd,d\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 218 of test - \nregexp = /((foo)|(bar))*/\nstring = 'foobar'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"foobar\", \"bar\", , \"bar\"]\nActual: [\"foobar\", \"bar\", \"\", \"bar\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 220 of test - \nregexp = /a(?:b|c|d){6,7}?(.)/\nstring = 'acdbcdbe'\nERROR !!! regexp FAILED to match anything !!!\nExpect: acdbcdbe,e\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 222 of test - \nregexp = /a(?:b|c|d){5,6}?(.)/\nstring = 'acdbcdbe'\nERROR !!! regexp FAILED to match anything !!!\nExpect: acdbcdb,b\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 224 of test - \nregexp = /a(?:b|c|d){5,7}?(.)/\nstring = 'acdbcdbe'\nERROR !!! regexp FAILED to match anything !!!\nExpect: acdbcdb,b\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 225 of test - \nregexp = /a(?:b|(c|e){1,2}?|d)+?(.)/\nstring = 'ace'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ace,c,e\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 227 of test - \nregexp = /^([^a-z])|(\\^)$/\nstring = '.'\nERROR !!! regexp failed to give expected match array:\nExpect: [\".\", \".\", , ]\nActual: [\".\", \".\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 234 of test - \nregexp = /(?:(f)(o)(o)|(b)(a)(r))*/\nstring = 'foobar'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"foobar\", , , , \"b\", \"a\", \"r\"]\nActual: [\"foobar\", \"\", \"\", \"\", \"b\", \"a\", \"r\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 240 of test - \nregexp = /(?:..)*?a/\nstring = 'aba'\nERROR !!! regexp FAILED to match anything !!!\nExpect: a\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 241 of test - \nregexp = /^(?:b|a(?=(.)))*\\1/\nstring = 'abc'\nERROR !!! match arrays have different lengths:\nExpect: [\"ab\", , ]\nActual: [\"ab\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 246 of test - \nregexp = /(a|x)*ab/\nstring = 'cab'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"ab\", , ]\nActual: [\"ab\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 247 of test - \nregexp = /(a)*ab/\nstring = 'cab'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"ab\", , ]\nActual: [\"ab\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 300 of test - \nregexp = /(?=(a+?))(\\1ab)/\nstring = 'aaab'\nERROR !!! regexp FAILED to match anything !!!\nExpect: aab,a,aab\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 303 of test - \nregexp = /(?=(a+?))(\\1ab)/\nstring = 'aaab'\nERROR !!! regexp FAILED to match anything !!!\nExpect: aab,a,aab\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 304 of test - \nregexp = /([\\w:]+::)?(\\w+)$/\nstring = 'abcd'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"abcd\", , \"abcd\"]\nActual: [\"abcd\", \"\", \"abcd\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 308 of test - \nregexp = /([\\w:]+::)?(\\w+)$/\nstring = 'abcd'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"abcd\", , \"abcd\"]\nActual: [\"abcd\", \"\", \"abcd\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 342 of test - \nregexp = /a$/m\nstring = 'a\\nb\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: a\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 344 of test - \nregexp = /a$/m\nstring = 'b\\na\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: a\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 353 of test - \nregexp = /aa$/m\nstring = 'aa\\nb\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: aa\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 355 of test - \nregexp = /aa$/m\nstring = 'b\\naa\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: aa\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 364 of test - \nregexp = /ab$/m\nstring = 'ab\\nb\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ab\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 366 of test - \nregexp = /ab$/m\nstring = 'b\\nab\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: ab\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 375 of test - \nregexp = /abb$/m\nstring = 'abb\\nb\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: abb\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 377 of test - \nregexp = /abb$/m\nstring = 'b\\nabb\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: abb\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 383 of test - \nregexp = /^d[x][x][x]/m\nstring = 'abcd\\ndxxx'\nERROR !!! regexp FAILED to match anything !!!\nExpect: dxxx\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 391 of test - \nregexp = /\\.c(pp|xx|c)?$/i\nstring = 'IO.c'\nERROR !!! regexp failed to give expected match array:\nExpect: [\".c\", , ]\nActual: [\".c\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 392 of test - \nregexp = /(\\.c(pp|xx|c)?$)/i\nstring = 'IO.c'\nERROR !!! regexp failed to give expected match array:\nExpect: [\".c\", \".c\", , ]\nActual: [\".c\", \".c\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 394 of test - \nregexp = /^([ab]*?)(b)?(c)$/\nstring = 'abac'\nERROR !!! regexp FAILED to match anything !!!\nExpect: abac,aba,,c\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 412 of test - \nregexp = /^(a(b)?)+$/\nstring = 'aba'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"aba\", \"a\", , ]\nActual: [\"aba\", \"a\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 413 of test - \nregexp = /^(aa(bb)?)+$/\nstring = 'aabbaa'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"aabbaa\", \"aa\", , ]\nActual: [\"aabbaa\", \"aa\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 414 of test - \nregexp = /^.{9}abc.*\\n/m\nstring = '123\\nabcabcabcabc\\n'\nERROR !!! regexp FAILED to match anything !!!\nExpect: abcabcabcabc\n\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 415 of test - \nregexp = /^(a)?a$/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", , ]\nActual: [\"a\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 416 of test - \nregexp = /^(a\\1?)(a\\1?)(a\\2?)(a\\3?)$/\nstring = 'aaaaaa'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"aaaaaa\", \"a\", \"aa\", \"a\", \"aa\"]\nActual: [\"aaaaaa\", \"aa\", \"a\", \"aa\", \"a\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 418 of test - \nregexp = /^(0+)?(?:x(1))?/\nstring = 'x1'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"x1\", , \"1\"]\nActual: [\"x1\", \"\", \"1\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 419 of test - \nregexp = /^([0-9a-fA-F]+)(?:x([0-9a-fA-F]+)?)(?:x([0-9a-fA-F]+))?/\nstring = '012cxx0190'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"012cxx0190\", \"012c\", , \"0190\"]\nActual: [\"012cxx0190\", \"012c\", \"\", \"0190\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 420 of test - \nregexp = /^(b+?|a){1,2}c/\nstring = 'bbbac'\nERROR !!! regexp FAILED to match anything !!!\nExpect: bbbac,a\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 421 of test - \nregexp = /^(b+?|a){1,2}c/\nstring = 'bbbbac'\nERROR !!! regexp FAILED to match anything !!!\nExpect: bbbbac,a\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-002.js", "Section 40 of test - \nregexp = /(a)|\\1/\nstring = 'x'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\", , ]\nActual: [\"\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-105972.js", "Section 1 of test - \nregexp = /^.*?$/\nstring = 'Hello World'\nERROR !!! regexp FAILED to match anything !!!\nExpect: Hello World\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-105972.js", "Section 2 of test - \nregexp = /^.*?/\nstring = 'Hello World'\nERROR !!! regexp FAILED to match anything !!!\nExpect: \nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-105972.js", "Section 3 of test - \nregexp = /^.*?(:|$)/\nstring = 'Hello: World'\nERROR !!! regexp FAILED to match anything !!!\nExpect: Hello:,:\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-123437.js", "Section 1 of test - \nregexp = /(a)?a/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", , ]\nActual: [\"a\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-123437.js", "Section 2 of test - \nregexp = /a|(b)/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", , ]\nActual: [\"a\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-123437.js", "Section 3 of test - \nregexp = /(a)?(a)/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", , \"a\"]\nActual: [\"a\", \"\", \"a\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-165353.js", "Section 1 of test - \nregexp = /^([a-z]+)*[a-z]$/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", , ]\nActual: [\"a\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-169497.js", "Section 1 of test - \nregexp = /<body.*>((.*\\n?)*?)<\\/body>/i\nstring = '<html>\\n<body onXXX=\"alert(event.type);\">\\n<p>Kibology for all</p>\\n<p>All for Kibology</p>\\n</body>\\n</html>'\nERROR !!! regexp FAILED to match anything !!!\nExpect: <body onXXX=\"alert(event.type);\">\n<p>Kibology for all</p>\n<p>All for Kibology</p>\n</body>,\n<p>Kibology for all</p>\n<p>All for Kibology</p>\n,<p>All for Kibology</p>\n\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-187133.js", "Section 5 of test - \nregexp = /(?!a|b)|c/\nstring = 'bc'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\"]\nActual: [\"c\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 1 of test - \nregexp = /(\\d|\\d\\s){2,}/\nstring = '12 3 45'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"12\", \"2\"]\nActual: [\"12 3 45\", \"5\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 3 of test - \nregexp = /(\\d|\\d\\s)+/\nstring = '12 3 45'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"12\", \"2\"]\nActual: [\"12 3 45\", \"5\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 8 of test - \nregexp = /(\\d|\\d\\s){2,}?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 12,2\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 9 of test - \nregexp = /(\\d|\\d\\s){4,}?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 12 3 4,4\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 10 of test - \nregexp = /(\\d|\\d\\s)+?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 1,1\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 11 of test - \nregexp = /(\\d\\s?){4,}?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 12 3 4,4\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 12 of test - \nregexp = /(\\d\\s|\\d){2,}?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 12 ,2 \nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 13 of test - \nregexp = /(\\d\\s|\\d){4,}?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 12 3 4,4\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-191479.js", "Section 14 of test - \nregexp = /(\\d\\s|\\d)+?/\nstring = '12 3 45'\nERROR !!! regexp FAILED to match anything !!!\nExpect: 1,1\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-202564.js", "Section 1 of test - \nregexp = /(?:(.+), )?(.+), (..) to (?:(.+), )?(.+), (..)/\nstring = 'Seattle, WA to Buckley, WA'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"Seattle, WA to Buckley, WA\", , \"Seattle\", \"WA\", , \"Buckley\", \"WA\"]\nActual: [\"Seattle, WA to Buckley, WA\", \"\", \"Seattle\", \"WA\", \"\", \"Buckley\", \"WA\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 2 of test - \nregexp = /(a|b*){5,}/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", \"\"]\nActual: [\"a\", \"a\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 3 of test - \nregexp = /(b*)*/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\", , ]\nActual: [\"\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 5 of test - \nregexp = /^\\-?(\\d{1,}|\\.{0,})*(\\,\\d{1,})?$/\nstring = '100.00'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"100.00\", \"00\", , ]\nActual: [\"100.00\", \"00\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-216591.js", "Section 1 of test - \nregexp = /\\{(([a-z0-9\\-_]+?\\.)+?)([a-z0-9\\-_]+?)\\}/i\nstring = 'a {result.data.DATA} b'\nERROR !!! regexp FAILED to match anything !!!\nExpect: {result.data.DATA},result.data.,data.,DATA\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-216591.js", "Section 2 of test - \nregexp = /\\{(([a-z0-9\\-_]+?\\.)+?)([a-z0-9\\-_]+?)\\}/gi\nstring = 'a {result.data.DATA} b'\nERROR !!! match arrays have different lengths:\nExpect: [\"{result.data.DATA}\"]\nActual: []\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-220367-001.js", "Section 1 of test - \nregexp = /(a)|(b)/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", \"a\", , ]\nActual: [\"a\", \"a\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-220367-001.js", "Section 2 of test - \nregexp = /(a)|(b)/\nstring = 'b'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"b\", , \"b\"]\nActual: [\"b\", \"\", \"b\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-223535.js", "Section 2 of test - \nregexp = /|a/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\"]\nActual: [\"a\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-223535.js", "Section 6 of test - \nregexp = /(|a)/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\", \"\"]\nActual: [\"a\", \"a\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-223535.js", "Section 7 of test - \nregexp = /(|a|)/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"\", \"\"]\nActual: [\"a\", \"a\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-224676.js", "Section 17 of test - \nregexp = /[x]b|(a)/\nstring = 'ZZZxbZZZ'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"xb\", , ]\nActual: [\"xb\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-224676.js", "Section 18 of test - \nregexp = /[x]b|()a/\nstring = 'ZZZxbZZZ'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"xb\", , ]\nActual: [\"xb\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-225289.js", "Section 7 of test - \nregexp = /(a)|([^a])/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", \"a\", , ]\nActual: [\"a\", \"a\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-225289.js", "Section 9 of test - \nregexp = /(a)|([^a])/\nstring = '()'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"(\", , \"(\"]\nActual: [\"(\", \"\", \"(\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-225289.js", "Section 10 of test - \nregexp = /((?:a|[^a])*)/g\nstring = 'a'\nERROR !!! match arrays have different lengths:\nExpect: [\"a\", \"\"]\nActual: [\"a\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-225289.js", "Section 11 of test - \nregexp = /((?:a|[^a])*)/g\nstring = ''\nERROR !!! match arrays have different lengths:\nExpect: [\"\"]\nActual: []\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-225289.js", "Section 12 of test - \nregexp = /((?:a|[^a])*)/g\nstring = '()'\nERROR !!! match arrays have different lengths:\nExpect: [\"()\", \"\"]\nActual: [\"()\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-31316.js", "Section 1 of test - \nregexp = /<([^\\/<>][^<>]*[^\\/])>|<([^\\/<>])>/\nstring = '<p>Some<br />test</p>'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"<p>\", , \"p\"]\nActual: [\"<p>\", \"\", \"p\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-330684.js", "Do not hang on RegExp", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-375711.js", "Do not assert with /[Q-b]/i.exec(\"\"): /[q-b]/.exec(\"\")", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-375711.js", "Do not assert with /[Q-b]/i.exec(\"\"): /[q-b]/i.exec(\"\")", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(?)'and flag 'i'", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(?)'and flag 'g'", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(?)'and flag 'm'", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(?)'and flag 'undefined'", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(a'and flag 'i'", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(a'and flag 'g'", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(a'and flag 'm'", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '(a'and flag 'undefined'", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '( ]'and flag 'i'", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '( ]'and flag 'g'", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '( ]'and flag 'm'", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-57631.js", "Testing for error creating illegal RegExp object on pattern '( ]'and flag 'undefined'", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-78156.js", "Section 1 of test - \nregexp = /^\\d/gm\nstring = 'aaa\\n789\\r\\nccc\\r\\n345'\nERROR !!! match arrays have different lengths:\nExpect: [\"7\", \"3\"]\nActual: []\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-78156.js", "Section 2 of test - \nregexp = /\\d$/gm\nstring = 'aaa\\n789\\r\\nccc\\r\\n345'\nERROR !!! match arrays have different lengths:\nExpect: [\"9\", \"5\"]\nActual: [\"5\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-78156.js", "Section 3 of test - \nregexp = /^\\d/gm\nstring = 'aaa\\n789\\r\\nccc\\r\\nddd'\nERROR !!! match arrays have different lengths:\nExpect: [\"7\"]\nActual: []\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-78156.js", "Section 4 of test - \nregexp = /\\d$/gm\nstring = 'aaa\\n789\\r\\nccc\\r\\nddd'\nERROR !!! match arrays have different lengths:\nExpect: [\"9\"]\nActual: []\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-85721.js", "Section 2 of test - \nregexp = /<sql:connection id=\"([^\\r\\n]*?)\">\\s*<sql:url>\\s*([^\\r\\n]*?)\\s*<\\/sql:url>\\s*<sql:driver>\\s*([^\\r\\n]*?)\\s*<\\/sql:driver>\\s*(\\s*<sql:userId>\\s*([^\\r\\n]*?)\\s*<\\/sql:userId>\\s*)?\\s*(\\s*<sql:password>\\s*([^\\r\\n]*?)\\s*<\\/sql:password>\\s*)?\\s*<\\/sql:connection>/\nstring = '<sql:connection id=\"conn1\"> <sql:url>www.m.com</sql:url> <sql:driver>drive.class</sql:driver>\\n<sql:userId>foo</sql:userId> <sql:password>goo</sql:password> </sql:connection>'\nERROR !!! regexp FAILED to match anything !!!\nExpect: <sql:connection id=\"conn1\"> <sql:url>www.m.com</sql:url> <sql:driver>drive.class</sql:driver>\n<sql:userId>foo</sql:userId> <sql:password>goo</sql:password> </sql:connection>,conn1,www.m.com,drive.class,<sql:userId>foo</sql:userId> ,foo,<sql:password>goo</sql:password> ,goo\nActual: null\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-87231.js", "Section 3 of test - \nregexp = /^(A)?(A.*)$/\nstring = 'A'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"A\", , \"A\"]\nActual: [\"A\", \"\", \"A\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-87231.js", "Section 6 of test - \nregexp = /(A)?(A.*)/\nstring = 'zxcasd;fl\\ ^AaaAAaaaf;lrlrzs'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"AaaAAaaaf;lrlrzs\", , \"AaaAAaaaf;lrlrzs\"]\nActual: [\"AaaAAaaaf;lrlrzs\", \"\", \"AaaAAaaaf;lrlrzs\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 24", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 28", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 30", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/String/15.5.4.14.js", "15.5.4.14 - String.prototype.split(/()/)", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Unicode/regress-352044-01.js", "issues with Unicode escape sequences in JavaScript source code", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Unicode/uc-001.js", "Unicode format-control character test (Category Cf.)", willFixInNextReleaseMessage); - - addFileExclusion(".+/15\\.9\\.2\\..+", "unstable on slow machines"); - addFileExclusion(".+/15\\.9\\.5\\..+", "too slooow"); - addFileExclusion("regress-130451.js", "asserts"); - addFileExclusion("regress-322135-01.js", "asserts"); - addFileExclusion("regress-322135-02.js", "asserts"); - addFileExclusion("regress-322135-03.js", "takes forever"); - addFileExclusion("regress-322135-04.js", "takes forever"); - addFileExclusion("ecma_3/RegExp/regress-375715-04.js", "bug"); - - addFileExclusion("ecma_3/RegExp/regress-289669.js", "Can fail due to relying on wall-clock time"); - - // Failures due to switch to JSC as back-end - addExpectedFailure("ecma/Array/15.4.3.1-2.js", "var props = ''; for ( p in Array ) { props += p } props", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Boolean/15.6.3.1-1.js", "var str='';for ( p in Boolean ) { str += p } str;", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Expressions/11.4.1.js", "var abc; delete(abc)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/FunctionObjects/15.3.3.1-2.js", "var str='';for (prop in Function ) str += prop; str;", willFixInNextReleaseMessage); - addExpectedFailure("ecma/ObjectObjects/15.2.3.1-1.js", "var str = '';for ( p in Object ) { str += p; }; str", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Statements/12.6.3-11.js", "result = \"\"; for ( p in Number ) { result += String(p) };", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Statements/12.6.3-2.js", "Boolean.prototype.foo = 34; for ( j in Boolean ) Boolean[j]", willFixInNextReleaseMessage); - addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "-\"\\u20001234\\u2001\"", willFixInNextReleaseMessage); - addExpectedFailure("ecma_2/RegExp/properties-001.js", "//.toString()", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Date/15.9.4.3.js", "15.9.4.3 - Date.UTC edge-case arguments.: date Infinity", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Date/15.9.4.3.js", "15.9.4.3 - Date.UTC edge-case arguments.: hours Infinity", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Date/15.9.4.3.js", "15.9.4.3 - Date.UTC edge-case arguments.: minutes Infinity", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Date/15.9.4.3.js", "15.9.4.3 - Date.UTC edge-case arguments.: seconds Infinity", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Function/regress-131964.js", "Section 1 of test - ", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Function/regress-313570.js", "length of objects whose prototype chain includes a function: immutable", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/FunExpr/fe-001.js", "Both functions were defined.", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 7 of test - \nregexp = /(z)((a+)?(b+)?(c))*/\nstring = 'zaacbbbcac'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"zaacbbbcac\", \"z\", \"ac\", \"a\", , \"c\"]\nActual: [\"zaacbbbcac\", \"z\", \"ac\", \"a\", \"bbb\", \"c\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/15.10.2-1.js", "Section 12 of test - \nregexp = /(.*?)a(?!(a+)b\\2c)\\2(.*)/\nstring = 'baaabaac'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"baaabaac\", \"ba\", , \"abaac\"]\nActual: [\"baaabaac\", \"ba\", \"aa\", \"abaac\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 218 of test - \nregexp = /((foo)|(bar))*/\nstring = 'foobar'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"foobar\", \"bar\", , \"bar\"]\nActual: [\"foobar\", \"bar\", \"foo\", \"bar\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 234 of test - \nregexp = /(?:(f)(o)(o)|(b)(a)(r))*/\nstring = 'foobar'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"foobar\", , , , \"b\", \"a\", \"r\"]\nActual: [\"foobar\", \"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 241 of test - \nregexp = /^(?:b|a(?=(.)))*\\1/\nstring = 'abc'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"ab\", , ]\nActual: [\"ab\", \"b\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 412 of test - \nregexp = /^(a(b)?)+$/\nstring = 'aba'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"aba\", \"a\", , ]\nActual: [\"aba\", \"a\", \"b\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/perlstress-001.js", "Section 413 of test - \nregexp = /^(aa(bb)?)+$/\nstring = 'aabbaa'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"aabbaa\", \"aa\", , ]\nActual: [\"aabbaa\", \"aa\", \"bb\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 1 of test - \nregexp = /(a|b*)*/\nstring = 'a'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"a\", \"a\"]\nActual: [\"a\", \"\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 5 of test - \nregexp = /^\\-?(\\d{1,}|\\.{0,})*(\\,\\d{1,})?$/\nstring = '100.00'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"100.00\", \"00\", , ]\nActual: [\"100.00\", \"\", , ]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 6 of test - \nregexp = /^\\-?(\\d{1,}|\\.{0,})*(\\,\\d{1,})?$/\nstring = '100,00'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"100,00\", \"100\", \",00\"]\nActual: [\"100,00\", \"\", \",00\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-209919.js", "Section 7 of test - \nregexp = /^\\-?(\\d{1,}|\\.{0,})*(\\,\\d{1,})?$/\nstring = '1.000,00'\nERROR !!! regexp failed to give expected match array:\nExpect: [\"1.000,00\", \"000\", \",00\"]\nActual: [\"1.000,00\", \"\", \",00\"]\n", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/RegExp/regress-311414.js", "RegExp captured tail match should be O(N) BigO 2 < 2", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 7", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/String/15.5.4.11.js", "Section 26", willFixInNextReleaseMessage); - -#ifdef Q_CC_MSVC - addExpectedFailure("ecma_3/Expressions/11.7.3-01.js", "11.7.3 - >>> should evaluate operands in order: order", "QTBUG-8056"); - addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.7.3 >>>", "QTBUG-8056"); - addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.13.2 >>>=", "QTBUG-8056"); -#endif - -#ifdef Q_CC_MINGW - addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(Infinity, Infinity)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(Infinity, -Infinity)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-Infinity, Infinity)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-Infinity, -Infinity)", willFixInNextReleaseMessage); -#endif - -#ifdef Q_OS_SOLARIS - addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -0; VAR2= Infinity; VAR2 /= VAR1", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -0; VAR2= -Infinity; VAR2 /= VAR1", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = 1; VAR2= -0; VAR1 /= VAR2", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Expressions/11.13.2-2.js", "VAR1 = -1; VAR2= -0; VAR1 /= VAR2", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Expressions/11.5.2.js", "Number.POSITIVE_INFINITY / -0", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Expressions/11.5.2.js", "Number.NEGATIVE_INFINITY / -0", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Expressions/11.5.2.js", "1 / -0", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Expressions/11.5.2.js", "-1 / -0", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.10.js", "Math.log(-0.0000001)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.10.js", "Math.log(-1)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.11.js", "Infinity/Math.max(-0,-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.12.js", "Infinity/Math.min(0,-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.12.js", "Infinity/Math.min(-0,-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(NaN,-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.13.js", "Infinity/Math.pow(-Infinity, -1)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(0, -1)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(0, -0.5)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(0, -1000)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.13.js", "Infinity/Math.pow(-0, 1)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.13.js", "Infinity/Math.pow(-0, 3)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(-0, -2)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.15.js", "Infinity/Math.round(-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.15.js", "Infinity/Math.round(-0.49)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.15.js", "Infinity/Math.round(-0.5)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.17.js", "Infinity/Math.sqrt(-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.18.js", "Infinity/Math.tan(-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.2.js", "Math.acos(1.00000001)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.2.js", "Math.acos(11.00000001)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.3.js", "Math.asin(1.000001)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.3.js", "Math.asin(-1.000001)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.3.js", "Infinity/Math.asin(-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.4.js", "Infinity/Math.atan(-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(0, -0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.5.js", "Infinity/Math.atan2(-0, 1)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-0,\t-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.5.js", "Math.atan2(-0,\t-1)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil('-0')", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil(-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil(-Number.MIN_VALUE)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.6.js", "Infinity/Math.ceil(-0.9)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.9.js", "Infinity/Math.floor(-0)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "var z = 0; print(1/-z)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/TypeConversion/9.3.1-3.js", "1/-1e-2000", willFixInNextReleaseMessage); -#endif - -#ifdef Q_OS_SYMBIAN - addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(-1, 0.5)", willFixInNextReleaseMessage); - addExpectedFailure("ecma/Math/15.8.2.13.js", "Math.pow(-1, -0.5)", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.5.1 *", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.5.2 /", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.6.2 -", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.13.2 *=", willFixInNextReleaseMessage); - addExpectedFailure("ecma_3/Operators/order-01.js", "operator evaluation order: 11.13.2 /=", willFixInNextReleaseMessage); -#endif - - static const char klass[] = "tst_QScriptJsTestSuite"; - - QVector<uint> *data = qt_meta_data_tst_Suite(); - // content: - *data << 1 // revision - << 0 // classname - << 0 << 0 // classinfo - << 0 << 10 // methods (backpatched later) - << 0 << 0 // properties - << 0 << 0 // enums/sets - ; - - QVector<char> *stringdata = qt_meta_stringdata_tst_Suite(); - appendCString(stringdata, klass); - appendCString(stringdata, ""); - // don't execute any tests on slow machines #if !defined(Q_OS_IRIX) // do all the test suites - QFileInfoList testSuiteDirInfos; - if (testsFound) - testSuiteDirInfos = testsDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot); + QFileInfoList testSuiteDirInfos = testsDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot); foreach (QFileInfo tsdi, testSuiteDirInfos) { QDir testSuiteDir(tsdi.absoluteFilePath()); // do all the dirs in the test suite QFileInfoList subSuiteDirInfos = testSuiteDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot); foreach (QFileInfo ssdi, subSuiteDirInfos) { subSuitePaths.append(ssdi.absoluteFilePath()); - // slot: signature, parameters, type, tag, flags - QString data_slot = QString::fromLatin1("%0/%1_data()") - .arg(testSuiteDir.dirName()).arg(ssdi.fileName()); - static const int nullbyte = sizeof(klass); - *data << stringdata->size() << nullbyte << nullbyte << nullbyte << 0x08; - appendCString(stringdata, data_slot.toLatin1()); - QString slot = QString::fromLatin1("%0/%1()") - .arg(testSuiteDir.dirName()).arg(ssdi.fileName()); - *data << stringdata->size() << nullbyte << nullbyte << nullbyte << 0x08; - appendCString(stringdata, slot.toLatin1()); + QString function = QString::fromLatin1("%0/%1") + .arg(testSuiteDir.dirName()).arg(ssdi.fileName()); + addTestFunction(function, CreateDataFunction); } } #endif - (*data)[4] = subSuitePaths.size() * 2; + finalizeMetaObject(); +} + +tst_QScriptJSTestSuite::~tst_QScriptJSTestSuite() +{ +} - *data << 0; // eod +void tst_QScriptJSTestSuite::configData(TestConfig::Mode mode, const QStringList &parts) +{ + switch (mode) { + case TestConfig::Skip: + addFileExclusion(parts.at(0), parts.value(1)); + break; + + case TestConfig::ExpectFail: + addExpectedFailure(parts.at(0), parts.value(1), parts.value(2)); + break; + } +} - // initialize staticMetaObject - staticMetaObject.d.superdata = &QObject::staticMetaObject; - staticMetaObject.d.stringdata = stringdata->constData(); - staticMetaObject.d.data = data->constData(); - staticMetaObject.d.extradata = 0; +void tst_QScriptJSTestSuite::writeSkipConfigFile(QTextStream &stream) +{ + stream << QString::fromLatin1("# testcase | message") << endl; } -tst_Suite::~tst_Suite() +void tst_QScriptJSTestSuite::writeExpectFailConfigFile(QTextStream &stream) { -#ifdef GENERATE_ADDEXPECTEDFAILURE_CODE - if (!generatedAddExpectedFailureCode.isEmpty()) { - QFile file("addexpectedfailures.cpp"); - file.open(QFile::WriteOnly); - QTextStream ts(&file); - ts << generatedAddExpectedFailureCode; + stream << QString::fromLatin1("# testcase | description | message") << endl; + for (int i = 0; i < expectedFailures.size(); ++i) { + const FailureItem &fail = expectedFailures.at(i); + if (fail.pathRegExp.pattern().isEmpty()) + continue; + stream << QString::fromLatin1("%0 | %1") + .arg(fail.pathRegExp.pattern()) + .arg(escape(fail.description)); + if (!fail.message.isEmpty()) + stream << QString::fromLatin1(" | %0").arg(escape(fail.message)); + stream << endl; } -#endif } -void tst_Suite::addExpectedFailure(const QRegExp &path, const QString &description, const QString &message) +void tst_QScriptJSTestSuite::addExpectedFailure(const QRegExp &path, const QString &description, const QString &message) { expectedFailures.append(FailureItem(FailureItem::ExpectFail, path, description, message)); } -void tst_Suite::addExpectedFailure(const QString &fileName, const QString &description, const QString &message) +void tst_QScriptJSTestSuite::addExpectedFailure(const QString &fileName, const QString &description, const QString &message) { expectedFailures.append(FailureItem(FailureItem::ExpectFail, QRegExp(fileName), description, message)); } -void tst_Suite::addSkip(const QRegExp &path, const QString &description, const QString &message) +void tst_QScriptJSTestSuite::addSkip(const QRegExp &path, const QString &description, const QString &message) { expectedFailures.append(FailureItem(FailureItem::Skip, path, description, message)); } -void tst_Suite::addSkip(const QString &fileName, const QString &description, const QString &message) +void tst_QScriptJSTestSuite::addSkip(const QString &fileName, const QString &description, const QString &message) { expectedFailures.append(FailureItem(FailureItem::Skip, QRegExp(fileName), description, message)); } -bool tst_Suite::isExpectedFailure(const QString &fileName, const QString &description, +bool tst_QScriptJSTestSuite::isExpectedFailure(const QString &fileName, const QString &description, QString *message, FailureItem::Action *action) const { for (int i = 0; i < expectedFailures.size(); ++i) { @@ -857,17 +430,17 @@ bool tst_Suite::isExpectedFailure(const QString &fileName, const QString &descri return false; } -void tst_Suite::addFileExclusion(const QString &fileName, const QString &message) +void tst_QScriptJSTestSuite::addFileExclusion(const QString &fileName, const QString &message) { fileExclusions.append(qMakePair(QRegExp(fileName), message)); } -void tst_Suite::addFileExclusion(const QRegExp &rx, const QString &message) +void tst_QScriptJSTestSuite::addFileExclusion(const QRegExp &rx, const QString &message) { fileExclusions.append(qMakePair(rx, message)); } -bool tst_Suite::isExcludedFile(const QString &fileName, QString *message) const +bool tst_QScriptJSTestSuite::isExcludedFile(const QString &fileName, QString *message) const { for (int i = 0; i < fileExclusions.size(); ++i) { if (fileExclusions.at(i).first.indexIn(fileName) != -1) { @@ -879,4 +452,4 @@ bool tst_Suite::isExcludedFile(const QString &fileName, QString *message) const return false; } -QTEST_MAIN(tst_Suite) +QTEST_MAIN(tst_QScriptJSTestSuite) diff --git a/tests/auto/qscriptv8testsuite/abstracttestsuite.cpp b/tests/auto/qscriptv8testsuite/abstracttestsuite.cpp new file mode 100644 index 0000000..90242a0 --- /dev/null +++ b/tests/auto/qscriptv8testsuite/abstracttestsuite.cpp @@ -0,0 +1,493 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "abstracttestsuite.h" +#include <QtTest/QtTest> +#include <QtCore/qset.h> +#include <QtCore/qtextstream.h> + +/*! + AbstractTestSuite provides a way of building QtTest test objects + dynamically. The use case is integration of JavaScript test suites + into QtTest autotests. + + Subclasses add their tests functions with addTestFunction() in the + constructor, and must reimplement runTestFunction(). Additionally, + subclasses can reimplement initTestCase() and cleanupTestCase() + (but make sure to call the base implementation). + + AbstractTestSuite uses configuration files for getting information + about skipped tests (skip.txt) and expected test failures + (expect_fail.txt). Subclasses must reimplement + createSkipConfigFile() and createExpectFailConfigFile() for + creating these files, and configData() for processing an entry of + such a file. + + The config file format is as follows: + - Lines starting with '#' are skipped. + - Lines of the form [SYMBOL] means that the upcoming data + should only be processed if the given SYMBOL is defined on + this platform. + - Any other line is split on ' | ' and handed off to the client. + + Subclasses must provide a default tests directory (where the + subclass expects to find the script files to run as tests), and a + default config file directory. Some environment variables can be + used to affect where AbstractTestSuite will look for files: + + - QTSCRIPT_TEST_CONFIG_DIR: Overrides the default test config path. + + - QTSCRIPT_TEST_CONFIG_SUFFIX: Is appended to "skip" and + "expect_fail" to create the test config name. This makes it easy to + maintain skip- and expect_fail-files corresponding to different + revisions of a test suite, and switch between them. + + - QTSCRIPT_TEST_DIR: Overrides the default test dir. + + AbstractTestSuite does _not_ define how the test dir itself is + processed or how tests are run; this is left up to the subclass. + + If no config files are found, AbstractTestSuite will ask the + subclass to create a default skip file. Also, the + shouldGenerateExpectedFailures variable will be set to true. The + subclass should check for this when a test fails, and add an entry + to its set of expected failures. When all tests have been run, + AbstractTestSuite will ask the subclass to create the expect_fail + file based on the tests that failed. The next time the autotest is + run, the created config files will be used. + + The reason for skipping a test is usually that it takes a very long + time to complete (or even hangs completely), or it crashes. It's + not possible for the test runner to know in advance which tests are + problematic, which is why the entries to the skip file are + typically added manually. When running tests for the first time, it + can be useful to run the autotest with the -v1 command line option, + so you can see the name of each test before it's run, and can add a + skip entry if appropriate. +*/ + +// Helper class for constructing the test class's QMetaObject contents +// at runtime. +class TestMetaObjectBuilder +{ +public: + TestMetaObjectBuilder(const QByteArray &className, + const QMetaObject *superClass); + + void appendPrivateVoidSlot(const char *signature); + void appendPrivateVoidSlot(const QString &signature) + { appendPrivateVoidSlot(signature.toLatin1().constData()); } + + void assignContents(QMetaObject &); + +private: + void appendString(const char *); + void finalize(); + + const QByteArray m_className; + const QMetaObject *m_superClass; + QVector<uint> m_data; + QVector<char> m_stringdata; + int m_emptyStringOffset; + bool m_finalized; +}; + +TestMetaObjectBuilder::TestMetaObjectBuilder( + const QByteArray &className, + const QMetaObject *superClass) + : m_className(className), m_superClass(superClass), + m_finalized(false) +{ + // header + m_data << 1 // revision + << 0 // classname + << 0 << 0 // classinfo + << 0 << 10 // methods (backpatched later) + << 0 << 0 // properties + << 0 << 0 // enums/sets + ; + + appendString(className.constData()); + m_emptyStringOffset = m_stringdata.size(); + appendString(""); +} + +void TestMetaObjectBuilder::appendString(const char *s) +{ + char c; + do { + c = *(s++); + m_stringdata << c; + } while (c != '\0'); +} + +void TestMetaObjectBuilder::appendPrivateVoidSlot(const char *signature) +{ + static const int methodCountOffset = 4; + // signature, parameters, type, tag, flags + m_data << m_stringdata.size() + << m_emptyStringOffset + << m_emptyStringOffset + << m_emptyStringOffset + << 0x08; + appendString(signature); + ++m_data[methodCountOffset]; +} + +void TestMetaObjectBuilder::finalize() +{ + if (m_finalized) + return; + m_data << 0; // eod + m_finalized = true; +} + +/** + Assigns this builder's contents to the meta-object \a mo. It's up + to the caller to ensure that this builder (and hence, its data) + stays alive as long as needed. +*/ +void TestMetaObjectBuilder::assignContents(QMetaObject &mo) +{ + finalize(); + mo.d.superdata = m_superClass; + mo.d.stringdata = m_stringdata.constData(); + mo.d.data = m_data.constData(); + mo.d.extradata = 0; +} + + +class TestConfigClientInterface; +// For parsing information about skipped tests and expected failures. +class TestConfigParser +{ +public: + static void parse(const QString &path, + TestConfig::Mode mode, + TestConfigClientInterface *client); + +private: + static QString unescape(const QString &); + static bool isKnownSymbol(const QString &); + static bool isDefined(const QString &); + + static QSet<QString> knownSymbols; + static QSet<QString> definedSymbols; +}; + +QSet<QString> TestConfigParser::knownSymbols; +QSet<QString> TestConfigParser::definedSymbols; + +/** + Parses the config file at the given \a path in the given \a mode. + Handling of errors and data is delegated to the given \a client. +*/ +void TestConfigParser::parse(const QString &path, + TestConfig::Mode mode, + TestConfigClientInterface *client) +{ + QFile file(path); + if (!file.open(QIODevice::ReadOnly)) + return; + QTextStream stream(&file); + int lineNumber = 0; + QString predicate; + const QString separator = QString::fromLatin1(" | "); + while (!stream.atEnd()) { + ++lineNumber; + QString line = stream.readLine(); + if (line.isEmpty()) + continue; + if (line.startsWith('#')) // Comment + continue; + if (line.startsWith('[')) { // Predicate + if (!line.endsWith(']')) { + client->configError(path, "malformed predicate", lineNumber); + return; + } + QString symbol = line.mid(1, line.size()-2); + if (isKnownSymbol(symbol)) { + predicate = symbol; + } else { + qWarning("symbol %s is not known -- add it to TestConfigParser!", qPrintable(symbol)); + predicate = QString(); + } + } else { + if (predicate.isEmpty() || isDefined(predicate)) { + QStringList parts = line.split(separator, QString::KeepEmptyParts); + for (int i = 0; i < parts.size(); ++i) + parts[i] = unescape(parts[i]); + client->configData(mode, parts); + } + } + } +} + +QString TestConfigParser::unescape(const QString &str) +{ + return QString(str).replace("\\n", "\n"); +} + +bool TestConfigParser::isKnownSymbol(const QString &symbol) +{ + if (knownSymbols.isEmpty()) { + knownSymbols + // If you add a symbol here, add a case for it in + // isDefined() as well. + << "Q_OS_LINUX" + << "Q_OS_SOLARIS" + << "Q_OS_WINCE" + << "Q_OS_SYMBIAN" + << "Q_OS_MAC" + << "Q_OS_WIN" + << "Q_CC_MSVC" + << "Q_CC_MINGW" + << "Q_CC_INTEL" + ; + } + return knownSymbols.contains(symbol); +} + +bool TestConfigParser::isDefined(const QString &symbol) +{ + if (definedSymbols.isEmpty()) { + definedSymbols +#ifdef Q_OS_LINUX + << "Q_OS_LINUX" +#endif +#ifdef Q_OS_SOLARIS + << "Q_OS_SOLARIS" +#endif +#ifdef Q_OS_WINCE + << "Q_OS_WINCE" +#endif +#ifdef Q_OS_SYMBIAN + << "Q_OS_SYMBIAN" +#endif +#ifdef Q_OS_MAC + << "Q_OS_MAC" +#endif +#ifdef Q_OS_WIN + << "Q_OS_WIN" +#endif +#ifdef Q_CC_MSVC + << "Q_CC_MSVC" +#endif +#ifdef Q_CC_MINGW + << "Q_CC_MINGW" +#endif +#ifdef Q_CC_INTEL + << "Q_CC_INTEL" +#endif + ; + } + return definedSymbols.contains(symbol); +} + + +QMetaObject AbstractTestSuite::staticMetaObject; + +const QMetaObject *AbstractTestSuite::metaObject() const +{ + return &staticMetaObject; +} + +void *AbstractTestSuite::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, staticMetaObject.d.stringdata)) + return static_cast<void*>(const_cast<AbstractTestSuite*>(this)); + return QObject::qt_metacast(_clname); +} + +int AbstractTestSuite::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QObject::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + switch (_id) { + case 0: + initTestCase(); + break; + case 1: + cleanupTestCase(); + break; + default: + // If another method is added above, this offset must be adjusted. + runTestFunction(_id - 2); + } + _id -= staticMetaObject.methodCount() - staticMetaObject.methodOffset(); + } + return _id; +} + +AbstractTestSuite::AbstractTestSuite(const QByteArray &className, + const QString &defaultTestsPath, + const QString &defaultConfigPath) + : shouldGenerateExpectedFailures(false), + metaBuilder(new TestMetaObjectBuilder(className, &QObject::staticMetaObject)) +{ + QString testConfigPath = qgetenv("QTSCRIPT_TEST_CONFIG_DIR"); + if (testConfigPath.isEmpty()) + testConfigPath = defaultConfigPath; + QString configSuffix = qgetenv("QTSCRIPT_TEST_CONFIG_SUFFIX"); + skipConfigPath = QString::fromLatin1("%0/skip%1.txt") + .arg(testConfigPath).arg(configSuffix); + expectFailConfigPath = QString::fromLatin1("%0/expect_fail%1.txt") + .arg(testConfigPath).arg(configSuffix); + + QString testsPath = qgetenv("QTSCRIPT_TEST_DIR"); + if (testsPath.isEmpty()) + testsPath = defaultTestsPath; + testsDir = QDir(testsPath); + + addTestFunction("initTestCase"); + addTestFunction("cleanupTestCase"); + + // Subclass constructors should add their custom test functions to + // the meta-object and call finalizeMetaObject(). +} + +AbstractTestSuite::~AbstractTestSuite() +{ + delete metaBuilder; +} + +void AbstractTestSuite::addTestFunction(const QString &name, + DataFunctionCreation dfc) +{ + if (dfc == CreateDataFunction) { + QString dataSignature = QString::fromLatin1("%0_data()").arg(name); + metaBuilder->appendPrivateVoidSlot(dataSignature); + } + QString signature = QString::fromLatin1("%0()").arg(name); + metaBuilder->appendPrivateVoidSlot(signature); +} + +void AbstractTestSuite::finalizeMetaObject() +{ + metaBuilder->assignContents(staticMetaObject); +} + +void AbstractTestSuite::initTestCase() +{ + if (!testsDir.exists()) { + QString message = QString::fromLatin1("tests directory (%0) doesn't exist.") + .arg(testsDir.path()); + QFAIL(qPrintable(message)); + return; + } + + if (QFileInfo(skipConfigPath).exists()) + TestConfigParser::parse(skipConfigPath, TestConfig::Skip, this); + else + createSkipConfigFile(); + + if (QFileInfo(expectFailConfigPath).exists()) + TestConfigParser::parse(expectFailConfigPath, TestConfig::ExpectFail, this); + else + shouldGenerateExpectedFailures = true; +} + +void AbstractTestSuite::cleanupTestCase() +{ + if (shouldGenerateExpectedFailures) + createExpectFailConfigFile(); +} + +void AbstractTestSuite::configError(const QString &path, const QString &message, int lineNumber) +{ + QString output; + output.append(path); + if (lineNumber != -1) + output.append(":").append(QString::number(lineNumber)); + output.append(": ").append(message); + QFAIL(qPrintable(output)); +} + +void AbstractTestSuite::createSkipConfigFile() +{ + QFile file(skipConfigPath); + if (!file.open(QIODevice::WriteOnly)) + return; + QWARN(qPrintable(QString::fromLatin1("creating %0").arg(skipConfigPath))); + QTextStream stream(&file); + + writeSkipConfigFile(stream); + + file.close(); +} + +void AbstractTestSuite::createExpectFailConfigFile() +{ + QFile file(expectFailConfigPath); + if (!file.open(QFile::WriteOnly)) + return; + QWARN(qPrintable(QString::fromLatin1("creating %0").arg(expectFailConfigPath))); + QTextStream stream(&file); + + writeExpectFailConfigFile(stream); + + file.close(); +} + +/*! + Convenience function for reading all contents of a file. + */ +QString AbstractTestSuite::readFile(const QString &filename) +{ + QFile file(filename); + if (!file.open(QFile::ReadOnly)) + return QString(); + QTextStream stream(&file); + stream.setCodec("UTF-8"); + return stream.readAll(); +} + +/*! + Escapes characters in the string \a str so it's suitable for writing + to a config file. + */ +QString AbstractTestSuite::escape(const QString &str) +{ + return QString(str).replace("\n", "\\n"); +} diff --git a/tests/auto/qscriptv8testsuite/abstracttestsuite.h b/tests/auto/qscriptv8testsuite/abstracttestsuite.h new file mode 100644 index 0000000..257de1a --- /dev/null +++ b/tests/auto/qscriptv8testsuite/abstracttestsuite.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ABSTRACTTESTSUITE_H +#define ABSTRACTTESTSUITE_H + +#include <QtCore/qobject.h> + +#include <QtCore/qbytearray.h> +#include <QtCore/qdir.h> +#include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> +#include <QtCore/qvector.h> +#include <QtCore/qtextstream.h> + +class TestMetaObjectBuilder; + +namespace TestConfig { +enum Mode { + Skip, + ExpectFail +}; +} + +// For receiving callbacks from the config parser. +class TestConfigClientInterface +{ +public: + virtual ~TestConfigClientInterface() {} + virtual void configData(TestConfig::Mode mode, + const QStringList &parts) = 0; + virtual void configError(const QString &path, + const QString &message, + int lineNumber) = 0; +}; + +class AbstractTestSuite : public QObject, + public TestConfigClientInterface +{ +// No Q_OBJECT macro, we implement the meta-object ourselves. +public: + AbstractTestSuite(const QByteArray &className, + const QString &defaultTestsPath, + const QString &defaultConfigPath); + virtual ~AbstractTestSuite(); + + static QMetaObject staticMetaObject; + virtual const QMetaObject *metaObject() const; + virtual void *qt_metacast(const char *); + virtual int qt_metacall(QMetaObject::Call, int, void **argv); + + static QString readFile(const QString &); + static QString escape(const QString &); + +protected: + enum DataFunctionCreation { + DontCreateDataFunction, + CreateDataFunction + }; + + void addTestFunction(const QString &, + DataFunctionCreation = DontCreateDataFunction); + void finalizeMetaObject(); + + virtual void initTestCase(); + virtual void cleanupTestCase(); + + virtual void writeSkipConfigFile(QTextStream &) = 0; + virtual void writeExpectFailConfigFile(QTextStream &) = 0; + + virtual void runTestFunction(int index) = 0; + + virtual void configError(const QString &path, const QString &message, int lineNumber); + + QDir testsDir; + bool shouldGenerateExpectedFailures; + +private: + TestMetaObjectBuilder *metaBuilder; + QString skipConfigPath, expectFailConfigPath; + +private: + void createSkipConfigFile(); + void createExpectFailConfigFile(); +}; + +#endif diff --git a/tests/auto/qscriptv8testsuite/abstracttestsuite.pri b/tests/auto/qscriptv8testsuite/abstracttestsuite.pri new file mode 100644 index 0000000..1de5b93 --- /dev/null +++ b/tests/auto/qscriptv8testsuite/abstracttestsuite.pri @@ -0,0 +1,4 @@ +SOURCES += $$PWD/abstracttestsuite.cpp +HEADERS += $$PWD/abstracttestsuite.h +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD diff --git a/tests/auto/qscriptv8testsuite/expect_fail.txt b/tests/auto/qscriptv8testsuite/expect_fail.txt new file mode 100644 index 0000000..a4eee73 --- /dev/null +++ b/tests/auto/qscriptv8testsuite/expect_fail.txt @@ -0,0 +1,16 @@ +# testcase | actual | expected | message +arguments-enum | 2 | 0 +const-redecl | undefined | TypeError | local:'const x; var x' +date-parse | NaN | 946713600000 | Sat, 01-Jan-2000 08:00:00 GMT+00:00 +delete-global-properties | true | false +delete | false | true | delete 100 +function-arguments-null | false | true +function-caller | null | function eval() {\n [native code]\n} +function-prototype | prototype | disconnectconnect +global-const-var-conflicts | false | true +number-tostring | 0 | 0.0000a7c5ac471b4788 +parse-int-float | 1e+21 | 1 +regexp | false | true +string-lastindexof | 0 | -1 +string-split | 4 | 3 | 19 - array length +substr | abcdefghijklmn | diff --git a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro index 03e26bd..e1c6234 100644 --- a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro +++ b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.pro @@ -1,10 +1,5 @@ load(qttest_p4) QT = core script SOURCES += tst_qscriptv8testsuite.cpp -!symbian:DEFINES += SRCDIR=\\\"$$PWD\\\" - -wince*|symbian: { -testFiles.sources = tests -testFiles.path = . -DEPLOYMENT += testFiles -} +RESOURCES += qscriptv8testsuite.qrc +include(abstracttestsuite.pri) diff --git a/tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc new file mode 100644 index 0000000..150ccf0 --- /dev/null +++ b/tests/auto/qscriptv8testsuite/qscriptv8testsuite.qrc @@ -0,0 +1,7 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>tests</file> + <file>expect_fail.txt</file> + <file>skip.txt</file> +</qresource> +</RCC> diff --git a/tests/auto/qscriptv8testsuite/skip.txt b/tests/auto/qscriptv8testsuite/skip.txt new file mode 100644 index 0000000..9658c2b --- /dev/null +++ b/tests/auto/qscriptv8testsuite/skip.txt @@ -0,0 +1,31 @@ +# testcase | message +debug-* | not applicable +mirror-* | not applicable +array-concat | Hangs on JSC backend +array-splice | Hangs on JSC backend +sparse-array-reverse | Hangs on JSC backend +string-case | V8-specific behavior? (Doesn't pass on SpiderMonkey either) + +[Q_OS_WINCE] +deep-recursion | Demands too much memory on WinCE +nested-repetition-count-overflow | Demands too much memory on WinCE +unicode-test | Demands too much memory on WinCE +mul-exhaustive | Demands too much memory on WinCE + +[Q_OS_SYMBIAN] +nested-repetition-count-overflow | Demands too much memory on Symbian +unicode-test | Demands too much memory on Symbian + +[Q_CC_INTEL] +math-min-max | Unresolved failures with intel compiler +negate-zero | Unresolved failures with intel compiler +smi-negative-zero | Unresolved failures with intel compiler +str-to-num | Unresolved failures with intel compiler +to-precision | Unresolved failures with intel compiler + +[Q_OS_MAC] +smi-negative-zero | Unresolved failures on Mac OS X (Cocoa) +to-precision | Unresolved failures on Mac OS X (Cocoa) + +[Q_OS_WIN] +to-precision | Unresolved failures on Windows diff --git a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp index 938cc3a..b02d3ab 100644 --- a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp +++ b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp @@ -40,72 +40,33 @@ ****************************************************************************/ +#include "abstracttestsuite.h" #include <QtTest/QtTest> -#include <QByteArray> - #include <QtScript> -#if defined(Q_OS_SYMBIAN) -# define SRCDIR "" -#endif - //TESTED_CLASS= //TESTED_FILES= -// Uncomment the following define to have the autotest generate -// addExpectedFailure() code for all the tests that fail. -// This is useful when a whole new test (sub)suite is added. -// The code is stored in addexpectedfailures.cpp. -// Paste the contents into this file after the existing -// addExpectedFailure() calls. - -//#define GENERATE_ADDEXPECTEDFAILURE_CODE - -static QString readFile(const QString &filename) -{ - QFile file(filename); - if (!file.open(QFile::ReadOnly)) - return QString(); - QTextStream stream(&file); - stream.setCodec("UTF-8"); - return stream.readAll(); -} - -static void appendCString(QVector<char> *v, const char *s) -{ - char c; - do { - c = *(s++); - *v << c; - } while (c != '\0'); -} - -struct ExpectedFailure -{ - ExpectedFailure(const QString &name, const QString &act, - const QString &exp, const QString &msg) - : testName(name), actual(act), expected(exp), message(msg) - { } - - QString testName; - QString actual; - QString expected; - QString message; -}; - -class tst_Suite : public QObject +class tst_QScriptV8TestSuite : public AbstractTestSuite { - public: - tst_Suite(); - virtual ~tst_Suite(); - - static QMetaObject staticMetaObject; - virtual const QMetaObject *metaObject() const; - virtual void *qt_metacast(const char *); - virtual int qt_metacall(QMetaObject::Call, int, void **argv); + tst_QScriptV8TestSuite(); + virtual ~tst_QScriptV8TestSuite(); + +protected: + struct ExpectedFailure + { + ExpectedFailure(const QString &name, const QString &act, + const QString &exp, const QString &msg) + : testName(name), actual(act), expected(exp), message(msg) + { } + + QString testName; + QString actual; + QString expected; + QString message; + }; -private: void addExpectedFailure(const QString &testName, const QString &actual, const QString &expected, const QString &message); bool isExpectedFailure(const QString &testName, const QString &actual, @@ -114,231 +75,172 @@ private: void addTestExclusion(const QRegExp &rx, const QString &message); bool isExcludedTest(const QString &testName, QString *message) const; - QDir testsDir; + virtual void initTestCase(); + virtual void configData(TestConfig::Mode mode, const QStringList &parts); + virtual void writeSkipConfigFile(QTextStream &); + virtual void writeExpectFailConfigFile(QTextStream &); + virtual void runTestFunction(int testIndex); + QStringList testNames; QList<ExpectedFailure> expectedFailures; QList<QPair<QRegExp, QString> > testExclusions; QString mjsunitContents; -#ifdef GENERATE_ADDEXPECTEDFAILURE_CODE - QString generatedAddExpectedFailureCode; -#endif }; -QMetaObject tst_Suite::staticMetaObject; - -Q_GLOBAL_STATIC(QVector<uint>, qt_meta_data_tst_Suite) -Q_GLOBAL_STATIC(QVector<char>, qt_meta_stringdata_tst_Suite) - -const QMetaObject *tst_Suite::metaObject() const -{ - return &staticMetaObject; -} - -void *tst_Suite::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_tst_Suite()->constData())) - return static_cast<void*>(const_cast<tst_Suite*>(this)); - return QObject::qt_metacast(_clname); -} - +// We expect failing tests to call the fail() function (defined in +// mjsunit.js) with arguments expected, actual, message_opt. This +// function intercepts the call, calls the real fail() function (which +// will throw an exception), and sets the original arguments on the +// exception object so that we can process them later. static QScriptValue qscript_fail(QScriptContext *ctx, QScriptEngine *eng) { QScriptValue realFail = ctx->callee().data(); - Q_ASSERT(realFail.isFunction()); + if (!realFail.isFunction()) + qFatal("%s: realFail must be a function", Q_FUNC_INFO); QScriptValue ret = realFail.call(ctx->thisObject(), ctx->argumentsObject()); - Q_ASSERT(eng->hasUncaughtException()); + if (!eng->hasUncaughtException()) + qFatal("%s: realFail function did not throw an exception", Q_FUNC_INFO); ret.setProperty("expected", ctx->argument(0)); ret.setProperty("actual", ctx->argument(1)); + ret.setProperty("message", ctx->argument(2)); QScriptContextInfo info(ctx->parentContext()->parentContext()); ret.setProperty("lineNumber", info.lineNumber()); return ret; } -int tst_Suite::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +void tst_QScriptV8TestSuite::writeSkipConfigFile(QTextStream &stream) { - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - QString name = testNames.at(_id); - QString path = testsDir.absoluteFilePath(name + ".js"); - QString excludeMessage; - if (isExcludedTest(name, &excludeMessage)) { - QTest::qSkip(excludeMessage.toLatin1(), QTest::SkipAll, path.toLatin1(), -1); - } else { - QScriptEngine engine; - engine.evaluate(mjsunitContents).toString(); - if (engine.hasUncaughtException()) { - QStringList bt = engine.uncaughtExceptionBacktrace(); - QString err = engine.uncaughtException().toString(); - qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); - } else { - QScriptValue fakeFail = engine.newFunction(qscript_fail); - fakeFail.setData(engine.globalObject().property("fail")); - engine.globalObject().setProperty("fail", fakeFail); - QString contents = readFile(path); - QScriptValue ret = engine.evaluate(contents); - if (engine.hasUncaughtException()) { - if (!ret.isError()) { - Q_ASSERT(ret.instanceOf(engine.globalObject().property("MjsUnitAssertionError"))); - QString actual = ret.property("actual").toString(); - QString expected = ret.property("expected").toString(); - int lineNumber = ret.property("lineNumber").toInt32(); - QString failMessage; - if (isExpectedFailure(name, actual, expected, &failMessage)) { - QTest::qExpectFail("", failMessage.toLatin1(), - QTest::Continue, path.toLatin1(), - lineNumber); - } -#ifdef GENERATE_ADDEXPECTEDFAILURE_CODE - else { - generatedAddExpectedFailureCode.append( - " addExpectedFailure(\"" + name - + "\", \"" + actual + "\", \"" + expected - + "\", willFixInNextReleaseMessage);\n"); - } -#endif - QTest::qCompare(actual, expected, "actual", "expect", - path.toLatin1(), lineNumber); - } else { - int lineNumber = ret.property("lineNumber").toInt32(); - QTest::qExpectFail("", ret.toString().toLatin1(), - QTest::Continue, path.toLatin1(), lineNumber); - QTest::qVerify(false, ret.toString().toLatin1(), "", path.toLatin1(), lineNumber); - } - } - } - } - _id -= testNames.size(); - } - return _id; + stream << QString::fromLatin1("# testcase | message") << endl; } -tst_Suite::tst_Suite() +void tst_QScriptV8TestSuite::writeExpectFailConfigFile(QTextStream &stream) { - testsDir = QDir(SRCDIR); - bool testsFound = testsDir.cd("tests"); - if (!testsFound) { - qWarning("*** no tests/ dir!"); - } else { - if (!testsDir.exists("mjsunit.js")) - qWarning("*** no tests/mjsunit.js file!"); - else { - mjsunitContents = readFile(testsDir.absoluteFilePath("mjsunit.js")); - if (mjsunitContents.isEmpty()) - qWarning("*** tests/mjsunit.js is empty!"); - } + stream << QString::fromLatin1("# testcase | actual | expected | message") << endl; + for (int i = 0; i < expectedFailures.size(); ++i) { + const ExpectedFailure &fail = expectedFailures.at(i); + stream << QString::fromLatin1("%0 | %1 | %2") + .arg(fail.testName) + .arg(escape(fail.actual)) + .arg(escape(fail.expected)); + if (!fail.message.isEmpty()) + stream << QString::fromLatin1(" | %0").arg(escape(fail.message)); + stream << endl; } - QString willFixInNextReleaseMessage = QString::fromLatin1("Will fix in next release"); - addExpectedFailure("arguments-enum", "2", "0", willFixInNextReleaseMessage); - addExpectedFailure("const-redecl", "undefined", "TypeError", willFixInNextReleaseMessage); - addExpectedFailure("global-const-var-conflicts", "false", "true", willFixInNextReleaseMessage); - addExpectedFailure("string-lastindexof", "0", "-1", "test is wrong?"); - -#ifndef Q_OS_LINUX - addExpectedFailure("to-precision", "1.235e+27", "1.234e+27", "QTBUG-8053: toPrecision(4) gives wrong result on Mac"); -#endif - -#ifdef Q_OS_SOLARIS - addExpectedFailure("math-min-max", "Infinity", "-Infinity", willFixInNextReleaseMessage); - addExpectedFailure("negate-zero", "false", "true", willFixInNextReleaseMessage); - addExpectedFailure("str-to-num", "Infinity", "-Infinity", willFixInNextReleaseMessage); -#endif - - addTestExclusion("debug-*", "not applicable"); - addTestExclusion("mirror-*", "not applicable"); - - addTestExclusion("array-concat", "Hangs on JSC backend"); - addTestExclusion("array-splice", "Hangs on JSC backend"); - addTestExclusion("sparse-array-reverse", "Hangs on JSC backend"); - - addTestExclusion("string-case", "V8-specific behavior? (Doesn't pass on SpiderMonkey either)"); - -#ifdef Q_OS_WINCE - addTestExclusion("deep-recursion", "Demands too much memory on WinCE"); - addTestExclusion("nested-repetition-count-overflow", "Demands too much memory on WinCE"); - addTestExclusion("unicode-test", "Demands too much memory on WinCE"); - addTestExclusion("mul-exhaustive", "Demands too much memory on WinCE"); -#endif - -#ifdef Q_OS_SYMBIAN - addTestExclusion("nested-repetition-count-overflow", "Demands too much memory on Symbian"); - addTestExclusion("unicode-test", "Demands too much memory on Symbian"); -#endif - // Failures due to switch to JSC as back-end - addExpectedFailure("date-parse", "NaN", "946713600000", willFixInNextReleaseMessage); - addExpectedFailure("delete-global-properties", "true", "false", willFixInNextReleaseMessage); - addExpectedFailure("delete", "false", "true", willFixInNextReleaseMessage); - addExpectedFailure("function-arguments-null", "false", "true", willFixInNextReleaseMessage); - addExpectedFailure("function-caller", "null", "function eval() {\n [native code]\n}", willFixInNextReleaseMessage); - addExpectedFailure("function-prototype", "prototype", "disconnectconnect", willFixInNextReleaseMessage); - addExpectedFailure("number-tostring", "0", "0.0000a7c5ac471b4788", willFixInNextReleaseMessage); - addExpectedFailure("parse-int-float", "1e+21", "1", willFixInNextReleaseMessage); - addExpectedFailure("regexp", "false", "true", willFixInNextReleaseMessage); - addExpectedFailure("smi-negative-zero", "-Infinity", "Infinity", willFixInNextReleaseMessage); - addExpectedFailure("string-split", "4", "3", willFixInNextReleaseMessage); - addExpectedFailure("substr", "abcdefghijklmn", "", willFixInNextReleaseMessage); +} - static const char klass[] = "tst_QScriptV8TestSuite"; +void tst_QScriptV8TestSuite::runTestFunction(int testIndex) +{ + QString name = testNames.at(testIndex); + QString path = testsDir.absoluteFilePath(name + ".js"); - QVector<uint> *data = qt_meta_data_tst_Suite(); - // content: - *data << 1 // revision - << 0 // classname - << 0 << 0 // classinfo - << 0 << 10 // methods (backpatched later) - << 0 << 0 // properties - << 0 << 0 // enums/sets - ; + QString excludeMessage; + if (isExcludedTest(name, &excludeMessage)) { + QTest::qSkip(excludeMessage.toLatin1(), QTest::SkipAll, path.toLatin1(), -1); + return; + } - QVector<char> *stringdata = qt_meta_stringdata_tst_Suite(); - appendCString(stringdata, klass); - appendCString(stringdata, ""); + QScriptEngine engine; + engine.evaluate(mjsunitContents); + if (engine.hasUncaughtException()) { + QStringList bt = engine.uncaughtExceptionBacktrace(); + QString err = engine.uncaughtException().toString(); + qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); + } else { + // Prepare to intercept calls to mjsunit's fail() function. + QScriptValue fakeFail = engine.newFunction(qscript_fail); + fakeFail.setData(engine.globalObject().property("fail")); + engine.globalObject().setProperty("fail", fakeFail); + + QString contents = readFile(path); + QScriptValue ret = engine.evaluate(contents); + if (engine.hasUncaughtException()) { + if (!ret.isError()) { + int lineNumber = ret.property("lineNumber").toInt32(); + QTest::qVerify(ret.instanceOf(engine.globalObject().property("MjsUnitAssertionError")), + ret.toString().toLatin1(), + "", + path.toLatin1(), + lineNumber); + QString actual = ret.property("actual").toString(); + QString expected = ret.property("expected").toString(); + QString failMessage; + if (shouldGenerateExpectedFailures) { + if (ret.property("message").isString()) + failMessage = ret.property("message").toString(); + addExpectedFailure(name, actual, expected, failMessage); + } else if (isExpectedFailure(name, actual, expected, &failMessage)) { + QTest::qExpectFail("", failMessage.toLatin1(), + QTest::Continue, path.toLatin1(), + lineNumber); + } + QTest::qCompare(actual, expected, "actual", "expect", + path.toLatin1(), lineNumber); + } else { + int lineNumber = ret.property("lineNumber").toInt32(); + QTest::qExpectFail("", ret.toString().toLatin1(), + QTest::Continue, path.toLatin1(), lineNumber); + QTest::qVerify(false, ret.toString().toLatin1(), "", path.toLatin1(), lineNumber); + } + } + } +} +tst_QScriptV8TestSuite::tst_QScriptV8TestSuite() + : AbstractTestSuite("tst_QScriptV8TestSuite", + ":/tests", ":/") +{ + // One test function per test file. QFileInfoList testFileInfos; - if (testsFound) - testFileInfos = testsDir.entryInfoList(QStringList() << "*.js", QDir::Files); + testFileInfos = testsDir.entryInfoList(QStringList() << "*.js", QDir::Files); foreach (QFileInfo tfi, testFileInfos) { QString name = tfi.baseName(); - // slot: signature, parameters, type, tag, flags - QString slot = QString::fromLatin1("%0()").arg(name); - static const int nullbyte = sizeof(klass); - *data << stringdata->size() << nullbyte << nullbyte << nullbyte << 0x08; - appendCString(stringdata, slot.toLatin1()); + addTestFunction(name); testNames.append(name); } - (*data)[4] = testFileInfos.size(); + finalizeMetaObject(); +} - *data << 0; // eod +tst_QScriptV8TestSuite::~tst_QScriptV8TestSuite() +{ +} - // initialize staticMetaObject - staticMetaObject.d.superdata = &QObject::staticMetaObject; - staticMetaObject.d.stringdata = stringdata->constData(); - staticMetaObject.d.data = data->constData(); - staticMetaObject.d.extradata = 0; +void tst_QScriptV8TestSuite::initTestCase() +{ + AbstractTestSuite::initTestCase(); + + // FIXME: These warnings should be QFAIL, but that would make the + // test fail right now. + if (!testsDir.exists("mjsunit.js")) + qWarning("*** no tests/mjsunit.js file!"); + else { + mjsunitContents = readFile(testsDir.absoluteFilePath("mjsunit.js")); + if (mjsunitContents.isEmpty()) + qWarning("*** tests/mjsunit.js is empty!"); + } } -tst_Suite::~tst_Suite() +void tst_QScriptV8TestSuite::configData(TestConfig::Mode mode, const QStringList &parts) { -#ifdef GENERATE_ADDEXPECTEDFAILURE_CODE - if (!generatedAddExpectedFailureCode.isEmpty()) { - QFile file("addexpectedfailures.cpp"); - file.open(QFile::WriteOnly); - QTextStream ts(&file); - ts << generatedAddExpectedFailureCode; + switch (mode) { + case TestConfig::Skip: + addTestExclusion(parts.at(0), parts.value(1)); + break; + + case TestConfig::ExpectFail: + addExpectedFailure(parts.at(0), parts.value(1), + parts.value(2), parts.value(3)); + break; } -#endif } -void tst_Suite::addExpectedFailure(const QString &testName, const QString &actual, +void tst_QScriptV8TestSuite::addExpectedFailure(const QString &testName, const QString &actual, const QString &expected, const QString &message) { expectedFailures.append(ExpectedFailure(testName, actual, expected, message)); } -bool tst_Suite::isExpectedFailure(const QString &testName, const QString &actual, +bool tst_QScriptV8TestSuite::isExpectedFailure(const QString &testName, const QString &actual, const QString &expected, QString *message) const { for (int i = 0; i < expectedFailures.size(); ++i) { @@ -352,17 +254,17 @@ bool tst_Suite::isExpectedFailure(const QString &testName, const QString &actual return false; } -void tst_Suite::addTestExclusion(const QString &testName, const QString &message) +void tst_QScriptV8TestSuite::addTestExclusion(const QString &testName, const QString &message) { testExclusions.append(qMakePair(QRegExp(testName), message)); } -void tst_Suite::addTestExclusion(const QRegExp &rx, const QString &message) +void tst_QScriptV8TestSuite::addTestExclusion(const QRegExp &rx, const QString &message) { testExclusions.append(qMakePair(rx, message)); } -bool tst_Suite::isExcludedTest(const QString &testName, QString *message) const +bool tst_QScriptV8TestSuite::isExcludedTest(const QString &testName, QString *message) const { for (int i = 0; i < testExclusions.size(); ++i) { if (testExclusions.at(i).first.indexIn(testName) != -1) { @@ -374,4 +276,4 @@ bool tst_Suite::isExcludedTest(const QString &testName, QString *message) const return false; } -QTEST_MAIN(tst_Suite) +QTEST_MAIN(tst_QScriptV8TestSuite) diff --git a/tests/auto/qscriptvalue/qscriptvalue.pro b/tests/auto/qscriptvalue/qscriptvalue.pro index c3e9912..0474c32 100644 --- a/tests/auto/qscriptvalue/qscriptvalue.pro +++ b/tests/auto/qscriptvalue/qscriptvalue.pro @@ -3,14 +3,6 @@ QT = core gui script SOURCES += tst_qscriptvalue.cpp HEADERS += tst_qscriptvalue.h -# Generated by testgen -SOURCES += \ - tst_qscriptvalue_generated_init.cpp \ - tst_qscriptvalue_generated_cast.cpp \ - tst_qscriptvalue_generated_comparison.cpp \ - tst_qscriptvalue_generated_isXXX.cpp \ - tst_qscriptvalue_generated_toXXX.cpp - win32-msvc* { # With -O2, MSVC takes up to 24 minutes to compile this test! QMAKE_CXXFLAGS_RELEASE -= -O1 -O2 diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp index c40be40..6779d9b 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp +++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp @@ -56,64 +56,11 @@ tst_QScriptValue::tst_QScriptValue() tst_QScriptValue::~tst_QScriptValue() { - delete engine; + if (engine) + delete engine; } -void tst_QScriptValue::dataHelper(InitDataFunction init, DefineDataFunction define) -{ - QTest::addColumn<QString>("__expression__"); - (this->*init)(); - QHash<QString,QScriptValue>::const_iterator it; - for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) { - m_currentExpression = it.key(); - (this->*define)(it.key().toLatin1()); - } - m_currentExpression = QString(); -} - -QTestData &tst_QScriptValue::newRow(const char *tag) -{ - return QTest::newRow(tag) << m_currentExpression; -} - -void tst_QScriptValue::testHelper(TestFunction fun) -{ - QFETCH(QString, __expression__); - QScriptValue value = m_values.value(__expression__); - (this->*fun)(__expression__.toLatin1(), value); -} - -void tst_QScriptValue::assignAndCopyConstruct_initData() -{ - QTest::addColumn<int>("dummy"); - initScriptValues(); -} - -void tst_QScriptValue::assignAndCopyConstruct_makeData(const char *expr) -{ - newRow(expr) << 0; -} - -void tst_QScriptValue::assignAndCopyConstruct_test(const char *, const QScriptValue &value) -{ - QScriptValue copy(value); - QCOMPARE(copy.strictlyEquals(value), !value.isNumber() || !qIsNaN(value.toNumber())); - QCOMPARE(copy.engine(), value.engine()); - - QScriptValue assigned = copy; - QCOMPARE(assigned.strictlyEquals(value), !copy.isNumber() || !qIsNaN(copy.toNumber())); - QCOMPARE(assigned.engine(), assigned.engine()); - - QScriptValue other(!value.toBool()); - assigned = other; - QVERIFY(!assigned.strictlyEquals(copy)); - QVERIFY(assigned.strictlyEquals(other)); - QCOMPARE(assigned.engine(), other.engine()); -} - -DEFINE_TEST_FUNCTION(assignAndCopyConstruct) - -void tst_QScriptValue::ctor() +void tst_QScriptValue::ctor_invalid() { QScriptEngine eng; { @@ -121,6 +68,11 @@ void tst_QScriptValue::ctor() QCOMPARE(v.isValid(), false); QCOMPARE(v.engine(), (QScriptEngine *)0); } +} + +void tst_QScriptValue::ctor_undefinedWithEngine() +{ + QScriptEngine eng; { QScriptValue v(&eng, QScriptValue::UndefinedValue); QCOMPARE(v.isValid(), true); @@ -128,6 +80,11 @@ void tst_QScriptValue::ctor() QCOMPARE(v.isObject(), false); QCOMPARE(v.engine(), &eng); } +} + +void tst_QScriptValue::ctor_nullWithEngine() +{ + QScriptEngine eng; { QScriptValue v(&eng, QScriptValue::NullValue); QCOMPARE(v.isValid(), true); @@ -135,6 +92,11 @@ void tst_QScriptValue::ctor() QCOMPARE(v.isObject(), false); QCOMPARE(v.engine(), &eng); } +} + +void tst_QScriptValue::ctor_boolWithEngine() +{ + QScriptEngine eng; { QScriptValue v(&eng, false); QCOMPARE(v.isValid(), true); @@ -144,6 +106,11 @@ void tst_QScriptValue::ctor() QCOMPARE(v.toBoolean(), false); QCOMPARE(v.engine(), &eng); } +} + +void tst_QScriptValue::ctor_intWithEngine() +{ + QScriptEngine eng; { QScriptValue v(&eng, int(1)); QCOMPARE(v.isValid(), true); @@ -152,132 +119,102 @@ void tst_QScriptValue::ctor() QCOMPARE(v.toNumber(), 1.0); QCOMPARE(v.engine(), &eng); } +} + +void tst_QScriptValue::ctor_int() +{ { QScriptValue v(int(0x43211234)); QVERIFY(v.isNumber()); QCOMPARE(v.toInt32(), 0x43211234); } { - QScriptValue v(&eng, uint(1)); + QScriptValue v(int(1)); QCOMPARE(v.isValid(), true); QCOMPARE(v.isNumber(), true); QCOMPARE(v.isObject(), false); QCOMPARE(v.toNumber(), 1.0); - QCOMPARE(v.engine(), &eng); - } - { - QScriptValue v(uint(0x43211234)); - QVERIFY(v.isNumber()); - QCOMPARE(v.toUInt32(), uint(0x43211234)); + QCOMPARE(v.engine(), (QScriptEngine *)0); } +} + +void tst_QScriptValue::ctor_uintWithEngine() +{ + QScriptEngine eng; { - QScriptValue v(&eng, 1.0); + QScriptValue v(&eng, uint(1)); QCOMPARE(v.isValid(), true); QCOMPARE(v.isNumber(), true); QCOMPARE(v.isObject(), false); QCOMPARE(v.toNumber(), 1.0); QCOMPARE(v.engine(), &eng); } +} + +void tst_QScriptValue::ctor_uint() +{ { - QScriptValue v(12345678910.5); + QScriptValue v(uint(0x43211234)); QVERIFY(v.isNumber()); - QCOMPARE(v.toNumber(), 12345678910.5); - } - { - QScriptValue v(&eng, "ciao"); - QCOMPARE(v.isValid(), true); - QCOMPARE(v.isString(), true); - QCOMPARE(v.isObject(), false); - QCOMPARE(v.toString(), QLatin1String("ciao")); - QCOMPARE(v.engine(), &eng); + QCOMPARE(v.toUInt32(), uint(0x43211234)); } { - QScriptValue v(&eng, QString("ciao")); + QScriptValue v(uint(1)); QCOMPARE(v.isValid(), true); - QCOMPARE(v.isString(), true); + QCOMPARE(v.isNumber(), true); QCOMPARE(v.isObject(), false); - QCOMPARE(v.toString(), QLatin1String("ciao")); - QCOMPARE(v.engine(), &eng); - } - // copy constructor, operator= - { - QScriptValue v(&eng, 1.0); - QScriptValue v2(v); - QCOMPARE(v2.strictlyEquals(v), true); - QCOMPARE(v2.engine(), &eng); - - QScriptValue v3(v); - QCOMPARE(v3.strictlyEquals(v), true); - QCOMPARE(v3.strictlyEquals(v2), true); - QCOMPARE(v3.engine(), &eng); - - QScriptValue v4(&eng, 2.0); - QCOMPARE(v4.strictlyEquals(v), false); - v3 = v4; - QCOMPARE(v3.strictlyEquals(v), false); - QCOMPARE(v3.strictlyEquals(v4), true); - - v2 = QScriptValue(); - QCOMPARE(v2.strictlyEquals(v), false); QCOMPARE(v.toNumber(), 1.0); - - QScriptValue v5(v); - QCOMPARE(v5.strictlyEquals(v), true); - v = QScriptValue(); - QCOMPARE(v5.strictlyEquals(v), false); - QCOMPARE(v5.toNumber(), 1.0); - } - - // constructors that take no engine argument - { - QScriptValue v(QScriptValue::UndefinedValue); - QCOMPARE(v.isValid(), true); - QCOMPARE(v.isUndefined(), true); - QCOMPARE(v.isObject(), false); - QCOMPARE(v.engine(), (QScriptEngine *)0); - } - { - QScriptValue v(QScriptValue::NullValue); - QCOMPARE(v.isValid(), true); - QCOMPARE(v.isNull(), true); - QCOMPARE(v.isObject(), false); - QCOMPARE(v.engine(), (QScriptEngine *)0); - } - { - QScriptValue v(false); - QCOMPARE(v.isValid(), true); - QCOMPARE(v.isBoolean(), true); - QCOMPARE(v.isBool(), true); - QCOMPARE(v.isObject(), false); - QCOMPARE(v.toBoolean(), false); QCOMPARE(v.engine(), (QScriptEngine *)0); } +} + +void tst_QScriptValue::ctor_floatWithEngine() +{ + QScriptEngine eng; { - QScriptValue v(int(1)); + QScriptValue v(&eng, 1.0); QCOMPARE(v.isValid(), true); QCOMPARE(v.isNumber(), true); QCOMPARE(v.isObject(), false); QCOMPARE(v.toNumber(), 1.0); - QCOMPARE(v.engine(), (QScriptEngine *)0); + QCOMPARE(v.engine(), &eng); } +} + +void tst_QScriptValue::ctor_float() +{ { - QScriptValue v(uint(1)); + QScriptValue v(12345678910.5); + QVERIFY(v.isNumber()); + QCOMPARE(v.toNumber(), 12345678910.5); + } + { + QScriptValue v(1.0); QCOMPARE(v.isValid(), true); QCOMPARE(v.isNumber(), true); QCOMPARE(v.isObject(), false); QCOMPARE(v.toNumber(), 1.0); QCOMPARE(v.engine(), (QScriptEngine *)0); } +} + +void tst_QScriptValue::ctor_stringWithEngine() +{ + QScriptEngine eng; { - QScriptValue v(1.0); + QScriptValue v(&eng, "ciao"); QCOMPARE(v.isValid(), true); - QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isString(), true); QCOMPARE(v.isObject(), false); - QCOMPARE(v.toNumber(), 1.0); - QCOMPARE(v.engine(), (QScriptEngine *)0); + QCOMPARE(v.toString(), QLatin1String("ciao")); + QCOMPARE(v.engine(), &eng); } +} + +void tst_QScriptValue::ctor_string() +{ { - QScriptValue v("ciao"); + QScriptValue v(QString("ciao")); QCOMPARE(v.isValid(), true); QCOMPARE(v.isString(), true); QCOMPARE(v.isObject(), false); @@ -285,26 +222,31 @@ void tst_QScriptValue::ctor() QCOMPARE(v.engine(), (QScriptEngine *)0); } { - QScriptValue v(QString("ciao")); + QScriptValue v("ciao"); QCOMPARE(v.isValid(), true); QCOMPARE(v.isString(), true); QCOMPARE(v.isObject(), false); QCOMPARE(v.toString(), QLatin1String("ciao")); QCOMPARE(v.engine(), (QScriptEngine *)0); } +} + +void tst_QScriptValue::ctor_copyAndAssignWithEngine() +{ + QScriptEngine eng; // copy constructor, operator= { - QScriptValue v(1.0); + QScriptValue v(&eng, 1.0); QScriptValue v2(v); QCOMPARE(v2.strictlyEquals(v), true); - QCOMPARE(v2.engine(), (QScriptEngine *)0); + QCOMPARE(v2.engine(), &eng); QScriptValue v3(v); QCOMPARE(v3.strictlyEquals(v), true); QCOMPARE(v3.strictlyEquals(v2), true); - QCOMPARE(v3.engine(), (QScriptEngine *)0); + QCOMPARE(v3.engine(), &eng); - QScriptValue v4(2.0); + QScriptValue v4(&eng, 2.0); QCOMPARE(v4.strictlyEquals(v), false); v3 = v4; QCOMPARE(v3.strictlyEquals(v), false); @@ -320,7 +262,68 @@ void tst_QScriptValue::ctor() QCOMPARE(v5.strictlyEquals(v), false); QCOMPARE(v5.toNumber(), 1.0); } +} + +void tst_QScriptValue::ctor_undefined() +{ + QScriptValue v(QScriptValue::UndefinedValue); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isUndefined(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.engine(), (QScriptEngine *)0); +} + +void tst_QScriptValue::ctor_null() +{ + QScriptValue v(QScriptValue::NullValue); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNull(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.engine(), (QScriptEngine *)0); +} + +void tst_QScriptValue::ctor_bool() +{ + QScriptValue v(false); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isBoolean(), true); + QCOMPARE(v.isBool(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toBoolean(), false); + QCOMPARE(v.engine(), (QScriptEngine *)0); +} + +void tst_QScriptValue::ctor_copyAndAssign() +{ + QScriptValue v(1.0); + QScriptValue v2(v); + QCOMPARE(v2.strictlyEquals(v), true); + QCOMPARE(v2.engine(), (QScriptEngine *)0); + + QScriptValue v3(v); + QCOMPARE(v3.strictlyEquals(v), true); + QCOMPARE(v3.strictlyEquals(v2), true); + QCOMPARE(v3.engine(), (QScriptEngine *)0); + + QScriptValue v4(2.0); + QCOMPARE(v4.strictlyEquals(v), false); + v3 = v4; + QCOMPARE(v3.strictlyEquals(v), false); + QCOMPARE(v3.strictlyEquals(v4), true); + + v2 = QScriptValue(); + QCOMPARE(v2.strictlyEquals(v), false); + QCOMPARE(v.toNumber(), 1.0); + + QScriptValue v5(v); + QCOMPARE(v5.strictlyEquals(v), true); + v = QScriptValue(); + QCOMPARE(v5.strictlyEquals(v), false); + QCOMPARE(v5.toNumber(), 1.0); +} +void tst_QScriptValue::ctor_nullEngine() +{ // 0 engine QVERIFY(QScriptValue(0, QScriptValue::UndefinedValue).isUndefined()); QVERIFY(QScriptValue(0, QScriptValue::NullValue).isNull()); @@ -337,7 +340,7 @@ static QScriptValue myFunction(QScriptContext *, QScriptEngine *eng) return eng->undefinedValue(); } -void tst_QScriptValue::toString_old() +void tst_QScriptValue::toString() { QScriptEngine eng; @@ -451,7 +454,7 @@ void tst_QScriptValue::toString_old() QVERIFY(variant.toString().isEmpty()); } -void tst_QScriptValue::toNumber_old() +void tst_QScriptValue::toNumber() { QScriptEngine eng; @@ -524,7 +527,7 @@ void tst_QScriptValue::toNumber_old() } } -void tst_QScriptValue::toBoolean_old() // deprecated +void tst_QScriptValue::toBoolean() // deprecated { QScriptEngine eng; @@ -621,7 +624,7 @@ void tst_QScriptValue::toBoolean_old() // deprecated } } -void tst_QScriptValue::toBool_old() +void tst_QScriptValue::toBool() { QScriptEngine eng; @@ -718,7 +721,7 @@ void tst_QScriptValue::toBool_old() } } -void tst_QScriptValue::toInteger_old() +void tst_QScriptValue::toInteger() { QScriptEngine eng; @@ -805,7 +808,7 @@ void tst_QScriptValue::toInteger_old() QCOMPARE(inv.toInteger(), 0.0); } -void tst_QScriptValue::toInt32_old() +void tst_QScriptValue::toInt32() { QScriptEngine eng; @@ -941,7 +944,7 @@ void tst_QScriptValue::toInt32_old() QCOMPARE(qscriptvalue_cast<qint32>(inv), 0); } -void tst_QScriptValue::toUInt32_old() +void tst_QScriptValue::toUInt32() { QScriptEngine eng; @@ -1073,7 +1076,7 @@ void tst_QScriptValue::toUInt32_old() QCOMPARE(qscriptvalue_cast<quint32>(inv), quint32(0)); } -void tst_QScriptValue::toUInt16_old() +void tst_QScriptValue::toUInt16() { QScriptEngine eng; @@ -1234,7 +1237,7 @@ void tst_QScriptValue::toUInt16_old() Q_DECLARE_METATYPE(QVariant) #endif -void tst_QScriptValue::toVariant_old() +void tst_QScriptValue::toVariant() { QScriptEngine eng; @@ -1251,6 +1254,10 @@ void tst_QScriptValue::toVariant_old() QCOMPARE(number.toVariant(), QVariant(123.0)); QCOMPARE(qscriptvalue_cast<QVariant>(number), QVariant(123.0)); + QScriptValue intNumber = QScriptValue(&eng, (qint32)123); + QCOMPARE(intNumber.toVariant().type(), QVariant((qint32)123).type()); + QCOMPARE((qscriptvalue_cast<QVariant>(number)).type(), QVariant((qint32)123).type()); + QScriptValue falskt = QScriptValue(&eng, false); QCOMPARE(falskt.toVariant(), QVariant(false)); QCOMPARE(qscriptvalue_cast<QVariant>(falskt), QVariant(false)); @@ -1338,52 +1345,53 @@ void tst_QScriptValue::toVariant_old() } } -// unfortunately, this is necessary in order to do qscriptvalue_cast<QPushButton*>(...) -Q_DECLARE_METATYPE(QPushButton*) - -void tst_QScriptValue::toQObject_old() +void tst_QScriptValue::toQObject_nonQObject_data() { - QScriptEngine eng; - - QScriptValue undefined = eng.undefinedValue(); - QCOMPARE(undefined.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(undefined), (QObject *)0); - - QScriptValue null = eng.nullValue(); - QCOMPARE(null.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(null), (QObject *)0); - - { - QScriptValue falskt = QScriptValue(&eng, false); - QCOMPARE(falskt.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(falskt), (QObject *)0); + newEngine(); + QTest::addColumn<QScriptValue>("value"); + + QTest::newRow("invalid") << QScriptValue(); + QTest::newRow("bool(false)") << QScriptValue(false); + QTest::newRow("bool(true)") << QScriptValue(true); + QTest::newRow("int") << QScriptValue(123); + QTest::newRow("string") << QScriptValue(QString::fromLatin1("ciao")); + QTest::newRow("undefined") << QScriptValue(QScriptValue::UndefinedValue); + QTest::newRow("null") << QScriptValue(QScriptValue::NullValue); + + QTest::newRow("bool bound(false)") << QScriptValue(engine, false); + QTest::newRow("bool bound(true)") << QScriptValue(engine, true); + QTest::newRow("int bound") << QScriptValue(engine, 123); + QTest::newRow("string bound") << QScriptValue(engine, QString::fromLatin1("ciao")); + QTest::newRow("undefined bound") << engine->undefinedValue(); + QTest::newRow("null bound") << engine->nullValue(); + QTest::newRow("object") << engine->newObject(); + QTest::newRow("array") << engine->newArray(); + QTest::newRow("date") << engine->newDate(124); + QTest::newRow("variant(12345)") << engine->newVariant(12345); + QTest::newRow("variant((QObject*)0)") << engine->newVariant(qVariantFromValue((QObject*)0)); + QTest::newRow("newQObject(0)") << engine->newQObject(0); +} - QScriptValue sant = QScriptValue(&eng, true); - QCOMPARE(sant.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(sant), (QObject *)0); - QScriptValue number = QScriptValue(&eng, 123.0); - QCOMPARE(number.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(number), (QObject *)0); +void tst_QScriptValue::toQObject_nonQObject() +{ + QFETCH(QScriptValue, value); + QCOMPARE(value.toQObject(), (QObject *)0); + QCOMPARE(qscriptvalue_cast<QObject*>(value), (QObject *)0); +} - QScriptValue str = QScriptValue(&eng, QString("ciao")); - QCOMPARE(str.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(str), (QObject *)0); - } +// unfortunately, this is necessary in order to do qscriptvalue_cast<QPushButton*>(...) +Q_DECLARE_METATYPE(QPushButton*); - QScriptValue object = eng.newObject(); - QCOMPARE(object.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(object), (QObject *)0); +void tst_QScriptValue::toQObject() +{ + QScriptEngine eng; QScriptValue qobject = eng.newQObject(this); QCOMPARE(qobject.toQObject(), (QObject *)this); QCOMPARE(qscriptvalue_cast<QObject*>(qobject), (QObject *)this); QCOMPARE(qscriptvalue_cast<QWidget*>(qobject), (QWidget *)0); - QScriptValue qobject2 = eng.newQObject(0); - QCOMPARE(qobject2.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(qobject2), (QObject *)0); - QWidget widget; QScriptValue qwidget = eng.newQObject(&widget); QCOMPARE(qwidget.toQObject(), (QObject *)&widget); @@ -1397,25 +1405,6 @@ void tst_QScriptValue::toQObject_old() QCOMPARE(qscriptvalue_cast<QWidget*>(qbutton), (QWidget *)&button); QCOMPARE(qscriptvalue_cast<QPushButton*>(qbutton), &button); - // V2 constructors - { - QScriptValue falskt = QScriptValue(false); - QCOMPARE(falskt.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(falskt), (QObject *)0); - - QScriptValue sant = QScriptValue(true); - QCOMPARE(sant.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(sant), (QObject *)0); - - QScriptValue number = QScriptValue(123.0); - QCOMPARE(number.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(number), (QObject *)0); - - QScriptValue str = QScriptValue(QString("ciao")); - QCOMPARE(str.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(str), (QObject *)0); - } - // wrapping a QObject* as variant QScriptValue variant = eng.newVariant(qVariantFromValue((QObject*)&button)); QCOMPARE(variant.toQObject(), (QObject*)&button); @@ -1434,10 +1423,6 @@ void tst_QScriptValue::toQObject_old() QCOMPARE(qscriptvalue_cast<QObject*>(variant3), (QObject*)0); QCOMPARE(qscriptvalue_cast<QWidget*>(variant3), (QWidget*)0); QCOMPARE(qscriptvalue_cast<QPushButton*>(variant3), &button); - - QScriptValue inv; - QCOMPARE(inv.toQObject(), (QObject *)0); - QCOMPARE(qscriptvalue_cast<QObject*>(inv), (QObject *)0); } void tst_QScriptValue::toObject() @@ -1548,7 +1533,7 @@ void tst_QScriptValue::toObject() } } -void tst_QScriptValue::toDateTime_old() +void tst_QScriptValue::toDateTime() { QScriptEngine eng; QDateTime dt = eng.evaluate("new Date(0)").toDateTime(); @@ -1566,7 +1551,7 @@ void tst_QScriptValue::toDateTime_old() QVERIFY(!eng.undefinedValue().toDateTime().isValid()); } -void tst_QScriptValue::toRegExp_old() +void tst_QScriptValue::toRegExp() { QScriptEngine eng; { @@ -1596,7 +1581,16 @@ void tst_QScriptValue::toRegExp_old() QVERIFY(eng.undefinedValue().toRegExp().isEmpty()); } -void tst_QScriptValue::instanceOf_old() +void tst_QScriptValue::instanceOf_twoEngines() +{ + QScriptEngine eng; + QScriptValue obj = eng.newObject(); + QScriptEngine otherEngine; + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::instanceof: cannot perform operation on a value created in a different engine"); + QCOMPARE(obj.instanceOf(otherEngine.globalObject().property("Object")), false); +} + +void tst_QScriptValue::instanceOf() { QScriptEngine eng; QScriptValue obj = eng.newObject(); @@ -1626,40 +1620,60 @@ void tst_QScriptValue::instanceOf_old() QCOMPARE(arr.instanceOf(eng.evaluate("QObject")), false); QCOMPARE(QScriptValue().instanceOf(arr), false); +} - QScriptEngine otherEngine; - QTest::ignoreMessage(QtWarningMsg, "QScriptValue::instanceof: cannot perform operation on a value created in a different engine"); - QCOMPARE(obj.instanceOf(otherEngine.globalObject().property("Object")), false); +void tst_QScriptValue::isArray_data() +{ + newEngine(); + + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("array"); + + QTest::newRow("[]") << engine->evaluate("[]") << true; + QTest::newRow("{}") << engine->evaluate("{}") << false; + QTest::newRow("globalObject") << engine->globalObject() << false; + QTest::newRow("invalid") << QScriptValue() << false; + QTest::newRow("number") << QScriptValue(123) << false; + QTest::newRow("bool") << QScriptValue(false) << false; + QTest::newRow("null") << engine->nullValue() << false; + QTest::newRow("undefined") << engine->undefinedValue() << false; } -void tst_QScriptValue::isArray_old() +void tst_QScriptValue::isArray() { - QScriptEngine eng; - QVERIFY(eng.evaluate("[]").isArray()); - QVERIFY(!eng.evaluate("{}").isArray()); - QVERIFY(!eng.globalObject().isArray()); - QVERIFY(!QScriptValue().isArray()); - QVERIFY(!QScriptValue(123).isArray()); - QVERIFY(!QScriptValue(false).isArray()); - QVERIFY(!eng.nullValue().isArray()); - QVERIFY(!eng.undefinedValue().isArray()); + QFETCH(QScriptValue, value); + QFETCH(bool, array); + + QCOMPARE(value.isArray(), array); } -void tst_QScriptValue::isDate_old() +void tst_QScriptValue::isDate_data() { - QScriptEngine eng; - QVERIFY(eng.evaluate("new Date()").isDate()); - QVERIFY(!eng.evaluate("[]").isDate()); - QVERIFY(!eng.evaluate("{}").isDate()); - QVERIFY(!eng.globalObject().isDate()); - QVERIFY(!QScriptValue().isDate()); - QVERIFY(!QScriptValue(123).isDate()); - QVERIFY(!QScriptValue(false).isDate()); - QVERIFY(!eng.nullValue().isDate()); - QVERIFY(!eng.undefinedValue().isDate()); + newEngine(); + + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("date"); + + QTest::newRow("date") << engine->evaluate("new Date()") << true; + QTest::newRow("[]") << engine->evaluate("[]") << false; + QTest::newRow("{}") << engine->evaluate("{}") << false; + QTest::newRow("globalObject") << engine->globalObject() << false; + QTest::newRow("invalid") << QScriptValue() << false; + QTest::newRow("number") << QScriptValue(123) << false; + QTest::newRow("bool") << QScriptValue(false) << false; + QTest::newRow("null") << engine->nullValue() << false; + QTest::newRow("undefined") << engine->undefinedValue() << false; +} + +void tst_QScriptValue::isDate() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, date); + + QCOMPARE(value.isDate(), date); } -void tst_QScriptValue::isError_old() +void tst_QScriptValue::isError_propertiesOfGlobalObject() { QStringList errors; errors << "Error" @@ -1675,27 +1689,60 @@ void tst_QScriptValue::isError_old() QVERIFY(ctor.isFunction()); QVERIFY(ctor.property("prototype").isError()); } - QVERIFY(!eng.globalObject().isError()); - QVERIFY(!QScriptValue().isError()); - QVERIFY(!QScriptValue(123).isError()); - QVERIFY(!QScriptValue(false).isError()); - QVERIFY(!eng.nullValue().isError()); - QVERIFY(!eng.undefinedValue().isError()); - QVERIFY(!eng.evaluate("new Object()").isError()); } -void tst_QScriptValue::isRegExp_old() +void tst_QScriptValue::isError_data() { - QScriptEngine eng; - QVERIFY(eng.evaluate("/foo/").isRegExp()); - QVERIFY(!eng.evaluate("[]").isRegExp()); - QVERIFY(!eng.evaluate("{}").isRegExp()); - QVERIFY(!eng.globalObject().isRegExp()); - QVERIFY(!QScriptValue().isRegExp()); - QVERIFY(!QScriptValue(123).isRegExp()); - QVERIFY(!QScriptValue(false).isRegExp()); - QVERIFY(!eng.nullValue().isRegExp()); - QVERIFY(!eng.undefinedValue().isRegExp()); + newEngine(); + + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("error"); + + QTest::newRow("syntax error") << engine->evaluate("%fsdg's") << true; + QTest::newRow("[]") << engine->evaluate("[]") << false; + QTest::newRow("{}") << engine->evaluate("{}") << false; + QTest::newRow("globalObject") << engine->globalObject() << false; + QTest::newRow("invalid") << QScriptValue() << false; + QTest::newRow("number") << QScriptValue(123) << false; + QTest::newRow("bool") << QScriptValue(false) << false; + QTest::newRow("null") << engine->nullValue() << false; + QTest::newRow("undefined") << engine->undefinedValue() << false; + QTest::newRow("newObject") << engine->newObject() << false; + QTest::newRow("new Object") << engine->evaluate("new Object()") << false; +} + +void tst_QScriptValue::isError() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, error); + + QCOMPARE(value.isError(), error); +} + +void tst_QScriptValue::isRegExp_data() +{ + newEngine(); + + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("regexp"); + + QTest::newRow("/foo/") << engine->evaluate("/foo/") << true; + QTest::newRow("[]") << engine->evaluate("[]") << false; + QTest::newRow("{}") << engine->evaluate("{}") << false; + QTest::newRow("globalObject") << engine->globalObject() << false; + QTest::newRow("invalid") << QScriptValue() << false; + QTest::newRow("number") << QScriptValue(123) << false; + QTest::newRow("bool") << QScriptValue(false) << false; + QTest::newRow("null") << engine->nullValue() << false; + QTest::newRow("undefined") << engine->undefinedValue() << false; +} + +void tst_QScriptValue::isRegExp() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, regexp); + + QCOMPARE(value.isRegExp(), regexp); } static QScriptValue getter(QScriptContext *ctx, QScriptEngine *) @@ -1731,48 +1778,9 @@ static QScriptValue getSet__proto__(QScriptContext *ctx, QScriptEngine *) return ctx->callee().property("value"); } -void tst_QScriptValue::getSetProperty() +void tst_QScriptValue::getSetProperty_HooliganTask162051() { QScriptEngine eng; - - QScriptValue object = eng.newObject(); - - QScriptValue str = QScriptValue(&eng, "bar"); - object.setProperty("foo", str); - QCOMPARE(object.property("foo").toString(), str.toString()); - - QScriptValue num = QScriptValue(&eng, 123.0); - object.setProperty("baz", num); - QCOMPARE(object.property("baz").toNumber(), num.toNumber()); - - QScriptValue strstr = QScriptValue("bar"); - QCOMPARE(strstr.engine(), (QScriptEngine *)0); - object.setProperty("foo", strstr); - QCOMPARE(object.property("foo").toString(), strstr.toString()); - QCOMPARE(strstr.engine(), &eng); // the value has been bound to the engine - - QScriptValue numnum = QScriptValue(123.0); - object.setProperty("baz", numnum); - QCOMPARE(object.property("baz").toNumber(), numnum.toNumber()); - - QScriptValue inv; - inv.setProperty("foo", num); - QCOMPARE(inv.property("foo").isValid(), false); - - QScriptValue array = eng.newArray(); - QVERIFY(array.isArray()); - array.setProperty(0, num); - QCOMPARE(array.property(0).toNumber(), num.toNumber()); - QCOMPARE(array.property("0").toNumber(), num.toNumber()); - QCOMPARE(array.property("length").toUInt32(), quint32(1)); - array.setProperty(1, str); - QCOMPARE(array.property(1).toString(), str.toString()); - QCOMPARE(array.property("1").toString(), str.toString()); - QCOMPARE(array.property("length").toUInt32(), quint32(2)); - array.setProperty("length", QScriptValue(&eng, 1)); - QCOMPARE(array.property("length").toUInt32(), quint32(1)); - QCOMPARE(array.property(1).isValid(), false); - // task 162051 -- detecting whether the property is an array index or not QVERIFY(eng.evaluate("a = []; a['00'] = 123; a['00']").strictlyEquals(QScriptValue(&eng, 123))); QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0))); @@ -1785,24 +1793,62 @@ void tst_QScriptValue::getSetProperty() QVERIFY(eng.evaluate("a[0]").isUndefined()); QVERIFY(eng.evaluate("a[0] = 789; a[0]").strictlyEquals(QScriptValue(&eng, 789))); QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 1))); +} +void tst_QScriptValue::getSetProperty_HooliganTask183072() +{ + QScriptEngine eng; // task 183072 -- 0x800000000 is not an array index eng.evaluate("a = []; a[0x800000000] = 123"); QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0))); QVERIFY(eng.evaluate("a[0]").isUndefined()); QVERIFY(eng.evaluate("a[0x800000000]").strictlyEquals(QScriptValue(&eng, 123))); +} - QScriptEngine otherEngine; - QScriptValue otherNum = QScriptValue(&otherEngine, 123); - QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty(oof) failed: cannot set value created in a different engine"); - object.setProperty("oof", otherNum); - QCOMPARE(object.property("oof").isValid(), false); +void tst_QScriptValue::getSetProperty_propertyRemoval() +{ + // test property removal (setProperty(QScriptValue())) + QScriptEngine eng; + QScriptValue object = eng.newObject(); + QScriptValue str = QScriptValue(&eng, "bar"); + QScriptValue num = QScriptValue(&eng, 123.0); + + object.setProperty("foo", num); + QCOMPARE(object.property("foo").strictlyEquals(num), true); + object.setProperty("bar", str); + QCOMPARE(object.property("bar").strictlyEquals(str), true); + object.setProperty("foo", QScriptValue()); + QCOMPARE(object.property("foo").isValid(), false); + QCOMPARE(object.property("bar").strictlyEquals(str), true); + object.setProperty("foo", num); + QCOMPARE(object.property("foo").strictlyEquals(num), true); + QCOMPARE(object.property("bar").strictlyEquals(str), true); + object.setProperty("bar", QScriptValue()); + QCOMPARE(object.property("bar").isValid(), false); + QCOMPARE(object.property("foo").strictlyEquals(num), true); + object.setProperty("foo", QScriptValue()); + object.setProperty("foo", QScriptValue()); + + eng.globalObject().setProperty("object3", object); + QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')") + .strictlyEquals(QScriptValue(&eng, false)), true); + object.setProperty("foo", num); + QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')") + .strictlyEquals(QScriptValue(&eng, true)), true); + eng.globalObject().setProperty("object3", QScriptValue()); + QCOMPARE(eng.evaluate("this.hasOwnProperty('object3')") + .strictlyEquals(QScriptValue(&eng, false)), true); +} +void tst_QScriptValue::getSetProperty_resolveMode() +{ // test ResolveMode - QScriptValue object2 = eng.newObject(); - object.setPrototype(object2); + QScriptEngine eng; + QScriptValue object = eng.newObject(); + QScriptValue prototype = eng.newObject(); + object.setPrototype(prototype); QScriptValue num2 = QScriptValue(&eng, 456.0); - object2.setProperty("propertyInPrototype", num2); + prototype.setProperty("propertyInPrototype", num2); // default is ResolvePrototype QCOMPARE(object.property("propertyInPrototype") .strictlyEquals(num2), true); @@ -1814,199 +1860,279 @@ void tst_QScriptValue::getSetProperty() .strictlyEquals(num2), false); QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveFull) .strictlyEquals(num2), true); +} - // test property removal (setProperty(QScriptValue())) - QScriptValue object3 = eng.newObject(); - object3.setProperty("foo", num); - QCOMPARE(object3.property("foo").strictlyEquals(num), true); - object3.setProperty("bar", str); - QCOMPARE(object3.property("bar").strictlyEquals(str), true); - object3.setProperty("foo", QScriptValue()); - QCOMPARE(object3.property("foo").isValid(), false); - QCOMPARE(object3.property("bar").strictlyEquals(str), true); - object3.setProperty("foo", num); - QCOMPARE(object3.property("foo").strictlyEquals(num), true); - QCOMPARE(object3.property("bar").strictlyEquals(str), true); - object3.setProperty("bar", QScriptValue()); - QCOMPARE(object3.property("bar").isValid(), false); - QCOMPARE(object3.property("foo").strictlyEquals(num), true); - object3.setProperty("foo", QScriptValue()); - object3.setProperty("foo", QScriptValue()); - - eng.globalObject().setProperty("object3", object3); - QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')") - .strictlyEquals(QScriptValue(&eng, false)), true); - object3.setProperty("foo", num); - QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')") - .strictlyEquals(QScriptValue(&eng, true)), true); - eng.globalObject().setProperty("object3", QScriptValue()); - QCOMPARE(eng.evaluate("this.hasOwnProperty('object3')") - .strictlyEquals(QScriptValue(&eng, false)), true); +void tst_QScriptValue::getSetProperty_twoEngines() +{ + QScriptEngine engine; + QScriptValue object = engine.newObject(); - // getters and setters - { - QScriptValue object4 = eng.newObject(); - for (int x = 0; x < 2; ++x) { - object4.setProperty("foo", QScriptValue()); - // getter() returns this.x - object4.setProperty("foo", eng.newFunction(getter), - QScriptValue::PropertyGetter | QScriptValue::UserRange); - QCOMPARE(object4.propertyFlags("foo") & ~QScriptValue::UserRange, - QScriptValue::PropertyGetter ); - - QEXPECT_FAIL("", "User-range flags are not retained for getter/setter properties", Continue); - QCOMPARE(object4.propertyFlags("foo"), - QScriptValue::PropertyGetter | QScriptValue::UserRange); - object4.setProperty("x", num); - QCOMPARE(object4.property("foo").strictlyEquals(num), true); - - // setter() sets this.x - object4.setProperty("foo", eng.newFunction(setter), - QScriptValue::PropertySetter); - QCOMPARE(object4.propertyFlags("foo") & ~QScriptValue::UserRange, - QScriptValue::PropertySetter | QScriptValue::PropertyGetter); - - QCOMPARE(object4.propertyFlags("foo"), - QScriptValue::PropertySetter | QScriptValue::PropertyGetter); - object4.setProperty("foo", str); - QCOMPARE(object4.property("x").strictlyEquals(str), true); - QCOMPARE(object4.property("foo").strictlyEquals(str), true); - - // kill the getter - object4.setProperty("foo", QScriptValue(), QScriptValue::PropertyGetter); - QVERIFY(!(object4.propertyFlags("foo") & QScriptValue::PropertyGetter)); - QVERIFY(object4.propertyFlags("foo") & QScriptValue::PropertySetter); - QCOMPARE(object4.property("foo").isUndefined(), true); - - // setter should still work - object4.setProperty("foo", num); - QCOMPARE(object4.property("x").strictlyEquals(num), true); - - // kill the setter too - object4.setProperty("foo", QScriptValue(), QScriptValue::PropertySetter); - QVERIFY(!(object4.propertyFlags("foo") & QScriptValue::PropertySetter)); - // now foo is just a regular property - object4.setProperty("foo", str); - QCOMPARE(object4.property("x").strictlyEquals(num), true); - QCOMPARE(object4.property("foo").strictlyEquals(str), true); - } + QScriptEngine otherEngine; + QScriptValue otherNum = QScriptValue(&otherEngine, 123); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty(oof) failed: cannot set value created in a different engine"); + object.setProperty("oof", otherNum); + QCOMPARE(object.property("oof").isValid(), false); +} - for (int x = 0; x < 2; ++x) { - object4.setProperty("foo", QScriptValue()); - // setter() sets this.x - object4.setProperty("foo", eng.newFunction(setter), QScriptValue::PropertySetter); - object4.setProperty("foo", str); - QCOMPARE(object4.property("x").strictlyEquals(str), true); - QCOMPARE(object4.property("foo").isUndefined(), true); - - // getter() returns this.x - object4.setProperty("foo", eng.newFunction(getter), QScriptValue::PropertyGetter); - object4.setProperty("x", num); - QCOMPARE(object4.property("foo").strictlyEquals(num), true); - - // kill the setter - object4.setProperty("foo", QScriptValue(), QScriptValue::PropertySetter); - QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty() failed: property 'foo' has a getter but no setter"); - object4.setProperty("foo", str); - - // getter should still work - QCOMPARE(object4.property("foo").strictlyEquals(num), true); - - // kill the getter too - object4.setProperty("foo", QScriptValue(), QScriptValue::PropertyGetter); - // now foo is just a regular property - object4.setProperty("foo", str); - QCOMPARE(object4.property("x").strictlyEquals(num), true); - QCOMPARE(object4.property("foo").strictlyEquals(str), true); - } - // use a single function as both getter and setter - object4.setProperty("foo", QScriptValue()); - object4.setProperty("foo", eng.newFunction(getterSetter), - QScriptValue::PropertyGetter | QScriptValue::PropertySetter); - QCOMPARE(object4.propertyFlags("foo"), - QScriptValue::PropertyGetter | QScriptValue::PropertySetter); - object4.setProperty("x", num); - QCOMPARE(object4.property("foo").strictlyEquals(num), true); - - // killing the getter will preserve the setter, even though they are the same function - object4.setProperty("foo", QScriptValue(), QScriptValue::PropertyGetter); - QVERIFY(object4.propertyFlags("foo") & QScriptValue::PropertySetter); - QCOMPARE(object4.property("foo").isUndefined(), true); - - // getter/setter that throws an error - { - QScriptValue object5 = eng.newObject(); - object5.setProperty("foo", eng.newFunction(getterSetterThrowingError), - QScriptValue::PropertyGetter | QScriptValue::PropertySetter); - QVERIFY(!eng.hasUncaughtException()); - QScriptValue ret = object5.property("foo"); - QVERIFY(ret.isError()); - QVERIFY(eng.hasUncaughtException()); - QVERIFY(ret.strictlyEquals(eng.uncaughtException())); - eng.evaluate("Object"); // clear exception state... - QVERIFY(!eng.hasUncaughtException()); - object5.setProperty("foo", str); - QVERIFY(eng.hasUncaughtException()); - QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo")); - } +void tst_QScriptValue::getSetProperty_gettersAndSetters() +{ + QScriptEngine eng; + QScriptValue str = QScriptValue(&eng, "bar"); + QScriptValue num = QScriptValue(&eng, 123.0); + QScriptValue object = eng.newObject(); + for (int x = 0; x < 2; ++x) { + object.setProperty("foo", QScriptValue()); + // getter() returns this.x + object.setProperty("foo", eng.newFunction(getter), + QScriptValue::PropertyGetter | QScriptValue::UserRange); + QCOMPARE(object.propertyFlags("foo") & ~QScriptValue::UserRange, + QScriptValue::PropertyGetter ); + + QEXPECT_FAIL("", "QTBUG-17615: User-range flags are not retained for getter/setter properties", Continue); + QCOMPARE(object.propertyFlags("foo"), + QScriptValue::PropertyGetter | QScriptValue::UserRange); + object.setProperty("x", num); + QCOMPARE(object.property("foo").strictlyEquals(num), true); + + // setter() sets this.x + object.setProperty("foo", eng.newFunction(setter), + QScriptValue::PropertySetter); + QCOMPARE(object.propertyFlags("foo") & ~QScriptValue::UserRange, + QScriptValue::PropertySetter | QScriptValue::PropertyGetter); + + QCOMPARE(object.propertyFlags("foo"), + QScriptValue::PropertySetter | QScriptValue::PropertyGetter); + object.setProperty("foo", str); + QCOMPARE(object.property("x").strictlyEquals(str), true); + QCOMPARE(object.property("foo").strictlyEquals(str), true); + + // kill the getter + object.setProperty("foo", QScriptValue(), QScriptValue::PropertyGetter); + QVERIFY(!(object.propertyFlags("foo") & QScriptValue::PropertyGetter)); + QVERIFY(object.propertyFlags("foo") & QScriptValue::PropertySetter); + QCOMPARE(object.property("foo").isUndefined(), true); + + // setter should still work + object.setProperty("foo", num); + QCOMPARE(object.property("x").strictlyEquals(num), true); + + // kill the setter too + object.setProperty("foo", QScriptValue(), QScriptValue::PropertySetter); + QVERIFY(!(object.propertyFlags("foo") & QScriptValue::PropertySetter)); + // now foo is just a regular property + object.setProperty("foo", str); + QCOMPARE(object.property("x").strictlyEquals(num), true); + QCOMPARE(object.property("foo").strictlyEquals(str), true); + } + + for (int x = 0; x < 2; ++x) { + object.setProperty("foo", QScriptValue()); + // setter() sets this.x + object.setProperty("foo", eng.newFunction(setter), QScriptValue::PropertySetter); + object.setProperty("foo", str); + QCOMPARE(object.property("x").strictlyEquals(str), true); + QCOMPARE(object.property("foo").isUndefined(), true); + + // getter() returns this.x + object.setProperty("foo", eng.newFunction(getter), QScriptValue::PropertyGetter); + object.setProperty("x", num); + QCOMPARE(object.property("foo").strictlyEquals(num), true); + + // kill the setter + object.setProperty("foo", QScriptValue(), QScriptValue::PropertySetter); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty() failed: property 'foo' has a getter but no setter"); + object.setProperty("foo", str); + + // getter should still work + QCOMPARE(object.property("foo").strictlyEquals(num), true); + + // kill the getter too + object.setProperty("foo", QScriptValue(), QScriptValue::PropertyGetter); + // now foo is just a regular property + object.setProperty("foo", str); + QCOMPARE(object.property("x").strictlyEquals(num), true); + QCOMPARE(object.property("foo").strictlyEquals(str), true); + } + + // use a single function as both getter and setter + object.setProperty("foo", QScriptValue()); + object.setProperty("foo", eng.newFunction(getterSetter), + QScriptValue::PropertyGetter | QScriptValue::PropertySetter); + QCOMPARE(object.propertyFlags("foo"), + QScriptValue::PropertyGetter | QScriptValue::PropertySetter); + object.setProperty("x", num); + QCOMPARE(object.property("foo").strictlyEquals(num), true); + + // killing the getter will preserve the setter, even though they are the same function + object.setProperty("foo", QScriptValue(), QScriptValue::PropertyGetter); + QVERIFY(object.propertyFlags("foo") & QScriptValue::PropertySetter); + QCOMPARE(object.property("foo").isUndefined(), true); +} - // attempt to install getter+setter on built-in (native) property - { - QScriptValue object6 = eng.newObject(); - QVERIFY(object6.property("__proto__").strictlyEquals(object6.prototype())); - - QScriptValue fun = eng.newFunction(getSet__proto__); - fun.setProperty("value", QScriptValue(&eng, "boo")); - QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty() failed: " - "cannot set getter or setter of native property " - "`__proto__'"); - object6.setProperty("__proto__", fun, - QScriptValue::PropertyGetter | QScriptValue::PropertySetter - | QScriptValue::UserRange); - QVERIFY(object6.property("__proto__").strictlyEquals(object6.prototype())); - - object6.setProperty("__proto__", QScriptValue(), - QScriptValue::PropertyGetter | QScriptValue::PropertySetter); - QVERIFY(object6.property("__proto__").strictlyEquals(object6.prototype())); - } +void tst_QScriptValue::getSetProperty_gettersAndSettersThrowErrorNative() +{ + // getter/setter that throws an error + QScriptEngine eng; + QScriptValue str = QScriptValue(&eng, "bar"); + QScriptValue object = eng.newObject(); - // global property that's a getter+setter - { - eng.globalObject().setProperty("globalGetterSetterProperty", eng.newFunction(getterSetter), - QScriptValue::PropertyGetter | QScriptValue::PropertySetter); - eng.evaluate("globalGetterSetterProperty = 123"); - { - QScriptValue ret = eng.evaluate("globalGetterSetterProperty"); - QVERIFY(ret.isNumber()); - QVERIFY(ret.strictlyEquals(QScriptValue(&eng, 123))); - } - QCOMPARE(eng.evaluate("typeof globalGetterSetterProperty").toString(), - QString::fromLatin1("number")); - { - QScriptValue ret = eng.evaluate("this.globalGetterSetterProperty()"); - QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'this.globalGetterSetterProperty' [123] is not a function.")); - } - { - QScriptValue ret = eng.evaluate("new this.globalGetterSetterProperty()"); - QVERIFY(ret.isError()); - QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'this.globalGetterSetterProperty' [123] is not a constructor.")); - } - } + object.setProperty("foo", eng.newFunction(getterSetterThrowingError), + QScriptValue::PropertyGetter | QScriptValue::PropertySetter); + QVERIFY(!eng.hasUncaughtException()); + QScriptValue ret = object.property("foo"); + QVERIFY(ret.isError()); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(ret.strictlyEquals(eng.uncaughtException())); + QCOMPARE(ret.toString(), QLatin1String("Error: get foo")); + eng.evaluate("Object"); // clear exception state... + QVERIFY(!eng.hasUncaughtException()); + object.setProperty("foo", str); + QVERIFY(eng.hasUncaughtException()); + QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo")); +} - // "upgrading" an existing property to become a getter+setter - { - QScriptValue object7 = eng.newObject(); - QScriptValue num(&eng, 123); - object7.setProperty("foo", num); - object7.setProperty("foo", eng.newFunction(getterSetter), - QScriptValue::PropertyGetter | QScriptValue::PropertySetter); - QVERIFY(!object7.property("x").isValid()); - object7.setProperty("foo", num); - QVERIFY(object7.property("x").equals(num)); - } +void tst_QScriptValue::getSetProperty_gettersAndSettersThrowErrorJS() +{ + // getter/setter that throws an error (from js function) + QScriptEngine eng; + QScriptValue str = QScriptValue(&eng, "bar"); + + eng.evaluate("o = new Object; " + "o.__defineGetter__('foo', function() { throw new Error('get foo') }); " + "o.__defineSetter__('foo', function() { throw new Error('set foo') }); "); + QScriptValue object = eng.evaluate("o"); + QVERIFY(!eng.hasUncaughtException()); + QScriptValue ret = object.property("foo"); + QEXPECT_FAIL("", "QTBUG-17616: Exception thrown from js function are not returned by the JSC port", Continue); + QVERIFY(ret.isError()); + QVERIFY(eng.hasUncaughtException()); + QEXPECT_FAIL("", "QTBUG-17616: Exception thrown from js function are not returned by the JSC port", Continue); + QVERIFY(ret.strictlyEquals(eng.uncaughtException())); + QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: get foo")); + eng.evaluate("Object"); // clear exception state... + QVERIFY(!eng.hasUncaughtException()); + object.setProperty("foo", str); + QVERIFY(eng.hasUncaughtException()); + QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo")); +} + +void tst_QScriptValue::getSetProperty_gettersAndSettersOnNative() +{ + // attempt to install getter+setter on built-in (native) property + QScriptEngine eng; + QScriptValue object = eng.newObject(); + QVERIFY(object.property("__proto__").strictlyEquals(object.prototype())); + + QScriptValue fun = eng.newFunction(getSet__proto__); + fun.setProperty("value", QScriptValue(&eng, "boo")); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty() failed: " + "cannot set getter or setter of native property " + "`__proto__'"); + object.setProperty("__proto__", fun, + QScriptValue::PropertyGetter | QScriptValue::PropertySetter + | QScriptValue::UserRange); + QVERIFY(object.property("__proto__").strictlyEquals(object.prototype())); + + object.setProperty("__proto__", QScriptValue(), + QScriptValue::PropertyGetter | QScriptValue::PropertySetter); + QVERIFY(object.property("__proto__").strictlyEquals(object.prototype())); +} + +void tst_QScriptValue::getSetProperty_gettersAndSettersOnGlobalObject() +{ + // global property that's a getter+setter + QScriptEngine eng; + eng.globalObject().setProperty("globalGetterSetterProperty", eng.newFunction(getterSetter), + QScriptValue::PropertyGetter | QScriptValue::PropertySetter); + eng.evaluate("globalGetterSetterProperty = 123"); + { + QScriptValue ret = eng.evaluate("globalGetterSetterProperty"); + QVERIFY(ret.isNumber()); + QVERIFY(ret.strictlyEquals(QScriptValue(&eng, 123))); } + QCOMPARE(eng.evaluate("typeof globalGetterSetterProperty").toString(), + QString::fromLatin1("number")); + { + QScriptValue ret = eng.evaluate("this.globalGetterSetterProperty()"); + QVERIFY(ret.isError()); + QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'this.globalGetterSetterProperty' [123] is not a function.")); + } + { + QScriptValue ret = eng.evaluate("new this.globalGetterSetterProperty()"); + QVERIFY(ret.isError()); + QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'this.globalGetterSetterProperty' [123] is not a constructor.")); + } +} + +void tst_QScriptValue::getSetProperty_gettersAndSettersChange() +{ + // "upgrading" an existing property to become a getter+setter + QScriptEngine eng; + QScriptValue object = eng.newObject(); + QScriptValue num(&eng, 123); + object.setProperty("foo", num); + object.setProperty("foo", eng.newFunction(getterSetter), + QScriptValue::PropertyGetter | QScriptValue::PropertySetter); + QVERIFY(!object.property("x").isValid()); + object.setProperty("foo", num); + QVERIFY(object.property("x").equals(num)); + + eng.globalObject().setProperty("object", object); + QScriptValue res = eng.evaluate("object.x = 89; var a = object.foo; object.foo = 65; a"); + QCOMPARE(res.toInt32(), 89); + QCOMPARE(object.property("x").toInt32(), 65); + QCOMPARE(object.property("foo").toInt32(), 65); +} + +void tst_QScriptValue::getSetProperty_array() +{ + QScriptEngine eng; + QScriptValue str = QScriptValue(&eng, "bar"); + QScriptValue num = QScriptValue(&eng, 123.0); + QScriptValue array = eng.newArray(); + + QVERIFY(array.isArray()); + array.setProperty(0, num); + QCOMPARE(array.property(0).toNumber(), num.toNumber()); + QCOMPARE(array.property("0").toNumber(), num.toNumber()); + QCOMPARE(array.property("length").toUInt32(), quint32(1)); + array.setProperty(1, str); + QCOMPARE(array.property(1).toString(), str.toString()); + QCOMPARE(array.property("1").toString(), str.toString()); + QCOMPARE(array.property("length").toUInt32(), quint32(2)); + array.setProperty("length", QScriptValue(&eng, 1)); + QCOMPARE(array.property("length").toUInt32(), quint32(1)); + QCOMPARE(array.property(1).isValid(), false); +} + +void tst_QScriptValue::getSetProperty() +{ + QScriptEngine eng; + + QScriptValue object = eng.newObject(); + + QScriptValue str = QScriptValue(&eng, "bar"); + object.setProperty("foo", str); + QCOMPARE(object.property("foo").toString(), str.toString()); + + QScriptValue num = QScriptValue(&eng, 123.0); + object.setProperty("baz", num); + QCOMPARE(object.property("baz").toNumber(), num.toNumber()); + + QScriptValue strstr = QScriptValue("bar"); + QCOMPARE(strstr.engine(), (QScriptEngine *)0); + object.setProperty("foo", strstr); + QCOMPARE(object.property("foo").toString(), strstr.toString()); + QCOMPARE(strstr.engine(), &eng); // the value has been bound to the engine + + QScriptValue numnum = QScriptValue(123.0); + object.setProperty("baz", numnum); + QCOMPARE(object.property("baz").toNumber(), numnum.toNumber()); + + QScriptValue inv; + inv.setProperty("foo", num); + QCOMPARE(inv.property("foo").isValid(), false); eng.globalObject().setProperty("object", object); @@ -2059,9 +2185,9 @@ void tst_QScriptValue::getSetProperty() } // should still be deletable from C++ object.setProperty("undeletableProperty", QScriptValue()); - QEXPECT_FAIL("", "With JSC-based back-end, undeletable properties can't be deleted from C++", Continue); + QEXPECT_FAIL("", "QTBUG-17617: With JSC-based back-end, undeletable properties can't be deleted from C++", Continue); QVERIFY(!object.property("undeletableProperty").isValid()); - QEXPECT_FAIL("", "With JSC-based back-end, undeletable properties can't be deleted from C++", Continue); + QEXPECT_FAIL("", "QTBUG-17617: With JSC-based back-end, undeletable properties can't be deleted from C++", Continue); QCOMPARE(object.propertyFlags("undeletableProperty"), 0); // SkipInEnumeration @@ -2155,50 +2281,123 @@ void tst_QScriptValue::arrayElementGetterSetter() QVERIFY(obj.propertyFlags("1") == 0); } -void tst_QScriptValue::getSetPrototype() +void tst_QScriptValue::getSetPrototype_cyclicPrototype() { QScriptEngine eng; - + QScriptValue prototype = eng.newObject(); QScriptValue object = eng.newObject(); + object.setPrototype(prototype); - QScriptValue object2 = eng.newObject(); - object2.setPrototype(object); + QScriptValue previousPrototype = prototype.prototype(); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value"); + prototype.setPrototype(prototype); + QCOMPARE(prototype.prototype().strictlyEquals(previousPrototype), true); + + object.setPrototype(prototype); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value"); + prototype.setPrototype(object); + QCOMPARE(prototype.prototype().strictlyEquals(previousPrototype), true); + +} - QCOMPARE(object2.prototype().strictlyEquals(object), true); +void tst_QScriptValue::getSetPrototype_evalCyclicPrototype() +{ + QScriptEngine eng; + QScriptValue ret = eng.evaluate("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o"); + QCOMPARE(eng.hasUncaughtException(), true); + QVERIFY(ret.strictlyEquals(eng.uncaughtException())); + QCOMPARE(ret.isError(), true); + QCOMPARE(ret.toString(), QLatin1String("Error: cyclic __proto__ value")); +} +void tst_QScriptValue::getSetPrototype_eval() +{ + QScriptEngine eng; + QScriptValue ret = eng.evaluate("p = { }; p.__proto__ = { }"); + QCOMPARE(eng.hasUncaughtException(), false); + QCOMPARE(ret.isError(), false); +} + +void tst_QScriptValue::getSetPrototype_invalidPrototype() +{ + QScriptEngine eng; QScriptValue inv; + QScriptValue object = eng.newObject(); + QScriptValue proto = object.prototype(); + QVERIFY(object.prototype().strictlyEquals(proto)); inv.setPrototype(object); QCOMPARE(inv.prototype().isValid(), false); + object.setPrototype(inv); + QVERIFY(object.prototype().strictlyEquals(proto)); +} +void tst_QScriptValue::getSetPrototype_twoEngines() +{ + QScriptEngine eng; + QScriptValue prototype = eng.newObject(); + QScriptValue object = eng.newObject(); + object.setPrototype(prototype); QScriptEngine otherEngine; - QScriptValue object3 = otherEngine.newObject(); + QScriptValue newPrototype = otherEngine.newObject(); QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cannot set a prototype created in a different engine"); - object2.setPrototype(object3); - QCOMPARE(object2.prototype().strictlyEquals(object), true); + object.setPrototype(newPrototype); + QCOMPARE(object.prototype().strictlyEquals(prototype), true); - // cyclic prototypes - QScriptValue old = object.prototype(); - QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value"); - object.setPrototype(object); - QCOMPARE(object.prototype().strictlyEquals(old), true); +} - object2.setPrototype(object); - QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value"); - object.setPrototype(object2); - QCOMPARE(object.prototype().strictlyEquals(old), true); +void tst_QScriptValue::getSetPrototype_null() +{ + QScriptEngine eng; + QScriptValue object = eng.newObject(); + object.setPrototype(QScriptValue(QScriptValue::NullValue)); + QVERIFY(object.prototype().isNull()); - { - QScriptValue ret = eng.evaluate("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o"); - QCOMPARE(eng.hasUncaughtException(), true); - QVERIFY(ret.strictlyEquals(eng.uncaughtException())); - QCOMPARE(ret.isError(), true); - QCOMPARE(ret.toString(), QLatin1String("Error: cyclic __proto__ value")); - } - { - QScriptValue ret = eng.evaluate("p.__proto__ = { }"); - QCOMPARE(eng.hasUncaughtException(), false); - QCOMPARE(ret.isError(), false); - } + QScriptValue newProto = eng.newObject(); + object.setPrototype(newProto); + QVERIFY(object.prototype().equals(newProto)); + + object.setPrototype(QScriptValue(&eng, QScriptValue::NullValue)); + QVERIFY(object.prototype().isNull()); +} + +void tst_QScriptValue::getSetPrototype_notObjectOrNull() +{ + QScriptEngine eng; + QScriptValue object = eng.newObject(); + QScriptValue originalProto = object.prototype(); + + // bool + object.setPrototype(true); + QVERIFY(object.prototype().equals(originalProto)); + object.setPrototype(QScriptValue(&eng, true)); + QVERIFY(object.prototype().equals(originalProto)); + + // number + object.setPrototype(123); + QVERIFY(object.prototype().equals(originalProto)); + object.setPrototype(QScriptValue(&eng, 123)); + QVERIFY(object.prototype().equals(originalProto)); + + // string + object.setPrototype("foo"); + QVERIFY(object.prototype().equals(originalProto)); + object.setPrototype(QScriptValue(&eng, "foo")); + QVERIFY(object.prototype().equals(originalProto)); + + // undefined + object.setPrototype(QScriptValue(QScriptValue::UndefinedValue)); + QVERIFY(object.prototype().equals(originalProto)); + object.setPrototype(QScriptValue(&eng, QScriptValue::UndefinedValue)); + QVERIFY(object.prototype().equals(originalProto)); +} + +void tst_QScriptValue::getSetPrototype() +{ + QScriptEngine eng; + QScriptValue prototype = eng.newObject(); + QScriptValue object = eng.newObject(); + object.setPrototype(prototype); + QCOMPARE(object.prototype().strictlyEquals(prototype), true); } void tst_QScriptValue::getSetScope() @@ -2235,10 +2434,24 @@ void tst_QScriptValue::getSetScope() QVERIFY(!object2.scope().isValid()); } -void tst_QScriptValue::getSetData() +void tst_QScriptValue::getSetData_objects_data() { - QScriptEngine eng; - QScriptValue object = eng.newObject(); + newEngine(); + + QTest::addColumn<QScriptValue>("object"); + + QTest::newRow("object from evaluate") << engine->evaluate("new Object()"); + QTest::newRow("object from engine") << engine->newObject(); + QTest::newRow("Array") << engine->newArray(); + QTest::newRow("Date") << engine->newDate(12324); + QTest::newRow("QObject") << engine->newQObject(this); + QTest::newRow("RegExp") << engine->newRegExp(QRegExp()); +} + +void tst_QScriptValue::getSetData_objects() +{ + QFETCH(QScriptValue, object); + QVERIFY(!object.data().isValid()); QScriptValue v1(true); object.setData(v1); @@ -2246,13 +2459,48 @@ void tst_QScriptValue::getSetData() QScriptValue v2(123); object.setData(v2); QVERIFY(object.data().strictlyEquals(v2)); - QScriptValue v3 = eng.newObject(); + QScriptValue v3 = engine->newObject(); object.setData(v3); QVERIFY(object.data().strictlyEquals(v3)); object.setData(QScriptValue()); QVERIFY(!object.data().isValid()); } +void tst_QScriptValue::getSetData_nonObjects_data() +{ + newEngine(); + + QTest::addColumn<QScriptValue>("value"); + + QTest::newRow("undefined (bound)") << engine->undefinedValue(); + QTest::newRow("null (bound)") << engine->nullValue(); + QTest::newRow("string (bound)") << QScriptValue(engine, "Pong"); + QTest::newRow("bool (bound)") << QScriptValue(engine, false); + + QTest::newRow("undefined") << QScriptValue(QScriptValue::UndefinedValue); + QTest::newRow("null") << QScriptValue(QScriptValue::NullValue); + QTest::newRow("string") << QScriptValue("Pong"); + QTest::newRow("bool") << QScriptValue(true); +} + +void tst_QScriptValue::getSetData_nonObjects() +{ + QFETCH(QScriptValue, value); + + QVERIFY(!value.data().isValid()); + QScriptValue v1(true); + value.setData(v1); + QVERIFY(!value.data().isValid()); + QScriptValue v2(123); + value.setData(v2); + QVERIFY(!value.data().isValid()); + QScriptValue v3 = engine->newObject(); + value.setData(v3); + QVERIFY(!value.data().isValid()); + value.setData(QScriptValue()); + QVERIFY(!value.data().isValid()); +} + void tst_QScriptValue::setData_QTBUG15144() { QScriptEngine eng; @@ -2266,30 +2514,59 @@ void tst_QScriptValue::setData_QTBUG15144() obj.setData("foodfight"); } } + class TestScriptClass : public QScriptClass { public: TestScriptClass(QScriptEngine *engine) : QScriptClass(engine) {} }; -void tst_QScriptValue::getSetScriptClass() +void tst_QScriptValue::getSetScriptClass_emptyClass_data() { - QScriptEngine eng; - QScriptValue inv; - QCOMPARE(inv.scriptClass(), (QScriptClass*)0); - QScriptValue num(123); - QCOMPARE(num.scriptClass(), (QScriptClass*)0); + newEngine(); + QTest::addColumn<QScriptValue>("value"); + + QTest::newRow("invalid") << QScriptValue(); + QTest::newRow("number") << QScriptValue(123); + QTest::newRow("string") << QScriptValue("pong"); + QTest::newRow("bool") << QScriptValue(false); + QTest::newRow("null") << QScriptValue(QScriptValue::NullValue); + QTest::newRow("undefined") << QScriptValue(QScriptValue::UndefinedValue); + + QTest::newRow("number") << QScriptValue(engine, 123); + QTest::newRow("string") << QScriptValue(engine, "pong"); + QTest::newRow("bool") << QScriptValue(engine, true); + QTest::newRow("null") << QScriptValue(engine->nullValue()); + QTest::newRow("undefined") << QScriptValue(engine->undefinedValue()); + QTest::newRow("object") << QScriptValue(engine->newObject()); + QTest::newRow("date") << QScriptValue(engine->evaluate("new Date()")); + QTest::newRow("qobject") << QScriptValue(engine->newQObject(this)); +} + +void tst_QScriptValue::getSetScriptClass_emptyClass() +{ + QFETCH(QScriptValue, value); + QCOMPARE(value.scriptClass(), (QScriptClass*)0); +} +void tst_QScriptValue::getSetScriptClass_JSObjectFromCpp() +{ + QScriptEngine eng; TestScriptClass testClass(&eng); // object created in C++ (newObject()) { QScriptValue obj = eng.newObject(); - QCOMPARE(obj.scriptClass(), (QScriptClass*)0); obj.setScriptClass(&testClass); QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass); obj.setScriptClass(0); QCOMPARE(obj.scriptClass(), (QScriptClass*)0); } +} + +void tst_QScriptValue::getSetScriptClass_JSObjectFromJS() +{ + QScriptEngine eng; + TestScriptClass testClass(&eng); // object created in JS { QScriptValue obj = eng.evaluate("new Object"); @@ -2304,6 +2581,12 @@ void tst_QScriptValue::getSetScriptClass() obj.setScriptClass(0); QCOMPARE(obj.scriptClass(), (QScriptClass*)0); } +} + +void tst_QScriptValue::getSetScriptClass_QVariant() +{ + QScriptEngine eng; + TestScriptClass testClass(&eng); // object that already has a(n internal) class { QScriptValue obj = eng.newVariant(QUrl("http://example.com")); @@ -2315,10 +2598,15 @@ void tst_QScriptValue::getSetScriptClass() QVERIFY(!obj.isVariant()); QCOMPARE(obj.toVariant(), QVariant(QVariantMap())); } +} + +void tst_QScriptValue::getSetScriptClass_QObject() +{ + QScriptEngine eng; + TestScriptClass testClass(&eng); { QScriptValue obj = eng.newQObject(this); QVERIFY(obj.isQObject()); - QCOMPARE(obj.scriptClass(), (QScriptClass*)0); obj.setScriptClass(&testClass); QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass); QVERIFY(obj.isObject()); @@ -2347,83 +2635,89 @@ static QScriptValue returnInvalidValue(QScriptContext *, QScriptEngine *) return QScriptValue(); } -void tst_QScriptValue::call() +void tst_QScriptValue::call_function() { QScriptEngine eng; + QScriptValue fun = eng.evaluate("(function() { return 1; })"); + QVERIFY(fun.isFunction()); + QScriptValue result = fun.call(); + QVERIFY(result.isNumber()); + QCOMPARE(result.toInt32(), 1); +} - { - QScriptValue fun = eng.evaluate("(function() { return 1; })"); - QVERIFY(fun.isFunction()); - QScriptValue result = fun.call(); - QVERIFY(result.isNumber()); - QCOMPARE(result.toInt32(), 1); - } - +void tst_QScriptValue::call_object() +{ + QScriptEngine eng; QScriptValue Object = eng.evaluate("Object"); QCOMPARE(Object.isFunction(), true); - { - QScriptValue result = Object.call(Object); - QCOMPARE(result.isObject(), true); - } + QScriptValue result = Object.call(Object); + QCOMPARE(result.isObject(), true); +} +void tst_QScriptValue::call_newObjects() +{ + QScriptEngine eng; // test that call() doesn't construct new objects QScriptValue Number = eng.evaluate("Number"); + QScriptValue Object = eng.evaluate("Object"); QCOMPARE(Object.isFunction(), true); - { - QScriptValueList args; - args << QScriptValue(&eng, 123); - QScriptValue result = Number.call(Object, args); - QCOMPARE(result.strictlyEquals(args.at(0)), true); - } + QScriptValueList args; + args << QScriptValue(&eng, 123); + QScriptValue result = Number.call(Object, args); + QCOMPARE(result.strictlyEquals(args.at(0)), true); +} +void tst_QScriptValue::call_this() +{ + QScriptEngine eng; // test that correct "this" object is used - { - QScriptValue fun = eng.evaluate("(function() { return this; })"); - QCOMPARE(fun.isFunction(), true); + QScriptValue fun = eng.evaluate("(function() { return this; })"); + QCOMPARE(fun.isFunction(), true); - { - QScriptValue numberObject = QScriptValue(&eng, 123.0).toObject(); - QScriptValue result = fun.call(numberObject); - QCOMPARE(result.isObject(), true); - QCOMPARE(result.toNumber(), 123.0); - } - } + QScriptValue numberObject = QScriptValue(&eng, 123.0).toObject(); + QScriptValue result = fun.call(numberObject); + QCOMPARE(result.isObject(), true); + QCOMPARE(result.toNumber(), 123.0); +} +void tst_QScriptValue::call_arguments() +{ + QScriptEngine eng; // test that correct arguments are passed - { - QScriptValue fun = eng.evaluate("(function() { return arguments[0]; })"); - QCOMPARE(fun.isFunction(), true); - - { - QScriptValue result = fun.call(eng.undefinedValue()); - QCOMPARE(result.isUndefined(), true); - } - - { - QScriptValueList args; - args << QScriptValue(&eng, 123.0); - QScriptValue result = fun.call(eng.undefinedValue(), args); - QCOMPARE(result.isNumber(), true); - QCOMPARE(result.toNumber(), 123.0); - } - // V2 constructors - { - QScriptValueList args; - args << QScriptValue(123.0); - QScriptValue result = fun.call(eng.undefinedValue(), args); - QCOMPARE(result.isNumber(), true); - QCOMPARE(result.toNumber(), 123.0); - } - { - QScriptValue args = eng.newArray(); - args.setProperty(0, 123); - QScriptValue result = fun.call(eng.undefinedValue(), args); - QVERIFY(result.isNumber()); - QCOMPARE(result.toNumber(), 123.0); - } + QScriptValue fun = eng.evaluate("(function() { return arguments[0]; })"); + QCOMPARE(fun.isFunction(), true); + { + QScriptValue result = fun.call(eng.undefinedValue()); + QCOMPARE(result.isUndefined(), true); } + { + QScriptValueList args; + args << QScriptValue(&eng, 123.0); + QScriptValue result = fun.call(eng.undefinedValue(), args); + QCOMPARE(result.isNumber(), true); + QCOMPARE(result.toNumber(), 123.0); + } + // V2 constructors + { + QScriptValueList args; + args << QScriptValue(123.0); + QScriptValue result = fun.call(eng.undefinedValue(), args); + QCOMPARE(result.isNumber(), true); + QCOMPARE(result.toNumber(), 123.0); + } + { + QScriptValue args = eng.newArray(); + args.setProperty(0, 123); + QScriptValue result = fun.call(eng.undefinedValue(), args); + QVERIFY(result.isNumber()); + QCOMPARE(result.toNumber(), 123.0); + } +} +void tst_QScriptValue::call() +{ + QScriptEngine eng; { QScriptValue fun = eng.evaluate("(function() { return arguments[1]; })"); QCOMPARE(fun.isFunction(), true); @@ -2444,7 +2738,6 @@ void tst_QScriptValue::call() QCOMPARE(result.toNumber(), 456.0); } } - { QScriptValue fun = eng.evaluate("(function() { throw new Error('foo'); })"); QCOMPARE(fun.isFunction(), true); @@ -2457,7 +2750,6 @@ void tst_QScriptValue::call() QVERIFY(result.strictlyEquals(eng.uncaughtException())); } } - { eng.clearExceptions(); QScriptValue fun = eng.newFunction(getArg); @@ -2485,7 +2777,6 @@ void tst_QScriptValue::call() QCOMPARE(result.toNumber(), 123.0); } } - { QScriptValue fun = eng.newFunction(evaluateArg); { @@ -2497,11 +2788,12 @@ void tst_QScriptValue::call() QCOMPARE(result.toNumber(), 123.0); } } +} - QScriptValue inv; - QCOMPARE(inv.call().isValid(), false); - +void tst_QScriptValue::call_invalidArguments() +{ // test that invalid arguments are handled gracefully + QScriptEngine eng; { QScriptValue fun = eng.newFunction(getArg); { @@ -2534,6 +2826,35 @@ void tst_QScriptValue::call() QCOMPARE(qIsNaN(ret.toNumber()), true); } } +} + +void tst_QScriptValue::call_invalidReturn() +{ + // test that invalid return value is handled gracefully + QScriptEngine eng; + QScriptValue fun = eng.newFunction(returnInvalidValue); + eng.globalObject().setProperty("returnInvalidValue", fun); + QScriptValue ret = eng.evaluate("returnInvalidValue() + returnInvalidValue()"); + QCOMPARE(ret.isValid(), true); + QCOMPARE(ret.isNumber(), true); + QCOMPARE(qIsNaN(ret.toNumber()), true); +} + +void tst_QScriptValue::call_twoEngines() +{ + QScriptEngine eng; + QScriptValue object = eng.evaluate("Object"); + QScriptEngine otherEngine; + QScriptValue fun = otherEngine.evaluate("(function() { return 1; })"); + QVERIFY(fun.isFunction()); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::call() failed: " + "cannot call function with thisObject created in " + "a different engine"); + QCOMPARE(fun.call(object).isValid(), false); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::call() failed: " + "cannot call function with argument created in " + "a different engine"); + QCOMPARE(fun.call(QScriptValue(), QScriptValueList() << QScriptValue(&eng, 123)).isValid(), false); { QScriptValue fun = eng.evaluate("Object"); QVERIFY(fun.isFunction()); @@ -2544,76 +2865,74 @@ void tst_QScriptValue::call() QTest::ignoreMessage(QtWarningMsg, "QScriptValue::call() failed: cannot call function with argument created in a different engine"); fun.call(QScriptValue(), args); } +} - // test that invalid return value is handled gracefully - { - QScriptValue fun = eng.newFunction(returnInvalidValue); - eng.globalObject().setProperty("returnInvalidValue", fun); - QScriptValue ret = eng.evaluate("returnInvalidValue() + returnInvalidValue()"); - QCOMPARE(ret.isValid(), true); - QCOMPARE(ret.isNumber(), true); - QCOMPARE(qIsNaN(ret.toNumber()), true); - } +void tst_QScriptValue::call_array() +{ + QScriptEngine eng; + QScriptValue fun = eng.evaluate("(function() { return arguments; })"); + QVERIFY(fun.isFunction()); + QScriptValue array = eng.newArray(3); + array.setProperty(0, QScriptValue(&eng, 123.0)); + array.setProperty(1, QScriptValue(&eng, 456.0)); + array.setProperty(2, QScriptValue(&eng, 789.0)); + // call with single array object as arguments + QScriptValue ret = fun.call(QScriptValue(), array); + QVERIFY(!eng.hasUncaughtException()); + QCOMPARE(ret.isError(), false); + QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true); + QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true); + QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true); + // call with arguments object as arguments + QScriptValue ret2 = fun.call(QScriptValue(), ret); + QCOMPARE(ret2.isError(), false); + QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true); + QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true); + QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true); + // call with null as arguments + QScriptValue ret3 = fun.call(QScriptValue(), eng.nullValue()); + QCOMPARE(ret3.isError(), false); + QCOMPARE(ret3.property("length").isNumber(), true); + QCOMPARE(ret3.property("length").toNumber(), 0.0); + // call with undefined as arguments + QScriptValue ret4 = fun.call(QScriptValue(), eng.undefinedValue()); + QCOMPARE(ret4.isError(), false); + QCOMPARE(ret4.property("length").isNumber(), true); + QCOMPARE(ret4.property("length").toNumber(), 0.0); + // call with something else as arguments + QScriptValue ret5 = fun.call(QScriptValue(), QScriptValue(&eng, 123.0)); + QCOMPARE(ret5.isError(), true); + // call with a non-array object as arguments + QScriptValue ret6 = fun.call(QScriptValue(), eng.globalObject()); + QVERIFY(ret6.isError()); + QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array")); +} - { - QScriptEngine otherEngine; - QScriptValue fun = otherEngine.evaluate("(function() { return 1; })"); - QVERIFY(fun.isFunction()); - QTest::ignoreMessage(QtWarningMsg, "QScriptValue::call() failed: " - "cannot call function with thisObject created in " - "a different engine"); - QCOMPARE(fun.call(Object).isValid(), false); - QTest::ignoreMessage(QtWarningMsg, "QScriptValue::call() failed: " - "cannot call function with argument created in " - "a different engine"); - QCOMPARE(fun.call(QScriptValue(), QScriptValueList() << QScriptValue(&eng, 123)).isValid(), false); - } - { - QScriptValue fun = eng.evaluate("(function() { return arguments; })"); - QVERIFY(fun.isFunction()); - QScriptValue array = eng.newArray(3); - array.setProperty(0, QScriptValue(&eng, 123.0)); - array.setProperty(1, QScriptValue(&eng, 456.0)); - array.setProperty(2, QScriptValue(&eng, 789.0)); - // call with single array object as arguments - QScriptValue ret = fun.call(QScriptValue(), array); - QVERIFY(!eng.hasUncaughtException()); - QCOMPARE(ret.isError(), false); - QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true); - QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true); - QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true); - // call with arguments object as arguments - QScriptValue ret2 = fun.call(QScriptValue(), ret); - QCOMPARE(ret2.isError(), false); - QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true); - QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true); - QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true); - // call with null as arguments - QScriptValue ret3 = fun.call(QScriptValue(), eng.nullValue()); - QCOMPARE(ret3.isError(), false); - QCOMPARE(ret3.property("length").isNumber(), true); - QCOMPARE(ret3.property("length").toNumber(), 0.0); - // call with undefined as arguments - QScriptValue ret4 = fun.call(QScriptValue(), eng.undefinedValue()); - QCOMPARE(ret4.isError(), false); - QCOMPARE(ret4.property("length").isNumber(), true); - QCOMPARE(ret4.property("length").toNumber(), 0.0); - // call with something else as arguments - QScriptValue ret5 = fun.call(QScriptValue(), QScriptValue(&eng, 123.0)); - QCOMPARE(ret5.isError(), true); - // call with a non-array object as arguments - QScriptValue ret6 = fun.call(QScriptValue(), eng.globalObject()); - QVERIFY(ret6.isError()); - QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array")); - } +void tst_QScriptValue::call_nonFunction_data() +{ + newEngine(); + QTest::addColumn<QScriptValue>("value"); + + QTest::newRow("invalid") << QScriptValue(); + QTest::newRow("bool") << QScriptValue(false); + QTest::newRow("int") << QScriptValue(123); + QTest::newRow("string") << QScriptValue(QString::fromLatin1("ciao")); + QTest::newRow("undefined") << QScriptValue(QScriptValue::UndefinedValue); + QTest::newRow("null") << QScriptValue(QScriptValue::NullValue); + + QTest::newRow("bool bound") << QScriptValue(engine, false); + QTest::newRow("int bound") << QScriptValue(engine, 123); + QTest::newRow("string bound") << QScriptValue(engine, QString::fromLatin1("ciao")); + QTest::newRow("undefined bound") << engine->undefinedValue(); + QTest::newRow("null bound") << engine->nullValue(); +} +void tst_QScriptValue::call_nonFunction() +{ // calling things that are not functions - QVERIFY(!QScriptValue(false).call().isValid()); - QVERIFY(!QScriptValue(123).call().isValid()); - QVERIFY(!QScriptValue(QString::fromLatin1("ciao")).call().isValid()); - QVERIFY(!QScriptValue(QScriptValue::UndefinedValue).call().isValid()); - QVERIFY(!QScriptValue(QScriptValue::NullValue).call().isValid()); + QFETCH(QScriptValue, value); + QVERIFY(!value.call().isValid()); } static QScriptValue ctorReturningUndefined(QScriptContext *ctx, QScriptEngine *) @@ -2629,127 +2948,169 @@ static QScriptValue ctorReturningNewObject(QScriptContext *, QScriptEngine *eng) return result; } -void tst_QScriptValue::construct() +void tst_QScriptValue::construct_nonFunction_data() +{ + newEngine(); + QTest::addColumn<QScriptValue>("value"); + + QTest::newRow("invalid") << QScriptValue(); + QTest::newRow("bool") << QScriptValue(false); + QTest::newRow("int") << QScriptValue(123); + QTest::newRow("string") << QScriptValue(QString::fromLatin1("ciao")); + QTest::newRow("undefined") << QScriptValue(QScriptValue::UndefinedValue); + QTest::newRow("null") << QScriptValue(QScriptValue::NullValue); + + QTest::newRow("bool bound") << QScriptValue(engine, false); + QTest::newRow("int bound") << QScriptValue(engine, 123); + QTest::newRow("string bound") << QScriptValue(engine, QString::fromLatin1("ciao")); + QTest::newRow("undefined bound") << engine->undefinedValue(); + QTest::newRow("null bound") << engine->nullValue(); +} + +void tst_QScriptValue::construct_nonFunction() +{ + QFETCH(QScriptValue, value); + QVERIFY(!value.construct().isValid()); +} + +void tst_QScriptValue::construct_simple() { QScriptEngine eng; + QScriptValue fun = eng.evaluate("(function () { this.foo = 123; })"); + QVERIFY(fun.isFunction()); + QScriptValue ret = fun.construct(); + QVERIFY(ret.isObject()); + QVERIFY(ret.instanceOf(fun)); + QCOMPARE(ret.property("foo").toInt32(), 123); +} - { - QScriptValue fun = eng.evaluate("(function () { this.foo = 123; })"); - QVERIFY(fun.isFunction()); - QScriptValue ret = fun.construct(); - QVERIFY(ret.isObject()); - QVERIFY(ret.instanceOf(fun)); - QCOMPARE(ret.property("foo").toInt32(), 123); - } +void tst_QScriptValue::construct_newObjectJS() +{ + QScriptEngine eng; // returning a different object overrides the default-constructed one - { - QScriptValue fun = eng.evaluate("(function () { return { bar: 456 }; })"); - QVERIFY(fun.isFunction()); - QScriptValue ret = fun.construct(); - QVERIFY(ret.isObject()); - QVERIFY(!ret.instanceOf(fun)); - QCOMPARE(ret.property("bar").toInt32(), 456); - } + QScriptValue fun = eng.evaluate("(function () { return { bar: 456 }; })"); + QVERIFY(fun.isFunction()); + QScriptValue ret = fun.construct(); + QVERIFY(ret.isObject()); + QVERIFY(!ret.instanceOf(fun)); + QCOMPARE(ret.property("bar").toInt32(), 456); +} - { - QScriptValue fun = eng.newFunction(ctorReturningUndefined); - QScriptValue ret = fun.construct(); - QVERIFY(ret.isObject()); - QVERIFY(ret.instanceOf(fun)); - QCOMPARE(ret.property("foo").toInt32(), 123); - } - { - QScriptValue fun = eng.newFunction(ctorReturningNewObject); - QScriptValue ret = fun.construct(); - QVERIFY(ret.isObject()); - QVERIFY(!ret.instanceOf(fun)); - QCOMPARE(ret.property("bar").toInt32(), 456); - } +void tst_QScriptValue::construct_undefined() +{ + QScriptEngine eng; + QScriptValue fun = eng.newFunction(ctorReturningUndefined); + QScriptValue ret = fun.construct(); + QVERIFY(ret.isObject()); + QVERIFY(ret.instanceOf(fun)); + QCOMPARE(ret.property("foo").toInt32(), 123); +} +void tst_QScriptValue::construct_newObjectCpp() +{ + QScriptEngine eng; + QScriptValue fun = eng.newFunction(ctorReturningNewObject); + QScriptValue ret = fun.construct(); + QVERIFY(ret.isObject()); + QVERIFY(!ret.instanceOf(fun)); + QCOMPARE(ret.property("bar").toInt32(), 456); +} + +void tst_QScriptValue::construct_arg() +{ + QScriptEngine eng; QScriptValue Number = eng.evaluate("Number"); QCOMPARE(Number.isFunction(), true); - { - QScriptValueList args; - args << QScriptValue(&eng, 123); - QScriptValue ret = Number.construct(args); - QCOMPARE(ret.isObject(), true); - QCOMPARE(ret.toNumber(), args.at(0).toNumber()); - } + QScriptValueList args; + args << QScriptValue(&eng, 123); + QScriptValue ret = Number.construct(args); + QCOMPARE(ret.isObject(), true); + QCOMPARE(ret.toNumber(), args.at(0).toNumber()); +} +void tst_QScriptValue::construct_proto() +{ + QScriptEngine eng; // test that internal prototype is set correctly - { - QScriptValue fun = eng.evaluate("(function() { return this.__proto__; })"); - QCOMPARE(fun.isFunction(), true); - QCOMPARE(fun.property("prototype").isObject(), true); - QScriptValue ret = fun.construct(); - QCOMPARE(fun.property("prototype").strictlyEquals(ret), true); - } + QScriptValue fun = eng.evaluate("(function() { return this.__proto__; })"); + QCOMPARE(fun.isFunction(), true); + QCOMPARE(fun.property("prototype").isObject(), true); + QScriptValue ret = fun.construct(); + QCOMPARE(fun.property("prototype").strictlyEquals(ret), true); +} +void tst_QScriptValue::construct_returnInt() +{ + QScriptEngine eng; // test that we return the new object even if a non-object value is returned from the function - { - QScriptValue fun = eng.evaluate("(function() { return 123; })"); - QCOMPARE(fun.isFunction(), true); - QScriptValue ret = fun.construct(); - QCOMPARE(ret.isObject(), true); - } + QScriptValue fun = eng.evaluate("(function() { return 123; })"); + QCOMPARE(fun.isFunction(), true); + QScriptValue ret = fun.construct(); + QCOMPARE(ret.isObject(), true); +} - { - QScriptValue fun = eng.evaluate("(function() { throw new Error('foo'); })"); - QCOMPARE(fun.isFunction(), true); - QScriptValue ret = fun.construct(); - QCOMPARE(ret.isError(), true); - QCOMPARE(eng.hasUncaughtException(), true); - QVERIFY(ret.strictlyEquals(eng.uncaughtException())); - } +void tst_QScriptValue::construct_throw() +{ + QScriptEngine eng; + QScriptValue fun = eng.evaluate("(function() { throw new Error('foo'); })"); + QCOMPARE(fun.isFunction(), true); + QScriptValue ret = fun.construct(); + QCOMPARE(ret.isError(), true); + QCOMPARE(eng.hasUncaughtException(), true); + QVERIFY(ret.strictlyEquals(eng.uncaughtException())); +} - QScriptValue inv; - QCOMPARE(inv.construct().isValid(), false); +void tst_QScriptValue::construct() +{ + QScriptEngine eng; + QScriptValue fun = eng.evaluate("(function() { return arguments; })"); + QVERIFY(fun.isFunction()); + QScriptValue array = eng.newArray(3); + array.setProperty(0, QScriptValue(&eng, 123.0)); + array.setProperty(1, QScriptValue(&eng, 456.0)); + array.setProperty(2, QScriptValue(&eng, 789.0)); + // construct with single array object as arguments + QScriptValue ret = fun.construct(array); + QVERIFY(!eng.hasUncaughtException()); + QVERIFY(ret.isValid()); + QVERIFY(ret.isObject()); + QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true); + QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true); + QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true); + // construct with arguments object as arguments + QScriptValue ret2 = fun.construct(ret); + QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true); + QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true); + QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true); + // construct with null as arguments + QScriptValue ret3 = fun.construct(eng.nullValue()); + QCOMPARE(ret3.isError(), false); + QCOMPARE(ret3.property("length").isNumber(), true); + QCOMPARE(ret3.property("length").toNumber(), 0.0); + // construct with undefined as arguments + QScriptValue ret4 = fun.construct(eng.undefinedValue()); + QCOMPARE(ret4.isError(), false); + QCOMPARE(ret4.property("length").isNumber(), true); + QCOMPARE(ret4.property("length").toNumber(), 0.0); + // construct with something else as arguments + QScriptValue ret5 = fun.construct(QScriptValue(&eng, 123.0)); + QCOMPARE(ret5.isError(), true); + // construct with a non-array object as arguments + QScriptValue ret6 = fun.construct(eng.globalObject()); + QVERIFY(ret6.isError()); + QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array")); +} - { - QScriptValue fun = eng.evaluate("(function() { return arguments; })"); - QVERIFY(fun.isFunction()); - QScriptValue array = eng.newArray(3); - array.setProperty(0, QScriptValue(&eng, 123.0)); - array.setProperty(1, QScriptValue(&eng, 456.0)); - array.setProperty(2, QScriptValue(&eng, 789.0)); - // construct with single array object as arguments - QScriptValue ret = fun.construct(array); - QVERIFY(!eng.hasUncaughtException()); - QVERIFY(ret.isValid()); - QVERIFY(ret.isObject()); - QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true); - QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true); - QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true); - // construct with arguments object as arguments - QScriptValue ret2 = fun.construct(ret); - QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true); - QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true); - QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true); - // construct with null as arguments - QScriptValue ret3 = fun.construct(eng.nullValue()); - QCOMPARE(ret3.isError(), false); - QCOMPARE(ret3.property("length").isNumber(), true); - QCOMPARE(ret3.property("length").toNumber(), 0.0); - // construct with undefined as arguments - QScriptValue ret4 = fun.construct(eng.undefinedValue()); - QCOMPARE(ret4.isError(), false); - QCOMPARE(ret4.property("length").isNumber(), true); - QCOMPARE(ret4.property("length").toNumber(), 0.0); - // construct with something else as arguments - QScriptValue ret5 = fun.construct(QScriptValue(&eng, 123.0)); - QCOMPARE(ret5.isError(), true); - // construct with a non-array object as arguments - QScriptValue ret6 = fun.construct(eng.globalObject()); - QVERIFY(ret6.isError()); - QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array")); - } - - // construct on things that are not functions - QVERIFY(!QScriptValue(false).construct().isValid()); - QVERIFY(!QScriptValue(123).construct().isValid()); - QVERIFY(!QScriptValue(QString::fromLatin1("ciao")).construct().isValid()); - QVERIFY(!QScriptValue(QScriptValue::UndefinedValue).construct().isValid()); - QVERIFY(!QScriptValue(QScriptValue::NullValue).construct().isValid()); +void tst_QScriptValue::construct_twoEngines() +{ + QScriptEngine engine; + QScriptEngine otherEngine; + QScriptValue ctor = engine.evaluate("(function (a, b) { this.foo = 123; })"); + QScriptValue arg(&otherEngine, 124567); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::construct() failed: cannot construct function with argument created in a different engine"); + QVERIFY(!ctor.construct(arg).isValid()); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::construct() failed: cannot construct function with argument created in a different engine"); + QVERIFY(!ctor.construct(QScriptValueList() << arg << otherEngine.newObject()).isValid()); } void tst_QScriptValue::construct_constructorThrowsPrimitive() @@ -2777,7 +3138,7 @@ void tst_QScriptValue::construct_constructorThrowsPrimitive() } } -void tst_QScriptValue::lessThan_old() +void tst_QScriptValue::lessThan() { QScriptEngine eng; @@ -2871,7 +3232,7 @@ void tst_QScriptValue::lessThan_old() QCOMPARE(date1.lessThan(QScriptValue(&otherEngine, 123)), false); } -void tst_QScriptValue::equals_old() +void tst_QScriptValue::equals() { QScriptEngine eng; @@ -3064,7 +3425,7 @@ void tst_QScriptValue::equals_old() QCOMPARE(date1.equals(QScriptValue(&otherEngine, 123)), false); } -void tst_QScriptValue::strictlyEquals_old() +void tst_QScriptValue::strictlyEquals() { QScriptEngine eng; @@ -3599,4 +3960,30 @@ void tst_QScriptValue::nestedObjectToVariant() QCOMPARE(o.toVariant(), expected); } +void tst_QScriptValue::propertyFlags_data() +{ + QTest::addColumn<QString>("program"); + QTest::addColumn<uint>("expected"); + + QTest::newRow("nothing") << "" << 0u; + QTest::newRow("getter") << "o.__defineGetter__('prop', function() { return 'blah' } );\n" << uint(QScriptValue::PropertyGetter); + QTest::newRow("setter") << "o.__defineSetter__('prop', function(a) { this.setted_prop2 = a; } );\n" << uint(QScriptValue::PropertySetter); + QTest::newRow("getterSetter") << "o.__defineGetter__('prop', function() { return 'ploup' } );\n" + "o.__defineSetter__('prop', function(a) { this.setted_prop3 = a; } );\n" << uint(QScriptValue::PropertySetter|QScriptValue::PropertyGetter); + QTest::newRow("nothing2") << "o.prop = 'nothing'" << 0u; +} + +void tst_QScriptValue::propertyFlags() +{ + QFETCH(QString, program); + QFETCH(uint, expected); + QScriptEngine eng; + eng.evaluate("o = new Object;"); + eng.evaluate(program); + QScriptValue o = eng.evaluate("o"); + + QCOMPARE(uint(o.propertyFlags("prop")), expected); +} + + QTEST_MAIN(tst_QScriptValue) diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.h b/tests/auto/qscriptvalue/tst_qscriptvalue.h index 39b156d..358f0d3 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue.h +++ b/tests/auto/qscriptvalue/tst_qscriptvalue.h @@ -49,8 +49,6 @@ #include <QtScript/qscriptvalue.h> #include <QtTest/QtTest> -#define DEFINE_TEST_VALUE(expr) m_values.insert(QString::fromLatin1(#expr), expr) - Q_DECLARE_METATYPE(QVariant) Q_DECLARE_METATYPE(QScriptValue) @@ -63,163 +61,115 @@ public: virtual ~tst_QScriptValue(); private slots: - // Generated test functions - void isArray_data(); - void isArray(); - - void isBool_data(); - void isBool(); + void toObject(); - void isBoolean_data(); - void isBoolean(); + void ctor_invalid(); + void ctor_undefinedWithEngine(); + void ctor_undefined(); + void ctor_nullWithEngine(); + void ctor_null(); + void ctor_boolWithEngine(); + void ctor_bool(); + void ctor_intWithEngine(); + void ctor_int(); + void ctor_uintWithEngine(); + void ctor_uint(); + void ctor_floatWithEngine(); + void ctor_float(); + void ctor_stringWithEngine(); + void ctor_string(); + void ctor_copyAndAssignWithEngine(); + void ctor_copyAndAssign(); + void ctor_nullEngine(); - void isDate_data(); + void toString(); + void toNumber(); + void toBoolean(); + void toBool(); + void toInteger(); + void toInt32(); + void toUInt32(); + void toUInt16(); + void toVariant(); + void toQObject_nonQObject_data(); + void toQObject_nonQObject(); + void toQObject(); + void toDateTime(); + void toRegExp(); + void instanceOf_twoEngines(); + void instanceOf(); + void isArray_data(); + void isArray(); void isDate(); - + void isDate_data(); + void isError_propertiesOfGlobalObject(); void isError_data(); void isError(); - - void isFunction_data(); - void isFunction(); - - void isNull_data(); - void isNull(); - - void isNumber_data(); - void isNumber(); - - void isObject_data(); - void isObject(); - - void isQMetaObject_data(); - void isQMetaObject(); - - void isQObject_data(); - void isQObject(); - void isRegExp_data(); void isRegExp(); - void isString_data(); - void isString(); - - void isUndefined_data(); - void isUndefined(); - - void isValid_data(); - void isValid(); - - void isVariant_data(); - void isVariant(); - - void toBool_data(); - void toBool(); - - void toBoolean_data(); - void toBoolean(); - -// void toDateTime_data(); -// void toDateTime(); - - void toInt32_data(); - void toInt32(); - - void toInteger_data(); - void toInteger(); - - void toNumber_data(); - void toNumber(); - -// void toQMetaObject_data(); -// void toQMetaObject(); - -// void toQObject_data(); -// void toQObject(); - -// void toRegExp_data(); -// void toRegExp(); - - void toString_data(); - void toString(); - - void toUInt16_data(); - void toUInt16(); - - void toUInt32_data(); - void toUInt32(); - -// void toVariant_data(); -// void toVariant(); - - void equals_data(); + void lessThan(); void equals(); - - void strictlyEquals_data(); void strictlyEquals(); - void lessThan_data(); - void lessThan(); - - void instanceOf_data(); - void instanceOf(); - - void assignAndCopyConstruct_data(); - void assignAndCopyConstruct(); - - void qscriptvalue_castQString_data(); - void qscriptvalue_castQString(); - - void qscriptvalue_castqsreal_data(); - void qscriptvalue_castqsreal(); - - void qscriptvalue_castbool_data(); - void qscriptvalue_castbool(); - - void qscriptvalue_castqint32_data(); - void qscriptvalue_castqint32(); - - void qscriptvalue_castquint32_data(); - void qscriptvalue_castquint32(); - - void qscriptvalue_castquint16_data(); - void qscriptvalue_castquint16(); - - // Non-generated test functions - - void toObject(); - void ctor(); - - void toString_old(); - void toNumber_old(); - void toBoolean_old(); - void toBool_old(); - void toInteger_old(); - void toInt32_old(); - void toUInt32_old(); - void toUInt16_old(); - void toVariant_old(); - void toQObject_old(); - void toDateTime_old(); - void toRegExp_old(); - void instanceOf_old(); - void isArray_old(); - void isDate_old(); - void isError_old(); - void isRegExp_old(); - - void lessThan_old(); - void equals_old(); - void strictlyEquals_old(); - + void getSetPrototype_cyclicPrototype(); + void getSetPrototype_evalCyclicPrototype(); + void getSetPrototype_eval(); + void getSetPrototype_invalidPrototype(); + void getSetPrototype_twoEngines(); + void getSetPrototype_null(); + void getSetPrototype_notObjectOrNull(); void getSetPrototype(); void getSetScope(); + void getSetProperty_HooliganTask162051(); + void getSetProperty_HooliganTask183072(); + void getSetProperty_propertyRemoval(); + void getSetProperty_resolveMode(); + void getSetProperty_twoEngines(); + void getSetProperty_gettersAndSetters(); + void getSetProperty_gettersAndSettersThrowErrorNative(); + void getSetProperty_gettersAndSettersThrowErrorJS(); + void getSetProperty_gettersAndSettersOnNative(); + void getSetProperty_gettersAndSettersOnGlobalObject(); + void getSetProperty_gettersAndSettersChange(); + void getSetProperty_array(); void getSetProperty(); void arrayElementGetterSetter(); - void getSetData(); + void getSetData_objects_data(); + void getSetData_objects(); + void getSetData_nonObjects_data(); + void getSetData_nonObjects(); void setData_QTBUG15144(); - void getSetScriptClass(); + void getSetScriptClass_emptyClass_data(); + void getSetScriptClass_emptyClass(); + void getSetScriptClass_JSObjectFromCpp(); + void getSetScriptClass_JSObjectFromJS(); + void getSetScriptClass_QVariant(); + void getSetScriptClass_QObject(); + void call_function(); + void call_object(); + void call_newObjects(); + void call_this(); + void call_arguments(); void call(); + void call_invalidArguments(); + void call_invalidReturn(); + void call_twoEngines(); + void call_array(); + void call_nonFunction_data(); + void call_nonFunction(); + void construct_nonFunction_data(); + void construct_nonFunction(); + void construct_simple(); + void construct_newObjectJS(); + void construct_undefined(); + void construct_newObjectCpp(); + void construct_arg(); + void construct_proto(); + void construct_returnInt(); + void construct_throw(); void construct(); + void construct_twoEngines(); void construct_constructorThrowsPrimitive(); void castToPointer(); void prettyPrinter_data(); @@ -229,188 +179,18 @@ private slots: void objectId(); void nestedObjectToVariant_data(); void nestedObjectToVariant(); + void propertyFlags_data(); + void propertyFlags(); -private: - typedef void (tst_QScriptValue::*InitDataFunction)(); - typedef void (tst_QScriptValue::*DefineDataFunction)(const char *); - void dataHelper(InitDataFunction init, DefineDataFunction define); - QTestData &newRow(const char *tag); - - typedef void (tst_QScriptValue::*TestFunction)(const char *, const QScriptValue &); - void testHelper(TestFunction fun); - - // Generated functions - - void initScriptValues(); - - void isArray_initData(); - void isArray_makeData(const char *expr); - void isArray_test(const char *expr, const QScriptValue &value); - - void isBool_initData(); - void isBool_makeData(const char *expr); - void isBool_test(const char *expr, const QScriptValue &value); - - void isBoolean_initData(); - void isBoolean_makeData(const char *expr); - void isBoolean_test(const char *expr, const QScriptValue &value); - - void isDate_initData(); - void isDate_makeData(const char *expr); - void isDate_test(const char *expr, const QScriptValue &value); - - void isError_initData(); - void isError_makeData(const char *expr); - void isError_test(const char *expr, const QScriptValue &value); - - void isFunction_initData(); - void isFunction_makeData(const char *expr); - void isFunction_test(const char *expr, const QScriptValue &value); - - void isNull_initData(); - void isNull_makeData(const char *expr); - void isNull_test(const char *expr, const QScriptValue &value); - - void isNumber_initData(); - void isNumber_makeData(const char *expr); - void isNumber_test(const char *expr, const QScriptValue &value); - - void isObject_initData(); - void isObject_makeData(const char *expr); - void isObject_test(const char *expr, const QScriptValue &value); - - void isQMetaObject_initData(); - void isQMetaObject_makeData(const char *expr); - void isQMetaObject_test(const char *expr, const QScriptValue &value); - - void isQObject_initData(); - void isQObject_makeData(const char *expr); - void isQObject_test(const char *expr, const QScriptValue &value); - - void isRegExp_initData(); - void isRegExp_makeData(const char *expr); - void isRegExp_test(const char *expr, const QScriptValue &value); - - void isString_initData(); - void isString_makeData(const char *expr); - void isString_test(const char *expr, const QScriptValue &value); - - void isUndefined_initData(); - void isUndefined_makeData(const char *expr); - void isUndefined_test(const char *expr, const QScriptValue &value); - - void isValid_initData(); - void isValid_makeData(const char *expr); - void isValid_test(const char *expr, const QScriptValue &value); - - void isVariant_initData(); - void isVariant_makeData(const char *expr); - void isVariant_test(const char *expr, const QScriptValue &value); - - void toBool_initData(); - void toBool_makeData(const char *); - void toBool_test(const char *, const QScriptValue &value); - - void toBoolean_initData(); - void toBoolean_makeData(const char *); - void toBoolean_test(const char *, const QScriptValue &value); - - void toDateTime_initData(); - void toDateTime_makeData(const char *); - void toDateTime_test(const char *, const QScriptValue &value); - - void toInt32_initData(); - void toInt32_makeData(const char *); - void toInt32_test(const char *, const QScriptValue &value); - - void toInteger_initData(); - void toInteger_makeData(const char *); - void toInteger_test(const char *, const QScriptValue &value); - - void toNumber_initData(); - void toNumber_makeData(const char *); - void toNumber_test(const char *, const QScriptValue &value); - - void toQMetaObject_initData(); - void toQMetaObject_makeData(const char *); - void toQMetaObject_test(const char *, const QScriptValue &value); - - void toQObject_initData(); - void toQObject_makeData(const char *); - void toQObject_test(const char *, const QScriptValue &value); - - void toRegExp_initData(); - void toRegExp_makeData(const char *); - void toRegExp_test(const char *, const QScriptValue &value); - - void toString_initData(); - void toString_makeData(const char *); - void toString_test(const char *, const QScriptValue &value); - - void toUInt16_initData(); - void toUInt16_makeData(const char *); - void toUInt16_test(const char *, const QScriptValue &value); - - void toUInt32_initData(); - void toUInt32_makeData(const char *); - void toUInt32_test(const char *, const QScriptValue &value); - - void toVariant_initData(); - void toVariant_makeData(const char *); - void toVariant_test(const char *, const QScriptValue &value); - - void equals_initData(); - void equals_makeData(const char *); - void equals_test(const char *, const QScriptValue &value); - - void strictlyEquals_initData(); - void strictlyEquals_makeData(const char *); - void strictlyEquals_test(const char *, const QScriptValue &value); - - void lessThan_initData(); - void lessThan_makeData(const char *); - void lessThan_test(const char *, const QScriptValue &value); - - void instanceOf_initData(); - void instanceOf_makeData(const char *); - void instanceOf_test(const char *, const QScriptValue &value); - - void assignAndCopyConstruct_initData(); - void assignAndCopyConstruct_makeData(const char *); - void assignAndCopyConstruct_test(const char *, const QScriptValue &value); - - void qscriptvalue_castQString_initData(); - void qscriptvalue_castQString_makeData(const char *); - void qscriptvalue_castQString_test(const char *, const QScriptValue &value); - - void qscriptvalue_castqsreal_initData(); - void qscriptvalue_castqsreal_makeData(const char *); - void qscriptvalue_castqsreal_test(const char *, const QScriptValue &value); - - void qscriptvalue_castbool_initData(); - void qscriptvalue_castbool_makeData(const char *); - void qscriptvalue_castbool_test(const char *, const QScriptValue &value); - - void qscriptvalue_castqint32_initData(); - void qscriptvalue_castqint32_makeData(const char *); - void qscriptvalue_castqint32_test(const char *, const QScriptValue &value); - - void qscriptvalue_castquint32_initData(); - void qscriptvalue_castquint32_makeData(const char *); - void qscriptvalue_castquint32_test(const char *, const QScriptValue &value); - - void qscriptvalue_castquint16_initData(); - void qscriptvalue_castquint16_makeData(const char *); - void qscriptvalue_castquint16_test(const char *, const QScriptValue &value); private: + void newEngine() + { + if (engine) + delete engine; + engine = new QScriptEngine(); + } QScriptEngine *engine; - QHash<QString, QScriptValue> m_values; - QString m_currentExpression; }; -#define DEFINE_TEST_FUNCTION(name) \ -void tst_QScriptValue::name##_data() { dataHelper(&tst_QScriptValue::name##_initData, &tst_QScriptValue::name##_makeData); } \ -void tst_QScriptValue::name() { testHelper(&tst_QScriptValue::name##_test); } - #endif diff --git a/tests/auto/qscriptvaluegenerated/.gitignore b/tests/auto/qscriptvaluegenerated/.gitignore new file mode 100644 index 0000000..f724cb9 --- /dev/null +++ b/tests/auto/qscriptvaluegenerated/.gitignore @@ -0,0 +1 @@ +tst_qscriptvalue diff --git a/tests/auto/qscriptvaluegenerated/qscriptvaluegenerated.pro b/tests/auto/qscriptvaluegenerated/qscriptvaluegenerated.pro new file mode 100644 index 0000000..c3e9912 --- /dev/null +++ b/tests/auto/qscriptvaluegenerated/qscriptvaluegenerated.pro @@ -0,0 +1,18 @@ +load(qttest_p4) +QT = core gui script +SOURCES += tst_qscriptvalue.cpp +HEADERS += tst_qscriptvalue.h + +# Generated by testgen +SOURCES += \ + tst_qscriptvalue_generated_init.cpp \ + tst_qscriptvalue_generated_cast.cpp \ + tst_qscriptvalue_generated_comparison.cpp \ + tst_qscriptvalue_generated_isXXX.cpp \ + tst_qscriptvalue_generated_toXXX.cpp + +win32-msvc* { + # With -O2, MSVC takes up to 24 minutes to compile this test! + QMAKE_CXXFLAGS_RELEASE -= -O1 -O2 + QMAKE_CXXFLAGS_RELEASE += -Od +} diff --git a/tests/auto/qscriptvalue/testgen/data.txt b/tests/auto/qscriptvaluegenerated/testgen/data.txt index 73677ec..2cc1229 100644 --- a/tests/auto/qscriptvalue/testgen/data.txt +++ b/tests/auto/qscriptvaluegenerated/testgen/data.txt @@ -116,6 +116,11 @@ engine->evaluate("/foo/") engine->evaluate("new Object()") engine->evaluate("new Array()") engine->evaluate("new Error()") +engine->evaluate("new Boolean(true)") +engine->evaluate("new Boolean(false)") +engine->evaluate("new Number(123)") +engine->evaluate("new RegExp('foo', 'gim')") +engine->evaluate("new String('ciao')") engine->evaluate("a = new Object(); a.foo = 22; a.foo") engine->evaluate("Undefined") engine->evaluate("Null") @@ -154,8 +159,9 @@ engine->newArray() engine->newArray(10) engine->newDate(QDateTime()) engine->newQMetaObject(&QObject::staticMetaObject) +engine->newRegExp("foo", "gim") engine->newVariant(QVariant()) engine->newVariant(QVariant(123)) engine->newVariant(QVariant(false)) engine->newQObject(0) -engine->newQObject(engine)
\ No newline at end of file +engine->newQObject(engine) diff --git a/tests/auto/qscriptvalue/testgen/gen.py b/tests/auto/qscriptvaluegenerated/testgen/gen.py index 594d65c..594d65c 100755 --- a/tests/auto/qscriptvalue/testgen/gen.py +++ b/tests/auto/qscriptvaluegenerated/testgen/gen.py diff --git a/tests/auto/qscriptvalue/testgen/main.cpp b/tests/auto/qscriptvaluegenerated/testgen/main.cpp index 427e584..427e584 100644 --- a/tests/auto/qscriptvalue/testgen/main.cpp +++ b/tests/auto/qscriptvaluegenerated/testgen/main.cpp diff --git a/tests/auto/qscriptvalue/testgen/testgen.pro b/tests/auto/qscriptvaluegenerated/testgen/testgen.pro index 47709a8..47709a8 100644 --- a/tests/auto/qscriptvalue/testgen/testgen.pro +++ b/tests/auto/qscriptvaluegenerated/testgen/testgen.pro diff --git a/tests/auto/qscriptvalue/testgen/testgenerator.cpp b/tests/auto/qscriptvaluegenerated/testgen/testgenerator.cpp index 89d6ed2..2aec22f 100644 --- a/tests/auto/qscriptvalue/testgen/testgenerator.cpp +++ b/tests/auto/qscriptvaluegenerated/testgen/testgenerator.cpp @@ -156,14 +156,14 @@ static QString generateLicence() static QString generateIsXXXDef(const QString& name, const QList<QString>& list) { - static const QString templ("void tst_QScriptValue::%1_initData()\n"\ + static const QString templ("void tst_QScriptValueGenerated::%1_initData()\n"\ "{\n"\ " QTest::addColumn<bool>(\"expected\");\n"\ " initScriptValues();\n"\ "}\n"\ "\n"\ - "static QString %1_array [] = {%2};\n\n"\ - "void tst_QScriptValue::%1_makeData(const char* expr)\n"\ + "static QString %1_array[] = {%2};\n\n"\ + "void tst_QScriptValueGenerated::%1_makeData(const char* expr)\n"\ "{\n"\ " static QSet<QString> %1;\n"\ " if (%1.isEmpty()) {\n"\ @@ -174,7 +174,7 @@ static QString generateIsXXXDef(const QString& name, const QList<QString>& list) " newRow(expr) << %1.contains(expr);\n"\ "}\n"\ "\n"\ - "void tst_QScriptValue::%1_test(const char*, const QScriptValue& value)\n"\ + "void tst_QScriptValueGenerated::%1_test(const char*, const QScriptValue& value)\n"\ "{\n"\ " QFETCH(bool, expected);\n"\ " QCOMPARE(value.%1(), expected);\n"\ @@ -193,10 +193,13 @@ static QString generateIsXXXDef(const QString& name, const QList<QString>& list) QStringList set; set.reserve(3 * list.count()); foreach(const QString& t, list) { + if (!set.isEmpty()) + set.append("\","); set.append("\n \""); set.append(escape(t)); - set.append("\","); } + if (!list.isEmpty()) + set.append("\"\n"); return result.arg(name, set.join(QString()), QString::number(list.count())); } @@ -205,15 +208,15 @@ template<typename T> static QString generateToXXXDef(const QString& name, const QList<QPair<QString, T> >& list) { static const QString templ = "\n"\ - "void tst_QScriptValue::%1_initData()\n"\ + "void tst_QScriptValueGenerated::%1_initData()\n"\ "{\n"\ " QTest::addColumn<%2>(\"expected\");\n"\ " initScriptValues();\n"\ "}\n"\ "\n"\ - "static QString %1_tagArray [] = {%4};\n\n"\ - "static %2 %1_valueArray [] = {%5};\n\n"\ - "void tst_QScriptValue::%1_makeData(const char* expr)\n"\ + "static QString %1_tagArray[] = {%4};\n\n"\ + "static %2 %1_valueArray[] = {%5};\n\n"\ + "void tst_QScriptValueGenerated::%1_makeData(const char* expr)\n"\ "{\n"\ " static QHash<QString, %2> %1;\n"\ " if (%1.isEmpty()) {\n"\ @@ -224,7 +227,7 @@ static QString generateToXXXDef(const QString& name, const QList<QPair<QString, " newRow(expr) << %1.value(expr);\n"\ "}\n"\ "\n"\ - "void tst_QScriptValue::%1_test(const char*, const QScriptValue& value)\n"\ + "void tst_QScriptValueGenerated::%1_test(const char*, const QScriptValue& value)\n"\ "{\n"\ " QFETCH(%2, expected);\n"\ " QCOMPARE(value.%1(), expected);\n"\ @@ -236,19 +239,23 @@ static QString generateToXXXDef(const QString& name, const QList<QPair<QString, typename QList<QPair<QString, T> >::const_iterator i = list.constBegin(); QStringList tagSet, valueSet; - tagSet.reserve(list.count()); - valueSet.reserve(list.count()); - int tmp = -1; - for(; i != list.constEnd(); ++i) { + tagSet.reserve(4 * list.count()); + valueSet.reserve(3 * list.count()); + for(int lineBreaker = 0; i != list.constEnd(); ++i) { QPair<QString, T> t = *i; t.first = escape(t.first); + if (!valueSet.isEmpty()) { + valueSet.append(QString(",")); + tagSet.append(QString::fromAscii(",")); + } tagSet.append(QString("\n \"")); tagSet.append(t.first); - tagSet.append(QString::fromAscii("\",")); - if (!((++tmp)%2)) + tagSet.append(QString::fromAscii("\"")); + if (!((lineBreaker++)%2)) valueSet.append(QString("\n ")); + else + valueSet.append(QString::fromAscii(" ")); valueSet.append(prepareToInsert<T>(t.second)); - valueSet.append(QString::fromAscii(", ")); } return result.arg(name, typeName<T>(), @@ -262,15 +269,15 @@ template<> QString generateToXXXDef<qsreal>(const QString& name, const QList<QPair<QString, qsreal> >& list) { static const QString templ = "\n"\ - "void tst_QScriptValue::%1_initData()\n"\ + "void tst_QScriptValueGenerated::%1_initData()\n"\ "{\n"\ " QTest::addColumn<%2>(\"expected\");\n"\ " initScriptValues();\n"\ "}\n"\ "\n"\ - "static QString %1_tagArray [] = {%3};\n"\ - "static %2 %1_valueArray [] = {%4};\n"\ - "void tst_QScriptValue::%1_makeData(const char* expr)\n"\ + "static QString %1_tagArray[] = {%3};\n"\ + "static %2 %1_valueArray[] = {%4};\n"\ + "void tst_QScriptValueGenerated::%1_makeData(const char* expr)\n"\ "{\n"\ " static QHash<QString, %2> %1;\n"\ " if (%1.isEmpty()) {\n"\ @@ -281,7 +288,7 @@ QString generateToXXXDef<qsreal>(const QString& name, const QList<QPair<QString, " newRow(expr) << %1.value(expr);\n"\ "}\n"\ "\n"\ - "void tst_QScriptValue::%1_test(const char*, const QScriptValue& value)\n"\ + "void tst_QScriptValueGenerated::%1_test(const char*, const QScriptValue& value)\n"\ "{\n"\ " QFETCH(%2, expected);\n"\ "%666" @@ -299,20 +306,25 @@ QString generateToXXXDef<qsreal>(const QString& name, const QList<QPair<QString, QList<QPair<QString, qsreal> >::const_iterator i = list.constBegin(); QStringList tagSet, valueSet; - tagSet.reserve(list.count()); - valueSet.reserve(list.count()); - int tmp = -1; - for(; i != list.constEnd(); ++i) { + tagSet.reserve(4 * list.count()); + valueSet.reserve(3 * list.count()); + for(int lineBreaker = 0; i != list.constEnd(); ++i) { QPair<QString, qsreal> t = *i; t.first = escape(t.first); + if (!valueSet.isEmpty()) { + valueSet.append(QString(",")); + tagSet.append(QString::fromAscii(",")); + } tagSet.append(QString("\n \"")); tagSet.append(t.first); - tagSet.append(QString::fromAscii("\",")); - if (!((++tmp)%10)) + tagSet.append(QString::fromAscii("\"")); + if (!((lineBreaker++)%10)) valueSet.append(QString("\n ")); + else + valueSet.append(QString::fromAscii(" ")); valueSet.append(prepareToInsert<qsreal>(t.second)); - valueSet.append(QString::fromAscii(", ")); } + // toInteger shouldn't return NaN, so it would be nice to catch the case. QString hook; if (name == "toNumber") { @@ -334,15 +346,15 @@ template<typename T> static QString generateCastDef(const QList<QPair<QString, T> >& list) { static const QString templ = "\n"\ - "void tst_QScriptValue::qscriptvalue_cast%1_initData()\n"\ + "void tst_QScriptValueGenerated::qscriptvalue_cast%1_initData()\n"\ "{\n"\ " QTest::addColumn<%1>(\"expected\");\n"\ " initScriptValues();\n"\ "}\n"\ "\n"\ - "static QString qscriptvalue_cast%1_tagArray [] = {%2};\n"\ - "static %1 qscriptvalue_cast%1_valueArray [] = {%3};\n"\ - "void tst_QScriptValue::qscriptvalue_cast%1_makeData(const char* expr)\n"\ + "static QString qscriptvalue_cast%1_tagArray[] = {%2};\n"\ + "static %1 qscriptvalue_cast%1_valueArray[] = {%3};\n"\ + "void tst_QScriptValueGenerated::qscriptvalue_cast%1_makeData(const char* expr)\n"\ "{\n"\ " static QHash<QString, %1> value;\n"\ " if (value.isEmpty()) {\n"\ @@ -353,7 +365,7 @@ static QString generateCastDef(const QList<QPair<QString, T> >& list) " newRow(expr) << value.value(expr);\n"\ "}\n"\ "\n"\ - "void tst_QScriptValue::qscriptvalue_cast%1_test(const char*, const QScriptValue& value)\n"\ + "void tst_QScriptValueGenerated::qscriptvalue_cast%1_test(const char*, const QScriptValue& value)\n"\ "{\n"\ " QFETCH(%1, expected);\n"\ " QCOMPARE(qscriptvalue_cast<%1>(value), expected);\n"\ @@ -365,19 +377,23 @@ static QString generateCastDef(const QList<QPair<QString, T> >& list) typename QList<QPair<QString, T> >::const_iterator i = list.constBegin(); QStringList tagSet, valueSet; - tagSet.reserve(list.count()); - valueSet.reserve(list.count()); - int tmp = -1; - for(; i != list.constEnd(); ++i) { + tagSet.reserve(4 * list.count()); + valueSet.reserve(3 * list.count()); + for(int lineBreaker = 0; i != list.constEnd(); ++i) { QPair<QString, T> t = *i; t.first = escape(t.first); + if (!valueSet.isEmpty()) { + valueSet.append(QString(",")); + tagSet.append(QString::fromAscii(",")); + } tagSet.append(QString("\n \"")); tagSet.append(t.first); - tagSet.append(QString::fromAscii("\",")); - if (!((++tmp)%2)) + tagSet.append(QString::fromAscii("\"")); + if (!((lineBreaker++)%2)) valueSet.append(QString("\n ")); + else + valueSet.append(QString::fromAscii(" ")); valueSet.append(prepareToInsert<T>(t.second)); - valueSet.append(QString::fromAscii(", ")); } return result.arg(typeName<T>(), tagSet.join(QString()), valueSet.join(QString()), QString::number(list.count())); } @@ -386,15 +402,15 @@ template<> QString generateCastDef<qsreal>(const QList<QPair<QString, qsreal> >& list) { static const QString templ = "\n"\ - "void tst_QScriptValue::qscriptvalue_cast%1_initData()\n"\ + "void tst_QScriptValueGenerated::qscriptvalue_cast%1_initData()\n"\ "{\n"\ " QTest::addColumn<%1>(\"expected\");\n"\ " initScriptValues();\n"\ "}\n"\ "\n"\ - "static QString qscriptvalue_cast%1_tagArray [] = {%2};\n"\ - "static %1 qscriptvalue_cast%1_valueArray [] = {%3};\n"\ - "void tst_QScriptValue::qscriptvalue_cast%1_makeData(const char* expr)\n"\ + "static QString qscriptvalue_cast%1_tagArray[] = {%2};\n"\ + "static %1 qscriptvalue_cast%1_valueArray[] = {%3};\n"\ + "void tst_QScriptValueGenerated::qscriptvalue_cast%1_makeData(const char* expr)\n"\ "{\n"\ " static QHash<QString, %1> value;\n"\ " if (value.isEmpty()) {\n"\ @@ -405,7 +421,7 @@ QString generateCastDef<qsreal>(const QList<QPair<QString, qsreal> >& list) " newRow(expr) << value.value(expr);\n"\ "}\n"\ "\n"\ - "void tst_QScriptValue::qscriptvalue_cast%1_test(const char*, const QScriptValue& value)\n"\ + "void tst_QScriptValueGenerated::qscriptvalue_cast%1_test(const char*, const QScriptValue& value)\n"\ "{\n"\ " QFETCH(%1, expected);\n"\ " if (qIsNaN(expected)) {\n" @@ -427,19 +443,23 @@ QString generateCastDef<qsreal>(const QList<QPair<QString, qsreal> >& list) QList<QPair<QString, qsreal> >::const_iterator i = list.constBegin(); QStringList tagSet, valueSet; - tagSet.reserve(list.count()); - valueSet.reserve(list.count()); - int tmp = -1; - for(; i != list.constEnd(); ++i) { + tagSet.reserve(4 * list.count()); + valueSet.reserve(3 * list.count()); + for(int lineBreaker = 0; i != list.constEnd(); ++i) { QPair<QString, qsreal> t = *i; t.first = escape(t.first); + if (!valueSet.isEmpty()) { + valueSet.append(QString(",")); + tagSet.append(QString::fromAscii(",")); + } tagSet.append(QString("\n \"")); tagSet.append(t.first); - tagSet.append(QString::fromAscii("\",")); - if (!((++tmp)%10)) + tagSet.append(QString::fromAscii("\"")); + if (!((lineBreaker++)%10)) valueSet.append(QString("\n ")); + else + valueSet.append(QString::fromAscii(" ")); valueSet.append(prepareToInsert<qsreal>(t.second)); - valueSet.append(QString::fromAscii(", ")); } return result.arg(typeName<qsreal>(), tagSet.join(QString()), @@ -447,18 +467,18 @@ QString generateCastDef<qsreal>(const QList<QPair<QString, qsreal> >& list) QString::number(list.count())); } -static QString generateCompareDef(const QString& comparisionType, const QList<QString> tags) +static QString generateCompareDef(const QString& comparisonType, const QList<QString> tags) { static const QString templ = "\n"\ - "void tst_QScriptValue::%1_initData()\n"\ + "void tst_QScriptValueGenerated::%1_initData()\n"\ "{\n"\ " QTest::addColumn<QScriptValue>(\"other\");\n"\ " QTest::addColumn<bool>(\"expected\");\n"\ " initScriptValues();\n"\ "}\n"\ "\n"\ - "static QString %1_array [] = {%2};\n\n"\ - "void tst_QScriptValue::%1_makeData(const char *expr)\n"\ + "static QString %1_array[] = {%2};\n\n"\ + "void tst_QScriptValueGenerated::%1_makeData(const char *expr)\n"\ "{\n"\ " static QSet<QString> equals;\n"\ " if (equals.isEmpty()) {\n"\ @@ -473,7 +493,7 @@ static QString generateCompareDef(const QString& comparisionType, const QList<QS " }\n"\ "}\n"\ "\n"\ - "void tst_QScriptValue::%1_test(const char *, const QScriptValue& value)\n"\ + "void tst_QScriptValueGenerated::%1_test(const char *, const QScriptValue& value)\n"\ "{\n"\ " QFETCH(QScriptValue, other);\n"\ " QFETCH(bool, expected);\n"\ @@ -481,26 +501,31 @@ static QString generateCompareDef(const QString& comparisionType, const QList<QS "}\n"\ "\n"\ "DEFINE_TEST_FUNCTION(%1)\n"; - Q_ASSERT(comparisionType == "strictlyEquals" - || comparisionType == "equals" - || comparisionType == "lessThan" - || comparisionType == "instanceOf"); + if (comparisonType != "strictlyEquals" + && comparisonType != "equals" + && comparisonType != "lessThan" + && comparisonType != "instanceOf") + qFatal("%s: Unknown comparisonType: %s", Q_FUNC_INFO, qPrintable(comparisonType)); QString result = templ; QStringList set; - set.reserve(tags.count()); + set.reserve(4 * tags.count()); foreach(const QString& tmp, tags) { - set.append("\n \"" + escape(tmp) + "\","); + if (!set.isEmpty()) + set.append(","); + set.append("\n \""); + set.append(escape(tmp)); + set.append("\""); } - return result.arg(comparisionType, set.join(""), QString::number(tags.count())); + return result.arg(comparisonType, set.join(""), QString::number(tags.count())); } static QString generateInitDef(const QVector<QString>& allDataTags) { - static const QString templ = "void tst_QScriptValue::initScriptValues()\n"\ + static const QString templ = "void tst_QScriptValueGenerated::initScriptValues()\n"\ "{\n"\ " m_values.clear();\n"\ - " if (engine) \n"\ + " if (engine)\n"\ " delete engine;\n"\ " engine = new QScriptEngine;\n"\ "%1\n}\n\n"; @@ -521,6 +546,17 @@ static void squashTags(QString dataTag, const QVector<bool>& results, QList<QStr } } +static QString streamStatusString(QDataStream::Status s) +{ + switch (s) { + case QDataStream::ReadPastEnd: + return QString("ReadPastEnd"); + case QDataStream::ReadCorruptData: + return QString("ReadCorruptData"); + default: + return QString("Unknown (%1)").arg(static_cast<int>(s)); + } +} QHash<QString, QString> TestGenerator::generateTest() { @@ -572,7 +608,10 @@ QHash<QString, QString> TestGenerator::generateTest() m_tempFile.seek(0); QDataStream in(&m_tempFile); in >> dataTags; - Q_ASSERT(in.status() == in.Ok); + if (in.status() != in.Ok) + qFatal("%s: stream has bad status %s after reading dataTags", + Q_FUNC_INFO, + qPrintable(streamStatusString(in.status()))); while(!in.atEnd()) { @@ -696,10 +735,13 @@ QHash<QString, QString> TestGenerator::generateTest() castUInt32List.append(QPair<QString, quint32>(dataTag, castUInt32Res)); castUInt16List.append(QPair<QString, quint16>(dataTag, castUInt16Res)); - Q_ASSERT(in.status() == in.Ok); + if (in.status() != in.Ok) + qFatal("%s: stream has bad status %s after reading data items", + Q_FUNC_INFO, + qPrintable(streamStatusString(in.status()))); } - - Q_ASSERT(in.atEnd()); + if (!in.atEnd()) + qFatal("%s: stream has more data after reading all data items", Q_FUNC_INFO); // Generate. QHash<QString, QString> result; diff --git a/tests/auto/qscriptvalue/testgen/testgenerator.h b/tests/auto/qscriptvaluegenerated/testgen/testgenerator.h index c9169c6..0dc3f18 100644 --- a/tests/auto/qscriptvalue/testgen/testgenerator.h +++ b/tests/auto/qscriptvaluegenerated/testgen/testgenerator.h @@ -59,7 +59,8 @@ public: void run() { prepareData(); - Q_ASSERT(m_tempFile.size()); + if (!m_tempFile.size()) + qFatal("%s: prepareData failed to generate any data", Q_FUNC_INFO); save(generateTest()); } diff --git a/tests/auto/qscriptvaluegenerated/tst_qscriptvalue.cpp b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue.cpp new file mode 100644 index 0000000..41e2601 --- /dev/null +++ b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue.cpp @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "tst_qscriptvalue.h" +#include <QtGui/QPushButton> + +//TESTED_CLASS= +//TESTED_FILES= + +QT_BEGIN_NAMESPACE +extern bool qt_script_isJITEnabled(); +QT_END_NAMESPACE + +tst_QScriptValueGenerated::tst_QScriptValueGenerated() + : engine(0) +{ +} + +tst_QScriptValueGenerated::~tst_QScriptValueGenerated() +{ + delete engine; +} + +void tst_QScriptValueGenerated::dataHelper(InitDataFunction init, DefineDataFunction define) +{ + QTest::addColumn<QString>("__expression__"); + (this->*init)(); + QHash<QString,QScriptValue>::const_iterator it; + for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) { + m_currentExpression = it.key(); + (this->*define)(it.key().toLatin1()); + } + m_currentExpression = QString(); +} + +QTestData &tst_QScriptValueGenerated::newRow(const char *tag) +{ + return QTest::newRow(tag) << m_currentExpression; +} + +void tst_QScriptValueGenerated::testHelper(TestFunction fun) +{ + QFETCH(QString, __expression__); + QScriptValue value = m_values.value(__expression__); + (this->*fun)(__expression__.toLatin1(), value); +} + +void tst_QScriptValueGenerated::assignAndCopyConstruct_initData() +{ + QTest::addColumn<int>("dummy"); + initScriptValues(); +} + +void tst_QScriptValueGenerated::assignAndCopyConstruct_makeData(const char *expr) +{ + newRow(expr) << 0; +} + +void tst_QScriptValueGenerated::assignAndCopyConstruct_test(const char *, const QScriptValue &value) +{ + QScriptValue copy(value); + QCOMPARE(copy.strictlyEquals(value), !value.isNumber() || !qIsNaN(value.toNumber())); + QCOMPARE(copy.engine(), value.engine()); + + QScriptValue assigned = copy; + QCOMPARE(assigned.strictlyEquals(value), !copy.isNumber() || !qIsNaN(copy.toNumber())); + QCOMPARE(assigned.engine(), assigned.engine()); + + QScriptValue other(!value.toBool()); + assigned = other; + QVERIFY(!assigned.strictlyEquals(copy)); + QVERIFY(assigned.strictlyEquals(other)); + QCOMPARE(assigned.engine(), other.engine()); +} + +DEFINE_TEST_FUNCTION(assignAndCopyConstruct) + +QTEST_MAIN(tst_QScriptValueGenerated) diff --git a/tests/auto/qscriptvaluegenerated/tst_qscriptvalue.h b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue.h new file mode 100644 index 0000000..d9baaa0 --- /dev/null +++ b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue.h @@ -0,0 +1,370 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TST_QSCRIPTVALUE_H +#define TST_QSCRIPTVALUE_H + +#include <QtCore/qobject.h> +#include <QtCore/qnumeric.h> +#include <QtScript/qscriptclass.h> +#include <QtScript/qscriptengine.h> +#include <QtScript/qscriptvalue.h> +#include <QtTest/QtTest> + +#define DEFINE_TEST_VALUE(expr) m_values.insert(QString::fromLatin1(#expr), expr) + +Q_DECLARE_METATYPE(QVariant) +Q_DECLARE_METATYPE(QScriptValue) + +class tst_QScriptValueGenerated : public QObject +{ + Q_OBJECT + +public: + tst_QScriptValueGenerated(); + virtual ~tst_QScriptValueGenerated(); + +private slots: + // Generated test functions + void isArray_data(); + void isArray(); + + void isBool_data(); + void isBool(); + + void isBoolean_data(); + void isBoolean(); + + void isDate_data(); + void isDate(); + + void isError_data(); + void isError(); + + void isFunction_data(); + void isFunction(); + + void isNull_data(); + void isNull(); + + void isNumber_data(); + void isNumber(); + + void isObject_data(); + void isObject(); + + void isQMetaObject_data(); + void isQMetaObject(); + + void isQObject_data(); + void isQObject(); + + void isRegExp_data(); + void isRegExp(); + + void isString_data(); + void isString(); + + void isUndefined_data(); + void isUndefined(); + + void isValid_data(); + void isValid(); + + void isVariant_data(); + void isVariant(); + + void toBool_data(); + void toBool(); + + void toBoolean_data(); + void toBoolean(); + +// void toDateTime_data(); +// void toDateTime(); + + void toInt32_data(); + void toInt32(); + + void toInteger_data(); + void toInteger(); + + void toNumber_data(); + void toNumber(); + +// void toQMetaObject_data(); +// void toQMetaObject(); + +// void toQObject_data(); +// void toQObject(); + +// void toRegExp_data(); +// void toRegExp(); + + void toString_data(); + void toString(); + + void toUInt16_data(); + void toUInt16(); + + void toUInt32_data(); + void toUInt32(); + +// void toVariant_data(); +// void toVariant(); + + void equals_data(); + void equals(); + + void strictlyEquals_data(); + void strictlyEquals(); + + void lessThan_data(); + void lessThan(); + + void instanceOf_data(); + void instanceOf(); + + void assignAndCopyConstruct_data(); + void assignAndCopyConstruct(); + + void qscriptvalue_castQString_data(); + void qscriptvalue_castQString(); + + void qscriptvalue_castqsreal_data(); + void qscriptvalue_castqsreal(); + + void qscriptvalue_castbool_data(); + void qscriptvalue_castbool(); + + void qscriptvalue_castqint32_data(); + void qscriptvalue_castqint32(); + + void qscriptvalue_castquint32_data(); + void qscriptvalue_castquint32(); + + void qscriptvalue_castquint16_data(); + void qscriptvalue_castquint16(); + +private: + typedef void (tst_QScriptValueGenerated::*InitDataFunction)(); + typedef void (tst_QScriptValueGenerated::*DefineDataFunction)(const char *); + void dataHelper(InitDataFunction init, DefineDataFunction define); + QTestData &newRow(const char *tag); + + typedef void (tst_QScriptValueGenerated::*TestFunction)(const char *, const QScriptValue &); + void testHelper(TestFunction fun); + + // Generated functions + + void initScriptValues(); + + void isArray_initData(); + void isArray_makeData(const char *expr); + void isArray_test(const char *expr, const QScriptValue &value); + + void isBool_initData(); + void isBool_makeData(const char *expr); + void isBool_test(const char *expr, const QScriptValue &value); + + void isBoolean_initData(); + void isBoolean_makeData(const char *expr); + void isBoolean_test(const char *expr, const QScriptValue &value); + + void isDate_initData(); + void isDate_makeData(const char *expr); + void isDate_test(const char *expr, const QScriptValue &value); + + void isError_initData(); + void isError_makeData(const char *expr); + void isError_test(const char *expr, const QScriptValue &value); + + void isFunction_initData(); + void isFunction_makeData(const char *expr); + void isFunction_test(const char *expr, const QScriptValue &value); + + void isNull_initData(); + void isNull_makeData(const char *expr); + void isNull_test(const char *expr, const QScriptValue &value); + + void isNumber_initData(); + void isNumber_makeData(const char *expr); + void isNumber_test(const char *expr, const QScriptValue &value); + + void isObject_initData(); + void isObject_makeData(const char *expr); + void isObject_test(const char *expr, const QScriptValue &value); + + void isQMetaObject_initData(); + void isQMetaObject_makeData(const char *expr); + void isQMetaObject_test(const char *expr, const QScriptValue &value); + + void isQObject_initData(); + void isQObject_makeData(const char *expr); + void isQObject_test(const char *expr, const QScriptValue &value); + + void isRegExp_initData(); + void isRegExp_makeData(const char *expr); + void isRegExp_test(const char *expr, const QScriptValue &value); + + void isString_initData(); + void isString_makeData(const char *expr); + void isString_test(const char *expr, const QScriptValue &value); + + void isUndefined_initData(); + void isUndefined_makeData(const char *expr); + void isUndefined_test(const char *expr, const QScriptValue &value); + + void isValid_initData(); + void isValid_makeData(const char *expr); + void isValid_test(const char *expr, const QScriptValue &value); + + void isVariant_initData(); + void isVariant_makeData(const char *expr); + void isVariant_test(const char *expr, const QScriptValue &value); + + void toBool_initData(); + void toBool_makeData(const char *); + void toBool_test(const char *, const QScriptValue &value); + + void toBoolean_initData(); + void toBoolean_makeData(const char *); + void toBoolean_test(const char *, const QScriptValue &value); + + void toDateTime_initData(); + void toDateTime_makeData(const char *); + void toDateTime_test(const char *, const QScriptValue &value); + + void toInt32_initData(); + void toInt32_makeData(const char *); + void toInt32_test(const char *, const QScriptValue &value); + + void toInteger_initData(); + void toInteger_makeData(const char *); + void toInteger_test(const char *, const QScriptValue &value); + + void toNumber_initData(); + void toNumber_makeData(const char *); + void toNumber_test(const char *, const QScriptValue &value); + + void toQMetaObject_initData(); + void toQMetaObject_makeData(const char *); + void toQMetaObject_test(const char *, const QScriptValue &value); + + void toQObject_initData(); + void toQObject_makeData(const char *); + void toQObject_test(const char *, const QScriptValue &value); + + void toRegExp_initData(); + void toRegExp_makeData(const char *); + void toRegExp_test(const char *, const QScriptValue &value); + + void toString_initData(); + void toString_makeData(const char *); + void toString_test(const char *, const QScriptValue &value); + + void toUInt16_initData(); + void toUInt16_makeData(const char *); + void toUInt16_test(const char *, const QScriptValue &value); + + void toUInt32_initData(); + void toUInt32_makeData(const char *); + void toUInt32_test(const char *, const QScriptValue &value); + + void toVariant_initData(); + void toVariant_makeData(const char *); + void toVariant_test(const char *, const QScriptValue &value); + + void equals_initData(); + void equals_makeData(const char *); + void equals_test(const char *, const QScriptValue &value); + + void strictlyEquals_initData(); + void strictlyEquals_makeData(const char *); + void strictlyEquals_test(const char *, const QScriptValue &value); + + void lessThan_initData(); + void lessThan_makeData(const char *); + void lessThan_test(const char *, const QScriptValue &value); + + void instanceOf_initData(); + void instanceOf_makeData(const char *); + void instanceOf_test(const char *, const QScriptValue &value); + + void assignAndCopyConstruct_initData(); + void assignAndCopyConstruct_makeData(const char *); + void assignAndCopyConstruct_test(const char *, const QScriptValue &value); + + void qscriptvalue_castQString_initData(); + void qscriptvalue_castQString_makeData(const char *); + void qscriptvalue_castQString_test(const char *, const QScriptValue &value); + + void qscriptvalue_castqsreal_initData(); + void qscriptvalue_castqsreal_makeData(const char *); + void qscriptvalue_castqsreal_test(const char *, const QScriptValue &value); + + void qscriptvalue_castbool_initData(); + void qscriptvalue_castbool_makeData(const char *); + void qscriptvalue_castbool_test(const char *, const QScriptValue &value); + + void qscriptvalue_castqint32_initData(); + void qscriptvalue_castqint32_makeData(const char *); + void qscriptvalue_castqint32_test(const char *, const QScriptValue &value); + + void qscriptvalue_castquint32_initData(); + void qscriptvalue_castquint32_makeData(const char *); + void qscriptvalue_castquint32_test(const char *, const QScriptValue &value); + + void qscriptvalue_castquint16_initData(); + void qscriptvalue_castquint16_makeData(const char *); + void qscriptvalue_castquint16_test(const char *, const QScriptValue &value); + +private: + QScriptEngine *engine; + QHash<QString, QScriptValue> m_values; + QString m_currentExpression; +}; + +#define DEFINE_TEST_FUNCTION(name) \ +void tst_QScriptValueGenerated::name##_data() { dataHelper(&tst_QScriptValueGenerated::name##_initData, &tst_QScriptValueGenerated::name##_makeData); } \ +void tst_QScriptValueGenerated::name() { testHelper(&tst_QScriptValueGenerated::name##_test); } + +#endif diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue_generated_cast.cpp b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue_generated_cast.cpp index 9d2deb2..89f39af 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue_generated_cast.cpp +++ b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue_generated_cast.cpp @@ -47,13 +47,13 @@ -void tst_QScriptValue::qscriptvalue_castQString_initData() +void tst_QScriptValueGenerated::qscriptvalue_castQString_initData() { QTest::addColumn<QString>("expected"); initScriptValues(); } -static QString qscriptvalue_castQString_tagArray [] = { +static QString qscriptvalue_castQString_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -157,6 +157,11 @@ static QString qscriptvalue_castQString_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -191,95 +196,99 @@ static QString qscriptvalue_castQString_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; -static QString qscriptvalue_castQString_valueArray [] = { - "", "", - "", "true", - "false", "122", - "124", "0", - "0", "123", - "6.37e-8", "-6.37e-8", - "1126240820", "65536", - "65537", "NaN", - "NaN", "Infinity", - "-Infinity", "NaN", - "Infinity", "-Infinity", - "ciao", "ciao", - "", "", - "0", "123", - "12.4", "", - "", "true", - "false", "122", - "124", "0", - "0", "123", - "6.37e-8", "-6.37e-8", - "1126240820", "65536", - "65537", "NaN", - "NaN", "Infinity", - "-Infinity", "NaN", - "Infinity", "-Infinity", - "ciao", "ciao", - "", "", - "0", "123", - "12.3", "", - "", "true", - "false", "122", - "124", "0", - "0", "123", - "6.37e-8", "-6.37e-8", - "1126240820", "65536", - "65537", "NaN", - "NaN", "Infinity", - "-Infinity", "NaN", - "Infinity", "-Infinity", - "ciao", "ciao", - "", "", - "0", "123", - "1.23", "", - "", "[object Object]", - "Invalid Date", "", - "function () {\n [native code]\n}", "Error: Unknown error", - "function Object() {\n [native code]\n}", "function Array() {\n [native code]\n}", - "function Number() {\n [native code]\n}", "function Function() {\n [native code]\n}", - "function () { return 1; }", "function () { return 'ciao'; }", - "function () { throw new Error('foo'); }", "/foo/", - "[object Object]", "", - "Error: Unknown error", "22", - "ReferenceError: Can't find variable: Undefined", "ReferenceError: Can't find variable: Null", - "ReferenceError: Can't find variable: True", "ReferenceError: Can't find variable: False", - "", "", - "true", "false", - "122", "124", - "0", "0", - "123", "6.37e-8", - "-6.37e-8", "1126240820", - "65536", "65537", - "NaN", "Infinity", - "-Infinity", "ciao", - "", "0", - "123", "12.4", - "", "", - "[object Object]", "", - ",,,,,,,,,", "Invalid Date", - "[object QMetaObject]", "undefined", - "123", "false", - "", "QScriptEngine(name = \"\")", }; -void tst_QScriptValue::qscriptvalue_castQString_makeData(const char* expr) + "engine->newQObject(engine)"}; +static QString qscriptvalue_castQString_valueArray[] = { + "", "", + "", "true", + "false", "122", + "124", "0", + "0", "123", + "6.37e-8", "-6.37e-8", + "1126240820", "65536", + "65537", "NaN", + "NaN", "Infinity", + "-Infinity", "NaN", + "Infinity", "-Infinity", + "ciao", "ciao", + "", "", + "0", "123", + "12.4", "", + "", "true", + "false", "122", + "124", "0", + "0", "123", + "6.37e-8", "-6.37e-8", + "1126240820", "65536", + "65537", "NaN", + "NaN", "Infinity", + "-Infinity", "NaN", + "Infinity", "-Infinity", + "ciao", "ciao", + "", "", + "0", "123", + "12.3", "", + "", "true", + "false", "122", + "124", "0", + "0", "123", + "6.37e-8", "-6.37e-8", + "1126240820", "65536", + "65537", "NaN", + "NaN", "Infinity", + "-Infinity", "NaN", + "Infinity", "-Infinity", + "ciao", "ciao", + "", "", + "0", "123", + "1.23", "", + "", "[object Object]", + "Invalid Date", "", + "function () {\n [native code]\n}", "Error: Unknown error", + "function Object() {\n [native code]\n}", "function Array() {\n [native code]\n}", + "function Number() {\n [native code]\n}", "function Function() {\n [native code]\n}", + "function () { return 1; }", "function () { return 'ciao'; }", + "function () { throw new Error('foo'); }", "/foo/", + "[object Object]", "", + "Error: Unknown error", "true", + "false", "123", + "/foo/gim", "ciao", + "22", "ReferenceError: Can't find variable: Undefined", + "ReferenceError: Can't find variable: Null", "ReferenceError: Can't find variable: True", + "ReferenceError: Can't find variable: False", "", + "", "true", + "false", "122", + "124", "0", + "0", "123", + "6.37e-8", "-6.37e-8", + "1126240820", "65536", + "65537", "NaN", + "Infinity", "-Infinity", + "ciao", "", + "0", "123", + "12.4", "", + "", "[object Object]", + "", ",,,,,,,,,", + "Invalid Date", "[object QMetaObject]", + "/foo/gim", "undefined", + "123", "false", + "", "QScriptEngine(name = \"\")"}; +void tst_QScriptValueGenerated::qscriptvalue_castQString_makeData(const char* expr) { static QHash<QString, QString> value; if (value.isEmpty()) { - value.reserve(142); - for (unsigned i = 0; i < 142; ++i) + value.reserve(148); + for (unsigned i = 0; i < 148; ++i) value.insert(qscriptvalue_castQString_tagArray[i], qscriptvalue_castQString_valueArray[i]); } newRow(expr) << value.value(expr); } -void tst_QScriptValue::qscriptvalue_castQString_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::qscriptvalue_castQString_test(const char*, const QScriptValue& value) { QFETCH(QString, expected); QCOMPARE(qscriptvalue_cast<QString>(value), expected); @@ -289,13 +298,13 @@ void tst_QScriptValue::qscriptvalue_castQString_test(const char*, const QScriptV DEFINE_TEST_FUNCTION(qscriptvalue_castQString) -void tst_QScriptValue::qscriptvalue_castqsreal_initData() +void tst_QScriptValueGenerated::qscriptvalue_castqsreal_initData() { QTest::addColumn<qsreal>("expected"); initScriptValues(); } -static QString qscriptvalue_castqsreal_tagArray [] = { +static QString qscriptvalue_castqsreal_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -399,6 +408,11 @@ static QString qscriptvalue_castqsreal_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -433,39 +447,40 @@ static QString qscriptvalue_castqsreal_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; -static qsreal qscriptvalue_castqsreal_valueArray [] = { - 0, qQNaN(), 0, 1, 0, 122, 124, 0, 0, 123, - 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), - qInf(), qInf(), qQNaN(), qQNaN(), 0, 0, 0, 123, 12.4, qQNaN(), - 0, 1, 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, - 1126240820, 65536, 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), qInf(), qInf(), - qQNaN(), qQNaN(), 0, 0, 0, 123, 12.3, qQNaN(), 0, 1, - 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, - 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), qInf(), qInf(), qQNaN(), qQNaN(), - 0, 0, 0, 123, 1.23, 0, qQNaN(), qQNaN(), qQNaN(), 0, - qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), - qQNaN(), 0, qQNaN(), 22, qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), 0, - 1, 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, - 65536, 65537, qQNaN(), qInf(), qInf(), qQNaN(), 0, 0, 123, 12.4, - 0, qQNaN(), qQNaN(), 0, qQNaN(), qQNaN(), qQNaN(), qQNaN(), 123, 0, - 0, qQNaN(), }; -void tst_QScriptValue::qscriptvalue_castqsreal_makeData(const char* expr) + "engine->newQObject(engine)"}; +static qsreal qscriptvalue_castqsreal_valueArray[] = { + 0, qQNaN(), 0, 1, 0, 122, 124, 0, 0, 123, + 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), + qInf(), qInf(), qQNaN(), qQNaN(), 0, 0, 0, 123, 12.4, qQNaN(), + 0, 1, 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, + 1126240820, 65536, 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), qInf(), qInf(), + qQNaN(), qQNaN(), 0, 0, 0, 123, 12.3, qQNaN(), 0, 1, + 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, + 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), qInf(), qInf(), qQNaN(), qQNaN(), + 0, 0, 0, 123, 1.23, 0, qQNaN(), qQNaN(), qQNaN(), 0, + qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), + qQNaN(), 0, qQNaN(), 1, 0, 123, qQNaN(), qQNaN(), 22, qQNaN(), + qQNaN(), qQNaN(), qQNaN(), qQNaN(), 0, 1, 0, 122, 124, 0, + 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, 65537, qQNaN(), qInf(), qInf(), + qQNaN(), 0, 0, 123, 12.4, 0, qQNaN(), qQNaN(), 0, qQNaN(), + qQNaN(), qQNaN(), qQNaN(), qQNaN(), 123, 0, 0, qQNaN()}; +void tst_QScriptValueGenerated::qscriptvalue_castqsreal_makeData(const char* expr) { static QHash<QString, qsreal> value; if (value.isEmpty()) { - value.reserve(142); - for (unsigned i = 0; i < 142; ++i) + value.reserve(148); + for (unsigned i = 0; i < 148; ++i) value.insert(qscriptvalue_castqsreal_tagArray[i], qscriptvalue_castqsreal_valueArray[i]); } newRow(expr) << value.value(expr); } -void tst_QScriptValue::qscriptvalue_castqsreal_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::qscriptvalue_castqsreal_test(const char*, const QScriptValue& value) { QFETCH(qsreal, expected); if (qIsNaN(expected)) { @@ -485,13 +500,13 @@ void tst_QScriptValue::qscriptvalue_castqsreal_test(const char*, const QScriptVa DEFINE_TEST_FUNCTION(qscriptvalue_castqsreal) -void tst_QScriptValue::qscriptvalue_castbool_initData() +void tst_QScriptValueGenerated::qscriptvalue_castbool_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString qscriptvalue_castbool_tagArray [] = { +static QString qscriptvalue_castbool_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -595,6 +610,11 @@ static QString qscriptvalue_castbool_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -629,95 +649,99 @@ static QString qscriptvalue_castbool_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; -static bool qscriptvalue_castbool_valueArray [] = { - false, false, - false, true, - false, true, - true, false, - false, true, - true, true, - true, true, - true, false, - false, true, - true, true, - true, true, - true, true, - false, false, - true, true, - true, false, - false, true, - false, true, - true, false, - false, true, - true, true, - true, true, - true, false, - false, true, - true, true, - true, true, - true, true, - false, false, - true, true, - true, false, - false, true, - false, true, - true, false, - false, true, - true, true, - true, true, - true, false, - false, true, - true, true, - true, true, - true, true, - false, false, - true, true, - true, true, - false, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - false, false, - true, false, - true, true, - false, false, - true, true, - true, true, - true, true, - false, true, - true, true, - false, true, - true, true, - false, false, - true, true, - true, true, - true, true, - true, true, - false, true, }; -void tst_QScriptValue::qscriptvalue_castbool_makeData(const char* expr) + "engine->newQObject(engine)"}; +static bool qscriptvalue_castbool_valueArray[] = { + false, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, true, + false, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + true, true, + true, false, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + true, true, + false, true}; +void tst_QScriptValueGenerated::qscriptvalue_castbool_makeData(const char* expr) { static QHash<QString, bool> value; if (value.isEmpty()) { - value.reserve(142); - for (unsigned i = 0; i < 142; ++i) + value.reserve(148); + for (unsigned i = 0; i < 148; ++i) value.insert(qscriptvalue_castbool_tagArray[i], qscriptvalue_castbool_valueArray[i]); } newRow(expr) << value.value(expr); } -void tst_QScriptValue::qscriptvalue_castbool_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::qscriptvalue_castbool_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(qscriptvalue_cast<bool>(value), expected); @@ -727,13 +751,13 @@ void tst_QScriptValue::qscriptvalue_castbool_test(const char*, const QScriptValu DEFINE_TEST_FUNCTION(qscriptvalue_castbool) -void tst_QScriptValue::qscriptvalue_castqint32_initData() +void tst_QScriptValueGenerated::qscriptvalue_castqint32_initData() { QTest::addColumn<qint32>("expected"); initScriptValues(); } -static QString qscriptvalue_castqint32_tagArray [] = { +static QString qscriptvalue_castqint32_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -837,6 +861,11 @@ static QString qscriptvalue_castqint32_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -871,95 +900,99 @@ static QString qscriptvalue_castqint32_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; -static qint32 qscriptvalue_castqint32_valueArray [] = { - 0, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 1126240820, 65536, - 65537, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 12, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 1126240820, 65536, - 65537, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 12, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 1126240820, 65536, - 65537, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 1, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 22, - 0, 0, - 0, 0, - 0, 0, - 1, 0, - 122, 124, - 0, 0, - 123, 0, - 0, 1126240820, - 65536, 65537, - 0, 0, - 0, 0, - 0, 0, - 123, 12, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 123, 0, - 0, 0, }; -void tst_QScriptValue::qscriptvalue_castqint32_makeData(const char* expr) + "engine->newQObject(engine)"}; +static qint32 qscriptvalue_castqint32_valueArray[] = { + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 1, + 0, 123, + 0, 0, + 22, 0, + 0, 0, + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 123, 0, + 0, 0}; +void tst_QScriptValueGenerated::qscriptvalue_castqint32_makeData(const char* expr) { static QHash<QString, qint32> value; if (value.isEmpty()) { - value.reserve(142); - for (unsigned i = 0; i < 142; ++i) + value.reserve(148); + for (unsigned i = 0; i < 148; ++i) value.insert(qscriptvalue_castqint32_tagArray[i], qscriptvalue_castqint32_valueArray[i]); } newRow(expr) << value.value(expr); } -void tst_QScriptValue::qscriptvalue_castqint32_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::qscriptvalue_castqint32_test(const char*, const QScriptValue& value) { QFETCH(qint32, expected); QCOMPARE(qscriptvalue_cast<qint32>(value), expected); @@ -969,13 +1002,13 @@ void tst_QScriptValue::qscriptvalue_castqint32_test(const char*, const QScriptVa DEFINE_TEST_FUNCTION(qscriptvalue_castqint32) -void tst_QScriptValue::qscriptvalue_castquint32_initData() +void tst_QScriptValueGenerated::qscriptvalue_castquint32_initData() { QTest::addColumn<quint32>("expected"); initScriptValues(); } -static QString qscriptvalue_castquint32_tagArray [] = { +static QString qscriptvalue_castquint32_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -1079,6 +1112,11 @@ static QString qscriptvalue_castquint32_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -1113,95 +1151,99 @@ static QString qscriptvalue_castquint32_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; -static quint32 qscriptvalue_castquint32_valueArray [] = { - 0, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 1126240820, 65536, - 65537, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 12, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 1126240820, 65536, - 65537, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 12, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 1126240820, 65536, - 65537, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 1, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 22, - 0, 0, - 0, 0, - 0, 0, - 1, 0, - 122, 124, - 0, 0, - 123, 0, - 0, 1126240820, - 65536, 65537, - 0, 0, - 0, 0, - 0, 0, - 123, 12, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 123, 0, - 0, 0, }; -void tst_QScriptValue::qscriptvalue_castquint32_makeData(const char* expr) + "engine->newQObject(engine)"}; +static quint32 qscriptvalue_castquint32_valueArray[] = { + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 1, + 0, 123, + 0, 0, + 22, 0, + 0, 0, + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 123, 0, + 0, 0}; +void tst_QScriptValueGenerated::qscriptvalue_castquint32_makeData(const char* expr) { static QHash<QString, quint32> value; if (value.isEmpty()) { - value.reserve(142); - for (unsigned i = 0; i < 142; ++i) + value.reserve(148); + for (unsigned i = 0; i < 148; ++i) value.insert(qscriptvalue_castquint32_tagArray[i], qscriptvalue_castquint32_valueArray[i]); } newRow(expr) << value.value(expr); } -void tst_QScriptValue::qscriptvalue_castquint32_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::qscriptvalue_castquint32_test(const char*, const QScriptValue& value) { QFETCH(quint32, expected); QCOMPARE(qscriptvalue_cast<quint32>(value), expected); @@ -1211,13 +1253,13 @@ void tst_QScriptValue::qscriptvalue_castquint32_test(const char*, const QScriptV DEFINE_TEST_FUNCTION(qscriptvalue_castquint32) -void tst_QScriptValue::qscriptvalue_castquint16_initData() +void tst_QScriptValueGenerated::qscriptvalue_castquint16_initData() { QTest::addColumn<quint16>("expected"); initScriptValues(); } -static QString qscriptvalue_castquint16_tagArray [] = { +static QString qscriptvalue_castquint16_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -1321,6 +1363,11 @@ static QString qscriptvalue_castquint16_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -1355,95 +1402,99 @@ static QString qscriptvalue_castquint16_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; -static quint16 qscriptvalue_castquint16_valueArray [] = { - 0, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 4660, 0, - 1, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 12, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 4660, 0, - 1, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 12, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 4660, 0, - 1, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 1, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 22, - 0, 0, - 0, 0, - 0, 0, - 1, 0, - 122, 124, - 0, 0, - 123, 0, - 0, 4660, - 0, 1, - 0, 0, - 0, 0, - 0, 0, - 123, 12, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 123, 0, - 0, 0, }; -void tst_QScriptValue::qscriptvalue_castquint16_makeData(const char* expr) + "engine->newQObject(engine)"}; +static quint16 qscriptvalue_castquint16_valueArray[] = { + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 4660, 0, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 4660, 0, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 4660, 0, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 1, + 0, 123, + 0, 0, + 22, 0, + 0, 0, + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 4660, 0, + 1, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 123, 0, + 0, 0}; +void tst_QScriptValueGenerated::qscriptvalue_castquint16_makeData(const char* expr) { static QHash<QString, quint16> value; if (value.isEmpty()) { - value.reserve(142); - for (unsigned i = 0; i < 142; ++i) + value.reserve(148); + for (unsigned i = 0; i < 148; ++i) value.insert(qscriptvalue_castquint16_tagArray[i], qscriptvalue_castquint16_valueArray[i]); } newRow(expr) << value.value(expr); } -void tst_QScriptValue::qscriptvalue_castquint16_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::qscriptvalue_castquint16_test(const char*, const QScriptValue& value) { QFETCH(quint16, expected); QCOMPARE(qscriptvalue_cast<quint16>(value), expected); diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue_generated_comparison.cpp b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue_generated_comparison.cpp index 7b70b7c..cc18895 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue_generated_comparison.cpp +++ b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue_generated_comparison.cpp @@ -47,14 +47,14 @@ -void tst_QScriptValue::equals_initData() +void tst_QScriptValueGenerated::equals_initData() { QTest::addColumn<QScriptValue>("other"); QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString equals_array [] = { +static QString equals_array[] = { "QScriptValue() <=> QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::NullValue)", @@ -83,6 +83,7 @@ static QString equals_array [] = { "QScriptValue(true) <=> QScriptValue(true)", "QScriptValue(true) <=> QScriptValue(0, true)", "QScriptValue(true) <=> QScriptValue(engine, true)", + "QScriptValue(true) <=> engine->evaluate(\"new Boolean(true)\")", "QScriptValue(true) <=> engine->evaluate(\"true\")", "QScriptValue(false) <=> QScriptValue(false)", "QScriptValue(false) <=> QScriptValue(0)", @@ -105,6 +106,7 @@ static QString equals_array [] = { "QScriptValue(false) <=> engine->evaluate(\"[]\")", "QScriptValue(false) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(false) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(false) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(false) <=> engine->evaluate(\"false\")", "QScriptValue(false) <=> engine->evaluate(\"0\")", "QScriptValue(false) <=> engine->evaluate(\"0.0\")", @@ -141,6 +143,7 @@ static QString equals_array [] = { "QScriptValue(0) <=> engine->evaluate(\"[]\")", "QScriptValue(0) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(0) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(0) <=> engine->evaluate(\"false\")", "QScriptValue(0) <=> engine->evaluate(\"0\")", "QScriptValue(0) <=> engine->evaluate(\"0.0\")", @@ -169,6 +172,7 @@ static QString equals_array [] = { "QScriptValue(0.0) <=> engine->evaluate(\"[]\")", "QScriptValue(0.0) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(0.0) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0.0) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(0.0) <=> engine->evaluate(\"false\")", "QScriptValue(0.0) <=> engine->evaluate(\"0\")", "QScriptValue(0.0) <=> engine->evaluate(\"0.0\")", @@ -182,6 +186,7 @@ static QString equals_array [] = { "QScriptValue(123.0) <=> QScriptValue(0, QString(\"123\"))", "QScriptValue(123.0) <=> QScriptValue(engine, 123.0)", "QScriptValue(123.0) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(123.0) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(123.0) <=> engine->evaluate(\"123.0\")", "QScriptValue(123.0) <=> engine->evaluate(\"'123'\")", "QScriptValue(123.0) <=> engine->newVariant(QVariant(123))", @@ -242,6 +247,7 @@ static QString equals_array [] = { "QScriptValue(\"ciao\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", "QScriptValue(\"ciao\") <=> QScriptValue(engine, \"ciao\")", "QScriptValue(\"ciao\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(\"ciao\") <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(\"ciao\") <=> engine->evaluate(\"'ciao'\")", "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(\"ciao\")", "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(QString::fromLatin1(\"ciao\"))", @@ -249,6 +255,7 @@ static QString equals_array [] = { "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, \"ciao\")", "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(QString::fromLatin1(\"ciao\")) <=> engine->evaluate(\"'ciao'\")", "QScriptValue(QString(\"\")) <=> QScriptValue(false)", "QScriptValue(QString(\"\")) <=> QScriptValue(0)", @@ -268,6 +275,7 @@ static QString equals_array [] = { "QScriptValue(QString(\"\")) <=> engine->evaluate(\"[]\")", "QScriptValue(QString(\"\")) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(QString(\"\")) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(QString(\"\")) <=> engine->evaluate(\"false\")", "QScriptValue(QString(\"\")) <=> engine->evaluate(\"0\")", "QScriptValue(QString(\"\")) <=> engine->evaluate(\"0.0\")", @@ -292,6 +300,7 @@ static QString equals_array [] = { "QScriptValue(QString()) <=> engine->evaluate(\"[]\")", "QScriptValue(QString()) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(QString()) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(QString()) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(QString()) <=> engine->evaluate(\"false\")", "QScriptValue(QString()) <=> engine->evaluate(\"0\")", "QScriptValue(QString()) <=> engine->evaluate(\"0.0\")", @@ -310,6 +319,7 @@ static QString equals_array [] = { "QScriptValue(QString(\"0\")) <=> QScriptValue(engine, 0)", "QScriptValue(QString(\"0\")) <=> QScriptValue(engine, 0.0)", "QScriptValue(QString(\"0\")) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"false\")", "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"0\")", "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"0.0\")", @@ -321,6 +331,7 @@ static QString equals_array [] = { "QScriptValue(QString(\"123\")) <=> QScriptValue(0, QString(\"123\"))", "QScriptValue(QString(\"123\")) <=> QScriptValue(engine, 123.0)", "QScriptValue(QString(\"123\")) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"123.0\")", "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"'123'\")", "QScriptValue(QString(\"123\")) <=> engine->newVariant(QVariant(123))", @@ -353,6 +364,7 @@ static QString equals_array [] = { "QScriptValue(0, true) <=> QScriptValue(true)", "QScriptValue(0, true) <=> QScriptValue(0, true)", "QScriptValue(0, true) <=> QScriptValue(engine, true)", + "QScriptValue(0, true) <=> engine->evaluate(\"new Boolean(true)\")", "QScriptValue(0, true) <=> engine->evaluate(\"true\")", "QScriptValue(0, false) <=> QScriptValue(false)", "QScriptValue(0, false) <=> QScriptValue(0)", @@ -375,6 +387,7 @@ static QString equals_array [] = { "QScriptValue(0, false) <=> engine->evaluate(\"[]\")", "QScriptValue(0, false) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(0, false) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0, false) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(0, false) <=> engine->evaluate(\"false\")", "QScriptValue(0, false) <=> engine->evaluate(\"0\")", "QScriptValue(0, false) <=> engine->evaluate(\"0.0\")", @@ -411,6 +424,7 @@ static QString equals_array [] = { "QScriptValue(0, 0) <=> engine->evaluate(\"[]\")", "QScriptValue(0, 0) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(0, 0) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0, 0) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(0, 0) <=> engine->evaluate(\"false\")", "QScriptValue(0, 0) <=> engine->evaluate(\"0\")", "QScriptValue(0, 0) <=> engine->evaluate(\"0.0\")", @@ -439,6 +453,7 @@ static QString equals_array [] = { "QScriptValue(0, 0.0) <=> engine->evaluate(\"[]\")", "QScriptValue(0, 0.0) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(0, 0.0) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(0, 0.0) <=> engine->evaluate(\"false\")", "QScriptValue(0, 0.0) <=> engine->evaluate(\"0\")", "QScriptValue(0, 0.0) <=> engine->evaluate(\"0.0\")", @@ -452,6 +467,7 @@ static QString equals_array [] = { "QScriptValue(0, 123.0) <=> QScriptValue(0, QString(\"123\"))", "QScriptValue(0, 123.0) <=> QScriptValue(engine, 123.0)", "QScriptValue(0, 123.0) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(0, 123.0) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0, 123.0) <=> engine->evaluate(\"123.0\")", "QScriptValue(0, 123.0) <=> engine->evaluate(\"'123'\")", "QScriptValue(0, 123.0) <=> engine->newVariant(QVariant(123))", @@ -512,6 +528,7 @@ static QString equals_array [] = { "QScriptValue(0, \"ciao\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", "QScriptValue(0, \"ciao\") <=> QScriptValue(engine, \"ciao\")", "QScriptValue(0, \"ciao\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, \"ciao\") <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(0, \"ciao\") <=> engine->evaluate(\"'ciao'\")", "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(\"ciao\")", "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(QString::fromLatin1(\"ciao\"))", @@ -519,6 +536,7 @@ static QString equals_array [] = { "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, \"ciao\")", "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> engine->evaluate(\"'ciao'\")", "QScriptValue(0, QString(\"\")) <=> QScriptValue(false)", "QScriptValue(0, QString(\"\")) <=> QScriptValue(0)", @@ -538,6 +556,7 @@ static QString equals_array [] = { "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"[]\")", "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"false\")", "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"0\")", "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"0.0\")", @@ -562,6 +581,7 @@ static QString equals_array [] = { "QScriptValue(0, QString()) <=> engine->evaluate(\"[]\")", "QScriptValue(0, QString()) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(0, QString()) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0, QString()) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(0, QString()) <=> engine->evaluate(\"false\")", "QScriptValue(0, QString()) <=> engine->evaluate(\"0\")", "QScriptValue(0, QString()) <=> engine->evaluate(\"0.0\")", @@ -580,6 +600,7 @@ static QString equals_array [] = { "QScriptValue(0, QString(\"0\")) <=> QScriptValue(engine, 0)", "QScriptValue(0, QString(\"0\")) <=> QScriptValue(engine, 0.0)", "QScriptValue(0, QString(\"0\")) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"false\")", "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"0\")", "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"0.0\")", @@ -591,6 +612,7 @@ static QString equals_array [] = { "QScriptValue(0, QString(\"123\")) <=> QScriptValue(0, QString(\"123\"))", "QScriptValue(0, QString(\"123\")) <=> QScriptValue(engine, 123.0)", "QScriptValue(0, QString(\"123\")) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"123.0\")", "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"'123'\")", "QScriptValue(0, QString(\"123\")) <=> engine->newVariant(QVariant(123))", @@ -622,6 +644,7 @@ static QString equals_array [] = { "QScriptValue(engine, true) <=> QScriptValue(true)", "QScriptValue(engine, true) <=> QScriptValue(0, true)", "QScriptValue(engine, true) <=> QScriptValue(engine, true)", + "QScriptValue(engine, true) <=> engine->evaluate(\"new Boolean(true)\")", "QScriptValue(engine, true) <=> engine->evaluate(\"true\")", "QScriptValue(engine, false) <=> QScriptValue(false)", "QScriptValue(engine, false) <=> QScriptValue(0)", @@ -644,6 +667,7 @@ static QString equals_array [] = { "QScriptValue(engine, false) <=> engine->evaluate(\"[]\")", "QScriptValue(engine, false) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(engine, false) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(engine, false) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(engine, false) <=> engine->evaluate(\"false\")", "QScriptValue(engine, false) <=> engine->evaluate(\"0\")", "QScriptValue(engine, false) <=> engine->evaluate(\"0.0\")", @@ -680,6 +704,7 @@ static QString equals_array [] = { "QScriptValue(engine, 0) <=> engine->evaluate(\"[]\")", "QScriptValue(engine, 0) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(engine, 0) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(engine, 0) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(engine, 0) <=> engine->evaluate(\"false\")", "QScriptValue(engine, 0) <=> engine->evaluate(\"0\")", "QScriptValue(engine, 0) <=> engine->evaluate(\"0.0\")", @@ -708,6 +733,7 @@ static QString equals_array [] = { "QScriptValue(engine, 0.0) <=> engine->evaluate(\"[]\")", "QScriptValue(engine, 0.0) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(engine, 0.0) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(engine, 0.0) <=> engine->evaluate(\"false\")", "QScriptValue(engine, 0.0) <=> engine->evaluate(\"0\")", "QScriptValue(engine, 0.0) <=> engine->evaluate(\"0.0\")", @@ -721,6 +747,7 @@ static QString equals_array [] = { "QScriptValue(engine, 123.0) <=> QScriptValue(0, QString(\"123\"))", "QScriptValue(engine, 123.0) <=> QScriptValue(engine, 123.0)", "QScriptValue(engine, 123.0) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, 123.0) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(engine, 123.0) <=> engine->evaluate(\"123.0\")", "QScriptValue(engine, 123.0) <=> engine->evaluate(\"'123'\")", "QScriptValue(engine, 123.0) <=> engine->newVariant(QVariant(123))", @@ -781,6 +808,7 @@ static QString equals_array [] = { "QScriptValue(engine, \"ciao\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", "QScriptValue(engine, \"ciao\") <=> QScriptValue(engine, \"ciao\")", "QScriptValue(engine, \"ciao\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, \"ciao\") <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(engine, \"ciao\") <=> engine->evaluate(\"'ciao'\")", "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(\"ciao\")", "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(QString::fromLatin1(\"ciao\"))", @@ -788,6 +816,7 @@ static QString equals_array [] = { "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, \"ciao\")", "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> engine->evaluate(\"'ciao'\")", "QScriptValue(engine, QString(\"\")) <=> QScriptValue(false)", "QScriptValue(engine, QString(\"\")) <=> QScriptValue(0)", @@ -807,6 +836,7 @@ static QString equals_array [] = { "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"[]\")", "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"false\")", "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"0\")", "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"0.0\")", @@ -831,6 +861,7 @@ static QString equals_array [] = { "QScriptValue(engine, QString()) <=> engine->evaluate(\"[]\")", "QScriptValue(engine, QString()) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(engine, QString()) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(engine, QString()) <=> engine->evaluate(\"false\")", "QScriptValue(engine, QString()) <=> engine->evaluate(\"0\")", "QScriptValue(engine, QString()) <=> engine->evaluate(\"0.0\")", @@ -849,6 +880,7 @@ static QString equals_array [] = { "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(engine, 0)", "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(engine, 0.0)", "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"new Boolean(false)\")", "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"false\")", "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"0\")", "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"0.0\")", @@ -860,6 +892,7 @@ static QString equals_array [] = { "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(0, QString(\"123\"))", "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(engine, 123.0)", "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"123.0\")", "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"'123'\")", "QScriptValue(engine, QString(\"123\")) <=> engine->newVariant(QVariant(123))", @@ -950,6 +983,53 @@ static QString equals_array [] = { "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"0.0\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"''\")", "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(true)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0, true)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(engine, true)", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"true\")", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(false)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0.0)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(QString(\"\"))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(QString())", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(QString(\"0\"))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, false)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, 0)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, 0.0)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, QString(\"\"))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, QString())", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, QString(\"0\"))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, false)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, 0)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, 0.0)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, QString(\"\"))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, QString())", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, QString(\"0\"))", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"false\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"0\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"0.0\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"''\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"'0'\")", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(123.0)", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(QString(\"123\"))", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(0, 123.0)", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(0, QString(\"123\"))", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(engine, 123.0)", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(engine, QString(\"123\"))", + "engine->evaluate(\"new Number(123)\") <=> engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new Number(123)\") <=> engine->evaluate(\"123.0\")", + "engine->evaluate(\"new Number(123)\") <=> engine->evaluate(\"'123'\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\") <=> QScriptValue(\"ciao\")", + "engine->evaluate(\"new String('ciao')\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"new String('ciao')\") <=> QScriptValue(0, \"ciao\")", + "engine->evaluate(\"new String('ciao')\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"new String('ciao')\") <=> QScriptValue(engine, \"ciao\")", + "engine->evaluate(\"new String('ciao')\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"new String('ciao')\") <=> engine->evaluate(\"new String('ciao')\")", + "engine->evaluate(\"new String('ciao')\") <=> engine->evaluate(\"'ciao'\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\") <=> engine->evaluate(\"Null\")", @@ -982,6 +1062,7 @@ static QString equals_array [] = { "engine->evaluate(\"true\") <=> QScriptValue(true)", "engine->evaluate(\"true\") <=> QScriptValue(0, true)", "engine->evaluate(\"true\") <=> QScriptValue(engine, true)", + "engine->evaluate(\"true\") <=> engine->evaluate(\"new Boolean(true)\")", "engine->evaluate(\"true\") <=> engine->evaluate(\"true\")", "engine->evaluate(\"false\") <=> QScriptValue(false)", "engine->evaluate(\"false\") <=> QScriptValue(0)", @@ -1004,6 +1085,7 @@ static QString equals_array [] = { "engine->evaluate(\"false\") <=> engine->evaluate(\"[]\")", "engine->evaluate(\"false\") <=> engine->evaluate(\"Array.prototype\")", "engine->evaluate(\"false\") <=> engine->evaluate(\"new Array()\")", + "engine->evaluate(\"false\") <=> engine->evaluate(\"new Boolean(false)\")", "engine->evaluate(\"false\") <=> engine->evaluate(\"false\")", "engine->evaluate(\"false\") <=> engine->evaluate(\"0\")", "engine->evaluate(\"false\") <=> engine->evaluate(\"0.0\")", @@ -1040,6 +1122,7 @@ static QString equals_array [] = { "engine->evaluate(\"0\") <=> engine->evaluate(\"[]\")", "engine->evaluate(\"0\") <=> engine->evaluate(\"Array.prototype\")", "engine->evaluate(\"0\") <=> engine->evaluate(\"new Array()\")", + "engine->evaluate(\"0\") <=> engine->evaluate(\"new Boolean(false)\")", "engine->evaluate(\"0\") <=> engine->evaluate(\"false\")", "engine->evaluate(\"0\") <=> engine->evaluate(\"0\")", "engine->evaluate(\"0\") <=> engine->evaluate(\"0.0\")", @@ -1068,6 +1151,7 @@ static QString equals_array [] = { "engine->evaluate(\"0.0\") <=> engine->evaluate(\"[]\")", "engine->evaluate(\"0.0\") <=> engine->evaluate(\"Array.prototype\")", "engine->evaluate(\"0.0\") <=> engine->evaluate(\"new Array()\")", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"new Boolean(false)\")", "engine->evaluate(\"0.0\") <=> engine->evaluate(\"false\")", "engine->evaluate(\"0.0\") <=> engine->evaluate(\"0\")", "engine->evaluate(\"0.0\") <=> engine->evaluate(\"0.0\")", @@ -1081,6 +1165,7 @@ static QString equals_array [] = { "engine->evaluate(\"123.0\") <=> QScriptValue(0, QString(\"123\"))", "engine->evaluate(\"123.0\") <=> QScriptValue(engine, 123.0)", "engine->evaluate(\"123.0\") <=> QScriptValue(engine, QString(\"123\"))", + "engine->evaluate(\"123.0\") <=> engine->evaluate(\"new Number(123)\")", "engine->evaluate(\"123.0\") <=> engine->evaluate(\"123.0\")", "engine->evaluate(\"123.0\") <=> engine->evaluate(\"'123'\")", "engine->evaluate(\"123.0\") <=> engine->newVariant(QVariant(123))", @@ -1124,6 +1209,7 @@ static QString equals_array [] = { "engine->evaluate(\"'ciao'\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", "engine->evaluate(\"'ciao'\") <=> QScriptValue(engine, \"ciao\")", "engine->evaluate(\"'ciao'\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"'ciao'\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"'ciao'\") <=> engine->evaluate(\"'ciao'\")", "engine->evaluate(\"''\") <=> QScriptValue(false)", "engine->evaluate(\"''\") <=> QScriptValue(0)", @@ -1143,6 +1229,7 @@ static QString equals_array [] = { "engine->evaluate(\"''\") <=> engine->evaluate(\"[]\")", "engine->evaluate(\"''\") <=> engine->evaluate(\"Array.prototype\")", "engine->evaluate(\"''\") <=> engine->evaluate(\"new Array()\")", + "engine->evaluate(\"''\") <=> engine->evaluate(\"new Boolean(false)\")", "engine->evaluate(\"''\") <=> engine->evaluate(\"false\")", "engine->evaluate(\"''\") <=> engine->evaluate(\"0\")", "engine->evaluate(\"''\") <=> engine->evaluate(\"0.0\")", @@ -1161,6 +1248,7 @@ static QString equals_array [] = { "engine->evaluate(\"'0'\") <=> QScriptValue(engine, 0)", "engine->evaluate(\"'0'\") <=> QScriptValue(engine, 0.0)", "engine->evaluate(\"'0'\") <=> QScriptValue(engine, QString(\"0\"))", + "engine->evaluate(\"'0'\") <=> engine->evaluate(\"new Boolean(false)\")", "engine->evaluate(\"'0'\") <=> engine->evaluate(\"false\")", "engine->evaluate(\"'0'\") <=> engine->evaluate(\"0\")", "engine->evaluate(\"'0'\") <=> engine->evaluate(\"0.0\")", @@ -1172,6 +1260,7 @@ static QString equals_array [] = { "engine->evaluate(\"'123'\") <=> QScriptValue(0, QString(\"123\"))", "engine->evaluate(\"'123'\") <=> QScriptValue(engine, 123.0)", "engine->evaluate(\"'123'\") <=> QScriptValue(engine, QString(\"123\"))", + "engine->evaluate(\"'123'\") <=> engine->evaluate(\"new Number(123)\")", "engine->evaluate(\"'123'\") <=> engine->evaluate(\"123.0\")", "engine->evaluate(\"'123'\") <=> engine->evaluate(\"'123'\")", "engine->evaluate(\"'123'\") <=> engine->newVariant(QVariant(123))", @@ -1225,6 +1314,7 @@ static QString equals_array [] = { "engine->newArray(10) <=> engine->newArray(10)", "engine->newDate(QDateTime()) <=> engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject) <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant()) <=> engine->newVariant(QVariant())", "engine->newVariant(QVariant(123)) <=> QScriptValue(123.0)", "engine->newVariant(QVariant(123)) <=> QScriptValue(QString(\"123\"))", @@ -1271,14 +1361,14 @@ static QString equals_array [] = { "engine->newQObject(0) <=> engine->nullValue()", "engine->newQObject(0) <=> engine->undefinedValue()", "engine->newQObject(0) <=> engine->newQObject(0)", - "engine->newQObject(engine) <=> engine->newQObject(engine)",}; + "engine->newQObject(engine) <=> engine->newQObject(engine)"}; -void tst_QScriptValue::equals_makeData(const char *expr) +void tst_QScriptValueGenerated::equals_makeData(const char *expr) { static QSet<QString> equals; if (equals.isEmpty()) { - equals.reserve(1217); - for (unsigned i = 0; i < 1217; ++i) + equals.reserve(1307); + for (unsigned i = 0; i < 1307; ++i) equals.insert(equals_array[i]); } QHash<QString, QScriptValue>::const_iterator it; @@ -1288,7 +1378,7 @@ void tst_QScriptValue::equals_makeData(const char *expr) } } -void tst_QScriptValue::equals_test(const char *, const QScriptValue& value) +void tst_QScriptValueGenerated::equals_test(const char *, const QScriptValue& value) { QFETCH(QScriptValue, other); QFETCH(bool, expected); @@ -1298,14 +1388,14 @@ void tst_QScriptValue::equals_test(const char *, const QScriptValue& value) DEFINE_TEST_FUNCTION(equals) -void tst_QScriptValue::strictlyEquals_initData() +void tst_QScriptValueGenerated::strictlyEquals_initData() { QTest::addColumn<QScriptValue>("other"); QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString strictlyEquals_array [] = { +static QString strictlyEquals_array[] = { "QScriptValue() <=> QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", @@ -1697,6 +1787,11 @@ static QString strictlyEquals_array [] = { "engine->evaluate(\"new Object()\") <=> engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\") <=> engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\") <=> engine->evaluate(\"Null\")", @@ -1819,6 +1914,7 @@ static QString strictlyEquals_array [] = { "engine->newArray(10) <=> engine->newArray(10)", "engine->newDate(QDateTime()) <=> engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject) <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant()) <=> engine->newVariant(QVariant())", "engine->newVariant(QVariant(123)) <=> engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false)) <=> engine->newVariant(QVariant(false))", @@ -1828,14 +1924,14 @@ static QString strictlyEquals_array [] = { "engine->newQObject(0) <=> engine->evaluate(\"null\")", "engine->newQObject(0) <=> engine->nullValue()", "engine->newQObject(0) <=> engine->newQObject(0)", - "engine->newQObject(engine) <=> engine->newQObject(engine)",}; + "engine->newQObject(engine) <=> engine->newQObject(engine)"}; -void tst_QScriptValue::strictlyEquals_makeData(const char *expr) +void tst_QScriptValueGenerated::strictlyEquals_makeData(const char *expr) { static QSet<QString> equals; if (equals.isEmpty()) { - equals.reserve(523); - for (unsigned i = 0; i < 523; ++i) + equals.reserve(529); + for (unsigned i = 0; i < 529; ++i) equals.insert(strictlyEquals_array[i]); } QHash<QString, QScriptValue>::const_iterator it; @@ -1845,7 +1941,7 @@ void tst_QScriptValue::strictlyEquals_makeData(const char *expr) } } -void tst_QScriptValue::strictlyEquals_test(const char *, const QScriptValue& value) +void tst_QScriptValueGenerated::strictlyEquals_test(const char *, const QScriptValue& value) { QFETCH(QScriptValue, other); QFETCH(bool, expected); @@ -1855,14 +1951,14 @@ void tst_QScriptValue::strictlyEquals_test(const char *, const QScriptValue& val DEFINE_TEST_FUNCTION(strictlyEquals) -void tst_QScriptValue::lessThan_initData() +void tst_QScriptValueGenerated::lessThan_initData() { QTest::addColumn<QScriptValue>("other"); QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString lessThan_array [] = { +static QString lessThan_array[] = { "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(true)", "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(int(122))", "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(uint(124))", @@ -1899,6 +1995,8 @@ static QString lessThan_array [] = { "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"true\")", "QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"122\")", @@ -1942,6 +2040,7 @@ static QString lessThan_array [] = { "QScriptValue(true) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(true) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(true) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(true) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(true) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(true) <=> engine->evaluate(\"122\")", "QScriptValue(true) <=> engine->evaluate(\"124\")", @@ -1989,6 +2088,8 @@ static QString lessThan_array [] = { "QScriptValue(false) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(false) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(false) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(false) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(false) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(false) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(false) <=> engine->evaluate(\"true\")", "QScriptValue(false) <=> engine->evaluate(\"122\")", @@ -2026,6 +2127,7 @@ static QString lessThan_array [] = { "QScriptValue(int(122)) <=> QScriptValue(engine, qInf())", "QScriptValue(int(122)) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(int(122)) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(int(122)) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(int(122)) <=> engine->evaluate(\"124\")", "QScriptValue(int(122)) <=> engine->evaluate(\"123.0\")", "QScriptValue(int(122)) <=> engine->evaluate(\"0x43211234\")", @@ -2089,6 +2191,8 @@ static QString lessThan_array [] = { "QScriptValue(0) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(0) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(0) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(0) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0) <=> engine->evaluate(\"true\")", "QScriptValue(0) <=> engine->evaluate(\"122\")", @@ -2138,6 +2242,8 @@ static QString lessThan_array [] = { "QScriptValue(0.0) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(0.0) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(0.0) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(0.0) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0.0) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0.0) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0.0) <=> engine->evaluate(\"true\")", "QScriptValue(0.0) <=> engine->evaluate(\"122\")", @@ -2207,6 +2313,8 @@ static QString lessThan_array [] = { "QScriptValue(6.37e-8) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(6.37e-8) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(6.37e-8) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(6.37e-8) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(6.37e-8) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(6.37e-8) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(6.37e-8) <=> engine->evaluate(\"true\")", "QScriptValue(6.37e-8) <=> engine->evaluate(\"122\")", @@ -2279,6 +2387,9 @@ static QString lessThan_array [] = { "QScriptValue(-6.37e-8) <=> engine->evaluate(\"[]\")", "QScriptValue(-6.37e-8) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(-6.37e-8) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(-6.37e-8) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(-6.37e-8) <=> engine->evaluate(\"new Boolean(false)\")", + "QScriptValue(-6.37e-8) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(-6.37e-8) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(-6.37e-8) <=> engine->evaluate(\"null\")", "QScriptValue(-6.37e-8) <=> engine->evaluate(\"true\")", @@ -2398,6 +2509,9 @@ static QString lessThan_array [] = { "QScriptValue(-qInf()) <=> engine->evaluate(\"[]\")", "QScriptValue(-qInf()) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(-qInf()) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(-qInf()) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(-qInf()) <=> engine->evaluate(\"new Boolean(false)\")", + "QScriptValue(-qInf()) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(-qInf()) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(-qInf()) <=> engine->evaluate(\"null\")", "QScriptValue(-qInf()) <=> engine->evaluate(\"true\")", @@ -2438,6 +2552,7 @@ static QString lessThan_array [] = { "QScriptValue(\"NaN\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "QScriptValue(\"NaN\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(\"NaN\") <=> engine->evaluate(\"new Object()\")", + "QScriptValue(\"NaN\") <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(\"NaN\") <=> engine->evaluate(\"Undefined\")", "QScriptValue(\"NaN\") <=> engine->evaluate(\"Null\")", "QScriptValue(\"NaN\") <=> engine->evaluate(\"True\")", @@ -2465,6 +2580,7 @@ static QString lessThan_array [] = { "QScriptValue(\"Infinity\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "QScriptValue(\"Infinity\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(\"Infinity\") <=> engine->evaluate(\"new Object()\")", + "QScriptValue(\"Infinity\") <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(\"Infinity\") <=> engine->evaluate(\"Undefined\")", "QScriptValue(\"Infinity\") <=> engine->evaluate(\"Null\")", "QScriptValue(\"Infinity\") <=> engine->evaluate(\"True\")", @@ -2549,6 +2665,11 @@ static QString lessThan_array [] = { "QScriptValue(\"-Infinity\") <=> engine->evaluate(\"/foo/\")", "QScriptValue(\"-Infinity\") <=> engine->evaluate(\"new Object()\")", "QScriptValue(\"-Infinity\") <=> engine->evaluate(\"new Error()\")", + "QScriptValue(\"-Infinity\") <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(\"-Infinity\") <=> engine->evaluate(\"new Boolean(false)\")", + "QScriptValue(\"-Infinity\") <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(\"-Infinity\") <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "QScriptValue(\"-Infinity\") <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(\"-Infinity\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(\"-Infinity\") <=> engine->evaluate(\"Undefined\")", "QScriptValue(\"-Infinity\") <=> engine->evaluate(\"Null\")", @@ -2575,6 +2696,7 @@ static QString lessThan_array [] = { "QScriptValue(\"-Infinity\") <=> engine->nullValue()", "QScriptValue(\"-Infinity\") <=> engine->newObject()", "QScriptValue(\"-Infinity\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "QScriptValue(\"-Infinity\") <=> engine->newRegExp(\"foo\", \"gim\")", "QScriptValue(\"-Infinity\") <=> engine->newVariant(QVariant(123))", "QScriptValue(\"-Infinity\") <=> engine->newVariant(QVariant(false))", "QScriptValue(\"-Infinity\") <=> engine->newQObject(0)", @@ -2659,6 +2781,10 @@ static QString lessThan_array [] = { "QScriptValue(QString(\"\")) <=> engine->evaluate(\"/foo/\")", "QScriptValue(QString(\"\")) <=> engine->evaluate(\"new Object()\")", "QScriptValue(QString(\"\")) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(QString(\"\")) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(QString(\"\")) <=> engine->evaluate(\"Undefined\")", "QScriptValue(QString(\"\")) <=> engine->evaluate(\"Null\")", @@ -2680,6 +2806,7 @@ static QString lessThan_array [] = { "QScriptValue(QString(\"\")) <=> engine->newObject()", "QScriptValue(QString(\"\")) <=> engine->newArray(10)", "QScriptValue(QString(\"\")) <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "QScriptValue(QString(\"\")) <=> engine->newRegExp(\"foo\", \"gim\")", "QScriptValue(QString(\"\")) <=> engine->newVariant(QVariant(123))", "QScriptValue(QString(\"\")) <=> engine->newQObject(engine)", "QScriptValue(QString()) <=> QScriptValue(true)", @@ -2746,6 +2873,10 @@ static QString lessThan_array [] = { "QScriptValue(QString()) <=> engine->evaluate(\"/foo/\")", "QScriptValue(QString()) <=> engine->evaluate(\"new Object()\")", "QScriptValue(QString()) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(QString()) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(QString()) <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(QString()) <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "QScriptValue(QString()) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(QString()) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(QString()) <=> engine->evaluate(\"Undefined\")", "QScriptValue(QString()) <=> engine->evaluate(\"Null\")", @@ -2767,6 +2898,7 @@ static QString lessThan_array [] = { "QScriptValue(QString()) <=> engine->newObject()", "QScriptValue(QString()) <=> engine->newArray(10)", "QScriptValue(QString()) <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "QScriptValue(QString()) <=> engine->newRegExp(\"foo\", \"gim\")", "QScriptValue(QString()) <=> engine->newVariant(QVariant(123))", "QScriptValue(QString()) <=> engine->newQObject(engine)", "QScriptValue(QString(\"0\")) <=> QScriptValue(true)", @@ -2826,6 +2958,9 @@ static QString lessThan_array [] = { "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"new Object()\")", "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"Undefined\")", "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"Null\")", @@ -2886,6 +3021,7 @@ static QString lessThan_array [] = { "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"new Object()\")", "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"Undefined\")", "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"Null\")", "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"True\")", @@ -2947,6 +3083,8 @@ static QString lessThan_array [] = { "QScriptValue(QString(\"12.4\")) <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(QString(\"12.4\")) <=> engine->evaluate(\"new Object()\")", "QScriptValue(QString(\"12.4\")) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(QString(\"12.4\")) <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(QString(\"12.4\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(QString(\"12.4\")) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(QString(\"12.4\")) <=> engine->evaluate(\"Undefined\")", "QScriptValue(QString(\"12.4\")) <=> engine->evaluate(\"Null\")", @@ -3001,6 +3139,8 @@ static QString lessThan_array [] = { "QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"true\")", "QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"122\")", @@ -3044,6 +3184,7 @@ static QString lessThan_array [] = { "QScriptValue(0, true) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(0, true) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(0, true) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(0, true) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0, true) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, true) <=> engine->evaluate(\"122\")", "QScriptValue(0, true) <=> engine->evaluate(\"124\")", @@ -3091,6 +3232,8 @@ static QString lessThan_array [] = { "QScriptValue(0, false) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(0, false) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(0, false) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(0, false) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0, false) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0, false) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, false) <=> engine->evaluate(\"true\")", "QScriptValue(0, false) <=> engine->evaluate(\"122\")", @@ -3128,6 +3271,7 @@ static QString lessThan_array [] = { "QScriptValue(0, int(122)) <=> QScriptValue(engine, qInf())", "QScriptValue(0, int(122)) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(0, int(122)) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(0, int(122)) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0, int(122)) <=> engine->evaluate(\"124\")", "QScriptValue(0, int(122)) <=> engine->evaluate(\"123.0\")", "QScriptValue(0, int(122)) <=> engine->evaluate(\"0x43211234\")", @@ -3191,6 +3335,8 @@ static QString lessThan_array [] = { "QScriptValue(0, 0) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(0, 0) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(0, 0) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(0, 0) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0, 0) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0, 0) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, 0) <=> engine->evaluate(\"true\")", "QScriptValue(0, 0) <=> engine->evaluate(\"122\")", @@ -3240,6 +3386,8 @@ static QString lessThan_array [] = { "QScriptValue(0, 0.0) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(0, 0.0) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(0, 0.0) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0, 0.0) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, 0.0) <=> engine->evaluate(\"true\")", "QScriptValue(0, 0.0) <=> engine->evaluate(\"122\")", @@ -3309,6 +3457,8 @@ static QString lessThan_array [] = { "QScriptValue(0, 6.37e-8) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(0, 6.37e-8) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(0, 6.37e-8) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(0, 6.37e-8) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0, 6.37e-8) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0, 6.37e-8) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, 6.37e-8) <=> engine->evaluate(\"true\")", "QScriptValue(0, 6.37e-8) <=> engine->evaluate(\"122\")", @@ -3381,6 +3531,9 @@ static QString lessThan_array [] = { "QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"[]\")", "QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"new Boolean(false)\")", + "QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"null\")", "QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"true\")", @@ -3500,6 +3653,9 @@ static QString lessThan_array [] = { "QScriptValue(0, -qInf()) <=> engine->evaluate(\"[]\")", "QScriptValue(0, -qInf()) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(0, -qInf()) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0, -qInf()) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0, -qInf()) <=> engine->evaluate(\"new Boolean(false)\")", + "QScriptValue(0, -qInf()) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(0, -qInf()) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, -qInf()) <=> engine->evaluate(\"null\")", "QScriptValue(0, -qInf()) <=> engine->evaluate(\"true\")", @@ -3540,6 +3696,7 @@ static QString lessThan_array [] = { "QScriptValue(0, \"NaN\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "QScriptValue(0, \"NaN\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(0, \"NaN\") <=> engine->evaluate(\"new Object()\")", + "QScriptValue(0, \"NaN\") <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(0, \"NaN\") <=> engine->evaluate(\"Undefined\")", "QScriptValue(0, \"NaN\") <=> engine->evaluate(\"Null\")", "QScriptValue(0, \"NaN\") <=> engine->evaluate(\"True\")", @@ -3567,6 +3724,7 @@ static QString lessThan_array [] = { "QScriptValue(0, \"Infinity\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "QScriptValue(0, \"Infinity\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(0, \"Infinity\") <=> engine->evaluate(\"new Object()\")", + "QScriptValue(0, \"Infinity\") <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(0, \"Infinity\") <=> engine->evaluate(\"Undefined\")", "QScriptValue(0, \"Infinity\") <=> engine->evaluate(\"Null\")", "QScriptValue(0, \"Infinity\") <=> engine->evaluate(\"True\")", @@ -3651,6 +3809,11 @@ static QString lessThan_array [] = { "QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"/foo/\")", "QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"new Object()\")", "QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"new Error()\")", + "QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"new Boolean(false)\")", + "QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"Undefined\")", "QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"Null\")", @@ -3677,6 +3840,7 @@ static QString lessThan_array [] = { "QScriptValue(0, \"-Infinity\") <=> engine->nullValue()", "QScriptValue(0, \"-Infinity\") <=> engine->newObject()", "QScriptValue(0, \"-Infinity\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "QScriptValue(0, \"-Infinity\") <=> engine->newRegExp(\"foo\", \"gim\")", "QScriptValue(0, \"-Infinity\") <=> engine->newVariant(QVariant(123))", "QScriptValue(0, \"-Infinity\") <=> engine->newVariant(QVariant(false))", "QScriptValue(0, \"-Infinity\") <=> engine->newQObject(0)", @@ -3761,6 +3925,10 @@ static QString lessThan_array [] = { "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"/foo/\")", "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"new Object()\")", "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"Undefined\")", "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"Null\")", @@ -3782,6 +3950,7 @@ static QString lessThan_array [] = { "QScriptValue(0, QString(\"\")) <=> engine->newObject()", "QScriptValue(0, QString(\"\")) <=> engine->newArray(10)", "QScriptValue(0, QString(\"\")) <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "QScriptValue(0, QString(\"\")) <=> engine->newRegExp(\"foo\", \"gim\")", "QScriptValue(0, QString(\"\")) <=> engine->newVariant(QVariant(123))", "QScriptValue(0, QString(\"\")) <=> engine->newQObject(engine)", "QScriptValue(0, QString()) <=> QScriptValue(true)", @@ -3848,6 +4017,10 @@ static QString lessThan_array [] = { "QScriptValue(0, QString()) <=> engine->evaluate(\"/foo/\")", "QScriptValue(0, QString()) <=> engine->evaluate(\"new Object()\")", "QScriptValue(0, QString()) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(0, QString()) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0, QString()) <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(0, QString()) <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "QScriptValue(0, QString()) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(0, QString()) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, QString()) <=> engine->evaluate(\"Undefined\")", "QScriptValue(0, QString()) <=> engine->evaluate(\"Null\")", @@ -3869,6 +4042,7 @@ static QString lessThan_array [] = { "QScriptValue(0, QString()) <=> engine->newObject()", "QScriptValue(0, QString()) <=> engine->newArray(10)", "QScriptValue(0, QString()) <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "QScriptValue(0, QString()) <=> engine->newRegExp(\"foo\", \"gim\")", "QScriptValue(0, QString()) <=> engine->newVariant(QVariant(123))", "QScriptValue(0, QString()) <=> engine->newQObject(engine)", "QScriptValue(0, QString(\"0\")) <=> QScriptValue(true)", @@ -3928,6 +4102,9 @@ static QString lessThan_array [] = { "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"new Object()\")", "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"Undefined\")", "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"Null\")", @@ -3988,6 +4165,7 @@ static QString lessThan_array [] = { "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"new Object()\")", "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"Undefined\")", "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"Null\")", "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"True\")", @@ -4050,6 +4228,8 @@ static QString lessThan_array [] = { "QScriptValue(0, QString(\"12.3\")) <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(0, QString(\"12.3\")) <=> engine->evaluate(\"new Object()\")", "QScriptValue(0, QString(\"12.3\")) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(0, QString(\"12.3\")) <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(0, QString(\"12.3\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(0, QString(\"12.3\")) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(0, QString(\"12.3\")) <=> engine->evaluate(\"Undefined\")", "QScriptValue(0, QString(\"12.3\")) <=> engine->evaluate(\"Null\")", @@ -4105,6 +4285,8 @@ static QString lessThan_array [] = { "QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(engine, QScriptValue::NullValue) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(engine, QScriptValue::NullValue) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(engine, QScriptValue::NullValue) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, QScriptValue::NullValue) <=> engine->evaluate(\"true\")", "QScriptValue(engine, QScriptValue::NullValue) <=> engine->evaluate(\"122\")", @@ -4148,6 +4330,7 @@ static QString lessThan_array [] = { "QScriptValue(engine, true) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(engine, true) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(engine, true) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(engine, true) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(engine, true) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, true) <=> engine->evaluate(\"122\")", "QScriptValue(engine, true) <=> engine->evaluate(\"124\")", @@ -4195,6 +4378,8 @@ static QString lessThan_array [] = { "QScriptValue(engine, false) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(engine, false) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(engine, false) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(engine, false) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(engine, false) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(engine, false) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, false) <=> engine->evaluate(\"true\")", "QScriptValue(engine, false) <=> engine->evaluate(\"122\")", @@ -4232,6 +4417,7 @@ static QString lessThan_array [] = { "QScriptValue(engine, int(122)) <=> QScriptValue(engine, qInf())", "QScriptValue(engine, int(122)) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(engine, int(122)) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, int(122)) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(engine, int(122)) <=> engine->evaluate(\"124\")", "QScriptValue(engine, int(122)) <=> engine->evaluate(\"123.0\")", "QScriptValue(engine, int(122)) <=> engine->evaluate(\"0x43211234\")", @@ -4295,6 +4481,8 @@ static QString lessThan_array [] = { "QScriptValue(engine, 0) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(engine, 0) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(engine, 0) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(engine, 0) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(engine, 0) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(engine, 0) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, 0) <=> engine->evaluate(\"true\")", "QScriptValue(engine, 0) <=> engine->evaluate(\"122\")", @@ -4344,6 +4532,8 @@ static QString lessThan_array [] = { "QScriptValue(engine, 0.0) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(engine, 0.0) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(engine, 0.0) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(engine, 0.0) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, 0.0) <=> engine->evaluate(\"true\")", "QScriptValue(engine, 0.0) <=> engine->evaluate(\"122\")", @@ -4413,6 +4603,8 @@ static QString lessThan_array [] = { "QScriptValue(engine, 6.37e-8) <=> QScriptValue(engine, \"Infinity\")", "QScriptValue(engine, 6.37e-8) <=> QScriptValue(engine, QString(\"123\"))", "QScriptValue(engine, 6.37e-8) <=> QScriptValue(engine, QString(\"1.23\"))", + "QScriptValue(engine, 6.37e-8) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(engine, 6.37e-8) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(engine, 6.37e-8) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, 6.37e-8) <=> engine->evaluate(\"true\")", "QScriptValue(engine, 6.37e-8) <=> engine->evaluate(\"122\")", @@ -4485,6 +4677,9 @@ static QString lessThan_array [] = { "QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"[]\")", "QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"new Boolean(false)\")", + "QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"null\")", "QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"true\")", @@ -4604,6 +4799,9 @@ static QString lessThan_array [] = { "QScriptValue(engine, -qInf()) <=> engine->evaluate(\"[]\")", "QScriptValue(engine, -qInf()) <=> engine->evaluate(\"Array.prototype\")", "QScriptValue(engine, -qInf()) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(engine, -qInf()) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(engine, -qInf()) <=> engine->evaluate(\"new Boolean(false)\")", + "QScriptValue(engine, -qInf()) <=> engine->evaluate(\"new Number(123)\")", "QScriptValue(engine, -qInf()) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, -qInf()) <=> engine->evaluate(\"null\")", "QScriptValue(engine, -qInf()) <=> engine->evaluate(\"true\")", @@ -4644,6 +4842,7 @@ static QString lessThan_array [] = { "QScriptValue(engine, \"NaN\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "QScriptValue(engine, \"NaN\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(engine, \"NaN\") <=> engine->evaluate(\"new Object()\")", + "QScriptValue(engine, \"NaN\") <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(engine, \"NaN\") <=> engine->evaluate(\"Undefined\")", "QScriptValue(engine, \"NaN\") <=> engine->evaluate(\"Null\")", "QScriptValue(engine, \"NaN\") <=> engine->evaluate(\"True\")", @@ -4671,6 +4870,7 @@ static QString lessThan_array [] = { "QScriptValue(engine, \"Infinity\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "QScriptValue(engine, \"Infinity\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(engine, \"Infinity\") <=> engine->evaluate(\"new Object()\")", + "QScriptValue(engine, \"Infinity\") <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(engine, \"Infinity\") <=> engine->evaluate(\"Undefined\")", "QScriptValue(engine, \"Infinity\") <=> engine->evaluate(\"Null\")", "QScriptValue(engine, \"Infinity\") <=> engine->evaluate(\"True\")", @@ -4755,6 +4955,11 @@ static QString lessThan_array [] = { "QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"/foo/\")", "QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"new Object()\")", "QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"new Error()\")", + "QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"new Boolean(false)\")", + "QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"Undefined\")", "QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"Null\")", @@ -4781,6 +4986,7 @@ static QString lessThan_array [] = { "QScriptValue(engine, \"-Infinity\") <=> engine->nullValue()", "QScriptValue(engine, \"-Infinity\") <=> engine->newObject()", "QScriptValue(engine, \"-Infinity\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "QScriptValue(engine, \"-Infinity\") <=> engine->newRegExp(\"foo\", \"gim\")", "QScriptValue(engine, \"-Infinity\") <=> engine->newVariant(QVariant(123))", "QScriptValue(engine, \"-Infinity\") <=> engine->newVariant(QVariant(false))", "QScriptValue(engine, \"-Infinity\") <=> engine->newQObject(0)", @@ -4865,6 +5071,10 @@ static QString lessThan_array [] = { "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"/foo/\")", "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"new Object()\")", "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"Undefined\")", "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"Null\")", @@ -4886,6 +5096,7 @@ static QString lessThan_array [] = { "QScriptValue(engine, QString(\"\")) <=> engine->newObject()", "QScriptValue(engine, QString(\"\")) <=> engine->newArray(10)", "QScriptValue(engine, QString(\"\")) <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "QScriptValue(engine, QString(\"\")) <=> engine->newRegExp(\"foo\", \"gim\")", "QScriptValue(engine, QString(\"\")) <=> engine->newVariant(QVariant(123))", "QScriptValue(engine, QString(\"\")) <=> engine->newQObject(engine)", "QScriptValue(engine, QString()) <=> QScriptValue(true)", @@ -4952,6 +5163,10 @@ static QString lessThan_array [] = { "QScriptValue(engine, QString()) <=> engine->evaluate(\"/foo/\")", "QScriptValue(engine, QString()) <=> engine->evaluate(\"new Object()\")", "QScriptValue(engine, QString()) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(engine, QString()) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, QString()) <=> engine->evaluate(\"Undefined\")", "QScriptValue(engine, QString()) <=> engine->evaluate(\"Null\")", @@ -4973,6 +5188,7 @@ static QString lessThan_array [] = { "QScriptValue(engine, QString()) <=> engine->newObject()", "QScriptValue(engine, QString()) <=> engine->newArray(10)", "QScriptValue(engine, QString()) <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "QScriptValue(engine, QString()) <=> engine->newRegExp(\"foo\", \"gim\")", "QScriptValue(engine, QString()) <=> engine->newVariant(QVariant(123))", "QScriptValue(engine, QString()) <=> engine->newQObject(engine)", "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(true)", @@ -5032,6 +5248,9 @@ static QString lessThan_array [] = { "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"new Object()\")", "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"new Boolean(true)\")", + "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"Undefined\")", "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"Null\")", @@ -5092,6 +5311,7 @@ static QString lessThan_array [] = { "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"new Object()\")", "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"Undefined\")", "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"Null\")", "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"True\")", @@ -5155,6 +5375,8 @@ static QString lessThan_array [] = { "QScriptValue(engine, QString(\"1.23\")) <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "QScriptValue(engine, QString(\"1.23\")) <=> engine->evaluate(\"new Object()\")", "QScriptValue(engine, QString(\"1.23\")) <=> engine->evaluate(\"new Error()\")", + "QScriptValue(engine, QString(\"1.23\")) <=> engine->evaluate(\"new Number(123)\")", + "QScriptValue(engine, QString(\"1.23\")) <=> engine->evaluate(\"new String('ciao')\")", "QScriptValue(engine, QString(\"1.23\")) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "QScriptValue(engine, QString(\"1.23\")) <=> engine->evaluate(\"Undefined\")", "QScriptValue(engine, QString(\"1.23\")) <=> engine->evaluate(\"Null\")", @@ -5238,6 +5460,10 @@ static QString lessThan_array [] = { "engine->evaluate(\"[]\") <=> engine->evaluate(\"/foo/\")", "engine->evaluate(\"[]\") <=> engine->evaluate(\"new Object()\")", "engine->evaluate(\"[]\") <=> engine->evaluate(\"new Error()\")", + "engine->evaluate(\"[]\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"[]\") <=> engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"[]\") <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"[]\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"[]\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"[]\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"[]\") <=> engine->evaluate(\"Null\")", @@ -5259,6 +5485,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"[]\") <=> engine->newObject()", "engine->evaluate(\"[]\") <=> engine->newArray(10)", "engine->evaluate(\"[]\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->evaluate(\"[]\") <=> engine->newRegExp(\"foo\", \"gim\")", "engine->evaluate(\"[]\") <=> engine->newVariant(QVariant(123))", "engine->evaluate(\"[]\") <=> engine->newQObject(engine)", "engine->evaluate(\"Object.prototype\") <=> QScriptValue(\"ciao\")", @@ -5275,6 +5502,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"Object.prototype\") <=> engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"Object.prototype\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "engine->evaluate(\"Object.prototype\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"Object.prototype\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"Object.prototype\") <=> engine->evaluate(\"'ciao'\")", "engine->evaluate(\"Object.prototype\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", "engine->evaluate(\"Array.prototype\") <=> QScriptValue(true)", @@ -5341,6 +5569,10 @@ static QString lessThan_array [] = { "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"/foo/\")", "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"new Object()\")", "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"new Error()\")", + "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"Null\")", @@ -5362,6 +5594,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"Array.prototype\") <=> engine->newObject()", "engine->evaluate(\"Array.prototype\") <=> engine->newArray(10)", "engine->evaluate(\"Array.prototype\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->evaluate(\"Array.prototype\") <=> engine->newRegExp(\"foo\", \"gim\")", "engine->evaluate(\"Array.prototype\") <=> engine->newVariant(QVariant(123))", "engine->evaluate(\"Array.prototype\") <=> engine->newQObject(engine)", "engine->evaluate(\"Function.prototype\") <=> engine->evaluate(\"Object\")", @@ -5393,6 +5626,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"Error.prototype\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "engine->evaluate(\"Error.prototype\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"Error.prototype\") <=> engine->evaluate(\"new Object()\")", + "engine->evaluate(\"Error.prototype\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"Error.prototype\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"Error.prototype\") <=> engine->evaluate(\"Null\")", "engine->evaluate(\"Error.prototype\") <=> engine->evaluate(\"True\")", @@ -5455,6 +5689,8 @@ static QString lessThan_array [] = { "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"new Object()\")", "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"new Error()\")", + "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"Null\")", "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"True\")", @@ -5465,6 +5701,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"'12.4'\")", "engine->evaluate(\"/foo/\") <=> engine->newObject()", "engine->evaluate(\"/foo/\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->evaluate(\"/foo/\") <=> engine->newRegExp(\"foo\", \"gim\")", "engine->evaluate(\"/foo/\") <=> engine->newQObject(engine)", "engine->evaluate(\"new Object()\") <=> QScriptValue(\"ciao\")", "engine->evaluate(\"new Object()\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))", @@ -5480,6 +5717,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"new Object()\") <=> engine->evaluate(\"(function() { return 1; })\")", "engine->evaluate(\"new Object()\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "engine->evaluate(\"new Object()\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"new Object()\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"new Object()\") <=> engine->evaluate(\"'ciao'\")", "engine->evaluate(\"new Object()\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", "engine->evaluate(\"new Array()\") <=> QScriptValue(true)", @@ -5546,6 +5784,10 @@ static QString lessThan_array [] = { "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"/foo/\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"Null\")", @@ -5567,6 +5809,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"new Array()\") <=> engine->newObject()", "engine->evaluate(\"new Array()\") <=> engine->newArray(10)", "engine->evaluate(\"new Array()\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->evaluate(\"new Array()\") <=> engine->newRegExp(\"foo\", \"gim\")", "engine->evaluate(\"new Array()\") <=> engine->newVariant(QVariant(123))", "engine->evaluate(\"new Array()\") <=> engine->newQObject(engine)", "engine->evaluate(\"new Error()\") <=> QScriptValue(\"NaN\")", @@ -5591,6 +5834,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"new Object()\")", + "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"Null\")", "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"True\")", @@ -5599,6 +5843,175 @@ static QString lessThan_array [] = { "engine->evaluate(\"new Error()\") <=> engine->newObject()", "engine->evaluate(\"new Error()\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", "engine->evaluate(\"new Error()\") <=> engine->newQObject(engine)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(int(122))", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(uint(124))", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(123.0)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0x43211234)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0x10000)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0x10001)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(qInf())", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(\"Infinity\")", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(QString(\"123\"))", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(QString(\"12.4\"))", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0, int(122))", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0, uint(124))", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0, 123.0)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0, 0x43211234)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0, 0x10000)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0, 0x10001)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0, qInf())", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0, \"Infinity\")", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0, QString(\"123\"))", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(0, QString(\"12.3\"))", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(engine, int(122))", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(engine, uint(124))", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(engine, 123.0)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(engine, 0x43211234)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(engine, 0x10000)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(engine, 0x10001)", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(engine, qInf())", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(engine, \"Infinity\")", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(engine, QString(\"123\"))", + "engine->evaluate(\"new Boolean(true)\") <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"122\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"124\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"123.0\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"0x10000\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"0x10001\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"Infinity\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"'123'\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"'12.4'\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->newVariant(QVariant(123))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(true)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(int(122))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(uint(124))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(123.0)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(6.37e-8)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0x43211234)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0x10000)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0x10001)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(qInf())", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(\"Infinity\")", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(QString(\"123\"))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(QString(\"12.4\"))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, true)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, int(122))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, uint(124))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, 123.0)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, 6.37e-8)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, 0x43211234)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, 0x10000)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, 0x10001)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, qInf())", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, \"Infinity\")", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, QString(\"123\"))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(0, QString(\"12.3\"))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, true)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, int(122))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, uint(124))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, 123.0)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, 6.37e-8)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, 0x43211234)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, 0x10000)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, 0x10001)", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, qInf())", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, \"Infinity\")", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, QString(\"123\"))", + "engine->evaluate(\"new Boolean(false)\") <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"true\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"122\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"124\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"123.0\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"0x10000\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"0x10001\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"Infinity\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"'123'\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"'12.4'\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->newVariant(QVariant(123))", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(uint(124))", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(0x43211234)", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(0x10000)", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(0x10001)", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(qInf())", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(\"Infinity\")", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(0, uint(124))", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(0, 0x43211234)", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(0, 0x10000)", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(0, 0x10001)", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(0, qInf())", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(0, \"Infinity\")", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(engine, uint(124))", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(engine, 0x43211234)", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(engine, 0x10000)", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(engine, 0x10001)", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(engine, qInf())", + "engine->evaluate(\"new Number(123)\") <=> QScriptValue(engine, \"Infinity\")", + "engine->evaluate(\"new Number(123)\") <=> engine->evaluate(\"124\")", + "engine->evaluate(\"new Number(123)\") <=> engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"new Number(123)\") <=> engine->evaluate(\"0x10000\")", + "engine->evaluate(\"new Number(123)\") <=> engine->evaluate(\"0x10001\")", + "engine->evaluate(\"new Number(123)\") <=> engine->evaluate(\"Infinity\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(\"NaN\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(\"Infinity\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(\"ciao\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(QString(\"0\"))", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(QString(\"123\"))", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(QString(\"12.4\"))", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(0, \"NaN\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(0, \"Infinity\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(0, \"ciao\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(0, QString(\"0\"))", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(0, QString(\"123\"))", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(0, QString(\"12.3\"))", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(engine, \"NaN\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(engine, \"Infinity\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(engine, \"ciao\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(engine, QString(\"0\"))", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(engine, QString(\"123\"))", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"Array\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"Number\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"Function\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"new Object()\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"new String('ciao')\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"Undefined\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"Null\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"True\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"False\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"'0'\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"'123'\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"'12.4'\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->newObject()", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->newQObject(engine)", + "engine->evaluate(\"new String('ciao')\") <=> engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"new String('ciao')\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"new String('ciao')\") <=> engine->evaluate(\"Array\")", + "engine->evaluate(\"new String('ciao')\") <=> engine->evaluate(\"Number\")", + "engine->evaluate(\"new String('ciao')\") <=> engine->evaluate(\"Function\")", + "engine->evaluate(\"new String('ciao')\") <=> engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"new String('ciao')\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"new String('ciao')\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> QScriptValue(int(122))", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> QScriptValue(uint(124))", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> QScriptValue(123.0)", @@ -5626,6 +6039,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> QScriptValue(engine, qInf())", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> QScriptValue(engine, \"Infinity\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> QScriptValue(engine, QString(\"123\"))", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> engine->evaluate(\"new Number(123)\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> engine->evaluate(\"122\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> engine->evaluate(\"124\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> engine->evaluate(\"123.0\")", @@ -5651,6 +6065,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"Undefined\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "engine->evaluate(\"Undefined\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"Undefined\") <=> engine->evaluate(\"new Object()\")", + "engine->evaluate(\"Undefined\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"Undefined\") <=> engine->evaluate(\"'ciao'\")", "engine->evaluate(\"Undefined\") <=> engine->newObject()", "engine->evaluate(\"Undefined\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", @@ -5670,6 +6085,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"Null\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "engine->evaluate(\"Null\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"Null\") <=> engine->evaluate(\"new Object()\")", + "engine->evaluate(\"Null\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"Null\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\") <=> engine->evaluate(\"True\")", "engine->evaluate(\"Null\") <=> engine->evaluate(\"'ciao'\")", @@ -5691,6 +6107,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"True\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "engine->evaluate(\"True\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"True\") <=> engine->evaluate(\"new Object()\")", + "engine->evaluate(\"True\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"True\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"True\") <=> engine->evaluate(\"'ciao'\")", "engine->evaluate(\"True\") <=> engine->newObject()", @@ -5711,6 +6128,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"False\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "engine->evaluate(\"False\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"False\") <=> engine->evaluate(\"new Object()\")", + "engine->evaluate(\"False\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"False\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"False\") <=> engine->evaluate(\"Null\")", "engine->evaluate(\"False\") <=> engine->evaluate(\"True\")", @@ -5753,6 +6171,8 @@ static QString lessThan_array [] = { "engine->evaluate(\"null\") <=> QScriptValue(engine, \"Infinity\")", "engine->evaluate(\"null\") <=> QScriptValue(engine, QString(\"123\"))", "engine->evaluate(\"null\") <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"null\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"null\") <=> engine->evaluate(\"new Number(123)\")", "engine->evaluate(\"null\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"null\") <=> engine->evaluate(\"true\")", "engine->evaluate(\"null\") <=> engine->evaluate(\"122\")", @@ -5796,6 +6216,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"true\") <=> QScriptValue(engine, \"Infinity\")", "engine->evaluate(\"true\") <=> QScriptValue(engine, QString(\"123\"))", "engine->evaluate(\"true\") <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"true\") <=> engine->evaluate(\"new Number(123)\")", "engine->evaluate(\"true\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"true\") <=> engine->evaluate(\"122\")", "engine->evaluate(\"true\") <=> engine->evaluate(\"124\")", @@ -5843,6 +6264,8 @@ static QString lessThan_array [] = { "engine->evaluate(\"false\") <=> QScriptValue(engine, \"Infinity\")", "engine->evaluate(\"false\") <=> QScriptValue(engine, QString(\"123\"))", "engine->evaluate(\"false\") <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"false\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"false\") <=> engine->evaluate(\"new Number(123)\")", "engine->evaluate(\"false\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"false\") <=> engine->evaluate(\"true\")", "engine->evaluate(\"false\") <=> engine->evaluate(\"122\")", @@ -5880,6 +6303,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"122\") <=> QScriptValue(engine, qInf())", "engine->evaluate(\"122\") <=> QScriptValue(engine, \"Infinity\")", "engine->evaluate(\"122\") <=> QScriptValue(engine, QString(\"123\"))", + "engine->evaluate(\"122\") <=> engine->evaluate(\"new Number(123)\")", "engine->evaluate(\"122\") <=> engine->evaluate(\"124\")", "engine->evaluate(\"122\") <=> engine->evaluate(\"123.0\")", "engine->evaluate(\"122\") <=> engine->evaluate(\"0x43211234\")", @@ -5943,6 +6367,8 @@ static QString lessThan_array [] = { "engine->evaluate(\"0\") <=> QScriptValue(engine, \"Infinity\")", "engine->evaluate(\"0\") <=> QScriptValue(engine, QString(\"123\"))", "engine->evaluate(\"0\") <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"0\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"0\") <=> engine->evaluate(\"new Number(123)\")", "engine->evaluate(\"0\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"0\") <=> engine->evaluate(\"true\")", "engine->evaluate(\"0\") <=> engine->evaluate(\"122\")", @@ -5992,6 +6418,8 @@ static QString lessThan_array [] = { "engine->evaluate(\"0.0\") <=> QScriptValue(engine, \"Infinity\")", "engine->evaluate(\"0.0\") <=> QScriptValue(engine, QString(\"123\"))", "engine->evaluate(\"0.0\") <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"new Number(123)\")", "engine->evaluate(\"0.0\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"0.0\") <=> engine->evaluate(\"true\")", "engine->evaluate(\"0.0\") <=> engine->evaluate(\"122\")", @@ -6061,6 +6489,8 @@ static QString lessThan_array [] = { "engine->evaluate(\"6.37e-8\") <=> QScriptValue(engine, \"Infinity\")", "engine->evaluate(\"6.37e-8\") <=> QScriptValue(engine, QString(\"123\"))", "engine->evaluate(\"6.37e-8\") <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"6.37e-8\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"6.37e-8\") <=> engine->evaluate(\"new Number(123)\")", "engine->evaluate(\"6.37e-8\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"6.37e-8\") <=> engine->evaluate(\"true\")", "engine->evaluate(\"6.37e-8\") <=> engine->evaluate(\"122\")", @@ -6133,6 +6563,9 @@ static QString lessThan_array [] = { "engine->evaluate(\"-6.37e-8\") <=> engine->evaluate(\"[]\")", "engine->evaluate(\"-6.37e-8\") <=> engine->evaluate(\"Array.prototype\")", "engine->evaluate(\"-6.37e-8\") <=> engine->evaluate(\"new Array()\")", + "engine->evaluate(\"-6.37e-8\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"-6.37e-8\") <=> engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"-6.37e-8\") <=> engine->evaluate(\"new Number(123)\")", "engine->evaluate(\"-6.37e-8\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"-6.37e-8\") <=> engine->evaluate(\"null\")", "engine->evaluate(\"-6.37e-8\") <=> engine->evaluate(\"true\")", @@ -6252,6 +6685,9 @@ static QString lessThan_array [] = { "engine->evaluate(\"-Infinity\") <=> engine->evaluate(\"[]\")", "engine->evaluate(\"-Infinity\") <=> engine->evaluate(\"Array.prototype\")", "engine->evaluate(\"-Infinity\") <=> engine->evaluate(\"new Array()\")", + "engine->evaluate(\"-Infinity\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"-Infinity\") <=> engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"-Infinity\") <=> engine->evaluate(\"new Number(123)\")", "engine->evaluate(\"-Infinity\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"-Infinity\") <=> engine->evaluate(\"null\")", "engine->evaluate(\"-Infinity\") <=> engine->evaluate(\"true\")", @@ -6348,6 +6784,10 @@ static QString lessThan_array [] = { "engine->evaluate(\"''\") <=> engine->evaluate(\"/foo/\")", "engine->evaluate(\"''\") <=> engine->evaluate(\"new Object()\")", "engine->evaluate(\"''\") <=> engine->evaluate(\"new Error()\")", + "engine->evaluate(\"''\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"''\") <=> engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"''\") <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"''\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"''\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"''\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"''\") <=> engine->evaluate(\"Null\")", @@ -6369,6 +6809,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"''\") <=> engine->newObject()", "engine->evaluate(\"''\") <=> engine->newArray(10)", "engine->evaluate(\"''\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->evaluate(\"''\") <=> engine->newRegExp(\"foo\", \"gim\")", "engine->evaluate(\"''\") <=> engine->newVariant(QVariant(123))", "engine->evaluate(\"''\") <=> engine->newQObject(engine)", "engine->evaluate(\"'0'\") <=> QScriptValue(true)", @@ -6428,6 +6869,9 @@ static QString lessThan_array [] = { "engine->evaluate(\"'0'\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"'0'\") <=> engine->evaluate(\"new Object()\")", "engine->evaluate(\"'0'\") <=> engine->evaluate(\"new Error()\")", + "engine->evaluate(\"'0'\") <=> engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"'0'\") <=> engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"'0'\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"'0'\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"'0'\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"'0'\") <=> engine->evaluate(\"Null\")", @@ -6488,6 +6932,7 @@ static QString lessThan_array [] = { "engine->evaluate(\"'123'\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"'123'\") <=> engine->evaluate(\"new Object()\")", "engine->evaluate(\"'123'\") <=> engine->evaluate(\"new Error()\")", + "engine->evaluate(\"'123'\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"'123'\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"'123'\") <=> engine->evaluate(\"Null\")", "engine->evaluate(\"'123'\") <=> engine->evaluate(\"True\")", @@ -6549,6 +6994,8 @@ static QString lessThan_array [] = { "engine->evaluate(\"'12.4'\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"'12.4'\") <=> engine->evaluate(\"new Object()\")", "engine->evaluate(\"'12.4'\") <=> engine->evaluate(\"new Error()\")", + "engine->evaluate(\"'12.4'\") <=> engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"'12.4'\") <=> engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"'12.4'\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"'12.4'\") <=> engine->evaluate(\"Undefined\")", "engine->evaluate(\"'12.4'\") <=> engine->evaluate(\"Null\")", @@ -6603,6 +7050,8 @@ static QString lessThan_array [] = { "engine->nullValue() <=> QScriptValue(engine, \"Infinity\")", "engine->nullValue() <=> QScriptValue(engine, QString(\"123\"))", "engine->nullValue() <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->nullValue() <=> engine->evaluate(\"new Boolean(true)\")", + "engine->nullValue() <=> engine->evaluate(\"new Number(123)\")", "engine->nullValue() <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->nullValue() <=> engine->evaluate(\"true\")", "engine->nullValue() <=> engine->evaluate(\"122\")", @@ -6630,6 +7079,7 @@ static QString lessThan_array [] = { "engine->newObject() <=> engine->evaluate(\"(function() { return 1; })\")", "engine->newObject() <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "engine->newObject() <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->newObject() <=> engine->evaluate(\"new String('ciao')\")", "engine->newObject() <=> engine->evaluate(\"'ciao'\")", "engine->newObject() <=> engine->newQMetaObject(&QObject::staticMetaObject)", "engine->newArray() <=> QScriptValue(true)", @@ -6696,6 +7146,10 @@ static QString lessThan_array [] = { "engine->newArray() <=> engine->evaluate(\"/foo/\")", "engine->newArray() <=> engine->evaluate(\"new Object()\")", "engine->newArray() <=> engine->evaluate(\"new Error()\")", + "engine->newArray() <=> engine->evaluate(\"new Boolean(true)\")", + "engine->newArray() <=> engine->evaluate(\"new Number(123)\")", + "engine->newArray() <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->newArray() <=> engine->evaluate(\"new String('ciao')\")", "engine->newArray() <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->newArray() <=> engine->evaluate(\"Undefined\")", "engine->newArray() <=> engine->evaluate(\"Null\")", @@ -6717,6 +7171,7 @@ static QString lessThan_array [] = { "engine->newArray() <=> engine->newObject()", "engine->newArray() <=> engine->newArray(10)", "engine->newArray() <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newArray() <=> engine->newRegExp(\"foo\", \"gim\")", "engine->newArray() <=> engine->newVariant(QVariant(123))", "engine->newArray() <=> engine->newQObject(engine)", "engine->newArray(10) <=> QScriptValue(\"NaN\")", @@ -6756,6 +7211,8 @@ static QString lessThan_array [] = { "engine->newArray(10) <=> engine->evaluate(\"/foo/\")", "engine->newArray(10) <=> engine->evaluate(\"new Object()\")", "engine->newArray(10) <=> engine->evaluate(\"new Error()\")", + "engine->newArray(10) <=> engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->newArray(10) <=> engine->evaluate(\"new String('ciao')\")", "engine->newArray(10) <=> engine->evaluate(\"Undefined\")", "engine->newArray(10) <=> engine->evaluate(\"Null\")", "engine->newArray(10) <=> engine->evaluate(\"True\")", @@ -6766,6 +7223,7 @@ static QString lessThan_array [] = { "engine->newArray(10) <=> engine->evaluate(\"'12.4'\")", "engine->newArray(10) <=> engine->newObject()", "engine->newArray(10) <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newArray(10) <=> engine->newRegExp(\"foo\", \"gim\")", "engine->newArray(10) <=> engine->newQObject(engine)", "engine->newQMetaObject(&QObject::staticMetaObject) <=> QScriptValue(\"ciao\")", "engine->newQMetaObject(&QObject::staticMetaObject) <=> QScriptValue(QString::fromLatin1(\"ciao\"))", @@ -6781,7 +7239,53 @@ static QString lessThan_array [] = { "engine->newQMetaObject(&QObject::staticMetaObject) <=> engine->evaluate(\"(function() { return 1; })\")", "engine->newQMetaObject(&QObject::staticMetaObject) <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "engine->newQMetaObject(&QObject::staticMetaObject) <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->newQMetaObject(&QObject::staticMetaObject) <=> engine->evaluate(\"new String('ciao')\")", "engine->newQMetaObject(&QObject::staticMetaObject) <=> engine->evaluate(\"'ciao'\")", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(\"NaN\")", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(\"Infinity\")", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(\"ciao\")", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(QString(\"0\"))", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(QString(\"123\"))", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(QString(\"12.4\"))", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(0, \"NaN\")", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(0, \"Infinity\")", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(0, \"ciao\")", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(0, QString(\"0\"))", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(0, QString(\"123\"))", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(0, QString(\"12.3\"))", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(engine, \"NaN\")", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(engine, \"Infinity\")", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(engine, \"ciao\")", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(engine, QString(\"0\"))", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(engine, QString(\"123\"))", + "engine->newRegExp(\"foo\", \"gim\") <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"Object.prototype\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"Function.prototype\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"Error.prototype\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"Object\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"Array\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"Number\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"Function\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"(function() { return 1; })\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"new Object()\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"new Error()\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"new String('ciao')\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"Undefined\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"Null\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"True\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"False\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"'ciao'\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"'0'\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"'123'\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"'12.4'\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->newObject()", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->newQObject(engine)", "engine->newVariant(QVariant(123)) <=> QScriptValue(uint(124))", "engine->newVariant(QVariant(123)) <=> QScriptValue(0x43211234)", "engine->newVariant(QVariant(123)) <=> QScriptValue(0x10000)", @@ -6841,6 +7345,8 @@ static QString lessThan_array [] = { "engine->newVariant(QVariant(false)) <=> QScriptValue(engine, \"Infinity\")", "engine->newVariant(QVariant(false)) <=> QScriptValue(engine, QString(\"123\"))", "engine->newVariant(QVariant(false)) <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->newVariant(QVariant(false)) <=> engine->evaluate(\"new Boolean(true)\")", + "engine->newVariant(QVariant(false)) <=> engine->evaluate(\"new Number(123)\")", "engine->newVariant(QVariant(false)) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->newVariant(QVariant(false)) <=> engine->evaluate(\"true\")", "engine->newVariant(QVariant(false)) <=> engine->evaluate(\"122\")", @@ -6890,6 +7396,8 @@ static QString lessThan_array [] = { "engine->newQObject(0) <=> QScriptValue(engine, \"Infinity\")", "engine->newQObject(0) <=> QScriptValue(engine, QString(\"123\"))", "engine->newQObject(0) <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->newQObject(0) <=> engine->evaluate(\"new Boolean(true)\")", + "engine->newQObject(0) <=> engine->evaluate(\"new Number(123)\")", "engine->newQObject(0) <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->newQObject(0) <=> engine->evaluate(\"true\")", "engine->newQObject(0) <=> engine->evaluate(\"122\")", @@ -6919,20 +7427,21 @@ static QString lessThan_array [] = { "engine->newQObject(engine) <=> engine->evaluate(\"(function() { return 'ciao'; })\")", "engine->newQObject(engine) <=> engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->newQObject(engine) <=> engine->evaluate(\"new Object()\")", + "engine->newQObject(engine) <=> engine->evaluate(\"new String('ciao')\")", "engine->newQObject(engine) <=> engine->evaluate(\"Undefined\")", "engine->newQObject(engine) <=> engine->evaluate(\"Null\")", "engine->newQObject(engine) <=> engine->evaluate(\"True\")", "engine->newQObject(engine) <=> engine->evaluate(\"False\")", "engine->newQObject(engine) <=> engine->evaluate(\"'ciao'\")", "engine->newQObject(engine) <=> engine->newObject()", - "engine->newQObject(engine) <=> engine->newQMetaObject(&QObject::staticMetaObject)",}; + "engine->newQObject(engine) <=> engine->newQMetaObject(&QObject::staticMetaObject)"}; -void tst_QScriptValue::lessThan_makeData(const char *expr) +void tst_QScriptValueGenerated::lessThan_makeData(const char *expr) { static QSet<QString> equals; if (equals.isEmpty()) { - equals.reserve(5063); - for (unsigned i = 0; i < 5063; ++i) + equals.reserve(5476); + for (unsigned i = 0; i < 5476; ++i) equals.insert(lessThan_array[i]); } QHash<QString, QScriptValue>::const_iterator it; @@ -6942,7 +7451,7 @@ void tst_QScriptValue::lessThan_makeData(const char *expr) } } -void tst_QScriptValue::lessThan_test(const char *, const QScriptValue& value) +void tst_QScriptValueGenerated::lessThan_test(const char *, const QScriptValue& value) { QFETCH(QScriptValue, other); QFETCH(bool, expected); @@ -6952,14 +7461,14 @@ void tst_QScriptValue::lessThan_test(const char *, const QScriptValue& value) DEFINE_TEST_FUNCTION(lessThan) -void tst_QScriptValue::instanceOf_initData() +void tst_QScriptValueGenerated::instanceOf_initData() { QTest::addColumn<QScriptValue>("other"); QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString instanceOf_array [] = { +static QString instanceOf_array[] = { "engine->evaluate(\"[]\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"[]\") <=> engine->evaluate(\"Array\")", "engine->evaluate(\"Date.prototype\") <=> engine->evaluate(\"Object\")", @@ -6985,6 +7494,12 @@ static QString instanceOf_array [] = { "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"Array\")", "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"new Boolean(true)\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"new Boolean(false)\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"new Number(123)\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"new Number(123)\") <=> engine->evaluate(\"Number\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"new String('ciao')\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"Undefined\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"Null\") <=> engine->evaluate(\"Object\")", "engine->evaluate(\"True\") <=> engine->evaluate(\"Object\")", @@ -6996,17 +7511,18 @@ static QString instanceOf_array [] = { "engine->newArray(10) <=> engine->evaluate(\"Array\")", "engine->newDate(QDateTime()) <=> engine->evaluate(\"Object\")", "engine->newQMetaObject(&QObject::staticMetaObject) <=> engine->evaluate(\"Object\")", + "engine->newRegExp(\"foo\", \"gim\") <=> engine->evaluate(\"Object\")", "engine->newVariant(QVariant()) <=> engine->evaluate(\"Object\")", "engine->newVariant(QVariant(123)) <=> engine->evaluate(\"Object\")", "engine->newVariant(QVariant(false)) <=> engine->evaluate(\"Object\")", - "engine->newQObject(engine) <=> engine->evaluate(\"Object\")",}; + "engine->newQObject(engine) <=> engine->evaluate(\"Object\")"}; -void tst_QScriptValue::instanceOf_makeData(const char *expr) +void tst_QScriptValueGenerated::instanceOf_makeData(const char *expr) { static QSet<QString> equals; if (equals.isEmpty()) { - equals.reserve(40); - for (unsigned i = 0; i < 40; ++i) + equals.reserve(47); + for (unsigned i = 0; i < 47; ++i) equals.insert(instanceOf_array[i]); } QHash<QString, QScriptValue>::const_iterator it; @@ -7016,7 +7532,7 @@ void tst_QScriptValue::instanceOf_makeData(const char *expr) } } -void tst_QScriptValue::instanceOf_test(const char *, const QScriptValue& value) +void tst_QScriptValueGenerated::instanceOf_test(const char *, const QScriptValue& value) { QFETCH(QScriptValue, other); QFETCH(bool, expected); diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue_generated_init.cpp b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue_generated_init.cpp index 1ea2ac2..9163529 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue_generated_init.cpp +++ b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue_generated_init.cpp @@ -46,10 +46,10 @@ #include "tst_qscriptvalue.h" -void tst_QScriptValue::initScriptValues() +void tst_QScriptValueGenerated::initScriptValues() { m_values.clear(); - if (engine) + if (engine) delete engine; engine = new QScriptEngine; DEFINE_TEST_VALUE(QScriptValue()); @@ -155,6 +155,11 @@ void tst_QScriptValue::initScriptValues() DEFINE_TEST_VALUE(engine->evaluate("new Object()")); DEFINE_TEST_VALUE(engine->evaluate("new Array()")); DEFINE_TEST_VALUE(engine->evaluate("new Error()")); + DEFINE_TEST_VALUE(engine->evaluate("new Boolean(true)")); + DEFINE_TEST_VALUE(engine->evaluate("new Boolean(false)")); + DEFINE_TEST_VALUE(engine->evaluate("new Number(123)")); + DEFINE_TEST_VALUE(engine->evaluate("new RegExp('foo', 'gim')")); + DEFINE_TEST_VALUE(engine->evaluate("new String('ciao')")); DEFINE_TEST_VALUE(engine->evaluate("a = new Object(); a.foo = 22; a.foo")); DEFINE_TEST_VALUE(engine->evaluate("Undefined")); DEFINE_TEST_VALUE(engine->evaluate("Null")); @@ -189,6 +194,7 @@ void tst_QScriptValue::initScriptValues() DEFINE_TEST_VALUE(engine->newArray(10)); DEFINE_TEST_VALUE(engine->newDate(QDateTime())); DEFINE_TEST_VALUE(engine->newQMetaObject(&QObject::staticMetaObject)); + DEFINE_TEST_VALUE(engine->newRegExp("foo", "gim")); DEFINE_TEST_VALUE(engine->newVariant(QVariant())); DEFINE_TEST_VALUE(engine->newVariant(QVariant(123))); DEFINE_TEST_VALUE(engine->newVariant(QVariant(false))); diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue_generated_isXXX.cpp b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue_generated_isXXX.cpp index 993a069..caff71f 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue_generated_isXXX.cpp +++ b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue_generated_isXXX.cpp @@ -46,13 +46,13 @@ #include "tst_qscriptvalue.h" -void tst_QScriptValue::isValid_initData() +void tst_QScriptValueGenerated::isValid_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isValid_array [] = { +static QString isValid_array[] = { "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", "QScriptValue(true)", @@ -155,6 +155,11 @@ static QString isValid_array [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -189,24 +194,26 @@ static QString isValid_array [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; + "engine->newQObject(engine)" +}; -void tst_QScriptValue::isValid_makeData(const char* expr) +void tst_QScriptValueGenerated::isValid_makeData(const char* expr) { static QSet<QString> isValid; if (isValid.isEmpty()) { - isValid.reserve(141); - for (unsigned i = 0; i < 141; ++i) + isValid.reserve(147); + for (unsigned i = 0; i < 147; ++i) isValid.insert(isValid_array[i]); } newRow(expr) << isValid.contains(expr); } -void tst_QScriptValue::isValid_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isValid_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isValid(), expected); @@ -216,13 +223,13 @@ void tst_QScriptValue::isValid_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isValid) -void tst_QScriptValue::isBool_initData() +void tst_QScriptValueGenerated::isBool_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isBool_array [] = { +static QString isBool_array[] = { "QScriptValue(true)", "QScriptValue(false)", "QScriptValue(0, true)", @@ -230,9 +237,10 @@ static QString isBool_array [] = { "QScriptValue(engine, true)", "QScriptValue(engine, false)", "engine->evaluate(\"true\")", - "engine->evaluate(\"false\")",}; + "engine->evaluate(\"false\")" +}; -void tst_QScriptValue::isBool_makeData(const char* expr) +void tst_QScriptValueGenerated::isBool_makeData(const char* expr) { static QSet<QString> isBool; if (isBool.isEmpty()) { @@ -243,7 +251,7 @@ void tst_QScriptValue::isBool_makeData(const char* expr) newRow(expr) << isBool.contains(expr); } -void tst_QScriptValue::isBool_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isBool_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isBool(), expected); @@ -253,13 +261,13 @@ void tst_QScriptValue::isBool_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isBool) -void tst_QScriptValue::isBoolean_initData() +void tst_QScriptValueGenerated::isBoolean_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isBoolean_array [] = { +static QString isBoolean_array[] = { "QScriptValue(true)", "QScriptValue(false)", "QScriptValue(0, true)", @@ -267,9 +275,10 @@ static QString isBoolean_array [] = { "QScriptValue(engine, true)", "QScriptValue(engine, false)", "engine->evaluate(\"true\")", - "engine->evaluate(\"false\")",}; + "engine->evaluate(\"false\")" +}; -void tst_QScriptValue::isBoolean_makeData(const char* expr) +void tst_QScriptValueGenerated::isBoolean_makeData(const char* expr) { static QSet<QString> isBoolean; if (isBoolean.isEmpty()) { @@ -280,7 +289,7 @@ void tst_QScriptValue::isBoolean_makeData(const char* expr) newRow(expr) << isBoolean.contains(expr); } -void tst_QScriptValue::isBoolean_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isBoolean_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isBoolean(), expected); @@ -290,13 +299,13 @@ void tst_QScriptValue::isBoolean_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isBoolean) -void tst_QScriptValue::isNumber_initData() +void tst_QScriptValueGenerated::isNumber_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isNumber_array [] = { +static QString isNumber_array[] = { "QScriptValue(int(122))", "QScriptValue(uint(124))", "QScriptValue(0)", @@ -352,9 +361,10 @@ static QString isNumber_array [] = { "engine->evaluate(\"0x10001\")", "engine->evaluate(\"NaN\")", "engine->evaluate(\"Infinity\")", - "engine->evaluate(\"-Infinity\")",}; + "engine->evaluate(\"-Infinity\")" +}; -void tst_QScriptValue::isNumber_makeData(const char* expr) +void tst_QScriptValueGenerated::isNumber_makeData(const char* expr) { static QSet<QString> isNumber; if (isNumber.isEmpty()) { @@ -365,7 +375,7 @@ void tst_QScriptValue::isNumber_makeData(const char* expr) newRow(expr) << isNumber.contains(expr); } -void tst_QScriptValue::isNumber_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isNumber_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isNumber(), expected); @@ -375,13 +385,13 @@ void tst_QScriptValue::isNumber_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isNumber) -void tst_QScriptValue::isFunction_initData() +void tst_QScriptValueGenerated::isFunction_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isFunction_array [] = { +static QString isFunction_array[] = { "engine->evaluate(\"Function.prototype\")", "engine->evaluate(\"Object\")", "engine->evaluate(\"Array\")", @@ -391,20 +401,23 @@ static QString isFunction_array [] = { "engine->evaluate(\"(function() { return 'ciao'; })\")", "engine->evaluate(\"(function() { throw new Error('foo'); })\")", "engine->evaluate(\"/foo/\")", - "engine->newQMetaObject(&QObject::staticMetaObject)",}; + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")" +}; -void tst_QScriptValue::isFunction_makeData(const char* expr) +void tst_QScriptValueGenerated::isFunction_makeData(const char* expr) { static QSet<QString> isFunction; if (isFunction.isEmpty()) { - isFunction.reserve(10); - for (unsigned i = 0; i < 10; ++i) + isFunction.reserve(12); + for (unsigned i = 0; i < 12; ++i) isFunction.insert(isFunction_array[i]); } newRow(expr) << isFunction.contains(expr); } -void tst_QScriptValue::isFunction_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isFunction_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isFunction(), expected); @@ -414,21 +427,22 @@ void tst_QScriptValue::isFunction_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isFunction) -void tst_QScriptValue::isNull_initData() +void tst_QScriptValueGenerated::isNull_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isNull_array [] = { +static QString isNull_array[] = { "QScriptValue(QScriptValue::NullValue)", "QScriptValue(0, QScriptValue::NullValue)", "QScriptValue(engine, QScriptValue::NullValue)", "engine->evaluate(\"null\")", "engine->nullValue()", - "engine->newQObject(0)",}; + "engine->newQObject(0)" +}; -void tst_QScriptValue::isNull_makeData(const char* expr) +void tst_QScriptValueGenerated::isNull_makeData(const char* expr) { static QSet<QString> isNull; if (isNull.isEmpty()) { @@ -439,7 +453,7 @@ void tst_QScriptValue::isNull_makeData(const char* expr) newRow(expr) << isNull.contains(expr); } -void tst_QScriptValue::isNull_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isNull_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isNull(), expected); @@ -449,13 +463,13 @@ void tst_QScriptValue::isNull_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isNull) -void tst_QScriptValue::isString_initData() +void tst_QScriptValueGenerated::isString_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isString_array [] = { +static QString isString_array[] = { "QScriptValue(\"NaN\")", "QScriptValue(\"Infinity\")", "QScriptValue(\"-Infinity\")", @@ -490,9 +504,10 @@ static QString isString_array [] = { "engine->evaluate(\"''\")", "engine->evaluate(\"'0'\")", "engine->evaluate(\"'123'\")", - "engine->evaluate(\"'12.4'\")",}; + "engine->evaluate(\"'12.4'\")" +}; -void tst_QScriptValue::isString_makeData(const char* expr) +void tst_QScriptValueGenerated::isString_makeData(const char* expr) { static QSet<QString> isString; if (isString.isEmpty()) { @@ -503,7 +518,7 @@ void tst_QScriptValue::isString_makeData(const char* expr) newRow(expr) << isString.contains(expr); } -void tst_QScriptValue::isString_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isString_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isString(), expected); @@ -513,21 +528,22 @@ void tst_QScriptValue::isString_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isString) -void tst_QScriptValue::isUndefined_initData() +void tst_QScriptValueGenerated::isUndefined_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isUndefined_array [] = { +static QString isUndefined_array[] = { "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(0, QScriptValue::UndefinedValue)", "QScriptValue(engine, QScriptValue::UndefinedValue)", "engine->evaluate(\"{}\")", "engine->evaluate(\"undefined\")", - "engine->undefinedValue()",}; + "engine->undefinedValue()" +}; -void tst_QScriptValue::isUndefined_makeData(const char* expr) +void tst_QScriptValueGenerated::isUndefined_makeData(const char* expr) { static QSet<QString> isUndefined; if (isUndefined.isEmpty()) { @@ -538,7 +554,7 @@ void tst_QScriptValue::isUndefined_makeData(const char* expr) newRow(expr) << isUndefined.contains(expr); } -void tst_QScriptValue::isUndefined_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isUndefined_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isUndefined(), expected); @@ -548,18 +564,19 @@ void tst_QScriptValue::isUndefined_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isUndefined) -void tst_QScriptValue::isVariant_initData() +void tst_QScriptValueGenerated::isVariant_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isVariant_array [] = { +static QString isVariant_array[] = { "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", - "engine->newVariant(QVariant(false))",}; + "engine->newVariant(QVariant(false))" +}; -void tst_QScriptValue::isVariant_makeData(const char* expr) +void tst_QScriptValueGenerated::isVariant_makeData(const char* expr) { static QSet<QString> isVariant; if (isVariant.isEmpty()) { @@ -570,7 +587,7 @@ void tst_QScriptValue::isVariant_makeData(const char* expr) newRow(expr) << isVariant.contains(expr); } -void tst_QScriptValue::isVariant_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isVariant_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isVariant(), expected); @@ -580,16 +597,17 @@ void tst_QScriptValue::isVariant_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isVariant) -void tst_QScriptValue::isQObject_initData() +void tst_QScriptValueGenerated::isQObject_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isQObject_array [] = { - "engine->newQObject(engine)",}; +static QString isQObject_array[] = { + "engine->newQObject(engine)" +}; -void tst_QScriptValue::isQObject_makeData(const char* expr) +void tst_QScriptValueGenerated::isQObject_makeData(const char* expr) { static QSet<QString> isQObject; if (isQObject.isEmpty()) { @@ -600,7 +618,7 @@ void tst_QScriptValue::isQObject_makeData(const char* expr) newRow(expr) << isQObject.contains(expr); } -void tst_QScriptValue::isQObject_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isQObject_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isQObject(), expected); @@ -610,16 +628,17 @@ void tst_QScriptValue::isQObject_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isQObject) -void tst_QScriptValue::isQMetaObject_initData() +void tst_QScriptValueGenerated::isQMetaObject_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isQMetaObject_array [] = { - "engine->newQMetaObject(&QObject::staticMetaObject)",}; +static QString isQMetaObject_array[] = { + "engine->newQMetaObject(&QObject::staticMetaObject)" +}; -void tst_QScriptValue::isQMetaObject_makeData(const char* expr) +void tst_QScriptValueGenerated::isQMetaObject_makeData(const char* expr) { static QSet<QString> isQMetaObject; if (isQMetaObject.isEmpty()) { @@ -630,7 +649,7 @@ void tst_QScriptValue::isQMetaObject_makeData(const char* expr) newRow(expr) << isQMetaObject.contains(expr); } -void tst_QScriptValue::isQMetaObject_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isQMetaObject_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isQMetaObject(), expected); @@ -640,13 +659,13 @@ void tst_QScriptValue::isQMetaObject_test(const char*, const QScriptValue& value DEFINE_TEST_FUNCTION(isQMetaObject) -void tst_QScriptValue::isObject_initData() +void tst_QScriptValueGenerated::isObject_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isObject_array [] = { +static QString isObject_array[] = { "engine->evaluate(\"[]\")", "engine->evaluate(\"Object.prototype\")", "engine->evaluate(\"Date.prototype\")", @@ -664,6 +683,11 @@ static QString isObject_array [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", "engine->evaluate(\"True\")", @@ -673,23 +697,25 @@ static QString isObject_array [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", - "engine->newQObject(engine)",}; + "engine->newQObject(engine)" +}; -void tst_QScriptValue::isObject_makeData(const char* expr) +void tst_QScriptValueGenerated::isObject_makeData(const char* expr) { static QSet<QString> isObject; if (isObject.isEmpty()) { - isObject.reserve(30); - for (unsigned i = 0; i < 30; ++i) + isObject.reserve(36); + for (unsigned i = 0; i < 36; ++i) isObject.insert(isObject_array[i]); } newRow(expr) << isObject.contains(expr); } -void tst_QScriptValue::isObject_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isObject_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isObject(), expected); @@ -699,17 +725,18 @@ void tst_QScriptValue::isObject_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isObject) -void tst_QScriptValue::isDate_initData() +void tst_QScriptValueGenerated::isDate_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isDate_array [] = { +static QString isDate_array[] = { "engine->evaluate(\"Date.prototype\")", - "engine->newDate(QDateTime())",}; + "engine->newDate(QDateTime())" +}; -void tst_QScriptValue::isDate_makeData(const char* expr) +void tst_QScriptValueGenerated::isDate_makeData(const char* expr) { static QSet<QString> isDate; if (isDate.isEmpty()) { @@ -720,7 +747,7 @@ void tst_QScriptValue::isDate_makeData(const char* expr) newRow(expr) << isDate.contains(expr); } -void tst_QScriptValue::isDate_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isDate_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isDate(), expected); @@ -730,27 +757,30 @@ void tst_QScriptValue::isDate_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isDate) -void tst_QScriptValue::isRegExp_initData() +void tst_QScriptValueGenerated::isRegExp_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isRegExp_array [] = { - "engine->evaluate(\"/foo/\")",}; +static QString isRegExp_array[] = { + "engine->evaluate(\"/foo/\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->newRegExp(\"foo\", \"gim\")" +}; -void tst_QScriptValue::isRegExp_makeData(const char* expr) +void tst_QScriptValueGenerated::isRegExp_makeData(const char* expr) { static QSet<QString> isRegExp; if (isRegExp.isEmpty()) { - isRegExp.reserve(1); - for (unsigned i = 0; i < 1; ++i) + isRegExp.reserve(3); + for (unsigned i = 0; i < 3; ++i) isRegExp.insert(isRegExp_array[i]); } newRow(expr) << isRegExp.contains(expr); } -void tst_QScriptValue::isRegExp_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isRegExp_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isRegExp(), expected); @@ -760,20 +790,21 @@ void tst_QScriptValue::isRegExp_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isRegExp) -void tst_QScriptValue::isArray_initData() +void tst_QScriptValueGenerated::isArray_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isArray_array [] = { +static QString isArray_array[] = { "engine->evaluate(\"[]\")", "engine->evaluate(\"Array.prototype\")", "engine->evaluate(\"new Array()\")", "engine->newArray()", - "engine->newArray(10)",}; + "engine->newArray(10)" +}; -void tst_QScriptValue::isArray_makeData(const char* expr) +void tst_QScriptValueGenerated::isArray_makeData(const char* expr) { static QSet<QString> isArray; if (isArray.isEmpty()) { @@ -784,7 +815,7 @@ void tst_QScriptValue::isArray_makeData(const char* expr) newRow(expr) << isArray.contains(expr); } -void tst_QScriptValue::isArray_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isArray_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isArray(), expected); @@ -794,21 +825,22 @@ void tst_QScriptValue::isArray_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(isArray) -void tst_QScriptValue::isError_initData() +void tst_QScriptValueGenerated::isError_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString isError_array [] = { +static QString isError_array[] = { "engine->evaluate(\"Error.prototype\")", "engine->evaluate(\"new Error()\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", "engine->evaluate(\"True\")", - "engine->evaluate(\"False\")",}; + "engine->evaluate(\"False\")" +}; -void tst_QScriptValue::isError_makeData(const char* expr) +void tst_QScriptValueGenerated::isError_makeData(const char* expr) { static QSet<QString> isError; if (isError.isEmpty()) { @@ -819,7 +851,7 @@ void tst_QScriptValue::isError_makeData(const char* expr) newRow(expr) << isError.contains(expr); } -void tst_QScriptValue::isError_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::isError_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.isError(), expected); diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue_generated_toXXX.cpp b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue_generated_toXXX.cpp index 3228e01..e6c9e6f 100644 --- a/tests/auto/qscriptvalue/tst_qscriptvalue_generated_toXXX.cpp +++ b/tests/auto/qscriptvaluegenerated/tst_qscriptvalue_generated_toXXX.cpp @@ -47,13 +47,13 @@ -void tst_QScriptValue::toString_initData() +void tst_QScriptValueGenerated::toString_initData() { QTest::addColumn<QString>("expected"); initScriptValues(); } -static QString toString_tagArray [] = { +static QString toString_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -157,6 +157,11 @@ static QString toString_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -191,97 +196,101 @@ static QString toString_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; + "engine->newQObject(engine)"}; -static QString toString_valueArray [] = { - "", "undefined", - "null", "true", - "false", "122", - "124", "0", - "0", "123", - "6.37e-8", "-6.37e-8", - "1126240820", "65536", - "65537", "NaN", - "NaN", "Infinity", - "-Infinity", "NaN", - "Infinity", "-Infinity", - "ciao", "ciao", - "", "", - "0", "123", - "12.4", "undefined", - "null", "true", - "false", "122", - "124", "0", - "0", "123", - "6.37e-8", "-6.37e-8", - "1126240820", "65536", - "65537", "NaN", - "NaN", "Infinity", - "-Infinity", "NaN", - "Infinity", "-Infinity", - "ciao", "ciao", - "", "", - "0", "123", - "12.3", "undefined", - "null", "true", - "false", "122", - "124", "0", - "0", "123", - "6.37e-8", "-6.37e-8", - "1126240820", "65536", - "65537", "NaN", - "NaN", "Infinity", - "-Infinity", "NaN", - "Infinity", "-Infinity", - "ciao", "ciao", - "", "", - "0", "123", - "1.23", "", - "undefined", "[object Object]", - "Invalid Date", "", - "function () {\n [native code]\n}", "Error: Unknown error", - "function Object() {\n [native code]\n}", "function Array() {\n [native code]\n}", - "function Number() {\n [native code]\n}", "function Function() {\n [native code]\n}", - "function () { return 1; }", "function () { return 'ciao'; }", - "function () { throw new Error('foo'); }", "/foo/", - "[object Object]", "", - "Error: Unknown error", "22", - "ReferenceError: Can't find variable: Undefined", "ReferenceError: Can't find variable: Null", - "ReferenceError: Can't find variable: True", "ReferenceError: Can't find variable: False", - "undefined", "null", - "true", "false", - "122", "124", - "0", "0", - "123", "6.37e-8", - "-6.37e-8", "1126240820", - "65536", "65537", - "NaN", "Infinity", - "-Infinity", "ciao", - "", "0", - "123", "12.4", - "null", "undefined", - "[object Object]", "", - ",,,,,,,,,", "Invalid Date", - "[object QMetaObject]", "undefined", - "123", "false", - "null", "QScriptEngine(name = \"\")", }; +static QString toString_valueArray[] = { + "", "undefined", + "null", "true", + "false", "122", + "124", "0", + "0", "123", + "6.37e-8", "-6.37e-8", + "1126240820", "65536", + "65537", "NaN", + "NaN", "Infinity", + "-Infinity", "NaN", + "Infinity", "-Infinity", + "ciao", "ciao", + "", "", + "0", "123", + "12.4", "undefined", + "null", "true", + "false", "122", + "124", "0", + "0", "123", + "6.37e-8", "-6.37e-8", + "1126240820", "65536", + "65537", "NaN", + "NaN", "Infinity", + "-Infinity", "NaN", + "Infinity", "-Infinity", + "ciao", "ciao", + "", "", + "0", "123", + "12.3", "undefined", + "null", "true", + "false", "122", + "124", "0", + "0", "123", + "6.37e-8", "-6.37e-8", + "1126240820", "65536", + "65537", "NaN", + "NaN", "Infinity", + "-Infinity", "NaN", + "Infinity", "-Infinity", + "ciao", "ciao", + "", "", + "0", "123", + "1.23", "", + "undefined", "[object Object]", + "Invalid Date", "", + "function () {\n [native code]\n}", "Error: Unknown error", + "function Object() {\n [native code]\n}", "function Array() {\n [native code]\n}", + "function Number() {\n [native code]\n}", "function Function() {\n [native code]\n}", + "function () { return 1; }", "function () { return 'ciao'; }", + "function () { throw new Error('foo'); }", "/foo/", + "[object Object]", "", + "Error: Unknown error", "true", + "false", "123", + "/foo/gim", "ciao", + "22", "ReferenceError: Can't find variable: Undefined", + "ReferenceError: Can't find variable: Null", "ReferenceError: Can't find variable: True", + "ReferenceError: Can't find variable: False", "undefined", + "null", "true", + "false", "122", + "124", "0", + "0", "123", + "6.37e-8", "-6.37e-8", + "1126240820", "65536", + "65537", "NaN", + "Infinity", "-Infinity", + "ciao", "", + "0", "123", + "12.4", "null", + "undefined", "[object Object]", + "", ",,,,,,,,,", + "Invalid Date", "[object QMetaObject]", + "/foo/gim", "undefined", + "123", "false", + "null", "QScriptEngine(name = \"\")"}; -void tst_QScriptValue::toString_makeData(const char* expr) +void tst_QScriptValueGenerated::toString_makeData(const char* expr) { static QHash<QString, QString> toString; if (toString.isEmpty()) { - toString.reserve(142); - for (unsigned i = 0; i < 142; ++i) + toString.reserve(148); + for (unsigned i = 0; i < 148; ++i) toString.insert(toString_tagArray[i], toString_valueArray[i]); } newRow(expr) << toString.value(expr); } -void tst_QScriptValue::toString_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::toString_test(const char*, const QScriptValue& value) { QFETCH(QString, expected); QCOMPARE(value.toString(), expected); @@ -291,13 +300,13 @@ void tst_QScriptValue::toString_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(toString) -void tst_QScriptValue::toNumber_initData() +void tst_QScriptValueGenerated::toNumber_initData() { QTest::addColumn<qsreal>("expected"); initScriptValues(); } -static QString toNumber_tagArray [] = { +static QString toNumber_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -401,6 +410,11 @@ static QString toNumber_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -435,39 +449,40 @@ static QString toNumber_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; -static qsreal toNumber_valueArray [] = { - 0, qQNaN(), 0, 1, 0, 122, 124, 0, 0, 123, - 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), - qInf(), qInf(), qQNaN(), qQNaN(), 0, 0, 0, 123, 12.4, qQNaN(), - 0, 1, 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, - 1126240820, 65536, 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), qInf(), qInf(), - qQNaN(), qQNaN(), 0, 0, 0, 123, 12.3, qQNaN(), 0, 1, - 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, - 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), qInf(), qInf(), qQNaN(), qQNaN(), - 0, 0, 0, 123, 1.23, 0, qQNaN(), qQNaN(), qQNaN(), 0, - qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), - qQNaN(), 0, qQNaN(), 22, qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), 0, - 1, 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, - 65536, 65537, qQNaN(), qInf(), qInf(), qQNaN(), 0, 0, 123, 12.4, - 0, qQNaN(), qQNaN(), 0, qQNaN(), qQNaN(), qQNaN(), qQNaN(), 123, 0, - 0, qQNaN(), }; -void tst_QScriptValue::toNumber_makeData(const char* expr) + "engine->newQObject(engine)"}; +static qsreal toNumber_valueArray[] = { + 0, qQNaN(), 0, 1, 0, 122, 124, 0, 0, 123, + 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), + qInf(), qInf(), qQNaN(), qQNaN(), 0, 0, 0, 123, 12.4, qQNaN(), + 0, 1, 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, + 1126240820, 65536, 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), qInf(), qInf(), + qQNaN(), qQNaN(), 0, 0, 0, 123, 12.3, qQNaN(), 0, 1, + 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, + 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), qInf(), qInf(), qQNaN(), qQNaN(), + 0, 0, 0, 123, 1.23, 0, qQNaN(), qQNaN(), qQNaN(), 0, + qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), + qQNaN(), 0, qQNaN(), 1, 0, 123, qQNaN(), qQNaN(), 22, qQNaN(), + qQNaN(), qQNaN(), qQNaN(), qQNaN(), 0, 1, 0, 122, 124, 0, + 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, 65537, qQNaN(), qInf(), qInf(), + qQNaN(), 0, 0, 123, 12.4, 0, qQNaN(), qQNaN(), 0, qQNaN(), + qQNaN(), qQNaN(), qQNaN(), qQNaN(), 123, 0, 0, qQNaN()}; +void tst_QScriptValueGenerated::toNumber_makeData(const char* expr) { static QHash<QString, qsreal> toNumber; if (toNumber.isEmpty()) { - toNumber.reserve(142); - for (unsigned i = 0; i < 142; ++i) + toNumber.reserve(148); + for (unsigned i = 0; i < 148; ++i) toNumber.insert(toNumber_tagArray[i], toNumber_valueArray[i]); } newRow(expr) << toNumber.value(expr); } -void tst_QScriptValue::toNumber_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::toNumber_test(const char*, const QScriptValue& value) { QFETCH(qsreal, expected); if (qIsNaN(expected)) { @@ -486,13 +501,13 @@ void tst_QScriptValue::toNumber_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(toNumber) -void tst_QScriptValue::toBool_initData() +void tst_QScriptValueGenerated::toBool_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString toBool_tagArray [] = { +static QString toBool_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -596,6 +611,11 @@ static QString toBool_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -630,97 +650,101 @@ static QString toBool_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; + "engine->newQObject(engine)"}; -static bool toBool_valueArray [] = { - false, false, - false, true, - false, true, - true, false, - false, true, - true, true, - true, true, - true, false, - false, true, - true, true, - true, true, - true, true, - false, false, - true, true, - true, false, - false, true, - false, true, - true, false, - false, true, - true, true, - true, true, - true, false, - false, true, - true, true, - true, true, - true, true, - false, false, - true, true, - true, false, - false, true, - false, true, - true, false, - false, true, - true, true, - true, true, - true, false, - false, true, - true, true, - true, true, - true, true, - false, false, - true, true, - true, true, - false, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - false, false, - true, false, - true, true, - false, false, - true, true, - true, true, - true, true, - false, true, - true, true, - false, true, - true, true, - false, false, - true, true, - true, true, - true, true, - true, true, - false, true, }; +static bool toBool_valueArray[] = { + false, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, true, + false, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + true, true, + true, false, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + true, true, + false, true}; -void tst_QScriptValue::toBool_makeData(const char* expr) +void tst_QScriptValueGenerated::toBool_makeData(const char* expr) { static QHash<QString, bool> toBool; if (toBool.isEmpty()) { - toBool.reserve(142); - for (unsigned i = 0; i < 142; ++i) + toBool.reserve(148); + for (unsigned i = 0; i < 148; ++i) toBool.insert(toBool_tagArray[i], toBool_valueArray[i]); } newRow(expr) << toBool.value(expr); } -void tst_QScriptValue::toBool_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::toBool_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.toBool(), expected); @@ -730,13 +754,13 @@ void tst_QScriptValue::toBool_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(toBool) -void tst_QScriptValue::toBoolean_initData() +void tst_QScriptValueGenerated::toBoolean_initData() { QTest::addColumn<bool>("expected"); initScriptValues(); } -static QString toBoolean_tagArray [] = { +static QString toBoolean_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -840,6 +864,11 @@ static QString toBoolean_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -874,97 +903,101 @@ static QString toBoolean_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; + "engine->newQObject(engine)"}; -static bool toBoolean_valueArray [] = { - false, false, - false, true, - false, true, - true, false, - false, true, - true, true, - true, true, - true, false, - false, true, - true, true, - true, true, - true, true, - false, false, - true, true, - true, false, - false, true, - false, true, - true, false, - false, true, - true, true, - true, true, - true, false, - false, true, - true, true, - true, true, - true, true, - false, false, - true, true, - true, false, - false, true, - false, true, - true, false, - false, true, - true, true, - true, true, - true, false, - false, true, - true, true, - true, true, - true, true, - false, false, - true, true, - true, true, - false, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - true, true, - false, false, - true, false, - true, true, - false, false, - true, true, - true, true, - true, true, - false, true, - true, true, - false, true, - true, true, - false, false, - true, true, - true, true, - true, true, - true, true, - false, true, }; +static bool toBoolean_valueArray[] = { + false, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, true, + false, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + true, true, + true, false, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + true, true, + false, true}; -void tst_QScriptValue::toBoolean_makeData(const char* expr) +void tst_QScriptValueGenerated::toBoolean_makeData(const char* expr) { static QHash<QString, bool> toBoolean; if (toBoolean.isEmpty()) { - toBoolean.reserve(142); - for (unsigned i = 0; i < 142; ++i) + toBoolean.reserve(148); + for (unsigned i = 0; i < 148; ++i) toBoolean.insert(toBoolean_tagArray[i], toBoolean_valueArray[i]); } newRow(expr) << toBoolean.value(expr); } -void tst_QScriptValue::toBoolean_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::toBoolean_test(const char*, const QScriptValue& value) { QFETCH(bool, expected); QCOMPARE(value.toBoolean(), expected); @@ -974,13 +1007,13 @@ void tst_QScriptValue::toBoolean_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(toBoolean) -void tst_QScriptValue::toInteger_initData() +void tst_QScriptValueGenerated::toInteger_initData() { QTest::addColumn<qsreal>("expected"); initScriptValues(); } -static QString toInteger_tagArray [] = { +static QString toInteger_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -1084,6 +1117,11 @@ static QString toInteger_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -1118,39 +1156,40 @@ static QString toInteger_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; -static qsreal toInteger_valueArray [] = { - 0, 0, 0, 1, 0, 122, 124, 0, 0, 123, - 0, 0, 1126240820, 65536, 65537, 0, 0, qInf(), qInf(), 0, - qInf(), qInf(), 0, 0, 0, 0, 0, 123, 12, 0, - 0, 1, 0, 122, 124, 0, 0, 123, 0, 0, - 1126240820, 65536, 65537, 0, 0, qInf(), qInf(), 0, qInf(), qInf(), - 0, 0, 0, 0, 0, 123, 12, 0, 0, 1, - 0, 122, 124, 0, 0, 123, 0, 0, 1126240820, 65536, - 65537, 0, 0, qInf(), qInf(), 0, qInf(), qInf(), 0, 0, - 0, 0, 0, 123, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, - 1, 0, 122, 124, 0, 0, 123, 0, 0, 1126240820, - 65536, 65537, 0, qInf(), qInf(), 0, 0, 0, 123, 12, - 0, 0, 0, 0, 0, 0, 0, 0, 123, 0, - 0, 0, }; -void tst_QScriptValue::toInteger_makeData(const char* expr) + "engine->newQObject(engine)"}; +static qsreal toInteger_valueArray[] = { + 0, 0, 0, 1, 0, 122, 124, 0, 0, 123, + 0, 0, 1126240820, 65536, 65537, 0, 0, qInf(), qInf(), 0, + qInf(), qInf(), 0, 0, 0, 0, 0, 123, 12, 0, + 0, 1, 0, 122, 124, 0, 0, 123, 0, 0, + 1126240820, 65536, 65537, 0, 0, qInf(), qInf(), 0, qInf(), qInf(), + 0, 0, 0, 0, 0, 123, 12, 0, 0, 1, + 0, 122, 124, 0, 0, 123, 0, 0, 1126240820, 65536, + 65537, 0, 0, qInf(), qInf(), 0, qInf(), qInf(), 0, 0, + 0, 0, 0, 123, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 123, 0, 0, 22, 0, + 0, 0, 0, 0, 0, 1, 0, 122, 124, 0, + 0, 123, 0, 0, 1126240820, 65536, 65537, 0, qInf(), qInf(), + 0, 0, 0, 123, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 123, 0, 0, 0}; +void tst_QScriptValueGenerated::toInteger_makeData(const char* expr) { static QHash<QString, qsreal> toInteger; if (toInteger.isEmpty()) { - toInteger.reserve(142); - for (unsigned i = 0; i < 142; ++i) + toInteger.reserve(148); + for (unsigned i = 0; i < 148; ++i) toInteger.insert(toInteger_tagArray[i], toInteger_valueArray[i]); } newRow(expr) << toInteger.value(expr); } -void tst_QScriptValue::toInteger_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::toInteger_test(const char*, const QScriptValue& value) { QFETCH(qsreal, expected); if (qIsInf(expected)) { @@ -1165,13 +1204,13 @@ void tst_QScriptValue::toInteger_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(toInteger) -void tst_QScriptValue::toInt32_initData() +void tst_QScriptValueGenerated::toInt32_initData() { QTest::addColumn<qint32>("expected"); initScriptValues(); } -static QString toInt32_tagArray [] = { +static QString toInt32_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -1275,6 +1314,11 @@ static QString toInt32_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -1309,97 +1353,101 @@ static QString toInt32_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; + "engine->newQObject(engine)"}; -static qint32 toInt32_valueArray [] = { - 0, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 1126240820, 65536, - 65537, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 12, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 1126240820, 65536, - 65537, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 12, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 1126240820, 65536, - 65537, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 1, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 22, - 0, 0, - 0, 0, - 0, 0, - 1, 0, - 122, 124, - 0, 0, - 123, 0, - 0, 1126240820, - 65536, 65537, - 0, 0, - 0, 0, - 0, 0, - 123, 12, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 123, 0, - 0, 0, }; +static qint32 toInt32_valueArray[] = { + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 1, + 0, 123, + 0, 0, + 22, 0, + 0, 0, + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 123, 0, + 0, 0}; -void tst_QScriptValue::toInt32_makeData(const char* expr) +void tst_QScriptValueGenerated::toInt32_makeData(const char* expr) { static QHash<QString, qint32> toInt32; if (toInt32.isEmpty()) { - toInt32.reserve(142); - for (unsigned i = 0; i < 142; ++i) + toInt32.reserve(148); + for (unsigned i = 0; i < 148; ++i) toInt32.insert(toInt32_tagArray[i], toInt32_valueArray[i]); } newRow(expr) << toInt32.value(expr); } -void tst_QScriptValue::toInt32_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::toInt32_test(const char*, const QScriptValue& value) { QFETCH(qint32, expected); QCOMPARE(value.toInt32(), expected); @@ -1409,13 +1457,13 @@ void tst_QScriptValue::toInt32_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(toInt32) -void tst_QScriptValue::toUInt32_initData() +void tst_QScriptValueGenerated::toUInt32_initData() { QTest::addColumn<quint32>("expected"); initScriptValues(); } -static QString toUInt32_tagArray [] = { +static QString toUInt32_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -1519,6 +1567,11 @@ static QString toUInt32_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -1553,97 +1606,101 @@ static QString toUInt32_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; + "engine->newQObject(engine)"}; -static quint32 toUInt32_valueArray [] = { - 0, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 1126240820, 65536, - 65537, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 12, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 1126240820, 65536, - 65537, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 12, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 1126240820, 65536, - 65537, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 1, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 22, - 0, 0, - 0, 0, - 0, 0, - 1, 0, - 122, 124, - 0, 0, - 123, 0, - 0, 1126240820, - 65536, 65537, - 0, 0, - 0, 0, - 0, 0, - 123, 12, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 123, 0, - 0, 0, }; +static quint32 toUInt32_valueArray[] = { + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 1, + 0, 123, + 0, 0, + 22, 0, + 0, 0, + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 123, 0, + 0, 0}; -void tst_QScriptValue::toUInt32_makeData(const char* expr) +void tst_QScriptValueGenerated::toUInt32_makeData(const char* expr) { static QHash<QString, quint32> toUInt32; if (toUInt32.isEmpty()) { - toUInt32.reserve(142); - for (unsigned i = 0; i < 142; ++i) + toUInt32.reserve(148); + for (unsigned i = 0; i < 148; ++i) toUInt32.insert(toUInt32_tagArray[i], toUInt32_valueArray[i]); } newRow(expr) << toUInt32.value(expr); } -void tst_QScriptValue::toUInt32_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::toUInt32_test(const char*, const QScriptValue& value) { QFETCH(quint32, expected); QCOMPARE(value.toUInt32(), expected); @@ -1653,13 +1710,13 @@ void tst_QScriptValue::toUInt32_test(const char*, const QScriptValue& value) DEFINE_TEST_FUNCTION(toUInt32) -void tst_QScriptValue::toUInt16_initData() +void tst_QScriptValueGenerated::toUInt16_initData() { QTest::addColumn<quint16>("expected"); initScriptValues(); } -static QString toUInt16_tagArray [] = { +static QString toUInt16_tagArray[] = { "QScriptValue()", "QScriptValue(QScriptValue::UndefinedValue)", "QScriptValue(QScriptValue::NullValue)", @@ -1763,6 +1820,11 @@ static QString toUInt16_tagArray [] = { "engine->evaluate(\"new Object()\")", "engine->evaluate(\"new Array()\")", "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"new Boolean(true)\")", + "engine->evaluate(\"new Boolean(false)\")", + "engine->evaluate(\"new Number(123)\")", + "engine->evaluate(\"new RegExp('foo', 'gim')\")", + "engine->evaluate(\"new String('ciao')\")", "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "engine->evaluate(\"Undefined\")", "engine->evaluate(\"Null\")", @@ -1797,97 +1859,101 @@ static QString toUInt16_tagArray [] = { "engine->newArray(10)", "engine->newDate(QDateTime())", "engine->newQMetaObject(&QObject::staticMetaObject)", + "engine->newRegExp(\"foo\", \"gim\")", "engine->newVariant(QVariant())", "engine->newVariant(QVariant(123))", "engine->newVariant(QVariant(false))", "engine->newQObject(0)", - "engine->newQObject(engine)",}; + "engine->newQObject(engine)"}; -static quint16 toUInt16_valueArray [] = { - 0, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 4660, 0, - 1, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 12, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 4660, 0, - 1, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 12, 0, - 0, 1, - 0, 122, - 124, 0, - 0, 123, - 0, 0, - 4660, 0, - 1, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 123, - 1, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 0, 22, - 0, 0, - 0, 0, - 0, 0, - 1, 0, - 122, 124, - 0, 0, - 123, 0, - 0, 4660, - 0, 1, - 0, 0, - 0, 0, - 0, 0, - 123, 12, - 0, 0, - 0, 0, - 0, 0, - 0, 0, - 123, 0, - 0, 0, }; +static quint16 toUInt16_valueArray[] = { + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 4660, 0, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 4660, 0, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 4660, 0, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 1, + 0, 123, + 0, 0, + 22, 0, + 0, 0, + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 4660, 0, + 1, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 123, 0, + 0, 0}; -void tst_QScriptValue::toUInt16_makeData(const char* expr) +void tst_QScriptValueGenerated::toUInt16_makeData(const char* expr) { static QHash<QString, quint16> toUInt16; if (toUInt16.isEmpty()) { - toUInt16.reserve(142); - for (unsigned i = 0; i < 142; ++i) + toUInt16.reserve(148); + for (unsigned i = 0; i < 148; ++i) toUInt16.insert(toUInt16_tagArray[i], toUInt16_valueArray[i]); } newRow(expr) << toUInt16.value(expr); } -void tst_QScriptValue::toUInt16_test(const char*, const QScriptValue& value) +void tst_QScriptValueGenerated::toUInt16_test(const char*, const QScriptValue& value) { QFETCH(quint16, expected); QCOMPARE(value.toUInt16(), expected); diff --git a/tests/auto/qscriptvalueiterator/tst_qscriptvalueiterator.cpp b/tests/auto/qscriptvalueiterator/tst_qscriptvalueiterator.cpp index a42fc29..fa43c0f 100644 --- a/tests/auto/qscriptvalueiterator/tst_qscriptvalueiterator.cpp +++ b/tests/auto/qscriptvalueiterator/tst_qscriptvalueiterator.cpp @@ -71,6 +71,8 @@ private slots: void iterateString(); void iterateGetterSetter(); void assignObjectToIterator(); + void iterateNonObject(); + void iterateOverObjectFromDeletedEngine(); }; tst_QScriptValueIterator::tst_QScriptValueIterator() @@ -104,7 +106,7 @@ void tst_QScriptValueIterator::iterateForward() QFETCH(QStringList, propertyNames); QFETCH(QStringList, propertyValues); QMap<QString, QString> pmap; - Q_ASSERT(propertyNames.size() == propertyValues.size()); + QVERIFY(propertyNames.size() == propertyValues.size()); QScriptEngine engine; QScriptValue object = engine.newObject(); @@ -163,7 +165,7 @@ void tst_QScriptValueIterator::iterateBackward() QFETCH(QStringList, propertyNames); QFETCH(QStringList, propertyValues); QMap<QString, QString> pmap; - Q_ASSERT(propertyNames.size() == propertyValues.size()); + QVERIFY(propertyNames.size() == propertyValues.size()); QScriptEngine engine; QScriptValue object = engine.newObject(); @@ -210,106 +212,138 @@ void tst_QScriptValueIterator::iterateBackward() void tst_QScriptValueIterator::iterateArray_data() { - QTest::addColumn<QStringList>("inputPropertyNames"); - QTest::addColumn<QStringList>("inputPropertyValues"); QTest::addColumn<QStringList>("propertyNames"); QTest::addColumn<QStringList>("propertyValues"); - QTest::newRow("no elements") << QStringList() << QStringList() << QStringList() << QStringList(); + QTest::newRow("no elements") << QStringList() << QStringList(); QTest::newRow("0=foo, 1=barr") << (QStringList() << "0" << "1") - << (QStringList() << "foo" << "bar") - << (QStringList() << "0" << "1") << (QStringList() << "foo" << "bar"); QTest::newRow("0=foo, 3=barr") << (QStringList() << "0" << "1" << "2" << "3") - << (QStringList() << "foo" << "" << "" << "bar") - << (QStringList() << "0" << "1" << "2" << "3") << (QStringList() << "foo" << "" << "" << "bar"); } void tst_QScriptValueIterator::iterateArray() { - QFETCH(QStringList, inputPropertyNames); - QFETCH(QStringList, inputPropertyValues); QFETCH(QStringList, propertyNames); QFETCH(QStringList, propertyValues); QScriptEngine engine; QScriptValue array = engine.newArray(); - for (int i = 0; i < inputPropertyNames.size(); ++i) { - array.setProperty(inputPropertyNames.at(i), inputPropertyValues.at(i)); + + // Fill the array + for (int i = 0; i < propertyNames.size(); ++i) { + array.setProperty(propertyNames.at(i), propertyValues.at(i)); } + // Iterate thru array properties. Note that the QScriptValueIterator doesn't guarantee + // any order on the iteration! int length = array.property("length").toInt32(); QCOMPARE(length, propertyNames.size()); + + bool iteratedThruLength = false; + QHash<QString, QScriptValue> arrayProperties; QScriptValueIterator it(array); - for (int i = 0; i < length; ++i) { - QCOMPARE(it.hasNext(), true); + + // Iterate forward + while (it.hasNext()) { it.next(); - QCOMPARE(it.name(), propertyNames.at(i)); - QCOMPARE(it.flags(), array.propertyFlags(propertyNames.at(i))); - QVERIFY(it.value().strictlyEquals(array.property(propertyNames.at(i)))); - QCOMPARE(it.value().toString(), propertyValues.at(i)); + + const QString name = it.name(); + if (name == QString::fromLatin1("length")) { + QVERIFY(it.value().isNumber()); + QCOMPARE(it.value().toInt32(), length); + QCOMPARE(it.flags(), QScriptValue::SkipInEnumeration | QScriptValue::Undeletable); + QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration."); + iteratedThruLength = true; + continue; + } + + // Storing the properties we iterate in a hash to compare with test data. + QVERIFY2(!arrayProperties.contains(name), "property appeared more than once during iteration."); + arrayProperties.insert(name, it.value()); + QCOMPARE(it.flags(), array.propertyFlags(name)); + QVERIFY(it.value().strictlyEquals(array.property(name))); } - QVERIFY(it.hasNext()); - it.next(); - QCOMPARE(it.name(), QString::fromLatin1("length")); - QVERIFY(it.value().isNumber()); - QCOMPARE(it.value().toInt32(), length); - QCOMPARE(it.flags(), QScriptValue::SkipInEnumeration | QScriptValue::Undeletable); - it.previous(); - QCOMPARE(it.hasPrevious(), length > 0); - for (int i = length - 1; i >= 0; --i) { - it.previous(); - QCOMPARE(it.name(), propertyNames.at(i)); - QCOMPARE(it.flags(), array.propertyFlags(propertyNames.at(i))); - QVERIFY(it.value().strictlyEquals(array.property(propertyNames.at(i)))); - QCOMPARE(it.value().toString(), propertyValues.at(i)); - QCOMPARE(it.hasPrevious(), i > 0); + // Verify properties + QVERIFY(iteratedThruLength); + QCOMPARE(arrayProperties.size(), propertyNames.size()); + for (int i = 0; i < propertyNames.size(); ++i) { + QVERIFY(arrayProperties.contains(propertyNames.at(i))); + QCOMPARE(arrayProperties.value(propertyNames.at(i)).toString(), propertyValues.at(i)); } - QCOMPARE(it.hasPrevious(), false); - // hasNext() and hasPrevious() cache their result; verify that the result is in sync - if (length > 1) { - QVERIFY(it.hasNext()); - it.next(); - QCOMPARE(it.name(), QString::fromLatin1("0")); - QVERIFY(it.hasNext()); + // Iterate backwards + arrayProperties.clear(); + iteratedThruLength = false; + it.toBack(); + + while (it.hasPrevious()) { it.previous(); - QCOMPARE(it.name(), QString::fromLatin1("0")); - QVERIFY(!it.hasPrevious()); - it.next(); - QCOMPARE(it.name(), QString::fromLatin1("0")); - QVERIFY(it.hasPrevious()); - it.next(); - QCOMPARE(it.name(), QString::fromLatin1("1")); - } - { - // same test as object: - QScriptValue originalArray = engine.newArray(); - for (int i = 0; i < inputPropertyNames.size(); ++i) { - originalArray.setProperty(inputPropertyNames.at(i), inputPropertyValues.at(i)); + + const QString name = it.name(); + if (name == QString::fromLatin1("length")) { + QVERIFY(it.value().isNumber()); + QCOMPARE(it.value().toInt32(), length); + QCOMPARE(it.flags(), QScriptValue::SkipInEnumeration | QScriptValue::Undeletable); + QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration."); + iteratedThruLength = true; + continue; } - QScriptValue array = originalArray.toObject(); - int length = array.property("length").toInt32(); - QCOMPARE(length, propertyNames.size()); - QScriptValueIterator it(array); - for (int i = 0; i < length; ++i) { - QCOMPARE(it.hasNext(), true); - it.next(); - QCOMPARE(it.name(), propertyNames.at(i)); - QCOMPARE(it.flags(), array.propertyFlags(propertyNames.at(i))); - QVERIFY(it.value().strictlyEquals(array.property(propertyNames.at(i)))); - QCOMPARE(it.value().toString(), propertyValues.at(i)); + + // Storing the properties we iterate in a hash to compare with test data. + QVERIFY2(!arrayProperties.contains(name), "property appeared more than once during iteration."); + arrayProperties.insert(name, it.value()); + QCOMPARE(it.flags(), array.propertyFlags(name)); + QVERIFY(it.value().strictlyEquals(array.property(name))); + } + + // Verify properties + QVERIFY(iteratedThruLength); + QCOMPARE(arrayProperties.size(), propertyNames.size()); + for (int i = 0; i < propertyNames.size(); ++i) { + QVERIFY(arrayProperties.contains(propertyNames.at(i))); + QCOMPARE(arrayProperties.value(propertyNames.at(i)).toString(), propertyValues.at(i)); + } + + // ### Do we still need this test? + // Forward test again but as object + arrayProperties.clear(); + iteratedThruLength = false; + QScriptValue arrayObject = engine.toObject(array); + QScriptValueIterator it2(arrayObject); + + while (it2.hasNext()) { + it2.next(); + + const QString name = it2.name(); + if (name == QString::fromLatin1("length")) { + QVERIFY(it2.value().isNumber()); + QCOMPARE(it2.value().toInt32(), length); + QCOMPARE(it2.flags(), QScriptValue::SkipInEnumeration | QScriptValue::Undeletable); + QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration."); + iteratedThruLength = true; + continue; } - QCOMPARE(it.hasNext(), true); - it.next(); - QCOMPARE(it.name(), QString::fromLatin1("length")); + + // Storing the properties we iterate in a hash to compare with test data. + QVERIFY2(!arrayProperties.contains(name), "property appeared more than once during iteration."); + arrayProperties.insert(name, it2.value()); + QCOMPARE(it2.flags(), arrayObject.propertyFlags(name)); + QVERIFY(it2.value().strictlyEquals(arrayObject.property(name))); + } + + // Verify properties + QVERIFY(iteratedThruLength); + QCOMPARE(arrayProperties.size(), propertyNames.size()); + for (int i = 0; i < propertyNames.size(); ++i) { + QVERIFY(arrayProperties.contains(propertyNames.at(i))); + QCOMPARE(arrayProperties.value(propertyNames.at(i)).toString(), propertyValues.at(i)); } } @@ -417,35 +451,59 @@ void tst_QScriptValueIterator::iterateString() QScriptValue str = QScriptValue(&engine, QString::fromLatin1("ciao")); QVERIFY(str.isString()); QScriptValue obj = str.toObject(); + QVERIFY(obj.property("length").isNumber()); int length = obj.property("length").toInt32(); QCOMPARE(length, 4); + QScriptValueIterator it(obj); - for (int i = 0; i < length; ++i) { - QCOMPARE(it.hasNext(), true); - QString indexStr = QScriptValue(&engine, i).toString(); + QHash<QString, QScriptValue> stringProperties; + bool iteratedThruLength = false; + + while (it.hasNext()) { it.next(); - QCOMPARE(it.name(), indexStr); - QCOMPARE(it.flags(), obj.propertyFlags(indexStr)); - QCOMPARE(it.value().strictlyEquals(obj.property(indexStr)), true); + const QString name = it.name(); + + if (name == QString::fromLatin1("length")) { + QVERIFY(it.value().isNumber()); + QCOMPARE(it.value().toInt32(), length); + QCOMPARE(it.flags(), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration | QScriptValue::Undeletable); + QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration."); + iteratedThruLength = true; + continue; + } + + QVERIFY2(!stringProperties.contains(name), "property appeared more than once during iteration."); + stringProperties.insert(name, it.value()); + QCOMPARE(it.flags(), obj.propertyFlags(name)); + QVERIFY(it.value().strictlyEquals(obj.property(name))); } - QVERIFY(it.hasNext()); - it.next(); - QCOMPARE(it.name(), QString::fromLatin1("length")); - QVERIFY(it.value().isNumber()); - QCOMPARE(it.value().toInt32(), length); - QCOMPARE(it.flags(), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration | QScriptValue::Undeletable); - it.previous(); - QCOMPARE(it.hasPrevious(), length > 0); - for (int i = length - 1; i >= 0; --i) { + QVERIFY(iteratedThruLength); + QCOMPARE(stringProperties.size(), length); + + // And going backwards + iteratedThruLength = false; + stringProperties.clear(); + it.toBack(); + + while (it.hasPrevious()) { it.previous(); - QString indexStr = QScriptValue(&engine, i).toString(); - QCOMPARE(it.name(), indexStr); - QCOMPARE(it.flags(), obj.propertyFlags(indexStr)); - QCOMPARE(it.value().strictlyEquals(obj.property(indexStr)), true); - QCOMPARE(it.hasPrevious(), i > 0); + const QString name = it.name(); + + if (name == QString::fromLatin1("length")) { + QVERIFY(it.value().isNumber()); + QCOMPARE(it.value().toInt32(), length); + QCOMPARE(it.flags(), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration | QScriptValue::Undeletable); + QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration."); + iteratedThruLength = true; + continue; + } + + QVERIFY2(!stringProperties.contains(name), "property appeared more than once during iteration."); + stringProperties.insert(name, it.value()); + QCOMPARE(it.flags(), obj.propertyFlags(name)); + QVERIFY(it.value().strictlyEquals(obj.property(name))); } - QCOMPARE(it.hasPrevious(), false); } static QScriptValue myGetterSetter(QScriptContext *ctx, QScriptEngine *) @@ -583,5 +641,70 @@ void tst_QScriptValueIterator::assignObjectToIterator() QCOMPARE(it.name(), QString::fromLatin1("bar")); } +void tst_QScriptValueIterator::iterateNonObject() +{ + QScriptValueIterator it(123); + QVERIFY(!it.hasNext()); + it.next(); + QVERIFY(!it.hasPrevious()); + it.previous(); + it.toFront(); + it.toBack(); + it.name(); + it.scriptName(); + it.flags(); + it.value(); + it.setValue(1); + it.remove(); + QScriptValue num(5); + it = num; + QVERIFY(!it.hasNext()); +} + +void tst_QScriptValueIterator::iterateOverObjectFromDeletedEngine() +{ + QScriptEngine *engine = new QScriptEngine; + QScriptValue objet = engine->newObject(); + + // populate object with properties + QHash<QString, int> properties; + properties.insert("foo",1235); + properties.insert("oof",5321); + properties.insert("ofo",3521); + QHash<QString, int>::const_iterator i = properties.constBegin(); + for(; i != properties.constEnd(); ++i) { + objet.setProperty(i.key(), i.value()); + } + + // start iterating + QScriptValueIterator it(objet); + it.next(); + QVERIFY(properties.contains(it.name())); + + delete engine; + + QVERIFY(!objet.isValid()); + QVERIFY(it.name().isEmpty()); + QVERIFY(!it.value().isValid()); + + QVERIFY(!it.hasNext()); + it.next(); + + QVERIFY(it.name().isEmpty()); + QVERIFY(!it.scriptName().isValid()); + QVERIFY(!it.value().isValid()); + it.setValue("1234567"); + it.remove(); + + QVERIFY(!it.hasPrevious()); + it.previous(); + + QVERIFY(it.name().isEmpty()); + QVERIFY(!it.scriptName().isValid()); + QVERIFY(!it.value().isValid()); + it.setValue("1234567"); + it.remove(); +} + QTEST_MAIN(tst_QScriptValueIterator) #include "tst_qscriptvalueiterator.moc" diff --git a/tests/auto/qsemaphore/qsemaphore.pro b/tests/auto/qsemaphore/qsemaphore.pro index f720c0b..5978215 100644 --- a/tests/auto/qsemaphore/qsemaphore.pro +++ b/tests/auto/qsemaphore/qsemaphore.pro @@ -3,3 +3,4 @@ SOURCES += tst_qsemaphore.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qsemaphore/tst_qsemaphore.cpp b/tests/auto/qsemaphore/tst_qsemaphore.cpp index a638d1d..a2c6bf1 100644 --- a/tests/auto/qsemaphore/tst_qsemaphore.cpp +++ b/tests/auto/qsemaphore/tst_qsemaphore.cpp @@ -244,6 +244,8 @@ void tst_QSemaphore::tryAcquireWithTimeout() QSemaphore semaphore; QTime time; +#define QVERIFYGE(a,b) {int e = a; if (a<b) qDebug() << #a << "=" << e << " !>= " << #b << "=" << b; QVERIFY(e>=b);} +#define QVERIFYLE(a,b) {int e = a; if (b<a) qDebug() << #a << "=" << e << " !<= " << #b << "=" << b; QVERIFY(e<=b);} QCOMPARE(semaphore.available(), 0); @@ -251,69 +253,69 @@ void tst_QSemaphore::tryAcquireWithTimeout() QCOMPARE(semaphore.available(), 1); time.start(); QVERIFY(!semaphore.tryAcquire(2, timeout)); - QVERIFY(time.elapsed() >= timeout); + QVERIFYGE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 1); semaphore.release(); QCOMPARE(semaphore.available(), 2); time.start(); QVERIFY(!semaphore.tryAcquire(3, timeout)); - QVERIFY(time.elapsed() >= timeout); + QVERIFYGE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 2); semaphore.release(10); QCOMPARE(semaphore.available(), 12); time.start(); QVERIFY(!semaphore.tryAcquire(100, timeout)); - QVERIFY(time.elapsed() >= timeout); + QVERIFYGE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 12); semaphore.release(10); QCOMPARE(semaphore.available(), 22); time.start(); QVERIFY(!semaphore.tryAcquire(100, timeout)); - QVERIFY(time.elapsed() >= timeout); + QVERIFYGE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 22); time.start(); QVERIFY(semaphore.tryAcquire(1, timeout)); - QVERIFY(time.elapsed() <= timeout); + QVERIFYLE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 21); time.start(); QVERIFY(semaphore.tryAcquire(1, timeout)); - QVERIFY(time.elapsed() <= timeout); + QVERIFYLE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 20); time.start(); QVERIFY(semaphore.tryAcquire(10, timeout)); - QVERIFY(time.elapsed() <= timeout); + QVERIFYLE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 10); time.start(); QVERIFY(semaphore.tryAcquire(10, timeout)); - QVERIFY(time.elapsed() <= timeout); + QVERIFYLE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 0); // should not be able to acquire more time.start(); QVERIFY(!semaphore.tryAcquire(1, timeout)); - QVERIFY(time.elapsed() >= timeout); + QVERIFYGE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 0); time.start(); QVERIFY(!semaphore.tryAcquire(1, timeout)); - QVERIFY(time.elapsed() >= timeout); + QVERIFYGE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 0); time.start(); QVERIFY(!semaphore.tryAcquire(10, timeout)); - QVERIFY(time.elapsed() >= timeout); + QVERIFYGE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 0); time.start(); QVERIFY(!semaphore.tryAcquire(10, timeout)); - QVERIFY(time.elapsed() >= timeout); + QVERIFYGE(time.elapsed(), timeout); QCOMPARE(semaphore.available(), 0); } diff --git a/tests/auto/qsequentialanimationgroup/qsequentialanimationgroup.pro b/tests/auto/qsequentialanimationgroup/qsequentialanimationgroup.pro index 01ef68a..c0c10c0 100644 --- a/tests/auto/qsequentialanimationgroup/qsequentialanimationgroup.pro +++ b/tests/auto/qsequentialanimationgroup/qsequentialanimationgroup.pro @@ -3,3 +3,4 @@ QT = core SOURCES += tst_qsequentialanimationgroup.cpp +CONFIG += parallel_test diff --git a/tests/auto/qset/qset.pro b/tests/auto/qset/qset.pro index b45a015..ebdf0d6 100644 --- a/tests/auto/qset/qset.pro +++ b/tests/auto/qset/qset.pro @@ -6,3 +6,4 @@ symbian: { TARGET.EPOCSTACKSIZE =0x5000 TARGET.EPOCHEAPSIZE="0x100000 0x1000000" # // Min 1Mb, max 16Mb } +CONFIG += parallel_test diff --git a/tests/auto/qset/tst_qset.cpp b/tests/auto/qset/tst_qset.cpp index 600a6b2..2529241 100644 --- a/tests/auto/qset/tst_qset.cpp +++ b/tests/auto/qset/tst_qset.cpp @@ -66,6 +66,7 @@ public: private slots: void operator_eq(); + void swap(); void size(); void capacity(); void reserve(); @@ -146,6 +147,16 @@ void tst_QSet::operator_eq() } } +void tst_QSet::swap() +{ + QSet<int> s1, s2; + s1.insert(1); + s2.insert(2); + s1.swap(s2); + QCOMPARE(*s1.begin(),2); + QCOMPARE(*s2.begin(),1); +} + void tst_QSet::size() { QSet<int> set; diff --git a/tests/auto/qsettings/qsettings.pro b/tests/auto/qsettings/qsettings.pro index 19513b3..fe104df 100644 --- a/tests/auto/qsettings/qsettings.pro +++ b/tests/auto/qsettings/qsettings.pro @@ -6,3 +6,5 @@ contains(QT_CONFIG, qt3support):QT += qt3support CONFIG -= debug CONFIG += release win32-msvc*:LIBS += advapi32.lib + +CONFIG += parallel_test diff --git a/tests/auto/qsharedpointer/externaltests.cpp b/tests/auto/qsharedpointer/externaltests.cpp index 013fdf2..d551be3 100644 --- a/tests/auto/qsharedpointer/externaltests.cpp +++ b/tests/auto/qsharedpointer/externaltests.cpp @@ -50,6 +50,7 @@ #include <QtCore/QDir> #include <QtCore/QDirIterator> #include <QtCore/QDateTime> +#include <QtCore/QDebug> #ifdef Q_OS_SYMBIAN #define DEFAULT_MAKESPEC "X:/STLsupport/mkspecs/symbian-abld/" @@ -342,7 +343,8 @@ namespace QTest { void QExternalTestPrivate::removeTemporaryDirectory() { - Q_ASSERT(!temporaryDir.isEmpty()); + if (temporaryDir.isEmpty()) + qWarning() << "Temporary directory is expected to be non-empty"; removeRecursive(temporaryDir); temporaryDir.clear(); } @@ -487,7 +489,8 @@ namespace QTest { bool QExternalTestPrivate::createProjectFile() { - Q_ASSERT(!temporaryDir.isEmpty()); + if (temporaryDir.isEmpty()) + qWarning() << "Temporary directory is expected to be non-empty"; QFile projectFile(temporaryDir + QLatin1String("/project.pro")); if (!projectFile.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { @@ -599,7 +602,9 @@ namespace QTest { bool QExternalTestPrivate::runQmake() { - Q_ASSERT(!temporaryDir.isEmpty()); + if (temporaryDir.isEmpty()) + qWarning() << "Temporary directory is expected to be non-empty"; + if (!createProjectFile()) return false; @@ -633,7 +638,8 @@ namespace QTest { bool QExternalTestPrivate::runMake(Target target) { - Q_ASSERT(!temporaryDir.isEmpty()); + if (temporaryDir.isEmpty()) + qWarning() << "Temporary directory is expected to be non-empty"; QExternalProcess make; make.setWorkingDirectory(temporaryDir); diff --git a/tests/auto/qsharedpointer/qsharedpointer.pro b/tests/auto/qsharedpointer/qsharedpointer.pro index bbd31d7..014006e 100644 --- a/tests/auto/qsharedpointer/qsharedpointer.pro +++ b/tests/auto/qsharedpointer/qsharedpointer.pro @@ -12,3 +12,4 @@ QT = core !symbian:DEFINES += SRCDIR=\\\"$$PWD/\\\" include(externaltests.pri) +CONFIG += parallel_test diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 4179c59..27d2d4d 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -139,7 +139,8 @@ public: virtual ~Data() { - Q_ASSERT_X(generation > 0, "tst_QSharedPointer", "Double deletion!"); + if (generation <= 0) + qFatal("tst_qsharedpointer: Double deletion!"); generation = 0; ++destructorCounter; } @@ -283,8 +284,8 @@ void tst_QSharedPointer::operators() QSharedPointer<char> p1; QSharedPointer<char> p2(new char); qptrdiff diff = p2.data() - p1.data(); - Q_ASSERT(p1.data() != p2.data()); - Q_ASSERT(diff != 0); + QVERIFY(p1.data() != p2.data()); + QVERIFY(diff != 0); // operator- QCOMPARE(p2 - p1.data(), diff); @@ -698,7 +699,7 @@ void tst_QSharedPointer::noSharedPointerFromWeakQObject() QSharedPointer<QObject> strong = weak.toStrongRef(); QVERIFY(strong.isNull()); - // is something went wrong, we'll probably crash here + // if something went wrong, we'll probably crash here } void tst_QSharedPointer::weakQObjectFromSharedPointer() @@ -732,7 +733,6 @@ void tst_QSharedPointer::objectCast() ptr = baseptr.objectCast<OtherObject>(); QVERIFY(ptr == data); -#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION // again: ptr = qobject_cast<OtherObject *>(baseptr); QVERIFY(ptr == data); @@ -740,7 +740,6 @@ void tst_QSharedPointer::objectCast() // again: ptr = qobject_cast<QSharedPointer<OtherObject> >(baseptr); QVERIFY(ptr == data); -#endif } check(); @@ -760,7 +759,6 @@ void tst_QSharedPointer::objectCast() ptr = baseptr.objectCast<const OtherObject>(); QVERIFY(ptr == data); -#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION // again: ptr = qobject_cast<const OtherObject *>(baseptr); QVERIFY(ptr == data); @@ -768,7 +766,6 @@ void tst_QSharedPointer::objectCast() // again: ptr = qobject_cast<QSharedPointer<const OtherObject> >(baseptr); QVERIFY(ptr == data); -#endif } check(); @@ -802,7 +799,6 @@ void tst_QSharedPointer::objectCast() QSharedPointer<OtherObject> otherptr = qSharedPointerObjectCast<OtherObject>(weakptr); QVERIFY(otherptr.isNull()); -#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION // again: otherptr = qobject_cast<OtherObject *>(weakptr); QVERIFY(otherptr.isNull()); @@ -810,7 +806,6 @@ void tst_QSharedPointer::objectCast() // again: otherptr = qobject_cast<QSharedPointer<OtherObject> >(weakptr); QVERIFY(otherptr.isNull()); -#endif } check(); } @@ -873,8 +868,8 @@ void tst_QSharedPointer::differentPointers() { DiffPtrDerivedData *aData = new DiffPtrDerivedData; Data *aBase = aData; - Q_ASSERT(aData == aBase); - Q_ASSERT(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); + QVERIFY(aData == aBase); + QVERIFY(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); QSharedPointer<Data> baseptr = QSharedPointer<Data>(aData); QSharedPointer<DiffPtrDerivedData> ptr = qSharedPointerCast<DiffPtrDerivedData>(baseptr); @@ -891,8 +886,8 @@ void tst_QSharedPointer::differentPointers() { DiffPtrDerivedData *aData = new DiffPtrDerivedData; Data *aBase = aData; - Q_ASSERT(aData == aBase); - Q_ASSERT(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); + QVERIFY(aData == aBase); + QVERIFY(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); QSharedPointer<DiffPtrDerivedData> ptr = QSharedPointer<DiffPtrDerivedData>(aData); QSharedPointer<Data> baseptr = ptr; @@ -914,8 +909,8 @@ void tst_QSharedPointer::virtualBaseDifferentPointers() { VirtualDerived *aData = new VirtualDerived; Data *aBase = aData; - Q_ASSERT(aData == aBase); - Q_ASSERT(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); + QVERIFY(aData == aBase); + QVERIFY(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); QSharedPointer<VirtualDerived> ptr = QSharedPointer<VirtualDerived>(aData); QSharedPointer<Data> baseptr = qSharedPointerCast<Data>(ptr); @@ -934,8 +929,8 @@ void tst_QSharedPointer::virtualBaseDifferentPointers() { VirtualDerived *aData = new VirtualDerived; Data *aBase = aData; - Q_ASSERT(aData == aBase); - Q_ASSERT(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); + QVERIFY(aData == aBase); + QVERIFY(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); QSharedPointer<VirtualDerived> ptr = QSharedPointer<VirtualDerived>(aData); QSharedPointer<Data> baseptr = ptr; @@ -1611,7 +1606,7 @@ void hashAndMapTest() QVERIFY(it != c.find(Key())); if (Ordered) { - Q_ASSERT(k0 < k1); + QVERIFY(k0 < k1); it = c.begin(); QCOMPARE(it.key(), k0); @@ -1736,12 +1731,10 @@ void tst_QSharedPointer::invalidConstructs_data() << &QTest::QExternalTest::tryCompileFail << "QSharedPointer<const QObject> baseptr = QSharedPointer<const QObject>(new QObject);\n" "qSharedPointerObjectCast<QCoreApplication>(baseptr);"; -#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION QTest::newRow("const-dropping-object-cast2") << &QTest::QExternalTest::tryCompileFail << "QSharedPointer<const QObject> baseptr = QSharedPointer<const QObject>(new QObject);\n" "qobject_cast<QCoreApplication *>(baseptr);"; -#endif // arithmethics through automatic cast operators QTest::newRow("arithmethic1") @@ -1755,7 +1748,6 @@ void tst_QSharedPointer::invalidConstructs_data() "QSharedPointer<Data> b;\n" "if (a + b) return;"; -#if QT_VERSION >= 0x040600 // two objects with the same pointer QTest::newRow("same-pointer") << &QTest::QExternalTest::tryRunFail @@ -1769,7 +1761,6 @@ void tst_QSharedPointer::invalidConstructs_data() << "Data *aData = new Data;\n" "QSharedPointer<Data> ptr1 = QSharedPointer<Data>(aData);" "ptr1 = QSharedPointer<Data>(aData);"; -#endif // any type of cast for unrelated types: // (we have no reinterpret_cast) diff --git a/tests/auto/qsignalspy/qsignalspy.pro b/tests/auto/qsignalspy/qsignalspy.pro index 4bc4a7b..d3ae63b 100644 --- a/tests/auto/qsignalspy/qsignalspy.pro +++ b/tests/auto/qsignalspy/qsignalspy.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qsignalspy.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qsize/qsize.pro b/tests/auto/qsize/qsize.pro index 14786b8..a1814ac 100644 --- a/tests/auto/qsize/qsize.pro +++ b/tests/auto/qsize/qsize.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qsize.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qsizef/qsizef.pro b/tests/auto/qsizef/qsizef.pro index 703d721..5aa07d7 100644 --- a/tests/auto/qsizef/qsizef.pro +++ b/tests/auto/qsizef/qsizef.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qsizef.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qsocketnotifier/qsocketnotifier.pro b/tests/auto/qsocketnotifier/qsocketnotifier.pro index c43c96a..27484c8 100644 --- a/tests/auto/qsocketnotifier/qsocketnotifier.pro +++ b/tests/auto/qsocketnotifier/qsocketnotifier.pro @@ -4,7 +4,7 @@ QT = core network requires(contains(QT_CONFIG,private_tests)) -include(../qnativesocketengine/qsocketengine.pri) +include(../platformsocketengine/platformsocketengine.pri) symbian: TARGET.CAPABILITY = NetworkServices diff --git a/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp index 27a101a..550cef9 100644 --- a/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp +++ b/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp @@ -46,7 +46,18 @@ #include <QtCore/QSocketNotifier> #include <QtNetwork/QTcpServer> #include <QtNetwork/QTcpSocket> +#ifdef Q_OS_SYMBIAN +#include <private/qsymbiansocketengine_p.h> +#define NATIVESOCKETENGINE QSymbianSocketEngine +#else #include <private/qnativesocketengine_p.h> +#define NATIVESOCKETENGINE QNativeSocketEngine +#endif +#ifdef Q_OS_UNIX +#include <private/qnet_unix_p.h> +#endif +#include <limits> +#include <select.h> class tst_QSocketNotifier : public QObject { @@ -58,6 +69,8 @@ public: private slots: void unexpectedDisconnection(); void mixingWithTimers(); + void posixSockets(); + void bogusFds(); }; tst_QSocketNotifier::tst_QSocketNotifier() @@ -71,10 +84,10 @@ class UnexpectedDisconnectTester : public QObject { Q_OBJECT public: - QNativeSocketEngine *readEnd1, *readEnd2; + NATIVESOCKETENGINE *readEnd1, *readEnd2; int sequence; - UnexpectedDisconnectTester(QNativeSocketEngine *s1, QNativeSocketEngine *s2) + UnexpectedDisconnectTester(NATIVESOCKETENGINE *s1, NATIVESOCKETENGINE *s2) : readEnd1(s1), readEnd2(s2), sequence(0) { QSocketNotifier *notifier1 = @@ -108,6 +121,9 @@ signals: void tst_QSocketNotifier::unexpectedDisconnection() { +#ifdef Q_OS_SYMBIAN + QSKIP("Symbian socket engine pseudo descriptors can't be used for QSocketNotifier", SkipAll); +#else /* Given two sockets and two QSocketNotifiers registered on each their socket. If both sockets receive data, and the first slot @@ -124,7 +140,7 @@ void tst_QSocketNotifier::unexpectedDisconnection() QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost, 0)); - QNativeSocketEngine readEnd1; + NATIVESOCKETENGINE readEnd1; readEnd1.initialize(QAbstractSocket::TcpSocket); bool b = readEnd1.connectToHost(server.serverAddress(), server.serverPort()); QVERIFY(readEnd1.waitForWrite()); @@ -135,7 +151,7 @@ void tst_QSocketNotifier::unexpectedDisconnection() QTcpSocket *writeEnd1 = server.nextPendingConnection(); QVERIFY(writeEnd1 != 0); - QNativeSocketEngine readEnd2; + NATIVESOCKETENGINE readEnd2; readEnd2.initialize(QAbstractSocket::TcpSocket); b = readEnd2.connectToHost(server.serverAddress(), server.serverPort()); QVERIFY(readEnd2.waitForWrite()); @@ -157,10 +173,14 @@ void tst_QSocketNotifier::unexpectedDisconnection() UnexpectedDisconnectTester tester(&readEnd1, &readEnd2); + QTimer timer; + timer.setSingleShot(true); + timer.start(30000); do { // we have to wait until sequence value changes // as any event can make us jump out processing QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); + QVERIFY(timer.isActive); //escape if test would hang } while(tester.sequence <= 0); QVERIFY(readEnd1.state() == QAbstractSocket::ConnectedState); @@ -173,6 +193,7 @@ void tst_QSocketNotifier::unexpectedDisconnection() writeEnd1->close(); writeEnd2->close(); server.close(); +#endif } class MixingWithTimersHelper : public QObject @@ -237,5 +258,99 @@ void tst_QSocketNotifier::mixingWithTimers() QCOMPARE(helper.socketActivated, true); } +void tst_QSocketNotifier::posixSockets() +{ +#ifndef Q_OS_UNIX + QSKIP("test only for posix", SkipAll); +#else + + QTcpServer server; + QVERIFY(server.listen(QHostAddress::LocalHost, 0)); + + int posixSocket = qt_safe_socket(AF_INET, SOCK_STREAM, 0); + sockaddr_in addr; + addr.sin_addr.s_addr = htonl(0x7f000001); + addr.sin_family = AF_INET; + addr.sin_port = htons(server.serverPort()); + qt_safe_connect(posixSocket, (const struct sockaddr*)&addr, sizeof(sockaddr_in)); + QVERIFY(server.waitForNewConnection(5000)); + QScopedPointer<QTcpSocket> passive(server.nextPendingConnection()); + + ::fcntl(posixSocket, F_SETFL, ::fcntl(posixSocket, F_GETFL) | O_NONBLOCK); + + { + QSocketNotifier rn(posixSocket, QSocketNotifier::Read); + connect(&rn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy readSpy(&rn, SIGNAL(activated(int))); + QSocketNotifier wn(posixSocket, QSocketNotifier::Write); + connect(&wn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy writeSpy(&wn, SIGNAL(activated(int))); + QSocketNotifier en(posixSocket, QSocketNotifier::Exception); + connect(&en, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy errorSpy(&en, SIGNAL(activated(int))); + + passive->write("hello",6); + passive->waitForBytesWritten(5000); + + QTestEventLoop::instance().enterLoop(3); + QCOMPARE(readSpy.count(), 1); + QCOMPARE(writeSpy.count(), 0); + QCOMPARE(errorSpy.count(), 0); + + char buffer[100]; + qt_safe_read(posixSocket, buffer, 100); + QCOMPARE(buffer, "hello"); + + qt_safe_write(posixSocket, "goodbye", 8); + + QTestEventLoop::instance().enterLoop(3); + QCOMPARE(readSpy.count(), 1); + QCOMPARE(writeSpy.count(), 1); + QCOMPARE(errorSpy.count(), 0); + QCOMPARE(passive->readAll(), QByteArray("goodbye",8)); + } + qt_safe_close(posixSocket); +#endif +} + +void tst_QSocketNotifier::bogusFds() +{ +#ifndef Q_OS_WIN + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Internal error"); +#endif + QSocketNotifier max(std::numeric_limits<int>::max(), QSocketNotifier::Read); + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Invalid socket specified"); +#ifndef Q_OS_WIN + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Internal error"); +#endif + QSocketNotifier min(std::numeric_limits<int>::min(), QSocketNotifier::Write); +#ifndef Q_OS_WIN + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Internal error"); +#endif + //bogus magic number is the first pseudo socket descriptor from symbian socket engine. + QSocketNotifier bogus(0x40000000, QSocketNotifier::Exception); + QSocketNotifier largestlegal(FD_SETSIZE - 1, QSocketNotifier::Read); + + QSignalSpy maxspy(&max, SIGNAL(activated(int))); + QSignalSpy minspy(&min, SIGNAL(activated(int))); + QSignalSpy bogspy(&bogus, SIGNAL(activated(int))); + QSignalSpy llspy(&largestlegal, SIGNAL(activated(int))); + + //generate some unrelated socket activity + QTcpServer server; + QVERIFY(server.listen(QHostAddress::LocalHost)); + connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTcpSocket client; + client.connectToHost(QHostAddress::LocalHost, server.serverPort()); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(server.hasPendingConnections()); + + //check no activity on bogus notifiers + QCOMPARE(maxspy.count(), 0); + QCOMPARE(minspy.count(), 0); + QCOMPARE(bogspy.count(), 0); + QCOMPARE(llspy.count(), 0); +} + QTEST_MAIN(tst_QSocketNotifier) #include <tst_qsocketnotifier.moc> diff --git a/tests/auto/qsocks5socketengine/qsocks5socketengine.pro b/tests/auto/qsocks5socketengine/qsocks5socketengine.pro index 171d428..c82c62d 100644 --- a/tests/auto/qsocks5socketengine/qsocks5socketengine.pro +++ b/tests/auto/qsocks5socketengine/qsocks5socketengine.pro @@ -2,7 +2,7 @@ load(qttest_p4) SOURCES += tst_qsocks5socketengine.cpp -include(../qnativesocketengine/qsocketengine.pri) +include(../platformsocketengine/platformsocketengine.pri) MOC_DIR=tmp diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 39d60f3..613c611 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -2802,10 +2802,12 @@ void tst_QSortFilterProxyModel::task252507_mapFromToSource() QCOMPARE(proxy.mapFromSource(QModelIndex()), QModelIndex()); QCOMPARE(proxy.mapToSource(QModelIndex()), QModelIndex()); +#ifdef QT_NO_DEBUG //if Qt is compiled in debug mode, this will assert QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapToSource "); QCOMPARE(proxy.mapToSource(source.index(2, 3)), QModelIndex()); QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapFromSource "); QCOMPARE(proxy.mapFromSource(proxy.index(6, 2)), QModelIndex()); +#endif } static QStandardItem *addEntry(QStandardItem* pParent, const QString &description) @@ -3212,7 +3214,6 @@ void tst_QSortFilterProxyModel::filteredColumns() insertCommand->setEndRow(0); // Parent is QModelIndex() insertCommand->doCommand(); - } void tst_QSortFilterProxyModel::taskQTBUG_17812_resetInvalidate_data() diff --git a/tests/auto/qsound/qsound.pro b/tests/auto/qsound/qsound.pro index bb1981c..b69d084 100644 --- a/tests/auto/qsound/qsound.pro +++ b/tests/auto/qsound/qsound.pro @@ -2,8 +2,8 @@ load(qttest_p4) SOURCES += tst_qsound.cpp wince*|symbian: { - deploy.sources += 4.wav - DEPLOYMENT = deploy + deploy.files += 4.wav + DEPLOYMENT += deploy !symbian:DEFINES += SRCDIR=\\\"\\\" } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/auto/qsound/tst_qsound.cpp b/tests/auto/qsound/tst_qsound.cpp index d31ecc4..c12124c 100644 --- a/tests/auto/qsound/tst_qsound.cpp +++ b/tests/auto/qsound/tst_qsound.cpp @@ -63,6 +63,9 @@ private slots: void tst_QSound::checkFinished() { +#if defined(Q_WS_QPA) + QSKIP("QSound is not implemented on Lighthouse", SkipAll); +#else QSound sound(SRCDIR"4.wav"); sound.setLoops(3); sound.play(); @@ -72,15 +75,17 @@ void tst_QSound::checkFinished() QEXPECT_FAIL("", "QSound buggy on embedded (task QTBUG-157)", Abort); #endif QVERIFY(sound.isFinished() ); +#endif } void tst_QSound::staticPlay() { QSKIP("Test disabled -- only for manual purposes", SkipAll); - +#if !defined(Q_WS_QPA) // Check that you hear sound with static play also. QSound::play(SRCDIR"4.wav"); QTest::qWait(2000); +#endif } QTEST_MAIN(tst_QSound); diff --git a/tests/auto/qsplitter/qsplitter.pro b/tests/auto/qsplitter/qsplitter.pro index b11e408..5422fae 100644 --- a/tests/auto/qsplitter/qsplitter.pro +++ b/tests/auto/qsplitter/qsplitter.pro @@ -5,7 +5,7 @@ SOURCES += tst_qsplitter.cpp contains(QT_CONFIG, qt3support): QT += qt3support wince*|symbian: { - addFiles.sources = extradata.txt setSizes3.dat + addFiles.files = extradata.txt setSizes3.dat addFiles.path = . DEPLOYMENT += addFiles !symbian:DEFINES += SRCDIR=\\\"./\\\" diff --git a/tests/auto/qsplitter/tst_qsplitter.cpp b/tests/auto/qsplitter/tst_qsplitter.cpp index a72973d..473018d 100644 --- a/tests/auto/qsplitter/tst_qsplitter.cpp +++ b/tests/auto/qsplitter/tst_qsplitter.cpp @@ -1340,14 +1340,14 @@ void tst_QSplitter::task187373_addAbstractScrollAreas() QFETCH(QString, className); QFETCH(bool, addInConstructor); QFETCH(bool, addOutsideConstructor); - Q_ASSERT(addInConstructor || addOutsideConstructor); + QVERIFY(addInConstructor || addOutsideConstructor); QSplitter *splitter = new QSplitter; splitter->show(); - Q_ASSERT(splitter->isVisible()); + QVERIFY(splitter->isVisible()); QAbstractScrollArea *w = task187373_createScrollArea(splitter, className, addInConstructor); - Q_ASSERT(w); + QVERIFY(w); if (addOutsideConstructor) splitter->addWidget(w); diff --git a/tests/auto/qsql/qsql.pro b/tests/auto/qsql/qsql.pro index 0ec581d..9bf30f8 100644 --- a/tests/auto/qsql/qsql.pro +++ b/tests/auto/qsql/qsql.pro @@ -13,7 +13,7 @@ symbian { qt_not_deployed { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { sqlite.path = /sys/bin - sqlite.sources = sqlite3.dll + sqlite.files = sqlite3.dll DEPLOYMENT += sqlite } } diff --git a/tests/auto/qsqldatabase/qsqldatabase.pro b/tests/auto/qsqldatabase/qsqldatabase.pro index 6381219..066c24f 100644 --- a/tests/auto/qsqldatabase/qsqldatabase.pro +++ b/tests/auto/qsqldatabase/qsqldatabase.pro @@ -13,7 +13,7 @@ win32: { wince*: { DEPLOYMENT_PLUGIN += qsqlite - testData.sources = testdata + testData.files = testdata testData.path = . DEPLOYMENT += testData @@ -26,7 +26,7 @@ symbian { qt_not_deployed { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { sqlite.path = /sys/bin - sqlite.sources = sqlite3.dll + sqlite.files = sqlite3.dll DEPLOYMENT += sqlite } } diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index e6a9337..91fd5a1 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -767,7 +767,7 @@ void tst_QSqlDatabase::checkValues(const FieldDef fieldDefs[], QSqlDatabase db) Q3SqlCursor cur(qTableName("qtestfields", __FILE__), true, db); QVERIFY_SQL(cur, select()); QSqlRecord* rec = cur.primeInsert(); - Q_ASSERT(rec); + QVERIFY(rec); rec->setValue("id", pkey++); int i = 0; for (i = 0; !fieldDefs[ i ].typeName.isNull(); ++i) { @@ -828,7 +828,7 @@ void tst_QSqlDatabase::checkNullValues(const FieldDef fieldDefs[], QSqlDatabase Q3SqlCursor cur(qTableName("qtestfields", __FILE__), true, db); QVERIFY_SQL(cur, select()); QSqlRecord* rec = cur.primeInsert(); - Q_ASSERT(rec); + QVERIFY(rec); rec->setValue("id", pkey++); int i = 0; for (i = 0; !fieldDefs[ i ].typeName.isNull(); ++i) { diff --git a/tests/auto/qsqldriver/qsqldriver.pro b/tests/auto/qsqldriver/qsqldriver.pro index 2e9ed67..c02d74a 100644 --- a/tests/auto/qsqldriver/qsqldriver.pro +++ b/tests/auto/qsqldriver/qsqldriver.pro @@ -4,7 +4,7 @@ SOURCES += tst_qsqldriver.cpp QT += sql wince*: { - plugFiles.sources = ../../../plugins/sqldrivers + plugFiles.files = ../../../plugins/sqldrivers plugFiles.path = . DEPLOYMENT += plugFiles LIBS += -lws2 @@ -20,7 +20,7 @@ symbian { qt_not_deployed { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { sqlite.path = /sys/bin - sqlite.sources = sqlite3.dll + sqlite.files = sqlite3.dll DEPLOYMENT += sqlite } } diff --git a/tests/auto/qsqlerror/qsqlerror.pro b/tests/auto/qsqlerror/qsqlerror.pro index 456f585..ebf6d24 100644 --- a/tests/auto/qsqlerror/qsqlerror.pro +++ b/tests/auto/qsqlerror/qsqlerror.pro @@ -11,7 +11,7 @@ symbian { qt_not_deployed { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { sqlite.path = /sys/bin - sqlite.sources = sqlite3.dll + sqlite.files = sqlite3.dll DEPLOYMENT += sqlite } } diff --git a/tests/auto/qsqlfield/qsqlfield.pro b/tests/auto/qsqlfield/qsqlfield.pro index 7339854..2359151 100644 --- a/tests/auto/qsqlfield/qsqlfield.pro +++ b/tests/auto/qsqlfield/qsqlfield.pro @@ -7,7 +7,7 @@ symbian { qt_not_deployed { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { sqlite.path = /sys/bin - sqlite.sources = sqlite3.dll + sqlite.files = sqlite3.dll DEPLOYMENT += sqlite } } diff --git a/tests/auto/qsqlquery/qsqlquery.pro b/tests/auto/qsqlquery/qsqlquery.pro index 97646ed..fbcc998 100644 --- a/tests/auto/qsqlquery/qsqlquery.pro +++ b/tests/auto/qsqlquery/qsqlquery.pro @@ -8,7 +8,7 @@ QT = core sql wince*: { - plugFiles.sources = ../../../plugins/sqldrivers + plugFiles.files = ../../../plugins/sqldrivers plugFiles.path = . DEPLOYMENT += plugFiles LIBS += -lws2 @@ -18,7 +18,7 @@ symbian { qt_not_deployed { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { sqlite.path = /sys/bin - sqlite.sources = sqlite3.dll + sqlite.files = sqlite3.dll DEPLOYMENT += sqlite } } diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 3928678..592b49a 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -928,13 +928,12 @@ void tst_QSqlQuery::record() QSqlQuery q( db ); QVERIFY( q.record().isEmpty() ); QVERIFY_SQL( q, exec( "select id, t_varchar, t_char from " + qtest + " order by id" ) ); - QSqlRecord rec = q.record(); QCOMPARE( q.record().fieldName( 0 ).toLower(), QString( "id" ) ); QCOMPARE( q.record().fieldName( 1 ).toLower(), QString( "t_varchar" ) ); QCOMPARE( q.record().fieldName( 2 ).toLower(), QString( "t_char" ) ); - QVERIFY( !q.record().value( 0 ).isValid() ); - QVERIFY( !q.record().value( 1 ).isValid() ); - QVERIFY( !q.record().value( 2 ).isValid() ); + QCOMPARE(q.record().value(0), QVariant(q.record().field(0).type())); + QCOMPARE(q.record().value(1), QVariant(q.record().field(1).type())); + QCOMPARE(q.record().value(2), QVariant(q.record().field(2).type())); QVERIFY( q.next() ); QVERIFY( q.next() ); diff --git a/tests/auto/qsqlquerymodel/qsqlquerymodel.pro b/tests/auto/qsqlquerymodel/qsqlquerymodel.pro index cda8cab..4b23e94 100644 --- a/tests/auto/qsqlquerymodel/qsqlquerymodel.pro +++ b/tests/auto/qsqlquerymodel/qsqlquerymodel.pro @@ -10,7 +10,7 @@ wince*: { qt_not_deployed { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { sqlite.path = /sys/bin - sqlite.sources = sqlite3.dll + sqlite.files = sqlite3.dll DEPLOYMENT += sqlite } } diff --git a/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp b/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp index 1bd640f..073f3da 100644 --- a/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp +++ b/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp @@ -428,9 +428,9 @@ void tst_QSqlQueryModel::record() QCOMPARE(rec.fieldName(0), isToUpper ? QString("ID") : QString("id")); QCOMPARE(rec.fieldName(1), isToUpper ? QString("NAME") : QString("name")); QCOMPARE(rec.fieldName(2), isToUpper ? QString("TITLE") : QString("title")); - QCOMPARE(rec.value(0), QVariant()); - QCOMPARE(rec.value(1), QVariant()); - QCOMPARE(rec.value(2), QVariant()); + QCOMPARE(rec.value(0), QVariant(rec.field(0).type())); + QCOMPARE(rec.value(1), QVariant(rec.field(1).type())); + QCOMPARE(rec.value(2), QVariant(rec.field(2).type())); rec = model.record(0); QCOMPARE(rec.fieldName(0), isToUpper ? QString("ID") : QString("id")); diff --git a/tests/auto/qsqlrecord/qsqlrecord.pro b/tests/auto/qsqlrecord/qsqlrecord.pro index f36f076..16e3ae4 100644 --- a/tests/auto/qsqlrecord/qsqlrecord.pro +++ b/tests/auto/qsqlrecord/qsqlrecord.pro @@ -5,7 +5,7 @@ symbian { qt_not_deployed { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { sqlite.path = /sys/bin - sqlite.sources = sqlite3.dll + sqlite.files = sqlite3.dll DEPLOYMENT += sqlite } } diff --git a/tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro b/tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro index c6681d5..dad42d5 100644 --- a/tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro +++ b/tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro @@ -4,7 +4,7 @@ SOURCES += tst_qsqlrelationaltablemodel.cpp QT += sql wince*: { - plugFiles.sources = ../../../plugins/sqldrivers + plugFiles.files = ../../../plugins/sqldrivers plugFiles.path = . DEPLOYMENT += plugFiles LIBS += -lws2 @@ -12,7 +12,7 @@ wince*: { qt_not_deployed { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { sqlite.path = /sys/bin - sqlite.sources = sqlite3.dll + sqlite.files = sqlite3.dll DEPLOYMENT += sqlite } } diff --git a/tests/auto/qsqltablemodel/qsqltablemodel.pro b/tests/auto/qsqltablemodel/qsqltablemodel.pro index 9a23237..e49020f 100644 --- a/tests/auto/qsqltablemodel/qsqltablemodel.pro +++ b/tests/auto/qsqltablemodel/qsqltablemodel.pro @@ -4,7 +4,7 @@ SOURCES += tst_qsqltablemodel.cpp QT += sql wince*: { - plugFiles.sources = ../../../plugins/sqldrivers + plugFiles.files = ../../../plugins/sqldrivers plugFiles.path = . DEPLOYMENT += plugFiles LIBS += -lws2 @@ -12,7 +12,7 @@ wince*: { qt_not_deployed { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { sqlite.path = /sys/bin - sqlite.sources = sqlite3.dll + sqlite.files = sqlite3.dll DEPLOYMENT += sqlite } } diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp index 60bc96f..0700e9d 100644 --- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp @@ -569,9 +569,9 @@ void tst_QSqlTableModel::insertMultiRecords() QVERIFY(model.insertRow(2)); - QCOMPARE(model.data(model.index(2, 0)), QVariant()); - QCOMPARE(model.data(model.index(2, 1)), QVariant()); - QCOMPARE(model.data(model.index(2, 2)), QVariant()); + QCOMPARE(model.data(model.index(2, 0)), QVariant(model.record().field(0).type())); + QCOMPARE(model.data(model.index(2, 1)), QVariant(model.record().field(1).type())); + QCOMPARE(model.data(model.index(2, 2)), QVariant(model.record().field(2).type())); QVERIFY(model.insertRow(3)); QVERIFY(model.insertRow(0)); diff --git a/tests/auto/qsqlthread/qsqlthread.pro b/tests/auto/qsqlthread/qsqlthread.pro index 5522232..2e4c72a 100644 --- a/tests/auto/qsqlthread/qsqlthread.pro +++ b/tests/auto/qsqlthread/qsqlthread.pro @@ -5,7 +5,7 @@ QT = core sql wince*: { - plugFiles.sources = ../../../plugins/sqldrivers + plugFiles.files = ../../../plugins/sqldrivers plugFiles.path = . DEPLOYMENT += plugFiles LIBS += -lws2 @@ -13,7 +13,7 @@ wince*: { qt_not_deployed { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { sqlite.path = /sys/bin - sqlite.sources = sqlite3.dll + sqlite.files = sqlite3.dll DEPLOYMENT += sqlite } } diff --git a/tests/auto/qsslcertificate/certificates/cert-ss-san-utf8.pem b/tests/auto/qsslcertificate/certificates/cert-ss-san-utf8.pem new file mode 100644 index 0000000..e1b731d --- /dev/null +++ b/tests/auto/qsslcertificate/certificates/cert-ss-san-utf8.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICkTCCAfqgAwIBAgIJAL1nF+PLAF2KMA0GCSqGSIb3DQEBBQUAMGkxKzApBgNV +BAoMIkjElcSCxrLDvyDKjeG6v8qI4bq34bi7IFLDqWPDtnJkxZ0xFTATBgNVBAsM +DOOIp0HjiYHvvatCQzEWMBQGA1UEAwwNSm9obm55IEd1aXRhcjELMAkGA1UEBhMC +Tk8wHhcNMTEwNTA1MDgxMzEwWhcNMTEwNjA0MDgxMzEwWjBpMSswKQYDVQQKDCJI +xJXEgsayw78gyo3hur/KiOG6t+G4uyBSw6ljw7ZyZMWdMRUwEwYDVQQLDAzjiKdB +44mB772rQkMxFjAUBgNVBAMMDUpvaG5ueSBHdWl0YXIxCzAJBgNVBAYTAk5PMIGf +MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2zSxS17I6596dJE/VAmGz+06D9S8n +3C0hnIGNVu+LwbgDJTvOw0SzNj4UP72UGgd3UI1KLBg5XWIsRNmE3COJMMh6syjI +L1Ept+tVXxGL6n4gl+0nZ7dkUyxJmeFtigYrL+qCH1yd5rmf3sC3jO4IosuAiG66 +IDkJEVo64NT8ZQIDAQABo0EwPzA9BgNVHREENjA0gQ9hcm5lQGZvb2Jhci5vcmeC +Dnd3dy5mb29iYXIub3JngRFiamFybmVAZm9vYmFyLm9yZzANBgkqhkiG9w0BAQUF +AAOBgQAqVhbC0/EUFdnKlYV3PrknwGX1dPEPGJuIQHa0KpoicvNiOhs1HxBDYbzc +F6wcAMEynq4YwGKhcQLZOs2mo0LreAjA9rU/yBnqrnUW/4gxtUUvmJKK+62IjfLp +eO1L+1NcEMJiaZf8fip4VXhXdOYUhgE8WUZ1UJRC6w3T/yAgcQ== +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/certificates/cert-ss-san-utf8.pem.san b/tests/auto/qsslcertificate/certificates/cert-ss-san-utf8.pem.san new file mode 100644 index 0000000..f46a637 --- /dev/null +++ b/tests/auto/qsslcertificate/certificates/cert-ss-san-utf8.pem.san @@ -0,0 +1,5 @@ +[subj_alt_name] +subjectAltName=\ + email:arne@foobar.org,\ + DNS:www.foobar.org,\ + email:bjarne@foobar.org diff --git a/tests/auto/qsslcertificate/certificates/gencertificates.sh b/tests/auto/qsslcertificate/certificates/gencertificates.sh index 9f873d9..0bac191 100755 --- a/tests/auto/qsslcertificate/certificates/gencertificates.sh +++ b/tests/auto/qsslcertificate/certificates/gencertificates.sh @@ -90,5 +90,15 @@ openssl req -x509 -in req-san.pem -out $outname -key rsa-pri-1024.pem \ -config san.cnf -extensions subj_alt_name /bin/cp san.cnf $outname.san +#--- Non-ASCII Subject --------------------------------------------------------------------- +echo -e "\n generating self signed root cert. with Subject containing UTF-8 characters ..." +outname=cert-ss-san-utf8.pem +#subject="/O=HĕĂƲÿ Êếʈặḻ RécördÅ/OU=㈧Aã‰ï½«BC/CN=Johnny Guitar/C=NO" +subject=$'/O=H\xc4\x95\xc4\x82\xc6\xb2\xc3\xbf \xca\x8d\xe1\xba\xbf\xca\x88\xe1\xba\xb7\xe1\xb8\xbb R\xc3\xa9c\xc3\xb6rd\xc5\x9d/OU=\xe3\x88\xa7A\xe3\x89\x81\xef\xbd\xabBC/CN=Johnny Guitar/C=NO' +openssl req -out req-san.pem -new -key rsa-pri-1024.pem -utf8 -subj "$subject" +openssl req -x509 -in req-san.pem -out $outname -key rsa-pri-1024.pem \ + -config san.cnf -extensions subj_alt_name -nameopt multiline,utf8,-esc_msb +/bin/cp san.cnf $outname.san + echo -e "\n cleaning up ..." /bin/rm rsa-pri-1024.pem rsa-pub-1024.* req*.pem diff --git a/tests/auto/qsslcertificate/qsslcertificate.pro b/tests/auto/qsslcertificate/qsslcertificate.pro index b04dde3..05cce8e 100644 --- a/tests/auto/qsslcertificate/qsslcertificate.pro +++ b/tests/auto/qsslcertificate/qsslcertificate.pro @@ -15,7 +15,7 @@ win32 { } wince*|symbian: { - certFiles.sources = certificates more-certificates + certFiles.files = certificates more-certificates certFiles.path = . DEPLOYMENT += certFiles } diff --git a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp index c38147d..9276685 100644 --- a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp @@ -96,6 +96,7 @@ private slots: void digest_data(); void digest(); void alternateSubjectNames_data(); + void utf8SubjectNames(); void alternateSubjectNames(); void publicKey_data(); void publicKey(); @@ -407,6 +408,27 @@ void tst_QSslCertificate::alternateSubjectNames() } } +void tst_QSslCertificate::utf8SubjectNames() +{ + QSslCertificate cert = QSslCertificate::fromPath("certificates/cert-ss-san-utf8.pem", QSsl::Pem, + QRegExp::FixedString).first(); + QVERIFY(!cert.isNull()); + + // O is "Heavy Metal Records" with heavy use of "decorations" like accents, umlauts etc., + // OU uses arabian / asian script letters near codepoint 64K. + // strings split where the compiler would otherwise find three-digit hex numbers + static const char *o = "H\xc4\x95\xc4\x82\xc6\xb2\xc3\xbf \xca\x8d\xe1\xba\xbf\xca\x88\xe1\xba" + "\xb7\xe1\xb8\xbb R\xc3\xa9" "c" "\xc3\xb6rd\xc5\x9d"; + static const char *ou = "\xe3\x88\xa7" "A" "\xe3\x89\x81\xef\xbd\xab" "BC"; + + // the following two tests should help find "\x"-literal encoding bugs in the test itself + QCOMPARE(cert.subjectInfo("O").length(), QString::fromUtf8(o).length()); + QCOMPARE (cert.subjectInfo("O").toUtf8().toHex(), QByteArray(o).toHex()); + + QCOMPARE(cert.subjectInfo("O"), QString::fromUtf8(o)); + QCOMPARE(cert.subjectInfo("OU"), QString::fromUtf8(ou)); +} + void tst_QSslCertificate::publicKey_data() { QTest::addColumn<QString>("certFilePath"); @@ -519,13 +541,13 @@ void tst_QSslCertificate::fromPath_data() QTest::newRow("\"certificates/*\" fixed der") << QString("certificates/*") << int(QRegExp::FixedString) << false << 0; QTest::newRow("\"certificates/*\" regexp pem") << QString("certificates/*") << int(QRegExp::RegExp) << true << 0; QTest::newRow("\"certificates/*\" regexp der") << QString("certificates/*") << int(QRegExp::RegExp) << false << 0; - QTest::newRow("\"certificates/*\" wildcard pem") << QString("certificates/*") << int(QRegExp::Wildcard) << true << 4; + QTest::newRow("\"certificates/*\" wildcard pem") << QString("certificates/*") << int(QRegExp::Wildcard) << true << 5; QTest::newRow("\"certificates/*\" wildcard der") << QString("certificates/*") << int(QRegExp::Wildcard) << false << 0; QTest::newRow("\"c*/c*.pem\" fixed pem") << QString("c*/c*.pem") << int(QRegExp::FixedString) << true << 0; QTest::newRow("\"c*/c*.pem\" fixed der") << QString("c*/c*.pem") << int(QRegExp::FixedString) << false << 0; QTest::newRow("\"c*/c*.pem\" regexp pem") << QString("c*/c*.pem") << int(QRegExp::RegExp) << true << 0; QTest::newRow("\"c*/c*.pem\" regexp der") << QString("c*/c*.pem") << int(QRegExp::RegExp) << false << 0; - QTest::newRow("\"c*/c*.pem\" wildcard pem") << QString("c*/c*.pem") << int(QRegExp::Wildcard) << true << 4; + QTest::newRow("\"c*/c*.pem\" wildcard pem") << QString("c*/c*.pem") << int(QRegExp::Wildcard) << true << 5; QTest::newRow("\"c*/c*.pem\" wildcard der") << QString("c*/c*.pem") << int(QRegExp::Wildcard) << false << 0; QTest::newRow("\"d*/c*.pem\" fixed pem") << QString("d*/c*.pem") << int(QRegExp::FixedString) << true << 0; QTest::newRow("\"d*/c*.pem\" fixed der") << QString("d*/c*.pem") << int(QRegExp::FixedString) << false << 0; @@ -535,7 +557,7 @@ void tst_QSslCertificate::fromPath_data() QTest::newRow("\"d*/c*.pem\" wildcard der") << QString("d*/c*.pem") << int(QRegExp::Wildcard) << false << 0; QTest::newRow("\"c.*/c.*.pem\" fixed pem") << QString("c.*/c.*.pem") << int(QRegExp::FixedString) << true << 0; QTest::newRow("\"c.*/c.*.pem\" fixed der") << QString("c.*/c.*.pem") << int(QRegExp::FixedString) << false << 0; - QTest::newRow("\"c.*/c.*.pem\" regexp pem") << QString("c.*/c.*.pem") << int(QRegExp::RegExp) << true << 4; + QTest::newRow("\"c.*/c.*.pem\" regexp pem") << QString("c.*/c.*.pem") << int(QRegExp::RegExp) << true << 5; QTest::newRow("\"c.*/c.*.pem\" regexp der") << QString("c.*/c.*.pem") << int(QRegExp::RegExp) << false << 0; QTest::newRow("\"c.*/c.*.pem\" wildcard pem") << QString("c.*/c.*.pem") << int(QRegExp::Wildcard) << true << 0; QTest::newRow("\"c.*/c.*.pem\" wildcard der") << QString("c.*/c.*.pem") << int(QRegExp::Wildcard) << false << 0; @@ -546,7 +568,7 @@ void tst_QSslCertificate::fromPath_data() QTest::newRow("\"d.*/c.*.pem\" wildcard pem") << QString("d.*/c.*.pem") << int(QRegExp::Wildcard) << true << 0; QTest::newRow("\"d.*/c.*.pem\" wildcard der") << QString("d.*/c.*.pem") << int(QRegExp::Wildcard) << false << 0; #ifdef Q_OS_LINUX - QTest::newRow("absolute path wildcard pem") << QString(QDir::currentPath() + "/certificates/*.pem") << int(QRegExp::Wildcard) << true << 4; + QTest::newRow("absolute path wildcard pem") << QString(QDir::currentPath() + "/certificates/*.pem") << int(QRegExp::Wildcard) << true << 5; #endif QTest::newRow("trailing-whitespace") << QString("more-certificates/trailing-whitespace.pem") << int(QRegExp::FixedString) << true << 1; @@ -769,7 +791,7 @@ void tst_QSslCertificate::nulInCN() QString cn = cert.subjectInfo(QSslCertificate::CommonName); QVERIFY(cn != "www.bank.com"); - static const char realCN[] = "www.bank.com\\x00.badguy.com"; + static const char realCN[] = "www.bank.com\0.badguy.com"; QCOMPARE(cn, QString::fromLatin1(realCN, sizeof realCN - 1)); } diff --git a/tests/auto/qsslkey/qsslkey.pro b/tests/auto/qsslkey/qsslkey.pro index dff0db1..5a90b76 100644 --- a/tests/auto/qsslkey/qsslkey.pro +++ b/tests/auto/qsslkey/qsslkey.pro @@ -15,10 +15,10 @@ win32 { } wince*|symbian: { - keyFiles.sources = keys + keyFiles.files = keys keyFiles.path = . - passphraseFiles.sources = rsa-without-passphrase.pem rsa-with-passphrase.pem + passphraseFiles.files = rsa-without-passphrase.pem rsa-with-passphrase.pem passphraseFiles.path = . DEPLOYMENT += keyFiles passphraseFiles diff --git a/tests/auto/qsslkey/tst_qsslkey.cpp b/tests/auto/qsslkey/tst_qsslkey.cpp index 7faed3c..ac966ce 100644 --- a/tests/auto/qsslkey/tst_qsslkey.cpp +++ b/tests/auto/qsslkey/tst_qsslkey.cpp @@ -108,10 +108,8 @@ tst_QSslKey::tst_QSslKey() #ifdef Q_WS_MAC // applicationDirPath() points to a path inside the app bundle on Mac. QDir dir(qApp->applicationDirPath() + QLatin1String("/../../../keys")); -#elif defined(Q_OS_WIN) || defined (Q_OS_SYMBIAN) - QDir dir(SRCDIR + QLatin1String("/keys")); // prefer this way to avoid ifdeffery and support shadow builds? #else - QDir dir(qApp->applicationDirPath() + QLatin1String("/keys")); + QDir dir(SRCDIR + QLatin1String("/keys")); // prefer this way to avoid ifdeffery and support shadow builds? #endif QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable); QRegExp rx(QLatin1String("^(rsa|dsa)-(pub|pri)-(\\d+)\\.(pem|der)$")); diff --git a/tests/auto/qsslsocket/qsslsocket.pro b/tests/auto/qsslsocket/qsslsocket.pro index accfa89..77517e0 100644 --- a/tests/auto/qsslsocket/qsslsocket.pro +++ b/tests/auto/qsslsocket/qsslsocket.pro @@ -18,15 +18,15 @@ win32 { wince* { DEFINES += SRCDIR=\\\"./\\\" - certFiles.sources = certs ssl.tar.gz + certFiles.files = certs ssl.tar.gz certFiles.path = . DEPLOYMENT += certFiles } else:symbian { DEFINES += QSSLSOCKET_CERTUNTRUSTED_WORKAROUND - TARGET.EPOCHEAPSIZE="0x100 0x1000000" - TARGET.CAPABILITY=NetworkServices + TARGET.EPOCHEAPSIZE="0x100 0x3000000" + TARGET.CAPABILITY=NetworkServices ReadUserData - certFiles.sources = certs ssl.tar.gz + certFiles.files = certs ssl.tar.gz certFiles.path = . DEPLOYMENT += certFiles INCLUDEPATH *= $$MW_LAYER_SYSTEMINCLUDE # Needed for e32svr.h in S^3 envs diff --git a/tests/auto/qsslsocket/tst_qsslsocket.cpp b/tests/auto/qsslsocket/tst_qsslsocket.cpp index 0016ed7..5a5bdcc 100644 --- a/tests/auto/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/qsslsocket/tst_qsslsocket.cpp @@ -66,6 +66,8 @@ Q_DECLARE_METATYPE(QSslSocket::SslMode) typedef QList<QSslError::SslError> SslErrorList; Q_DECLARE_METATYPE(SslErrorList) Q_DECLARE_METATYPE(QSslError) +Q_DECLARE_METATYPE(QSsl::SslProtocol) +Q_DECLARE_METATYPE(QSslConfiguration) #endif #if defined Q_OS_HPUX && defined Q_CC_GNU @@ -145,12 +147,16 @@ private slots: void peerCertificateChain(); void privateKey(); void protocol(); + void protocolServerSide_data(); + void protocolServerSide(); void setCaCertificates(); void setLocalCertificate(); void setPrivateKey(); - void setProtocol(); void setSocketDescriptor(); + void setSslConfiguration_data(); + void setSslConfiguration(); void waitForEncrypted(); + void waitForEncryptedMinusOne(); void waitForConnectedEncryptedReadyRead(); void startClientEncryption(); void startServerEncryption(); @@ -183,7 +189,7 @@ private slots: void ignoreSslErrorsListWithSlot(); void readFromClosedSocket(); void writeBigChunk(); - void blacklist(); + void blacklistedCertificates(); void setEmptyDefaultConfiguration(); static void exitLoop() @@ -386,11 +392,14 @@ void tst_QSslSocket::constructing() QVERIFY(!socket.waitForConnected(10)); QTest::ignoreMessage(QtWarningMsg, "QSslSocket::waitForDisconnected() is not allowed in UnconnectedState"); QVERIFY(!socket.waitForDisconnected(10)); - QCOMPARE(socket.protocol(), QSsl::SslV3); + QCOMPARE(socket.protocol(), QSsl::SecureProtocols); QSslConfiguration savedDefault = QSslConfiguration::defaultConfiguration(); // verify that changing the default config doesn't affect this socket + // (on Unix, the ca certs might be empty, depending on whether we load + // them on demand or not, so set them explicitly) + socket.setCaCertificates(QSslSocket::systemCaCertificates()); QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>()); QSslSocket::setDefaultCiphers(QList<QSslCipher>()); QVERIFY(!socket.caCertificates().isEmpty()); @@ -519,11 +528,6 @@ void tst_QSslSocket::sslErrors_data() << 993 << (SslErrorList() << QSslError::HostNameMismatch << QSslError::SelfSignedCertificate); - - QTest::newRow("imap.trolltech.com") - << "imap.trolltech.com" - << 993 - << (SslErrorList() << QSslError::SelfSignedCertificateInChain); } void tst_QSslSocket::sslErrors() @@ -534,6 +538,8 @@ void tst_QSslSocket::sslErrors() QSslSocketPtr socket = newSocket(); socket->connectToHostEncrypted(host, port); + if (!socket->waitForConnected()) + QEXPECT_FAIL("imap.trolltech.com", "server not open to internet", Continue); socket->waitForEncrypted(5000); SslErrorList output; @@ -542,7 +548,7 @@ void tst_QSslSocket::sslErrors() } #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND - if (output.last() == QSslError::CertificateUntrusted) + if (output.count() && output.last() == QSslError::CertificateUntrusted) output.takeLast(); #endif QCOMPARE(output, expected); @@ -651,7 +657,7 @@ void tst_QSslSocket::sessionCipher() connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot())); QVERIFY(socket->sessionCipher().isNull()); socket->connectToHost(QtNetworkSettings::serverName(), 443 /* https */); - QVERIFY(socket->waitForConnected(5000)); + QVERIFY(socket->waitForConnected(10000)); QVERIFY(socket->sessionCipher().isNull()); socket->startClientEncryption(); QVERIFY(socket->waitForEncrypted(5000)); @@ -685,7 +691,7 @@ void tst_QSslSocket::localCertificate() socket->setPrivateKey(QLatin1String(SRCDIR "certs/fluke.key")); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); - QVERIFY(socket->waitForEncrypted(5000)); + QVERIFY(socket->waitForEncrypted(10000)); } void tst_QSslSocket::mode() @@ -766,15 +772,13 @@ void tst_QSslSocket::protocol() this->socket = socket; QList<QSslCertificate> certs = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem"); -// qDebug() << "certs:" << certs.at(0).issuerInfo(QSslCertificate::CommonName); socket->setCaCertificates(certs); #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(untrustedWorkaroundSlot(QList<QSslError>))); #endif -// qDebug() << "socket cert:" << socket->caCertificates().at(0).issuerInfo(QSslCertificate::CommonName); - QCOMPARE(socket->protocol(), QSsl::SslV3); + QCOMPARE(socket->protocol(), QSsl::SecureProtocols); { // Fluke allows SSLv3. socket->setProtocol(QSsl::SslV3); @@ -838,31 +842,22 @@ void tst_QSslSocket::protocol() QCOMPARE(socket->protocol(), QSsl::AnyProtocol); socket->abort(); } -} - -void tst_QSslSocket::setCaCertificates() -{ - if (!QSslSocket::supportsSsl()) - return; - - QSslSocket socket; - QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates()); - socket.setCaCertificates(QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem")); - QCOMPARE(socket.caCertificates().size(), 1); - socket.setCaCertificates(socket.defaultCaCertificates()); - QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates()); -} - -void tst_QSslSocket::setLocalCertificate() -{ -} - -void tst_QSslSocket::setPrivateKey() -{ -} - -void tst_QSslSocket::setProtocol() -{ + { + // Fluke allows SSLV3, so it allows NoSslV2 + socket->setProtocol(QSsl::TlsV1SslV3); + QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3); + socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); + QVERIFY(socket->waitForEncrypted()); + QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3); + socket->abort(); + QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3); + socket->connectToHost(QtNetworkSettings::serverName(), 443); + QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString())); + socket->startClientEncryption(); + QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString())); + QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3); + socket->abort(); + } } class SslServer : public QTcpServer @@ -871,9 +866,11 @@ class SslServer : public QTcpServer public: SslServer(const QString &keyFile = SRCDIR "certs/fluke.key", const QString &certFile = SRCDIR "certs/fluke.cert") : socket(0), + protocol(QSsl::TlsV1), m_keyFile(keyFile), m_certFile(certFile) { } QSslSocket *socket; + QSsl::SslProtocol protocol; QString m_keyFile; QString m_certFile; @@ -881,6 +878,7 @@ protected: void incomingConnection(int socketDescriptor) { socket = new QSslSocket(this); + socket->setProtocol(protocol); connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot())); QFile file(m_keyFile); @@ -910,6 +908,118 @@ protected slots: } }; +void tst_QSslSocket::protocolServerSide_data() +{ + + QTest::addColumn<QSsl::SslProtocol>("serverProtocol"); + QTest::addColumn<QSsl::SslProtocol>("clientProtocol"); + QTest::addColumn<bool>("works"); + + QTest::newRow("ssl2-ssl2") << QSsl::SslV2 << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2 + QTest::newRow("ssl3-ssl3") << QSsl::SslV3 << QSsl::SslV3 << true; + QTest::newRow("tls1-tls1") << QSsl::TlsV1 << QSsl::TlsV1 << true; + QTest::newRow("tls1ssl3-tls1ssl3") << QSsl::TlsV1SslV3 << QSsl::TlsV1SslV3 << true; + QTest::newRow("any-any") << QSsl::AnyProtocol << QSsl::AnyProtocol << true; + QTest::newRow("secure-secure") << QSsl::SecureProtocols << QSsl::SecureProtocols << true; + + QTest::newRow("ssl2-ssl3") << QSsl::SslV2 << QSsl::SslV3 << false; + QTest::newRow("ssl2-tls1") << QSsl::SslV2 << QSsl::TlsV1 << false; + QTest::newRow("ssl2-tls1ssl3") << QSsl::SslV2 << QSsl::TlsV1SslV3 << false; + QTest::newRow("ssl2-secure") << QSsl::SslV2 << QSsl::SecureProtocols << false; + QTest::newRow("ssl2-any") << QSsl::SslV2 << QSsl::AnyProtocol << false; // no idea why it does not work, but we don't care about SSL 2 + + QTest::newRow("ssl3-ssl2") << QSsl::SslV3 << QSsl::SslV2 << false; + QTest::newRow("ssl3-tls1") << QSsl::SslV3 << QSsl::TlsV1 << false; + QTest::newRow("ssl3-tls1ssl3") << QSsl::SslV3 << QSsl::TlsV1SslV3 << true; + QTest::newRow("ssl3-secure") << QSsl::SslV3 << QSsl::SecureProtocols << true; + QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << false; // we wont set a SNI header here because we connect to a + // numerical IP, so OpenSSL will send a SSL 2 handshake + + QTest::newRow("tls1-ssl2") << QSsl::TlsV1 << QSsl::SslV2 << false; + QTest::newRow("tls1-ssl3") << QSsl::TlsV1 << QSsl::SslV3 << false; + QTest::newRow("tls1-tls1ssl3") << QSsl::TlsV1 << QSsl::TlsV1SslV3 << true; + QTest::newRow("tls1-secure") << QSsl::TlsV1 << QSsl::SecureProtocols << true; + QTest::newRow("tls1-any") << QSsl::TlsV1 << QSsl::AnyProtocol << false; // we wont set a SNI header here because we connect to a + // numerical IP, so OpenSSL will send a SSL 2 handshake + + QTest::newRow("tls1ssl3-ssl2") << QSsl::TlsV1SslV3 << QSsl::SslV2 << false; + QTest::newRow("tls1ssl3-ssl3") << QSsl::TlsV1SslV3 << QSsl::SslV3 << true; + QTest::newRow("tls1ssl3-tls1") << QSsl::TlsV1SslV3 << QSsl::TlsV1 << true; + QTest::newRow("tls1ssl3-secure") << QSsl::TlsV1SslV3 << QSsl::SecureProtocols << true; + QTest::newRow("tls1ssl3-any") << QSsl::TlsV1SslV3 << QSsl::AnyProtocol << true; + + QTest::newRow("secure-ssl2") << QSsl::SecureProtocols << QSsl::SslV2 << false; + QTest::newRow("secure-ssl3") << QSsl::SecureProtocols << QSsl::SslV3 << true; + QTest::newRow("secure-tls1") << QSsl::SecureProtocols << QSsl::TlsV1 << true; + QTest::newRow("secure-tls1ssl3") << QSsl::SecureProtocols << QSsl::TlsV1SslV3 << true; + QTest::newRow("secure-any") << QSsl::SecureProtocols << QSsl::AnyProtocol << true; + + QTest::newRow("any-ssl2") << QSsl::AnyProtocol << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2 + QTest::newRow("any-ssl3") << QSsl::AnyProtocol << QSsl::SslV3 << true; + QTest::newRow("any-tls1") << QSsl::AnyProtocol << QSsl::TlsV1 << true; + QTest::newRow("any-tls1ssl3") << QSsl::AnyProtocol << QSsl::TlsV1SslV3 << true; + QTest::newRow("any-secure") << QSsl::AnyProtocol << QSsl::SecureProtocols << true; +} + +void tst_QSslSocket::protocolServerSide() +{ + if (!QSslSocket::supportsSsl()) { + qWarning("SSL not supported, skipping test"); + return; + } + + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + QFETCH(QSsl::SslProtocol, serverProtocol); + SslServer server; + server.protocol = serverProtocol; + QVERIFY(server.listen()); + + QEventLoop loop; + QTimer::singleShot(5000, &loop, SLOT(quit())); + + QSslSocketPtr client = new QSslSocket; + socket = client; + QFETCH(QSsl::SslProtocol, clientProtocol); + socket->setProtocol(clientProtocol); + // upon SSL wrong version error, error will be triggered, not sslErrors + connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), &loop, SLOT(quit())); + connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot())); + connect(client, SIGNAL(encrypted()), &loop, SLOT(quit())); + + client->connectToHostEncrypted(QHostAddress(QHostAddress::LocalHost).toString(), server.serverPort()); + + loop.exec(); + + QFETCH(bool, works); + QAbstractSocket::SocketState expectedState = (works) ? QAbstractSocket::ConnectedState : QAbstractSocket::UnconnectedState; + QCOMPARE(client->state(), expectedState); + QCOMPARE(client->isEncrypted(), works); +} + +void tst_QSslSocket::setCaCertificates() +{ + if (!QSslSocket::supportsSsl()) + return; + + QSslSocket socket; + QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates()); + socket.setCaCertificates(QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem")); + QCOMPARE(socket.caCertificates().size(), 1); + socket.setCaCertificates(socket.defaultCaCertificates()); + QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates()); +} + +void tst_QSslSocket::setLocalCertificate() +{ +} + +void tst_QSslSocket::setPrivateKey() +{ +} + void tst_QSslSocket::setSocketDescriptor() { if (!QSslSocket::supportsSsl()) @@ -942,6 +1052,39 @@ void tst_QSslSocket::setSocketDescriptor() QVERIFY(client->localPort() != 0); } +void tst_QSslSocket::setSslConfiguration_data() +{ + QTest::addColumn<QSslConfiguration>("configuration"); + QTest::addColumn<bool>("works"); + + QTest::newRow("empty") << QSslConfiguration() << false; + QSslConfiguration conf = QSslConfiguration::defaultConfiguration(); + QTest::newRow("default") << conf << false; // does not contain test server cert + QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(SRCDIR "certs/qt-test-server-cacert.pem"); + conf.setCaCertificates(testServerCert); + QTest::newRow("set-root-cert") << conf << true; + conf.setProtocol(QSsl::SecureProtocols); + QTest::newRow("secure") << conf << true; +} + +void tst_QSslSocket::setSslConfiguration() +{ + if (!QSslSocket::supportsSsl()) + return; + + QSslSocketPtr socket = newSocket(); + QFETCH(QSslConfiguration, configuration); + socket->setSslConfiguration(configuration); + this->socket = socket; + socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); + QFETCH(bool, works); + QCOMPARE(socket->waitForEncrypted(10000), works); + if (works) { + socket->disconnectFromHost(); + QVERIFY2(socket->waitForDisconnected(), qPrintable(socket->errorString())); + } +} + void tst_QSslSocket::waitForEncrypted() { if (!QSslSocket::supportsSsl()) @@ -956,6 +1099,20 @@ void tst_QSslSocket::waitForEncrypted() QVERIFY(socket->waitForEncrypted(10000)); } +void tst_QSslSocket::waitForEncryptedMinusOne() +{ + if (!QSslSocket::supportsSsl()) + return; + + QSslSocketPtr socket = newSocket(); + this->socket = socket; + + connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot())); + socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); + + QVERIFY(socket->waitForEncrypted(-1)); +} + void tst_QSslSocket::waitForConnectedEncryptedReadyRead() { if (!QSslSocket::supportsSsl()) @@ -1423,8 +1580,8 @@ protected: // delayed start of encryption QTest::qSleep(100); QSslSocket *socket = server.socket; - Q_ASSERT(socket); - Q_ASSERT(socket->isValid()); + if (!socket || !socket->isValid()) + return; // error socket->ignoreSslErrors(); socket->startServerEncryption(); if (!socket->waitForEncrypted(2000)) @@ -1614,7 +1771,7 @@ void tst_QSslSocket::disconnectFromHostWhenConnecting() QCOMPARE(state, socket->state()); QVERIFY(socket->state() == QAbstractSocket::HostLookupState || socket->state() == QAbstractSocket::ConnectingState); - QVERIFY(socket->waitForDisconnected(5000)); + QVERIFY(socket->waitForDisconnected(10000)); QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState); // we did not call close, so the socket must be still open QVERIFY(socket->isOpen()); @@ -1843,7 +2000,7 @@ void tst_QSslSocket::writeBigChunk() socket->close(); } -void tst_QSslSocket::blacklist() +void tst_QSslSocket::blacklistedCertificates() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) @@ -1864,14 +2021,15 @@ void tst_QSslSocket::blacklist() QVERIFY(sender->state() == QAbstractSocket::ConnectedState); receiver->setObjectName("receiver"); sender->setObjectName("sender"); - receiver->ignoreSslErrors(); receiver->startClientEncryption(); - connect(receiver, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(exitLoop())); + connect(receiver, SIGNAL(sslErrors(QList<QSslError>)), SLOT(exitLoop())); connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop())); enterLoop(1); - QCOMPARE(receiver->error(), QAbstractSocket::SslHandshakeFailedError); - QCOMPARE(receiver->errorString(), QString("The peer certificate is blacklisted")); + QList<QSslError> sslErrors = receiver->sslErrors(); + QVERIFY(sslErrors.count() > 0); + // there are more errors (self signed cert and hostname mismatch), but we only care about the blacklist error + QCOMPARE(sslErrors.at(0).error(), QSslError::CertificateBlacklisted); } void tst_QSslSocket::setEmptyDefaultConfiguration() @@ -1885,8 +2043,9 @@ void tst_QSslSocket::setEmptyDefaultConfiguration() QSslConfiguration::setDefaultConfiguration(emptyConf); QSslSocketPtr socket = newSocket(); + connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot())); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); - + QVERIFY2(!socket->waitForEncrypted(4000), qPrintable(socket->errorString())); } #endif // QT_NO_OPENSSL diff --git a/tests/auto/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro b/tests/auto/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro new file mode 100644 index 0000000..53020eb --- /dev/null +++ b/tests/auto/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro @@ -0,0 +1,28 @@ +load(qttest_p4) + +SOURCES += tst_qsslsocket_onDemandCertificates_member.cpp +!wince*:win32:LIBS += -lws2_32 +QT += network +QT -= gui + +TARGET = tst_qsslsocket_onDemandCertificates_member + +win32 { + CONFIG(debug, debug|release) { + DESTDIR = debug +} else { + DESTDIR = release + } +} + +wince* { + DEFINES += SRCDIR=\\\"./\\\" +} else:symbian { + TARGET.EPOCHEAPSIZE="0x100 0x1000000" + TARGET.CAPABILITY=NetworkServices ReadUserData + INCLUDEPATH *= $$MW_LAYER_SYSTEMINCLUDE # Needed for e32svr.h in S^3 envs +} else { + DEFINES += SRCDIR=\\\"$$PWD/\\\" +} + +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp b/tests/auto/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp new file mode 100644 index 0000000..7e15162 --- /dev/null +++ b/tests/auto/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp @@ -0,0 +1,232 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtNetwork> +#include <QtTest/QtTest> + +#include <QNetworkProxy> +#include <QAuthenticator> + +#include "private/qhostinfo_p.h" + +#include "../network-settings.h" + +#ifdef Q_OS_SYMBIAN +#define SRCDIR "" +#endif + +#ifndef QT_NO_OPENSSL +class QSslSocketPtr: public QSharedPointer<QSslSocket> +{ +public: + inline QSslSocketPtr(QSslSocket *ptr = 0) + : QSharedPointer<QSslSocket>(ptr) + { } + + inline operator QSslSocket *() const { return data(); } +}; +#endif + +class tst_QSslSocket_onDemandCertificates_member : public QObject +{ + Q_OBJECT + + int proxyAuthCalled; + +public: + tst_QSslSocket_onDemandCertificates_member(); + virtual ~tst_QSslSocket_onDemandCertificates_member(); + +#ifndef QT_NO_OPENSSL + QSslSocketPtr newSocket(); +#endif + +public slots: + void initTestCase_data(); + void init(); + void cleanup(); + void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth); + +#ifndef QT_NO_OPENSSL +private slots: + void onDemandRootCertLoadingMemberMethods(); + +private: + QSslSocket *socket; +#endif // QT_NO_OPENSSL +}; + +tst_QSslSocket_onDemandCertificates_member::tst_QSslSocket_onDemandCertificates_member() +{ + Q_SET_DEFAULT_IAP +} + +tst_QSslSocket_onDemandCertificates_member::~tst_QSslSocket_onDemandCertificates_member() +{ +} + +enum ProxyTests { + NoProxy = 0x00, + Socks5Proxy = 0x01, + HttpProxy = 0x02, + TypeMask = 0x0f, + + NoAuth = 0x00, + AuthBasic = 0x10, + AuthNtlm = 0x20, + AuthMask = 0xf0 +}; + +void tst_QSslSocket_onDemandCertificates_member::initTestCase_data() +{ + QTest::addColumn<bool>("setProxy"); + QTest::addColumn<int>("proxyType"); + + QTest::newRow("WithoutProxy") << false << 0; + QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy); + QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic); + + QTest::newRow("WithHttpProxy") << true << int(HttpProxy); + QTest::newRow("WithHttpProxyBasicAuth") << true << int(HttpProxy | AuthBasic); + // uncomment the line below when NTLM works +// QTest::newRow("WithHttpProxyNtlmAuth") << true << int(HttpProxy | AuthNtlm); +} + +void tst_QSslSocket_onDemandCertificates_member::init() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) { + QFETCH_GLOBAL(int, proxyType); + QString testServer = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(); + QNetworkProxy proxy; + + switch (proxyType) { + case Socks5Proxy: + proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, testServer, 1080); + break; + + case Socks5Proxy | AuthBasic: + proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, testServer, 1081); + break; + + case HttpProxy | NoAuth: + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3128); + break; + + case HttpProxy | AuthBasic: + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3129); + break; + + case HttpProxy | AuthNtlm: + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3130); + break; + } + QNetworkProxy::setApplicationProxy(proxy); + } + + qt_qhostinfo_clear_cache(); +} + +void tst_QSslSocket_onDemandCertificates_member::cleanup() +{ + QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy); +} + +#ifndef QT_NO_OPENSSL +QSslSocketPtr tst_QSslSocket_onDemandCertificates_member::newSocket() +{ + QSslSocket *socket = new QSslSocket; + + proxyAuthCalled = 0; + connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + Qt::DirectConnection); + + return QSslSocketPtr(socket); +} +#endif + +void tst_QSslSocket_onDemandCertificates_member::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth) +{ + ++proxyAuthCalled; + auth->setUser("qsockstest"); + auth->setPassword("password"); +} + +#ifndef QT_NO_OPENSSL + +void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMethods() +{ + QString host("qt.nokia.com"); + + // not using any root certs -> should not work + QSslSocketPtr socket2 = newSocket(); + this->socket = socket2; + socket2->setCaCertificates(QList<QSslCertificate>()); + socket2->connectToHostEncrypted(host, 443); + QVERIFY(!socket2->waitForEncrypted()); + + // default: using on demand loading -> should work + QSslSocketPtr socket = newSocket(); + this->socket = socket; + socket->connectToHostEncrypted(host, 443); + QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString())); + + // not using any root certs again -> should not work + QSslSocketPtr socket3 = newSocket(); + this->socket = socket3; + socket3->setCaCertificates(QList<QSslCertificate>()); + socket3->connectToHostEncrypted(host, 443); + QVERIFY(!socket3->waitForEncrypted()); + + // setting empty SSL configuration explicitly -> should not work + QSslSocketPtr socket4 = newSocket(); + this->socket = socket4; + socket4->setSslConfiguration(QSslConfiguration()); + socket4->connectToHostEncrypted(host, 443); + QVERIFY(!socket4->waitForEncrypted()); +} + +#endif // QT_NO_OPENSSL + +QTEST_MAIN(tst_QSslSocket_onDemandCertificates_member) +#include "tst_qsslsocket_onDemandCertificates_member.moc" diff --git a/tests/auto/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro b/tests/auto/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro new file mode 100644 index 0000000..3452a92 --- /dev/null +++ b/tests/auto/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro @@ -0,0 +1,28 @@ +load(qttest_p4) + +SOURCES += tst_qsslsocket_onDemandCertificates_static.cpp +!wince*:win32:LIBS += -lws2_32 +QT += network +QT -= gui + +TARGET = tst_qsslsocket_onDemandCertificates_static + +win32 { + CONFIG(debug, debug|release) { + DESTDIR = debug +} else { + DESTDIR = release + } +} + +wince* { + DEFINES += SRCDIR=\\\"./\\\" +} else:symbian { + TARGET.EPOCHEAPSIZE="0x100 0x1000000" + TARGET.CAPABILITY=NetworkServices ReadUserData + INCLUDEPATH *= $$MW_LAYER_SYSTEMINCLUDE # Needed for e32svr.h in S^3 envs +} else { + DEFINES += SRCDIR=\\\"$$PWD/\\\" +} + +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp b/tests/auto/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp new file mode 100644 index 0000000..0338a2f --- /dev/null +++ b/tests/auto/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp @@ -0,0 +1,238 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtNetwork> +#include <QtTest/QtTest> + +#include <QNetworkProxy> +#include <QAuthenticator> + +#include "private/qhostinfo_p.h" + +#include "../network-settings.h" + +#ifdef Q_OS_SYMBIAN +#define SRCDIR "" +#endif + +#ifndef QT_NO_OPENSSL +class QSslSocketPtr: public QSharedPointer<QSslSocket> +{ +public: + inline QSslSocketPtr(QSslSocket *ptr = 0) + : QSharedPointer<QSslSocket>(ptr) + { } + + inline operator QSslSocket *() const { return data(); } +}; +#endif + +class tst_QSslSocket_onDemandCertificates_static : public QObject +{ + Q_OBJECT + + int proxyAuthCalled; + +public: + tst_QSslSocket_onDemandCertificates_static(); + virtual ~tst_QSslSocket_onDemandCertificates_static(); + +#ifndef QT_NO_OPENSSL + QSslSocketPtr newSocket(); +#endif + +public slots: + void initTestCase_data(); + void init(); + void cleanup(); + void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth); + +#ifndef QT_NO_OPENSSL +private slots: + void onDemandRootCertLoadingStaticMethods(); + +private: + QSslSocket *socket; +#endif // QT_NO_OPENSSL +}; + +tst_QSslSocket_onDemandCertificates_static::tst_QSslSocket_onDemandCertificates_static() +{ + Q_SET_DEFAULT_IAP +} + +tst_QSslSocket_onDemandCertificates_static::~tst_QSslSocket_onDemandCertificates_static() +{ +} + +enum ProxyTests { + NoProxy = 0x00, + Socks5Proxy = 0x01, + HttpProxy = 0x02, + TypeMask = 0x0f, + + NoAuth = 0x00, + AuthBasic = 0x10, + AuthNtlm = 0x20, + AuthMask = 0xf0 +}; + +void tst_QSslSocket_onDemandCertificates_static::initTestCase_data() +{ + QTest::addColumn<bool>("setProxy"); + QTest::addColumn<int>("proxyType"); + + QTest::newRow("WithoutProxy") << false << 0; + QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy); + QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic); + + QTest::newRow("WithHttpProxy") << true << int(HttpProxy); + QTest::newRow("WithHttpProxyBasicAuth") << true << int(HttpProxy | AuthBasic); + // uncomment the line below when NTLM works +// QTest::newRow("WithHttpProxyNtlmAuth") << true << int(HttpProxy | AuthNtlm); +} + +void tst_QSslSocket_onDemandCertificates_static::init() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) { + QFETCH_GLOBAL(int, proxyType); + QString testServer = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(); + QNetworkProxy proxy; + + switch (proxyType) { + case Socks5Proxy: + proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, testServer, 1080); + break; + + case Socks5Proxy | AuthBasic: + proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, testServer, 1081); + break; + + case HttpProxy | NoAuth: + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3128); + break; + + case HttpProxy | AuthBasic: + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3129); + break; + + case HttpProxy | AuthNtlm: + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3130); + break; + } + QNetworkProxy::setApplicationProxy(proxy); + } + + qt_qhostinfo_clear_cache(); +} + +void tst_QSslSocket_onDemandCertificates_static::cleanup() +{ + QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy); +} + +#ifndef QT_NO_OPENSSL +QSslSocketPtr tst_QSslSocket_onDemandCertificates_static::newSocket() +{ + QSslSocket *socket = new QSslSocket; + + proxyAuthCalled = 0; + connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + Qt::DirectConnection); + + return QSslSocketPtr(socket); +} +#endif + +void tst_QSslSocket_onDemandCertificates_static::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth) +{ + ++proxyAuthCalled; + auth->setUser("qsockstest"); + auth->setPassword("password"); +} + +#ifndef QT_NO_OPENSSL + +void tst_QSslSocket_onDemandCertificates_static::onDemandRootCertLoadingStaticMethods() +{ + QString host("qt.nokia.com"); + + // not using any root certs -> should not work + QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>()); + QSslSocketPtr socket = newSocket(); + this->socket = socket; + socket->connectToHostEncrypted(host, 443); + QVERIFY(!socket->waitForEncrypted()); + + // using system root certs -> should work + QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates()); + QSslSocketPtr socket2 = newSocket(); + this->socket = socket2; + socket2->connectToHostEncrypted(host, 443); + QVERIFY2(socket2->waitForEncrypted(), qPrintable(socket2->errorString())); + + // not using any root certs again -> should not work + QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>()); + QSslSocketPtr socket3 = newSocket(); + this->socket = socket3; + socket3->connectToHostEncrypted(host, 443); + QVERIFY(!socket3->waitForEncrypted()); + + QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates()); + + // setting empty default configuration -> should not work + QSslConfiguration conf; + QSslConfiguration originalDefaultConf = QSslConfiguration::defaultConfiguration(); + QSslConfiguration::setDefaultConfiguration(conf); + QSslSocketPtr socket4 = newSocket(); + this->socket = socket4; + socket4->connectToHostEncrypted(host, 443); + QVERIFY(!socket4->waitForEncrypted(4000)); + QSslConfiguration::setDefaultConfiguration(originalDefaultConf); // restore old behaviour for run with proxies etc. +} + +#endif // QT_NO_OPENSSL + +QTEST_MAIN(tst_QSslSocket_onDemandCertificates_static) +#include "tst_qsslsocket_onDemandCertificates_static.moc" diff --git a/tests/auto/qstate/qstate.pro b/tests/auto/qstate/qstate.pro index 9131fa8..6ee7e0c 100644 --- a/tests/auto/qstate/qstate.pro +++ b/tests/auto/qstate/qstate.pro @@ -3,3 +3,4 @@ QT = core SOURCES += tst_qstate.cpp +CONFIG += parallel_test diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 764e5a0..a1bb971 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -211,6 +211,9 @@ private slots: void postEventFromOtherThread(); void eventFilterForApplication(); void eventClassesExported(); + void stopInTransitionToFinalState(); + void stopInEventTest_data(); + void stopInEventTest(); }; tst_QStateMachine::tst_QStateMachine() @@ -4374,5 +4377,70 @@ void tst_QStateMachine::eventClassesExported() QStateMachine::SignalEvent *signalEvent = new QStateMachine::SignalEvent(0, 0, QList<QVariant>()); } +void tst_QStateMachine::stopInTransitionToFinalState() +{ + QStateMachine machine; + QState *s1 = new QState(&machine); + QFinalState *s2 = new QFinalState(&machine); + QAbstractTransition *t1 = s1->addTransition(s2); + 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())); + machine.start(); + + // Stopping should take precedence over finished. + QTRY_COMPARE(stoppedSpy.count(), 1); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(s2EnteredSpy.count(), 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); +} + +class StopInEventTestTransition : public QAbstractTransition +{ +public: + bool eventTest(QEvent *e) + { + if (e->type() == QEvent::User) + machine()->stop(); + return false; + } + void onTransition(QEvent *) + { } +}; + +void tst_QStateMachine::stopInEventTest_data() +{ + QTest::addColumn<int>("eventPriority"); + QTest::newRow("NormalPriority") << int(QStateMachine::NormalPriority); + QTest::newRow("HighPriority") << int(QStateMachine::HighPriority); +} + +void tst_QStateMachine::stopInEventTest() +{ + QFETCH(int, eventPriority); + + QStateMachine machine; + QState *s1 = new QState(&machine); + s1->addTransition(new StopInEventTestTransition()); + machine.setInitialState(s1); + + QSignalSpy startedSpy(&machine, SIGNAL(started())); + machine.start(); + QTRY_COMPARE(startedSpy.count(), 1); + + QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.postEvent(new QEvent(QEvent::User), QStateMachine::EventPriority(eventPriority)); + + QTRY_COMPARE(stoppedSpy.count(), 1); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" diff --git a/tests/auto/qstatictext/tst_qstatictext.cpp b/tests/auto/qstatictext/tst_qstatictext.cpp index b6f06d3..29845d9 100644 --- a/tests/auto/qstatictext/tst_qstatictext.cpp +++ b/tests/auto/qstatictext/tst_qstatictext.cpp @@ -79,8 +79,11 @@ private slots: void rotatedPainter(); void scaledPainter(); void projectedPainter(); +#if 0 + void rotatedScaledAndTranslatedPainter_data(); void rotatedScaledAndTranslatedPainter(); - void transformationChanged(); +#endif + void transformationChanged(); void plainTextVsRichText(); @@ -358,7 +361,7 @@ bool tst_QStaticText::supportsTransformations() const QPaintEngine::Type type = engine->type(); if (type == QPaintEngine::OpenGL -#if !defined Q_WS_WIN +#if !defined(Q_WS_WIN) && !defined(Q_WS_X11) || type == QPaintEngine::Raster #endif ) @@ -455,12 +458,26 @@ void tst_QStaticText::projectedPainter() QCOMPARE(imageDrawStaticText, imageDrawText); } +#if 0 +void tst_QStaticText::rotatedScaledAndTranslatedPainter_data() +{ + QTest::addColumn<qreal>("offset"); + + for (int i=0; i<100; ++i) { + qreal offset = 300 + i / 100.; + QTest::newRow(QByteArray::number(offset).constData()) << offset; + } +} + void tst_QStaticText::rotatedScaledAndTranslatedPainter() { + QFETCH(qreal, offset); + QPixmap imageDrawText(1000, 1000); imageDrawText.fill(Qt::white); { QPainter p(&imageDrawText); + p.translate(offset, 0); p.rotate(45.0); p.scale(2.0, 2.0); p.translate(100, 200); @@ -472,6 +489,7 @@ void tst_QStaticText::rotatedScaledAndTranslatedPainter() imageDrawStaticText.fill(Qt::white); { QPainter p(&imageDrawStaticText); + p.translate(offset, 0); p.rotate(45.0); p.scale(2.0, 2.0); p.translate(100, 200); @@ -491,6 +509,7 @@ void tst_QStaticText::rotatedScaledAndTranslatedPainter() QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort); QCOMPARE(imageDrawStaticText, imageDrawText); } +#endif void tst_QStaticText::transformationChanged() { diff --git a/tests/auto/qstl/qstl.pro b/tests/auto/qstl/qstl.pro index 5c99874..a0c9db1 100644 --- a/tests/auto/qstl/qstl.pro +++ b/tests/auto/qstl/qstl.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qstl.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qstring/qstring.pro b/tests/auto/qstring/qstring.pro index ed758c6..1c123ad 100644 --- a/tests/auto/qstring/qstring.pro +++ b/tests/auto/qstring/qstring.pro @@ -6,3 +6,6 @@ symbian:LIBS += -llibm QT = core DEFINES += QT_NO_CAST_TO_ASCII +CONFIG += parallel_test + +contains(QT_CONFIG,icu):DEFINES += QT_USE_ICU diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp index c009f4c..11fd986 100644 --- a/tests/auto/qstring/tst_qstring.cpp +++ b/tests/auto/qstring/tst_qstring.cpp @@ -57,6 +57,10 @@ Q_DECLARE_METATYPE(qlonglong) //TESTED_CLASS= //TESTED_FILES= +#define CREATE_REF(string) \ + const QString padded = QString::fromLatin1(" %1 ").arg(string); \ + QStringRef ref = padded.midRef(1, padded.size() - 2); + class tst_QString : public QObject { Q_OBJECT @@ -110,6 +114,7 @@ private slots: void remove_string(); void remove_regexp_data(); void remove_regexp(); + void swap(); void prepend(); void prepend_bytearray_data(); void prepend_bytearray(); @@ -136,6 +141,7 @@ private slots: void leftRef(); void stringRef(); void contains(); + void count(); void lastIndexOf_data(); void lastIndexOf(); void indexOf_data(); @@ -170,6 +176,12 @@ private slots: void fromLatin1Roundtrip(); void toLatin1Roundtrip_data(); void toLatin1Roundtrip(); + void stringRef_toLatin1Roundtrip_data(); + void stringRef_toLatin1Roundtrip(); + void stringRef_utf8_data(); + void stringRef_utf8(); + void stringRef_local8Bit_data(); + void stringRef_local8Bit(); void fromLatin1(); void fromAscii(); void arg(); @@ -210,6 +222,8 @@ private slots: void task262677remove(); void QTBUG10404_compareRef(); void QTBUG9281_arg_locale(); + + void toUpperLower_icu(); }; typedef QList<int> IntList; @@ -685,11 +699,11 @@ void tst_QString::acc_01() QVERIFY(a<=c); QVERIFY(!(c<=a)); QVERIFY(!(d<=a)); - QCOMPARE(a+b,(QString)"ABCABC"); - QCOMPARE(a +"XXXX",(QString)"ABCXXXX"); - QCOMPARE(a+'X',(QString)"ABCX"); - QCOMPARE("XXXX"+a,(QString)"XXXXABC"); - QCOMPARE('X'+a,(QString)"XABC"); + QCOMPARE(QString(a+b),(QString)"ABCABC"); + QCOMPARE(QString(a+"XXXX"),(QString)"ABCXXXX"); + QCOMPARE(QString(a+'X'),(QString)"ABCX"); + QCOMPARE(QString("XXXX"+a),(QString)"XXXXABC"); + QCOMPARE(QString('X'+a),(QString)"XABC"); a = (const char*)0; QVERIFY(a.isNull()); QVERIFY(*a.toLatin1().constData() == '\0'); @@ -1048,12 +1062,12 @@ void tst_QString::indexOf_data() QString veryBigHaystack(500, 'a'); veryBigHaystack += 'B'; QTest::newRow("BoyerMooreStressTest") << veryBigHaystack << veryBigHaystack << 0 << true << 0; - QTest::newRow("BoyerMooreStressTest2") << veryBigHaystack + 'c' << veryBigHaystack << 0 << true << 0; - QTest::newRow("BoyerMooreStressTest3") << 'c' + veryBigHaystack << veryBigHaystack << 0 << true << 1; - QTest::newRow("BoyerMooreStressTest4") << veryBigHaystack << veryBigHaystack + 'c' << 0 << true << -1; - QTest::newRow("BoyerMooreStressTest5") << veryBigHaystack << 'c' + veryBigHaystack << 0 << true << -1; - QTest::newRow("BoyerMooreStressTest6") << 'd' + veryBigHaystack << 'c' + veryBigHaystack << 0 << true << -1; - QTest::newRow("BoyerMooreStressTest6") << veryBigHaystack + 'c' << 'c' + veryBigHaystack << 0 << true << -1; + QTest::newRow("BoyerMooreStressTest2") << QString(veryBigHaystack + 'c') << veryBigHaystack << 0 << true << 0; + QTest::newRow("BoyerMooreStressTest3") << QString('c' + veryBigHaystack) << veryBigHaystack << 0 << true << 1; + QTest::newRow("BoyerMooreStressTest4") << veryBigHaystack << QString(veryBigHaystack + 'c') << 0 << true << -1; + QTest::newRow("BoyerMooreStressTest5") << veryBigHaystack << QString('c' + veryBigHaystack) << 0 << true << -1; + QTest::newRow("BoyerMooreStressTest6") << QString('d' + veryBigHaystack) << QString('c' + veryBigHaystack) << 0 << true << -1; + QTest::newRow("BoyerMooreStressTest6") << QString(veryBigHaystack + 'c') << QString('c' + veryBigHaystack) << 0 << true << -1; QTest::newRow("BoyerMooreInsensitiveStressTest") << veryBigHaystack << veryBigHaystack << 0 << false << 0; @@ -1066,12 +1080,14 @@ void tst_QString::indexOf() QFETCH( int, startpos ); QFETCH( bool, bcs ); QFETCH( int, resultpos ); + CREATE_REF(needle); Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive; bool needleIsLatin = (QString::fromLatin1(needle.toLatin1()) == needle); QCOMPARE( haystack.indexOf(needle, startpos, cs), resultpos ); + QCOMPARE( haystack.indexOf(ref, startpos, cs), resultpos ); if (needleIsLatin) { QCOMPARE( haystack.indexOf(needle.toLatin1(), startpos, cs), resultpos ); QCOMPARE( haystack.indexOf(needle.toLatin1().data(), startpos, cs), resultpos ); @@ -1099,12 +1115,14 @@ void tst_QString::indexOf() if (cs == Qt::CaseSensitive) { QCOMPARE( haystack.indexOf(needle, startpos), resultpos ); + QCOMPARE( haystack.indexOf(ref, startpos), resultpos ); if (needleIsLatin) { QCOMPARE( haystack.indexOf(needle.toLatin1(), startpos), resultpos ); QCOMPARE( haystack.indexOf(needle.toLatin1().data(), startpos), resultpos ); } if (startpos == 0) { QCOMPARE( haystack.indexOf(needle), resultpos ); + QCOMPARE( haystack.indexOf(ref), resultpos ); if (needleIsLatin) { QCOMPARE( haystack.indexOf(needle.toLatin1()), resultpos ); QCOMPARE( haystack.indexOf(needle.toLatin1().data()), resultpos ); @@ -1113,6 +1131,7 @@ void tst_QString::indexOf() } if (needle.size() == 1) { QCOMPARE(haystack.indexOf(needle.at(0), startpos, cs), resultpos); + QCOMPARE(haystack.indexOf(ref.at(0), startpos, cs), resultpos); } } @@ -1158,14 +1177,14 @@ void tst_QString::indexOf2_data() QString whale = "a5zby6cx7dw8evf9ug0th1si2rj3qkp4lomn"; QString minnow = "zby"; QTest::newRow( "data40" ) << whale << minnow << 2; - QTest::newRow( "data41" ) << (whale + whale) << minnow << 2; - QTest::newRow( "data42" ) << (minnow + whale) << minnow << 0; + QTest::newRow( "data41" ) << QString(whale + whale) << minnow << 2; + QTest::newRow( "data42" ) << QString(minnow + whale) << minnow << 0; QTest::newRow( "data43" ) << whale << whale << 0; - QTest::newRow( "data44" ) << (whale + whale) << whale << 0; - QTest::newRow( "data45" ) << whale << (whale + whale) << -1; - QTest::newRow( "data46" ) << (whale + whale) << (whale + whale) << 0; - QTest::newRow( "data47" ) << (whale + whale) << (whale + minnow) << -1; - QTest::newRow( "data48" ) << (minnow + whale) << whale << (int)minnow.length(); + QTest::newRow( "data44" ) << QString(whale + whale) << whale << 0; + QTest::newRow( "data45" ) << whale << QString(whale + whale) << -1; + QTest::newRow( "data46" ) << QString(whale + whale) << QString(whale + whale) << 0; + QTest::newRow( "data47" ) << QString(whale + whale) << QString(whale + minnow) << -1; + QTest::newRow( "data48" ) << QString(minnow + whale) << whale << (int)minnow.length(); } void tst_QString::indexOf2() @@ -1173,14 +1192,17 @@ void tst_QString::indexOf2() QFETCH( QString, haystack ); QFETCH( QString, needle ); QFETCH( int, resultpos ); + CREATE_REF(needle); QByteArray chaystack = haystack.toLatin1(); QByteArray cneedle = needle.toLatin1(); int got; QCOMPARE( haystack.indexOf(needle, 0, Qt::CaseSensitive), resultpos ); + QCOMPARE( haystack.indexOf(ref, 0, Qt::CaseSensitive), resultpos ); QCOMPARE( QStringMatcher(needle, Qt::CaseSensitive).indexIn(haystack, 0), resultpos ); QCOMPARE( haystack.indexOf(needle, 0, Qt::CaseInsensitive), resultpos ); + QCOMPARE( haystack.indexOf(ref, 0, Qt::CaseInsensitive), resultpos ); QCOMPARE( QStringMatcher(needle, Qt::CaseInsensitive).indexIn(haystack, 0), resultpos ); if ( needle.length() > 0 ) { got = haystack.lastIndexOf( needle, -1, Qt::CaseSensitive ); @@ -1247,10 +1269,12 @@ void tst_QString::lastIndexOf() QFETCH(int, from); QFETCH(int, expected); QFETCH(bool, caseSensitive); + CREATE_REF(needle); Qt::CaseSensitivity cs = (caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); QCOMPARE(haystack.lastIndexOf(needle, from, cs), expected); + QCOMPARE(haystack.lastIndexOf(ref, from, cs), expected); QCOMPARE(haystack.lastIndexOf(needle.toLatin1(), from, cs), expected); QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data(), from, cs), expected); @@ -1280,20 +1304,23 @@ void tst_QString::lastIndexOf() if (cs == Qt::CaseSensitive) { QCOMPARE(haystack.lastIndexOf(needle, from), expected); + QCOMPARE(haystack.lastIndexOf(ref, from), expected); QCOMPARE(haystack.lastIndexOf(needle.toLatin1(), from), expected); QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data(), from), expected); if (from == -1) { QCOMPARE(haystack.lastIndexOf(needle), expected); + QCOMPARE(haystack.lastIndexOf(ref), expected); QCOMPARE(haystack.lastIndexOf(needle.toLatin1()), expected); QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data()), expected); } } if (needle.size() == 1) { QCOMPARE(haystack.lastIndexOf(needle.at(0), from), expected); + QCOMPARE(haystack.lastIndexOf(ref.at(0), from), expected); } } -void tst_QString::contains() +void tst_QString::count() { QString a; a="ABCDEFGHIEfGEFG"; // 15 chars @@ -1308,8 +1335,42 @@ void tst_QString::contains() QCOMPARE(a.count( "", Qt::CaseInsensitive), 16); QCOMPARE(a.count(QRegExp("[FG][HI]")),1); QCOMPARE(a.count(QRegExp("[G][HE]")),2); + + CREATE_REF(QLatin1String("FG")); + QCOMPARE(a.count(ref),2); + QCOMPARE(a.count(ref,Qt::CaseInsensitive),3); + QCOMPARE(a.count( QStringRef(), Qt::CaseInsensitive), 16); + QStringRef emptyRef(&a, 0, 0); + QCOMPARE(a.count( emptyRef, Qt::CaseInsensitive), 16); + } +void tst_QString::contains() +{ + QString a; + a="ABCDEFGHIEfGEFG"; // 15 chars + QVERIFY(a.contains('A')); + QVERIFY(!a.contains('Z')); + QVERIFY(a.contains('E')); + QVERIFY(a.contains('F')); + QVERIFY(a.contains('F',Qt::CaseInsensitive)); + QVERIFY(a.contains("FG")); + QVERIFY(a.contains("FG",Qt::CaseInsensitive)); + QVERIFY(a.contains( QString(), Qt::CaseInsensitive)); + QVERIFY(a.contains( "", Qt::CaseInsensitive)); + QVERIFY(a.contains(QRegExp("[FG][HI]"))); + QVERIFY(a.contains(QRegExp("[G][HE]"))); + + CREATE_REF(QLatin1String("FG")); + QVERIFY(a.contains(ref)); + QVERIFY(a.contains(ref, Qt::CaseInsensitive)); + QVERIFY(a.contains( QStringRef(), Qt::CaseInsensitive)); + QStringRef emptyRef(&a, 0, 0); + QVERIFY(a.contains(emptyRef, Qt::CaseInsensitive)); + +} + + void tst_QString::left() { QString a; @@ -1544,6 +1605,11 @@ void tst_QString::toUpper() QCOMPARE( lower.toUpper(), upper); +#ifdef QT_USE_ICU + // test doesn't work with ICU support, since QChar is unaware of any locale + QEXPECT_FAIL("", "test doesn't work with ICU support, since QChar is unaware of any locale", Continue); + QVERIFY(false); +#else for (int i = 0; i < 65536; ++i) { QString str(1, QChar(i)); QString upper = str.toUpper(); @@ -1551,6 +1617,7 @@ void tst_QString::toUpper() if (upper.length() == 1) QVERIFY(upper == QString(1, QChar(i).toUpper())); } +#endif } void tst_QString::toLower() @@ -1572,7 +1639,7 @@ void tst_QString::toLower() QCOMPARE( QString("`ABYZ{").toLower(), QString("`abyz{")); QCOMPARE( QString("`abyz{").toLower(), QString("`abyz{")); - QCOMPARE( QString(1, QChar(0x130)).toLower(), QString(1, QChar(0x69)) + QChar(0x307)); + QCOMPARE( QString(1, QChar(0x130)).toLower(), QString(QString(1, QChar(0x69)) + QChar(0x307))); QString lower; lower += QChar(QChar::highSurrogate(0x10428)); @@ -1582,6 +1649,11 @@ void tst_QString::toLower() upper += QChar(QChar::lowSurrogate(0x10400)); QCOMPARE( upper.toLower(), lower); +#ifdef QT_USE_ICU + // test doesn't work with ICU support, since QChar is unaware of any locale + QEXPECT_FAIL("", "test doesn't work with ICU support, since QChar is unaware of any locale", Continue); + QVERIFY(false); +#else for (int i = 0; i < 65536; ++i) { QString str(1, QChar(i)); QString lower = str.toLower(); @@ -1589,6 +1661,7 @@ void tst_QString::toLower() if (lower.length() == 1) QVERIFY(str.toLower() == QString(1, QChar(i).toLower())); } +#endif } void tst_QString::trimmed() @@ -1794,6 +1867,16 @@ void tst_QString::operator_pluseq_bytearray() } } +void tst_QString::swap() +{ + QString s1, s2; + s1 = "s1"; + s2 = "s2"; + s1.swap(s2); + QCOMPARE(s1,QLatin1String("s2")); + QCOMPARE(s2,QLatin1String("s1")); +} + void tst_QString::prepend() { QString a; @@ -2830,6 +2913,14 @@ void tst_QString::startsWith() QVERIFY( !a.startsWith(QChar(), Qt::CaseSensitive) ); QVERIFY( !a.startsWith(QLatin1Char(0), Qt::CaseSensitive) ); +#define TEST_REF_STARTS_WITH(string, yes) { CREATE_REF(string); QCOMPARE(a.startsWith(ref), yes); } + + TEST_REF_STARTS_WITH("A", true); + TEST_REF_STARTS_WITH("AB", true); + TEST_REF_STARTS_WITH("C", false); + TEST_REF_STARTS_WITH("ABCDEF", false); +#undef TEST_REF_STARTS_WITH + a = ""; QVERIFY( a.startsWith("") ); QVERIFY( a.startsWith(QString::null) ); @@ -2855,6 +2946,7 @@ void tst_QString::startsWith() QVERIFY( !a.startsWith(QLatin1Char(0)) ); QVERIFY( !a.startsWith(QLatin1Char('x')) ); QVERIFY( !a.startsWith(QChar()) ); + } void tst_QString::endsWith() @@ -2922,6 +3014,17 @@ void tst_QString::endsWith() QVERIFY( !a.endsWith(QChar(), Qt::CaseSensitive) ); QVERIFY( !a.endsWith(QLatin1Char(0), Qt::CaseSensitive) ); + +#define TEST_REF_ENDS_WITH(string, yes) { CREATE_REF(string); QCOMPARE(a.endsWith(ref), yes); } + TEST_REF_ENDS_WITH(QLatin1String("B"), true); + TEST_REF_ENDS_WITH(QLatin1String("AB"), true); + TEST_REF_ENDS_WITH(QLatin1String("C"), false); + TEST_REF_ENDS_WITH(QLatin1String("ABCDEF"), false); + TEST_REF_ENDS_WITH(QLatin1String(""), true); + TEST_REF_ENDS_WITH(QLatin1String(0), true); + +#undef TEST_REF_STARTS_WITH + a = ""; QVERIFY( a.endsWith("") ); QVERIFY( a.endsWith(QString::null) ); @@ -3094,6 +3197,20 @@ void tst_QString::utf8() QCOMPARE( utf8, QByteArray(res.toUtf8()) ); } +void tst_QString::stringRef_utf8_data() +{ + utf8_data(); +} + +void tst_QString::stringRef_utf8() +{ + QFETCH( QByteArray, utf8 ); + QFETCH( QString, res ); + + QStringRef ref(&res, 0, res.length()); + QCOMPARE( utf8, QByteArray(ref.toUtf8()) ); +} + // copied to tst_QTextCodec::utf8Codec_data() void tst_QString::fromUtf8_data() { @@ -3273,6 +3390,20 @@ void tst_QString::local8Bit() QCOMPARE(local8Bit.toLocal8Bit(), QByteArray(result)); } +void tst_QString::stringRef_local8Bit_data() +{ + local8Bit_data(); +} + +void tst_QString::stringRef_local8Bit() +{ + QFETCH(QString, local8Bit); + QFETCH(QByteArray, result); + + QStringRef ref(&local8Bit, 0, local8Bit.length()); + QCOMPARE(ref.toLocal8Bit(), QByteArray(result)); +} + void tst_QString::fromLatin1Roundtrip_data() { QTest::addColumn<QByteArray>("latin1"); @@ -3298,9 +3429,9 @@ void tst_QString::fromLatin1Roundtrip() QFETCH(QString, unicode); // QtTest safety check: - Q_ASSERT(latin1.isNull() == unicode.isNull()); - Q_ASSERT(latin1.isEmpty() == unicode.isEmpty()); - Q_ASSERT(latin1.length() == unicode.length()); + QCOMPARE(latin1.isNull(), unicode.isNull()); + QCOMPARE(latin1.isEmpty(), unicode.isEmpty()); + QCOMPARE(latin1.length(), unicode.length()); if (!latin1.isEmpty()) while (latin1.length() < 128) { @@ -3353,12 +3484,12 @@ void tst_QString::toLatin1Roundtrip() QFETCH(QString, unicodedst); // QtTest safety check: - Q_ASSERT(latin1.isNull() == unicodesrc.isNull()); - Q_ASSERT(latin1.isEmpty() == unicodesrc.isEmpty()); - Q_ASSERT(latin1.length() == unicodesrc.length()); - Q_ASSERT(latin1.isNull() == unicodedst.isNull()); - Q_ASSERT(latin1.isEmpty() == unicodedst.isEmpty()); - Q_ASSERT(latin1.length() == unicodedst.length()); + QCOMPARE(latin1.isNull(), unicodesrc.isNull()); + QCOMPARE(latin1.isEmpty(), unicodesrc.isEmpty()); + QCOMPARE(latin1.length(), unicodesrc.length()); + QCOMPARE(latin1.isNull(), unicodedst.isNull()); + QCOMPARE(latin1.isEmpty(), unicodedst.isEmpty()); + QCOMPARE(latin1.length(), unicodedst.length()); if (!latin1.isEmpty()) while (latin1.length() < 128) { @@ -3376,6 +3507,38 @@ void tst_QString::toLatin1Roundtrip() QCOMPARE(QString::fromLatin1(latin1, latin1.length()), unicodedst); } +void tst_QString::stringRef_toLatin1Roundtrip_data() +{ + toLatin1Roundtrip_data(); +} + +void tst_QString::stringRef_toLatin1Roundtrip() +{ + QFETCH(QByteArray, latin1); + QFETCH(QString, unicodesrc); + QFETCH(QString, unicodedst); + + // QtTest safety check: + QCOMPARE(latin1.isNull(), unicodesrc.isNull()); + QCOMPARE(latin1.isEmpty(), unicodesrc.isEmpty()); + QCOMPARE(latin1.length(), unicodesrc.length()); + QCOMPARE(latin1.isNull(), unicodedst.isNull()); + QCOMPARE(latin1.isEmpty(), unicodedst.isEmpty()); + QCOMPARE(latin1.length(), unicodedst.length()); + + if (!latin1.isEmpty()) + while (latin1.length() < 128) { + latin1 += latin1; + unicodesrc += unicodesrc; + unicodedst += unicodedst; + } + + // toLatin1 + QStringRef src(&unicodesrc, 0, unicodesrc.length()); + QCOMPARE(src.toLatin1().length(), latin1.length()); + QCOMPARE(src.toLatin1(), latin1); +} + void tst_QString::fromLatin1() { QString a; @@ -4170,6 +4333,9 @@ void tst_QString::localeAwareCompare_data() void tst_QString::localeAwareCompare() { +#ifdef Q_OS_SYMBIAN + QSKIP("QTBUG-16921: There is no way to set up the system locale, so this test is not reliable in Symbian."); +#else #ifdef Q_OS_WIN # ifndef Q_OS_WINCE QSKIP("On others than Win CE, we cannot set the system or user locale.", SkipAll); @@ -4200,6 +4366,8 @@ void tst_QString::localeAwareCompare() #elif defined (Q_WS_MAC) QSKIP("Setting the locale is not supported on OS X (you can set the C locale, but that won't affect CFStringCompare which is used to compare strings)", SkipAll); +#elif defined(QT_USE_ICU) + QLocale::setDefault(QLocale(locale)); #else if (!locale.isEmpty()) { const char *newLocale = setlocale(LC_ALL, locale.toLatin1()); @@ -4211,6 +4379,11 @@ void tst_QString::localeAwareCompare() } #endif +#ifdef QT_USE_ICU + // ### for c1, ICU disagrees with libc on how to compare + QEXPECT_FAIL("c1", "ICU disagrees with test", Abort); +#endif + int testres = QString::localeAwareCompare(s1, s2); if (result < 0) { QVERIFY(testres < 0); @@ -4267,6 +4440,7 @@ void tst_QString::localeAwareCompare() if (!locale.isEmpty()) setlocale(LC_ALL, ""); #endif +#endif // Q_OS_SYMBIAN } void tst_QString::split_data() @@ -4912,6 +5086,40 @@ void tst_QString::QTBUG9281_arg_locale() QLocale::setDefault(QLocale::C); } +void tst_QString::toUpperLower_icu() +{ +#ifndef QT_USE_ICU + QSKIP("Qt was built without ICU support", SkipAll); +#endif + + QString s = QString::fromLatin1("i"); + + QCOMPARE(s.toUpper(), QString::fromLatin1("I")); + QCOMPARE(s.toLower(), QString::fromLatin1("i")); + + QLocale::setDefault(QLocale(QLocale::Turkish, QLocale::Turkey)); + + // turkish locale has a capital I with a dot (U+0130, utf8 c4b0) + + QCOMPARE(s.toUpper(), QString::fromUtf8("\xc4\xb0")); + QCOMPARE(QString::fromUtf8("\xc4\xb0").toLower(), s); + + // nothing should happen here + QCOMPARE(s.toLower(), s); + QCOMPARE(QString::fromLatin1("I").toUpper(), QString::fromLatin1("I")); + + // U+0131, utf8 c4b1 is the lower-case i without a dot + QString sup = QString::fromUtf8("\xc4\xb1"); + + QCOMPARE(sup.toUpper(), QString::fromLatin1("I")); + QCOMPARE(QString::fromLatin1("I").toLower(), sup); + + // nothing should happen here + QCOMPARE(sup.toLower(), sup); + QCOMPARE(QString::fromLatin1("i").toLower(), QString::fromLatin1("i")); + + // the cleanup function will restore the default locale +} QTEST_APPLESS_MAIN(tst_QString) diff --git a/tests/auto/qstringbuilder1/qstringbuilder1.pro b/tests/auto/qstringbuilder1/qstringbuilder1.pro index 5bb14d4..dc9062f 100644 --- a/tests/auto/qstringbuilder1/qstringbuilder1.pro +++ b/tests/auto/qstringbuilder1/qstringbuilder1.pro @@ -4,3 +4,4 @@ QT = core SOURCES += tst_qstringbuilder1.cpp +CONFIG += parallel_test diff --git a/tests/auto/qstringbuilder1/stringbuilder.cpp b/tests/auto/qstringbuilder1/stringbuilder.cpp index 1b220b0..2327ef5 100644 --- a/tests/auto/qstringbuilder1/stringbuilder.cpp +++ b/tests/auto/qstringbuilder1/stringbuilder.cpp @@ -40,9 +40,13 @@ ****************************************************************************/ #define LITERAL "some literal" +#define LITERAL_LEN (sizeof(LITERAL)-1) +#define LITERAL_EXTRA "some literal" "EXTRA" // "some literal", but replacing all vocals by their umlauted UTF-8 string :) #define UTF8_LITERAL "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l" +#define UTF8_LITERAL_LEN (sizeof(UTF8_LITERAL)-1) +#define UTF8_LITERAL_EXTRA "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l" "EXTRA" //fix for gcc4.0: if the operator+ does not exist without QT_USE_FAST_OPERATOR_PLUS @@ -65,7 +69,6 @@ void runScenario() QLatin1Char achar('c'); QString r2(QLatin1String(LITERAL LITERAL)); QString r; - QByteArray ba(LITERAL); r = l1literal Q l1literal; QCOMPARE(r, r2); @@ -86,6 +89,15 @@ void runScenario() QCOMPARE(r, r2); r = LITERAL P string; QCOMPARE(r, r2); + + QByteArray ba = QByteArray(LITERAL); + r = ba P string; + QCOMPARE(r, r2); + r = string P ba; + QCOMPARE(r, r2); + + static const char badata[] = LITERAL_EXTRA; + ba = QByteArray::fromRawData(badata, LITERAL_LEN); r = ba P string; QCOMPARE(r, r2); r = string P ba; @@ -109,5 +121,76 @@ void runScenario() QCOMPARE(r, r2); r = string P ba; QCOMPARE(r, r2); + + ba = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN); + r = ba P string; + QCOMPARE(r, r2); + r = string P ba; + QCOMPARE(r, r2); + + ba = QByteArray(); // empty + r = ba P string; + QCOMPARE(r, string); + r = string P ba; + QCOMPARE(r, string); #endif + + string = QString::fromLatin1(LITERAL); + QCOMPARE(QByteArray(qPrintable(string P string)), QByteArray(string.toLatin1() + string.toLatin1())); + + + + //QByteArray + { + QByteArray ba = LITERAL; + QByteArray superba = ba P ba P LITERAL; + QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL)); + + QByteArray testWith0 = ba P "test\0with\0zero" P ba; + QCOMPARE(testWith0, QByteArray(LITERAL "test" LITERAL)); + + QByteArray ba2 = ba P '\0' + LITERAL; + QCOMPARE(ba2, QByteArray(LITERAL "\0" LITERAL, ba.size()*2+1)); + + const char *mmh = "test\0foo"; + QCOMPARE(QByteArray(ba P mmh P ba), testWith0); + + QByteArray raw = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN); + QByteArray r = "hello" P raw; + QByteArray r2 = "hello" UTF8_LITERAL; + QCOMPARE(r, r2); + r2 = QByteArray("hello\0") P UTF8_LITERAL; + QCOMPARE(r, r2); + } + + //operator QString += + { + QString str = QString::fromUtf8(UTF8_LITERAL); + str += QLatin1String(LITERAL) P str; + QCOMPARE(str, QString::fromUtf8(UTF8_LITERAL LITERAL UTF8_LITERAL)); +#ifndef QT_NO_CAST_FROM_ASCII + str = (QString::fromUtf8(UTF8_LITERAL) += QLatin1String(LITERAL) P UTF8_LITERAL); + QCOMPARE(str, QString::fromUtf8(UTF8_LITERAL LITERAL UTF8_LITERAL)); +#endif + } + + //operator QByteArray += + { + QByteArray ba = UTF8_LITERAL; + ba += QByteArray(LITERAL) P UTF8_LITERAL; + QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL)); + ba += LITERAL P QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN); + QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL LITERAL UTF8_LITERAL)); + QByteArray withZero = QByteArray(LITERAL "\0" LITERAL, LITERAL_LEN*2+1); + QByteArray ba2 = withZero; + ba2 += ba2 P withZero; + QCOMPARE(ba2, QByteArray(withZero + withZero + withZero)); +#ifndef QT_NO_CAST_TO_ASCII + ba = UTF8_LITERAL; + ba2 = (ba += QLatin1String(LITERAL) + QString::fromUtf8(UTF8_LITERAL)); + QCOMPARE(ba2, ba); + QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL)); +#endif + } + } diff --git a/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp b/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp index 9f81958..134da1d 100644 --- a/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp +++ b/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp @@ -44,8 +44,7 @@ // this is the "no harm done" version. Only operator% is active, // with NO_CAST * defined #define P % -#undef QT_USE_FAST_OPERATOR_PLUS -#undef QT_USE_FAST_CONCATENATION +#undef QT_USE_QSTRINGBUILDER #define QT_NO_CAST_FROM_ASCII #define QT_NO_CAST_TO_ASCII diff --git a/tests/auto/qstringbuilder2/qstringbuilder2.pro b/tests/auto/qstringbuilder2/qstringbuilder2.pro index 4152dc3..a57c6f1 100644 --- a/tests/auto/qstringbuilder2/qstringbuilder2.pro +++ b/tests/auto/qstringbuilder2/qstringbuilder2.pro @@ -3,3 +3,4 @@ load(qttest_p4) QT = core SOURCES += tst_qstringbuilder2.cpp +CONFIG += parallel_test diff --git a/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp b/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp index 0779f3a..b74cea0 100644 --- a/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp +++ b/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp @@ -45,8 +45,7 @@ // based version // with NO_CAST * defined #define P + -#define QT_USE_FAST_OPERATOR_PLUS -#define QT_USE_FAST_CONCATENATION +#define QT_USE_QSTRINGBUILDER #define QT_NO_CAST_FROM_ASCII #define QT_NO_CAST_TO_ASCII diff --git a/tests/auto/qstringbuilder3/qstringbuilder3.pro b/tests/auto/qstringbuilder3/qstringbuilder3.pro index b4d2225..5aced7c 100644 --- a/tests/auto/qstringbuilder3/qstringbuilder3.pro +++ b/tests/auto/qstringbuilder3/qstringbuilder3.pro @@ -3,3 +3,4 @@ load(qttest_p4) QT = core SOURCES += tst_qstringbuilder3.cpp +CONFIG += parallel_test diff --git a/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp b/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp index ef594db..0320ed2 100644 --- a/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp +++ b/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp @@ -44,8 +44,7 @@ // this is the "no harm done" version. Only operator% is active, // with NO_CAST * _not_ defined #define P % -#undef QT_USE_FAST_OPERATOR_PLUS -#undef QT_USE_FAST_CONCATENATION +#undef QT_USE_QSTRINGBUILDER #undef QT_NO_CAST_FROM_ASCII #undef QT_NO_CAST_TO_ASCII diff --git a/tests/auto/qstringbuilder4/qstringbuilder4.pro b/tests/auto/qstringbuilder4/qstringbuilder4.pro index 6ec5228..0532a9b 100644 --- a/tests/auto/qstringbuilder4/qstringbuilder4.pro +++ b/tests/auto/qstringbuilder4/qstringbuilder4.pro @@ -3,3 +3,4 @@ load(qttest_p4) QT = core SOURCES += tst_qstringbuilder4.cpp +CONFIG += parallel_test diff --git a/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp b/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp index e75b874..7013780 100644 --- a/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp +++ b/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp @@ -45,8 +45,7 @@ // based version // with NO_CAST * _not_ defined #define P + -#define QT_USE_FAST_OPERATOR_PLUS -#define QT_USE_FAST_CONCATENATION +#define QT_USE_QSTRINGBUILDER #undef QT_NO_CAST_FROM_ASCII #undef QT_NO_CAST_TO_ASCII diff --git a/tests/auto/qstringlist/qstringlist.pro b/tests/auto/qstringlist/qstringlist.pro index aee074b..d82a348 100644 --- a/tests/auto/qstringlist/qstringlist.pro +++ b/tests/auto/qstringlist/qstringlist.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qstringlist.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qstringlist/tst_qstringlist.cpp b/tests/auto/qstringlist/tst_qstringlist.cpp index 9ee4981..3342ec0 100644 --- a/tests/auto/qstringlist/tst_qstringlist.cpp +++ b/tests/auto/qstringlist/tst_qstringlist.cpp @@ -78,6 +78,8 @@ private slots: void join() const; void join_data() const; void joinEmptiness() const; + + void initializeList() const; }; extern const char email[]; @@ -321,5 +323,16 @@ void tst_QStringList::joinEmptiness() const QVERIFY(string.isNull()); } +void tst_QStringList::initializeList() const +{ +#ifdef Q_COMPILER_INITIALIZER_LISTS + QStringList v1{QLatin1String("hello"),"world",QString::fromLatin1("plop")}; + QCOMPARE(v1, (QStringList() << "hello" << "world" << "plop")); + QCOMPARE(v1, (QStringList{"hello","world","plop"})); +#else + QSKIP("Require C++0x support, pass the right flag to the compiler", SkipAll); +#endif +} + QTEST_APPLESS_MAIN(tst_QStringList) #include "tst_qstringlist.moc" diff --git a/tests/auto/qstringmatcher/qstringmatcher.pro b/tests/auto/qstringmatcher/qstringmatcher.pro index 2c15097..c5249ec 100644 --- a/tests/auto/qstringmatcher/qstringmatcher.pro +++ b/tests/auto/qstringmatcher/qstringmatcher.pro @@ -3,3 +3,4 @@ SOURCES += tst_qstringmatcher.cpp QT = core DEFINES += QT_NO_CAST_TO_ASCII +CONFIG += parallel_test diff --git a/tests/auto/qstringref/qstringref.pro b/tests/auto/qstringref/qstringref.pro new file mode 100644 index 0000000..34f2de4 --- /dev/null +++ b/tests/auto/qstringref/qstringref.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +SOURCES += tst_qstringref.cpp + +QT = core +CONFIG += parallel_test diff --git a/tests/auto/qstringref/tst_qstringref.cpp b/tests/auto/qstringref/tst_qstringref.cpp new file mode 100644 index 0000000..dbf8ee7 --- /dev/null +++ b/tests/auto/qstringref/tst_qstringref.cpp @@ -0,0 +1,881 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <qstringlist.h> +#include <qvariant.h> + +#include <qlocale.h> +#include <locale.h> + +Q_DECLARE_METATYPE(qlonglong) + +//TESTED_CLASS= +//TESTED_FILES= + + +class tst_QStringRef : public QObject +{ + Q_OBJECT + +public: + tst_QStringRef(); + virtual ~tst_QStringRef(); + + +public slots: + void init(); + void cleanup(); +private slots: + void endsWith(); + void startsWith(); + void contains(); + void count(); + void lastIndexOf_data(); + void lastIndexOf(); + void indexOf_data(); + void indexOf(); + void indexOf2_data(); + void indexOf2(); + void length_data(); + void length(); + void isEmpty(); + void compare_data(); + void compare(); + void operator_eqeq_nullstring(); +}; + +static QStringRef emptyRef() +{ + static const QString empty(""); + return empty.midRef(0); +} + +#define CREATE_REF(string) \ + const QString padded = QString::fromLatin1(" %1 ").arg(string); \ + QStringRef ref = padded.midRef(1, padded.size() - 2); + +typedef QList<int> IntList; + +Q_DECLARE_METATYPE(QList<QVariant>) +Q_DECLARE_METATYPE(IntList) + +// This next bit is needed for the NAN and INF in string -> number conversion tests +#include <float.h> +#include <limits.h> +#include <math.h> +#if defined(Q_WS_WIN) +# include <windows.h> +// mingw defines NAN and INFINITY to 0/0 and x/0 +# if defined(Q_CC_GNU) +# undef NAN +# undef INFINITY +# else +# define isnan(d) _isnan(d) +# endif +#endif +#if defined(Q_OS_MAC) && !defined isnan +#define isnan(d) __isnand(d) +#endif +#if defined(Q_OS_SOLARIS) +# include <ieeefp.h> +#endif +#if defined(Q_OS_OSF) && (defined(__DECC) || defined(__DECCXX)) +# define INFINITY DBL_INFINITY +# define NAN DBL_QNAN +#endif +#if defined(Q_OS_IRIX) && defined(Q_CC_GNU) +# include <ieeefp.h> +# define isnan(d) isnand(d) +#endif + +enum { + LittleEndian, + BigEndian +#ifdef Q_BYTE_ORDER +# if Q_BYTE_ORDER == Q_BIG_ENDIAN + , ByteOrder = BigEndian +# elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN + , ByteOrder = LittleEndian +# else +# error "undefined byte order" +# endif +}; +#else +}; +static const unsigned int one = 1; +static const bool ByteOrder = ((*((unsigned char *) &one) == 0) ? BigEndian : LittleEndian); +#endif +#if !defined(INFINITY) +static const unsigned char be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0,0 }; +static const unsigned char le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; +static inline double inf() +{ + if (ByteOrder == BigEndian) + return *reinterpret_cast<const double *>(be_inf_bytes); + return *reinterpret_cast<const double *>(le_inf_bytes); +} +# define INFINITY (::inf()) +#endif +#if !defined(NAN) +static const unsigned char be_nan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0,0 }; +static const unsigned char le_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; +static inline double nan() +{ + if (ByteOrder == BigEndian) + return *reinterpret_cast<const double *>(be_nan_bytes); + return *reinterpret_cast<const double *>(le_nan_bytes); +} +# define NAN (::nan()) +#endif + +tst_QStringRef::tst_QStringRef() +{ +} + +tst_QStringRef::~tst_QStringRef() +{ +} + +void tst_QStringRef::init() +{ +} + +void tst_QStringRef::cleanup() +{ + QLocale::setDefault(QString(QLatin1Char('C'))); +} + +void tst_QStringRef::length_data() +{ + QTest::addColumn<QString>("s1"); + QTest::addColumn<int>("res"); + + QTest::newRow("data0") << QString("Test") << 4; + QTest::newRow("data1") << QString("The quick brown fox jumps over the lazy dog") << 43; + QTest::newRow("data2") << QString() << 0; + QTest::newRow("data3") << QString("A") << 1; + QTest::newRow("data4") << QString("AB") << 2; + QTest::newRow("data5") << QString("AB\n") << 3; + QTest::newRow("data6") << QString("AB\nC") << 4; + QTest::newRow("data7") << QString("\n") << 1; + QTest::newRow("data8") << QString("\nA") << 2; + QTest::newRow("data9") << QString("\nAB") << 3; + QTest::newRow("data10") << QString("\nAB\nCDE") << 7; + QTest::newRow("data11") << QString("shdnftrheid fhgnt gjvnfmd chfugkh bnfhg thgjf vnghturkf chfnguh bjgnfhvygh hnbhgutjfv dhdnjds dcjs d") << 100; + QTest::newRow("data12") << QString("") << 0; +} + + +void tst_QStringRef::length() +{ + QFETCH(QString, s1); + CREATE_REF(s1); + QTEST(ref.length(), "res"); +} + + +void tst_QStringRef::isEmpty() +{ + QStringRef a; + QVERIFY(a.isEmpty()); + QVERIFY(emptyRef().isEmpty()); + CREATE_REF("Not empty"); + QVERIFY(!ref.isEmpty()); +} + +void tst_QStringRef::indexOf_data() +{ + QTest::addColumn<QString>("haystack"); + QTest::addColumn<QString>("needle"); + QTest::addColumn<int>("startpos"); + QTest::addColumn<bool>("bcs"); + QTest::addColumn<int>("resultpos"); + + QTest::newRow("data0") << QString("abc") << QString("a") << 0 << true << 0; + QTest::newRow("data1") << QString("abc") << QString("a") << 0 << false << 0; + QTest::newRow("data2") << QString("abc") << QString("A") << 0 << true << -1; + QTest::newRow("data3") << QString("abc") << QString("A") << 0 << false << 0; + QTest::newRow("data4") << QString("abc") << QString("a") << 1 << true << -1; + QTest::newRow("data5") << QString("abc") << QString("a") << 1 << false << -1; + QTest::newRow("data6") << QString("abc") << QString("A") << 1 << true << -1; + QTest::newRow("data7") << QString("abc") << QString("A") << 1 << false << -1; + QTest::newRow("data8") << QString("abc") << QString("b") << 0 << true << 1; + QTest::newRow("data9") << QString("abc") << QString("b") << 0 << false << 1; + QTest::newRow("data10") << QString("abc") << QString("B") << 0 << true << -1; + QTest::newRow("data11") << QString("abc") << QString("B") << 0 << false << 1; + QTest::newRow("data12") << QString("abc") << QString("b") << 1 << true << 1; + QTest::newRow("data13") << QString("abc") << QString("b") << 1 << false << 1; + QTest::newRow("data14") << QString("abc") << QString("B") << 1 << true << -1; + QTest::newRow("data15") << QString("abc") << QString("B") << 1 << false << 1; + QTest::newRow("data16") << QString("abc") << QString("b") << 2 << true << -1; + QTest::newRow("data17") << QString("abc") << QString("b") << 2 << false << -1; + + QTest::newRow("data20") << QString("ABC") << QString("A") << 0 << true << 0; + QTest::newRow("data21") << QString("ABC") << QString("A") << 0 << false << 0; + QTest::newRow("data22") << QString("ABC") << QString("a") << 0 << true << -1; + QTest::newRow("data23") << QString("ABC") << QString("a") << 0 << false << 0; + QTest::newRow("data24") << QString("ABC") << QString("A") << 1 << true << -1; + QTest::newRow("data25") << QString("ABC") << QString("A") << 1 << false << -1; + QTest::newRow("data26") << QString("ABC") << QString("a") << 1 << true << -1; + QTest::newRow("data27") << QString("ABC") << QString("a") << 1 << false << -1; + QTest::newRow("data28") << QString("ABC") << QString("B") << 0 << true << 1; + QTest::newRow("data29") << QString("ABC") << QString("B") << 0 << false << 1; + QTest::newRow("data30") << QString("ABC") << QString("b") << 0 << true << -1; + QTest::newRow("data31") << QString("ABC") << QString("b") << 0 << false << 1; + QTest::newRow("data32") << QString("ABC") << QString("B") << 1 << true << 1; + QTest::newRow("data33") << QString("ABC") << QString("B") << 1 << false << 1; + QTest::newRow("data34") << QString("ABC") << QString("b") << 1 << true << -1; + QTest::newRow("data35") << QString("ABC") << QString("b") << 1 << false << 1; + QTest::newRow("data36") << QString("ABC") << QString("B") << 2 << true << -1; + QTest::newRow("data37") << QString("ABC") << QString("B") << 2 << false << -1; + + QTest::newRow("data40") << QString("aBc") << QString("bc") << 0 << true << -1; + QTest::newRow("data41") << QString("aBc") << QString("Bc") << 0 << true << 1; + QTest::newRow("data42") << QString("aBc") << QString("bC") << 0 << true << -1; + QTest::newRow("data43") << QString("aBc") << QString("BC") << 0 << true << -1; + QTest::newRow("data44") << QString("aBc") << QString("bc") << 0 << false << 1; + QTest::newRow("data45") << QString("aBc") << QString("Bc") << 0 << false << 1; + QTest::newRow("data46") << QString("aBc") << QString("bC") << 0 << false << 1; + QTest::newRow("data47") << QString("aBc") << QString("BC") << 0 << false << 1; + QTest::newRow("data48") << QString("AbC") << QString("bc") << 0 << true << -1; + QTest::newRow("data49") << QString("AbC") << QString("Bc") << 0 << true << -1; + QTest::newRow("data50") << QString("AbC") << QString("bC") << 0 << true << 1; + QTest::newRow("data51") << QString("AbC") << QString("BC") << 0 << true << -1; + QTest::newRow("data52") << QString("AbC") << QString("bc") << 0 << false << 1; + QTest::newRow("data53") << QString("AbC") << QString("Bc") << 0 << false << 1; + + QTest::newRow("data54") << QString("AbC") << QString("bC") << 0 << false << 1; + QTest::newRow("data55") << QString("AbC") << QString("BC") << 0 << false << 1; + QTest::newRow("data56") << QString("AbC") << QString("BC") << 1 << false << 1; + QTest::newRow("data57") << QString("AbC") << QString("BC") << 2 << false << -1; +#if 0 + QTest::newRow("null-in-null") << QString() << QString() << 0 << false << 0; + QTest::newRow("empty-in-null") << QString() << QString("") << 0 << false << 0; + QTest::newRow("null-in-empty") << QString("") << QString() << 0 << false << 0; + QTest::newRow("empty-in-empty") << QString("") << QString("") << 0 << false << 0; +#endif + + + QString s1 = "abc"; + s1 += QChar(0xb5); + QString s2; + s2 += QChar(0x3bc); + QTest::newRow("data58") << QString(s1) << QString(s2) << 0 << false << 3; + s2.prepend("C"); + QTest::newRow("data59") << QString(s1) << QString(s2) << 0 << false << 2; + + QString veryBigHaystack(500, 'a'); + veryBigHaystack += 'B'; + QTest::newRow("BoyerMooreStressTest") << veryBigHaystack << veryBigHaystack << 0 << true << 0; + QTest::newRow("BoyerMooreStressTest2") << veryBigHaystack + 'c' << veryBigHaystack << 0 << true << 0; + QTest::newRow("BoyerMooreStressTest3") << 'c' + veryBigHaystack << veryBigHaystack << 0 << true << 1; + QTest::newRow("BoyerMooreStressTest4") << veryBigHaystack << veryBigHaystack + 'c' << 0 << true << -1; + QTest::newRow("BoyerMooreStressTest5") << veryBigHaystack << 'c' + veryBigHaystack << 0 << true << -1; + QTest::newRow("BoyerMooreStressTest6") << 'd' + veryBigHaystack << 'c' + veryBigHaystack << 0 << true << -1; + QTest::newRow("BoyerMooreStressTest6") << veryBigHaystack + 'c' << 'c' + veryBigHaystack << 0 << true << -1; + + QTest::newRow("BoyerMooreInsensitiveStressTest") << veryBigHaystack << veryBigHaystack << 0 << false << 0; + +} + +void tst_QStringRef::indexOf() +{ + QFETCH(QString, haystack); + QFETCH(QString, needle); + QFETCH(int, startpos); + QFETCH(bool, bcs); + QFETCH(int, resultpos); + + const QString haystackPadded = QString::fromLatin1(" %1 ").arg(haystack); + const QString needlePadded = QString::fromLatin1(" %1 ").arg(needle); + const QStringRef haystackRef(&haystackPadded, 1, haystack.size()); + const QStringRef needleRef(&needlePadded, 1, needle.size()); + + Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive; + + QCOMPARE(haystack.indexOf(needle, startpos, cs), resultpos); + QCOMPARE(haystackRef.indexOf(needle, startpos, cs), resultpos); + QCOMPARE(haystackRef.indexOf(needleRef, startpos, cs), resultpos); + QCOMPARE(haystack.indexOf(needleRef, startpos, cs), resultpos); + + if (cs == Qt::CaseSensitive) { + QCOMPARE(haystack.indexOf(needle, startpos), resultpos); + QCOMPARE(haystackRef.indexOf(needle, startpos), resultpos); + QCOMPARE(haystackRef.indexOf(needleRef, startpos), resultpos); + QCOMPARE(haystack.indexOf(needleRef, startpos), resultpos); + if (startpos == 0) { + QCOMPARE(haystack.indexOf(needle), resultpos); + QCOMPARE(haystackRef.indexOf(needle), resultpos); + QCOMPARE(haystackRef.indexOf(needleRef), resultpos); + QCOMPARE(haystack.indexOf(needleRef), resultpos); + } + } + if (needle.size() == 1) { + QCOMPARE(needle.at(0), needleRef.at(0)); + QCOMPARE(haystack.indexOf(needleRef.at(0), startpos, cs), resultpos); + QCOMPARE(haystackRef.indexOf(needle.at(0), startpos, cs), resultpos); + QCOMPARE(haystackRef.indexOf(needleRef.at(0), startpos, cs), resultpos); + QCOMPARE(haystack.indexOf(needleRef.at(0), startpos ,cs), resultpos); + } +} + +void tst_QStringRef::indexOf2_data() +{ + QTest::addColumn<QString>("haystack"); + QTest::addColumn<QString>("needle"); + QTest::addColumn<int>("resultpos"); + + QTest::newRow("data0") << QString() << QString() << 0; + QTest::newRow("data1") << QString() << QString("") << 0; + QTest::newRow("data2") << QString("") << QString() << 0; + QTest::newRow("data3") << QString("") << QString("") << 0; + QTest::newRow("data4") << QString() << QString("a") << -1; + QTest::newRow("data5") << QString() << QString("abcdefg") << -1; + QTest::newRow("data6") << QString("") << QString("a") << -1; + QTest::newRow("data7") << QString("") << QString("abcdefg") << -1; + + QTest::newRow("data8") << QString("a") << QString() << 0; + QTest::newRow("data9") << QString("a") << QString("") << 0; + QTest::newRow("data10") << QString("a") << QString("a") << 0; + QTest::newRow("data11") << QString("a") << QString("b") << -1; + QTest::newRow("data12") << QString("a") << QString("abcdefg") << -1; + QTest::newRow("data13") << QString("ab") << QString() << 0; + QTest::newRow("data14") << QString("ab") << QString("") << 0; + QTest::newRow("data15") << QString("ab") << QString("a") << 0; + QTest::newRow("data16") << QString("ab") << QString("b") << 1; + QTest::newRow("data17") << QString("ab") << QString("ab") << 0; + QTest::newRow("data18") << QString("ab") << QString("bc") << -1; + QTest::newRow("data19") << QString("ab") << QString("abcdefg") << -1; + + QTest::newRow("data30") << QString("abc") << QString("a") << 0; + QTest::newRow("data31") << QString("abc") << QString("b") << 1; + QTest::newRow("data32") << QString("abc") << QString("c") << 2; + QTest::newRow("data33") << QString("abc") << QString("d") << -1; + QTest::newRow("data34") << QString("abc") << QString("ab") << 0; + QTest::newRow("data35") << QString("abc") << QString("bc") << 1; + QTest::newRow("data36") << QString("abc") << QString("cd") << -1; + QTest::newRow("data37") << QString("abc") << QString("ac") << -1; + + // sizeof(whale) > 32 + QString whale = "a5zby6cx7dw8evf9ug0th1si2rj3qkp4lomn"; + QString minnow = "zby"; + QTest::newRow("data40") << whale << minnow << 2; + QTest::newRow("data41") << (whale + whale) << minnow << 2; + QTest::newRow("data42") << (minnow + whale) << minnow << 0; + QTest::newRow("data43") << whale << whale << 0; + QTest::newRow("data44") << (whale + whale) << whale << 0; + QTest::newRow("data45") << whale << (whale + whale) << -1; + QTest::newRow("data46") << (whale + whale) << (whale + whale) << 0; + QTest::newRow("data47") << (whale + whale) << (whale + minnow) << -1; + QTest::newRow("data48") << (minnow + whale) << whale << (int)minnow.length(); +} + +void tst_QStringRef::indexOf2() +{ + QFETCH(QString, haystack); + QFETCH(QString, needle); + QFETCH(int, resultpos); + + const QString haystackPadded = QString::fromLatin1(" %1 ").arg(haystack); + const QString needlePadded = QString::fromLatin1(" %1 ").arg(needle); + const QStringRef haystackRef(&haystackPadded, 1, haystack.size()); + const QStringRef needleRef(&needlePadded, 1, needle.size()); + + + int got; + + QCOMPARE(haystack.indexOf(needleRef, 0, Qt::CaseSensitive), resultpos); + QCOMPARE(haystackRef.indexOf(needle, 0, Qt::CaseSensitive), resultpos); + QCOMPARE(haystackRef.indexOf(needleRef, 0, Qt::CaseSensitive), resultpos); + QCOMPARE(haystack.indexOf(needleRef, 0, Qt::CaseInsensitive), resultpos); + QCOMPARE(haystackRef.indexOf(needle, 0, Qt::CaseInsensitive), resultpos); + QCOMPARE(haystackRef.indexOf(needleRef, 0, Qt::CaseInsensitive), resultpos); + if (needle.length() > 0) { + got = haystackRef.lastIndexOf(needle, -1, Qt::CaseSensitive); + QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos)); + got = haystackRef.lastIndexOf(needle, -1, Qt::CaseInsensitive); + QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos)); + + got = haystack.lastIndexOf(needleRef, -1, Qt::CaseSensitive); + QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos)); + got = haystack.lastIndexOf(needleRef, -1, Qt::CaseInsensitive); + QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos)); + + got = haystackRef.lastIndexOf(needleRef, -1, Qt::CaseSensitive); + QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos)); + got = haystackRef.lastIndexOf(needleRef, -1, Qt::CaseInsensitive); + QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos)); + } +} + +void tst_QStringRef::lastIndexOf_data() +{ + QTest::addColumn<QString>("haystack"); + QTest::addColumn<QString>("needle"); + QTest::addColumn<int>("from"); + QTest::addColumn<int>("expected"); + QTest::addColumn<bool>("caseSensitive"); + + QString a = "ABCDEFGHIEfGEFG"; + + QTest::newRow("-1") << a << "G" << a.size() - 1 << 14 << true; + QTest::newRow("1") << a << "G" << - 1 << 14 << true; + QTest::newRow("2") << a << "G" << -3 << 11 << true; + QTest::newRow("3") << a << "G" << -5 << 6 << true; + QTest::newRow("4") << a << "G" << 14 << 14 << true; + QTest::newRow("5") << a << "G" << 13 << 11 << true; + QTest::newRow("6") << a << "B" << a.size() - 1 << 1 << true; + QTest::newRow("6") << a << "B" << - 1 << 1 << true; + QTest::newRow("7") << a << "B" << 1 << 1 << true; + QTest::newRow("8") << a << "B" << 0 << -1 << true; + + QTest::newRow("9") << a << "G" << -1 << a.size()-1 << true; + QTest::newRow("10") << a << "G" << a.size()-1 << a.size()-1 << true; + QTest::newRow("11") << a << "G" << a.size() << -1 << true; + QTest::newRow("12") << a << "A" << 0 << 0 << true; + QTest::newRow("13") << a << "A" << -1*a.size() << 0 << true; + + QTest::newRow("15") << a << "efg" << 0 << -1 << false; + QTest::newRow("16") << a << "efg" << a.size() << -1 << false; + QTest::newRow("17") << a << "efg" << -1 * a.size() << -1 << false; + QTest::newRow("19") << a << "efg" << a.size() - 1 << 12 << false; + QTest::newRow("20") << a << "efg" << 12 << 12 << false; + QTest::newRow("21") << a << "efg" << -12 << -1 << false; + QTest::newRow("22") << a << "efg" << 11 << 9 << false; + + QTest::newRow("24") << "" << "asdf" << -1 << -1 << false; + QTest::newRow("25") << "asd" << "asdf" << -1 << -1 << false; + QTest::newRow("26") << "" << QString() << -1 << -1 << false; + + QTest::newRow("27") << a << "" << a.size() << a.size() << false; + QTest::newRow("28") << a << "" << a.size() + 10 << -1 << false; +} + +void tst_QStringRef::lastIndexOf() +{ + QFETCH(QString, haystack); + QFETCH(QString, needle); + QFETCH(int, from); + QFETCH(int, expected); + QFETCH(bool, caseSensitive); + + const QString haystackPadded = QString::fromLatin1(" %1 ").arg(haystack); + const QString needlePadded = QString::fromLatin1(" %1 ").arg(needle); + const QStringRef haystackRef(&haystackPadded, 1, haystack.size()); + const QStringRef needleRef(&needlePadded, 1, needle.size()); + + Qt::CaseSensitivity cs = (caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); + + QCOMPARE(haystack.lastIndexOf(needleRef, from, cs), expected); + QCOMPARE(haystackRef.lastIndexOf(needle, from, cs), expected); + QCOMPARE(haystackRef.lastIndexOf(needleRef, from, cs), expected); + + + if (cs == Qt::CaseSensitive) { + QCOMPARE(haystack.lastIndexOf(needleRef, from), expected); + QCOMPARE(haystackRef.lastIndexOf(needle, from), expected); + QCOMPARE(haystackRef.lastIndexOf(needleRef, from), expected); + + if (from == -1) { + QCOMPARE(haystack.lastIndexOf(needleRef), expected); + QCOMPARE(haystackRef.lastIndexOf(needle), expected); + QCOMPARE(haystackRef.lastIndexOf(needleRef), expected); + + } + } + if (needle.size() == 1) { + QCOMPARE(haystack.lastIndexOf(needleRef.at(0), from), expected); + QCOMPARE(haystackRef.lastIndexOf(needle.at(0), from), expected); + QCOMPARE(haystackRef.lastIndexOf(needleRef.at(0), from), expected); + } +} + +void tst_QStringRef::count() +{ + const QString a = QString::fromLatin1("ABCDEFGHIEfGEFG"); // 15 chars + CREATE_REF(a); + QCOMPARE(ref.count('A'),1); + QCOMPARE(ref.count('Z'),0); + QCOMPARE(ref.count('E'),3); + QCOMPARE(ref.count('F'),2); + QCOMPARE(ref.count('F',Qt::CaseInsensitive),3); + QCOMPARE(ref.count("FG"),2); + QCOMPARE(ref.count("FG",Qt::CaseInsensitive),3); + QCOMPARE(ref.count(QString(), Qt::CaseInsensitive), 16); + QCOMPARE(ref.count("", Qt::CaseInsensitive), 16); +} + +void tst_QStringRef::contains() +{ + const QString a = QString::fromLatin1("ABCDEFGHIEfGEFG"); // 15 chars + CREATE_REF(a); + QVERIFY(ref.contains('A')); + QVERIFY(!ref.contains('Z')); + QVERIFY(ref.contains('E')); + QVERIFY(ref.contains('F')); + QVERIFY(ref.contains('F',Qt::CaseInsensitive)); + QVERIFY(ref.contains("FG")); + QVERIFY(ref.contains(QString("FG").midRef(0))); + const QString ref2 = QString::fromLatin1(" FG "); + QVERIFY(ref.contains(ref2.midRef(1, 2),Qt::CaseInsensitive)); + QVERIFY(ref.contains(QString(), Qt::CaseInsensitive)); + QVERIFY(ref.contains("", Qt::CaseInsensitive)); // apparently +} + +void tst_QStringRef::startsWith() +{ + { + const QString a = QString::fromLatin1("AB"); + CREATE_REF(a); + QVERIFY(ref.startsWith("A")); + QVERIFY(ref.startsWith("AB")); + QVERIFY(!ref.startsWith("C")); + QVERIFY(!ref.startsWith("ABCDEF")); + QVERIFY(ref.startsWith("")); + QVERIFY(ref.startsWith(QString::null)); + QVERIFY(ref.startsWith('A')); + QVERIFY(ref.startsWith(QLatin1Char('A'))); + QVERIFY(ref.startsWith(QChar('A'))); + QVERIFY(!ref.startsWith('C')); + QVERIFY(!ref.startsWith(QChar())); + QVERIFY(!ref.startsWith(QLatin1Char(0))); + + QVERIFY(ref.startsWith(QLatin1String("A"))); + QVERIFY(ref.startsWith(QLatin1String("AB"))); + QVERIFY(!ref.startsWith(QLatin1String("C"))); + QVERIFY(!ref.startsWith(QLatin1String("ABCDEF"))); + QVERIFY(ref.startsWith(QLatin1String(""))); + QVERIFY(ref.startsWith(QLatin1String(0))); + + QVERIFY(ref.startsWith("A", Qt::CaseSensitive)); + QVERIFY(ref.startsWith("A", Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith("a", Qt::CaseSensitive)); + QVERIFY(ref.startsWith("a", Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith("aB", Qt::CaseSensitive)); + QVERIFY(ref.startsWith("aB", Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith("C", Qt::CaseSensitive)); + QVERIFY(!ref.startsWith("C", Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith("c", Qt::CaseSensitive)); + QVERIFY(!ref.startsWith("c", Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith("abcdef", Qt::CaseInsensitive)); + QVERIFY(ref.startsWith("", Qt::CaseInsensitive)); + QVERIFY(ref.startsWith(QString::null, Qt::CaseInsensitive)); + QVERIFY(ref.startsWith('a', Qt::CaseInsensitive)); + QVERIFY(ref.startsWith('A', Qt::CaseInsensitive)); + QVERIFY(ref.startsWith(QLatin1Char('a'), Qt::CaseInsensitive)); + QVERIFY(ref.startsWith(QChar('a'), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith('c', Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QChar(), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QLatin1Char(0), Qt::CaseInsensitive)); + + QVERIFY(ref.startsWith(QLatin1String("A"), Qt::CaseSensitive)); + QVERIFY(ref.startsWith(QLatin1String("A"), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QLatin1String("a"), Qt::CaseSensitive)); + QVERIFY(ref.startsWith(QLatin1String("a"), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QLatin1String("aB"), Qt::CaseSensitive)); + QVERIFY(ref.startsWith(QLatin1String("aB"), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QLatin1String("C"), Qt::CaseSensitive)); + QVERIFY(!ref.startsWith(QLatin1String("C"), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QLatin1String("c"), Qt::CaseSensitive)); + QVERIFY(!ref.startsWith(QLatin1String("c"), Qt::CaseInsensitive)); + QVERIFY(!ref.startsWith(QLatin1String("abcdef"), Qt::CaseInsensitive)); + QVERIFY(ref.startsWith(QLatin1String(""), Qt::CaseInsensitive)); + QVERIFY(ref.startsWith(QLatin1String(0), Qt::CaseInsensitive)); + QVERIFY(ref.startsWith('A', Qt::CaseSensitive)); + QVERIFY(ref.startsWith(QLatin1Char('A'), Qt::CaseSensitive)); + QVERIFY(ref.startsWith(QChar('A'), Qt::CaseSensitive)); + QVERIFY(!ref.startsWith('a', Qt::CaseSensitive)); + QVERIFY(!ref.startsWith(QChar(), Qt::CaseSensitive)); + QVERIFY(!ref.startsWith(QLatin1Char(0), Qt::CaseSensitive)); + } + { + const QString a = QString::fromLatin1(""); + CREATE_REF(a); + QVERIFY(ref.startsWith("")); + QVERIFY(ref.startsWith(QString::null)); + QVERIFY(!ref.startsWith("ABC")); + + QVERIFY(ref.startsWith(QLatin1String(""))); + QVERIFY(ref.startsWith(QLatin1String(0))); + QVERIFY(!ref.startsWith(QLatin1String("ABC"))); + + QVERIFY(!ref.startsWith(QLatin1Char(0))); + QVERIFY(!ref.startsWith(QLatin1Char('x'))); + QVERIFY(!ref.startsWith(QChar())); + } + { + const QStringRef ref; + QVERIFY(!ref.startsWith("")); + QVERIFY(ref.startsWith(QString::null)); + QVERIFY(!ref.startsWith("ABC")); + + QVERIFY(!ref.startsWith(QLatin1String(""))); + QVERIFY(ref.startsWith(QLatin1String(0))); + QVERIFY(!ref.startsWith(QLatin1String("ABC"))); + + QVERIFY(!ref.startsWith(QLatin1Char(0))); + QVERIFY(!ref.startsWith(QLatin1Char('x'))); + QVERIFY(!ref.startsWith(QChar())); + } +} + +void tst_QStringRef::endsWith() +{ + { + const QString a = QString::fromLatin1("AB"); + CREATE_REF(a); + QVERIFY(ref.endsWith("B")); + QVERIFY(ref.endsWith("AB")); + QVERIFY(!ref.endsWith("C")); + QVERIFY(!ref.endsWith("ABCDEF")); + QVERIFY(ref.endsWith("")); + QVERIFY(ref.endsWith(QString::null)); + QVERIFY(ref.endsWith('B')); + QVERIFY(ref.endsWith(QLatin1Char('B'))); + QVERIFY(ref.endsWith(QChar('B'))); + QVERIFY(!ref.endsWith('C')); + QVERIFY(!ref.endsWith(QChar())); + QVERIFY(!ref.endsWith(QLatin1Char(0))); + + QVERIFY(ref.endsWith(QLatin1String("B"))); + QVERIFY(ref.endsWith(QLatin1String("AB"))); + QVERIFY(!ref.endsWith(QLatin1String("C"))); + QVERIFY(!ref.endsWith(QLatin1String("ABCDEF"))); + QVERIFY(ref.endsWith(QLatin1String(""))); + QVERIFY(ref.endsWith(QLatin1String(0))); + + QVERIFY(ref.endsWith("B", Qt::CaseSensitive)); + QVERIFY(ref.endsWith("B", Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith("b", Qt::CaseSensitive)); + QVERIFY(ref.endsWith("b", Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith("aB", Qt::CaseSensitive)); + QVERIFY(ref.endsWith("aB", Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith("C", Qt::CaseSensitive)); + QVERIFY(!ref.endsWith("C", Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith("c", Qt::CaseSensitive)); + QVERIFY(!ref.endsWith("c", Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith("abcdef", Qt::CaseInsensitive)); + QVERIFY(ref.endsWith("", Qt::CaseInsensitive)); + QVERIFY(ref.endsWith(QString::null, Qt::CaseInsensitive)); + QVERIFY(ref.endsWith('b', Qt::CaseInsensitive)); + QVERIFY(ref.endsWith('B', Qt::CaseInsensitive)); + QVERIFY(ref.endsWith(QLatin1Char('b'), Qt::CaseInsensitive)); + QVERIFY(ref.endsWith(QChar('b'), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith('c', Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QChar(), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QLatin1Char(0), Qt::CaseInsensitive)); + + QVERIFY(ref.endsWith(QLatin1String("B"), Qt::CaseSensitive)); + QVERIFY(ref.endsWith(QLatin1String("B"), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QLatin1String("b"), Qt::CaseSensitive)); + QVERIFY(ref.endsWith(QLatin1String("b"), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QLatin1String("aB"), Qt::CaseSensitive)); + QVERIFY(ref.endsWith(QLatin1String("aB"), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QLatin1String("C"), Qt::CaseSensitive)); + QVERIFY(!ref.endsWith(QLatin1String("C"), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QLatin1String("c"), Qt::CaseSensitive)); + QVERIFY(!ref.endsWith(QLatin1String("c"), Qt::CaseInsensitive)); + QVERIFY(!ref.endsWith(QLatin1String("abcdef"), Qt::CaseInsensitive)); + QVERIFY(ref.endsWith(QLatin1String(""), Qt::CaseInsensitive)); + QVERIFY(ref.endsWith(QLatin1String(0), Qt::CaseInsensitive)); + QVERIFY(ref.endsWith('B', Qt::CaseSensitive)); + QVERIFY(ref.endsWith(QLatin1Char('B'), Qt::CaseSensitive)); + QVERIFY(ref.endsWith(QChar('B'), Qt::CaseSensitive)); + QVERIFY(!ref.endsWith('b', Qt::CaseSensitive)); + QVERIFY(!ref.endsWith(QChar(), Qt::CaseSensitive)); + QVERIFY(!ref.endsWith(QLatin1Char(0), Qt::CaseSensitive)); + + } + { + const QString a = QString::fromLatin1(""); + CREATE_REF(a); + QVERIFY(ref.endsWith("")); + QVERIFY(ref.endsWith(QString::null)); + QVERIFY(!ref.endsWith("ABC")); + QVERIFY(!ref.endsWith(QLatin1Char(0))); + QVERIFY(!ref.endsWith(QLatin1Char('x'))); + QVERIFY(!ref.endsWith(QChar())); + + QVERIFY(ref.endsWith(QLatin1String(""))); + QVERIFY(ref.endsWith(QLatin1String(0))); + QVERIFY(!ref.endsWith(QLatin1String("ABC"))); + } + + { + QStringRef ref; + QVERIFY(!ref.endsWith("")); + QVERIFY(ref.endsWith(QString::null)); + QVERIFY(!ref.endsWith("ABC")); + + QVERIFY(!ref.endsWith(QLatin1String(""))); + QVERIFY(ref.endsWith(QLatin1String(0))); + QVERIFY(!ref.endsWith(QLatin1String("ABC"))); + + QVERIFY(!ref.endsWith(QLatin1Char(0))); + QVERIFY(!ref.endsWith(QLatin1Char('x'))); + QVERIFY(!ref.endsWith(QChar())); + } +} + +void tst_QStringRef::operator_eqeq_nullstring() +{ + /* Some of these might not be all that logical but it's the behaviour we've had since 3.0.0 + so we should probably stick with it. */ + + QVERIFY(QStringRef() == ""); + QVERIFY("" == QStringRef()); + + QVERIFY(QString("") == ""); + QVERIFY("" == QString("")); + + QVERIFY(QStringRef().size() == 0); + + QVERIFY(QString("").size() == 0); + + QVERIFY(QStringRef() == QString("")); + QVERIFY(QString("") == QString()); +} + +static inline int sign(int x) +{ + return x == 0 ? 0 : (x < 0 ? -1 : 1); +} + +void tst_QStringRef::compare_data() +{ + QTest::addColumn<QString>("s1"); + QTest::addColumn<QString>("s2"); + QTest::addColumn<int>("csr"); // case sensitive result + QTest::addColumn<int>("cir"); // case insensitive result + + + // null strings + QTest::newRow("data0") << QString("") << QString("") << 0 << 0; + QTest::newRow("data1") << QString("a") << QString("") << 1 << 1; + QTest::newRow("data2") << QString("") << QString("a") << -1 << -1; + + // equal length + QTest::newRow("data3") << QString("abc") << QString("abc") << 0 << 0; + QTest::newRow("data4") << QString("abC") << QString("abc") << -1 << 0; + QTest::newRow("data5") << QString("abc") << QString("abC") << 1 << 0; + + // different length + QTest::newRow("data6") << QString("abcdef") << QString("abc") << 1 << 1; + QTest::newRow("data6") << QString("abCdef") << QString("abc") << -1 << 1; + QTest::newRow("data7") << QString("abc") << QString("abcdef") << -1 << -1; + + QString upper; + upper += QChar(QChar::highSurrogate(0x10400)); + upper += QChar(QChar::lowSurrogate(0x10400)); + QString lower; + lower += QChar(QChar::highSurrogate(0x10428)); + lower += QChar(QChar::lowSurrogate(0x10428)); + QTest::newRow("data8") << upper << lower << -1 << 0; + + // embedded nulls + // These dont work as of now. Its OK that these dont work since \0 is not a valid unicode + /*QTest::newRow("data9") << QString(QByteArray("\0", 1)) << QString(QByteArray("\0", 1)) << 0 << 0; + QTest::newRow("data10") << QString(QByteArray("\0", 1)) << QString("") << 1 << 1; + QTest::newRow("data11") << QString("") << QString(QByteArray("\0", 1)) << -1 << -1; + QTest::newRow("data12") << QString("ab\0c") << QString(QByteArray("ab\0c", 4)) << 0 << 0; + QTest::newRow("data13") << QString(QByteArray("ab\0c", 4)) << QString("abc") << -1 << -1; + QTest::newRow("data14") << QString("abc") << QString(QByteArray("ab\0c", 4)) << 1 << 1;*/ +} + +static bool isLatin(const QString &s) +{ + for (int i = 0; i < s.length(); ++i) + if (s.at(i).unicode() > 0xff) + return false; + return true; +} + +void tst_QStringRef::compare() +{ + QFETCH(QString, s1); + QFETCH(QString, s2); + QFETCH(int, csr); + QFETCH(int, cir); + + QStringRef r1(&s1, 0, s1.length()); + QStringRef r2(&s2, 0, s2.length()); + + QCOMPARE(sign(QString::compare(s1, s2)), csr); + QCOMPARE(sign(QStringRef::compare(r1, r2)), csr); + QCOMPARE(sign(s1.compare(s2)), csr); + QCOMPARE(sign(s1.compare(r2)), csr); + QCOMPARE(sign(r1.compare(r2)), csr); + + QCOMPARE(sign(s1.compare(s2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(s1.compare(s2, Qt::CaseInsensitive)), cir); + QCOMPARE(sign(s1.compare(r2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(s1.compare(r2, Qt::CaseInsensitive)), cir); + QCOMPARE(sign(r1.compare(r2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(r1.compare(r2, Qt::CaseInsensitive)), cir); + + QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseInsensitive)), cir); + QCOMPARE(sign(QString::compare(s1, r2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(QString::compare(s1, r2, Qt::CaseInsensitive)), cir); + QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseInsensitive)), cir); + + if (!cir) { + QCOMPARE(s1.toCaseFolded(), s2.toCaseFolded()); + } + + if (isLatin(s2)) { + QCOMPARE(sign(QString::compare(s1, QLatin1String(s2.toLatin1()))), csr); + QCOMPARE(sign(QString::compare(s1, QLatin1String(s2.toLatin1()), Qt::CaseInsensitive)), cir); + QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(s2.toLatin1()))), csr); + QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(s2.toLatin1()), Qt::CaseInsensitive)), cir); + } + + if (isLatin(s1)) { + QCOMPARE(sign(QString::compare(QLatin1String(s1.toLatin1()), s2)), csr); + QCOMPARE(sign(QString::compare(QLatin1String(s1.toLatin1()), s2, Qt::CaseInsensitive)), cir); + } +} + +QTEST_APPLESS_MAIN(tst_QStringRef) + +#include "tst_qstringref.moc" diff --git a/tests/auto/qstyle/qstyle.pro b/tests/auto/qstyle/qstyle.pro index 11f5943..eb198e2 100644 --- a/tests/auto/qstyle/qstyle.pro +++ b/tests/auto/qstyle/qstyle.pro @@ -4,7 +4,7 @@ SOURCES += tst_qstyle.cpp wince*|symbian: { !symbian:DEFINES += SRCDIR=\\\".\\\" - addPixmap.sources = task_25863.png + addPixmap.files = task_25863.png addPixmap.path = . DEPLOYMENT += addPixmap } else { diff --git a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp index 3805081..1799019 100644 --- a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -105,6 +105,7 @@ private slots: //at the end because it mess with the style. void widgetStyle(); void appStyle(); + void QTBUG11658_cachecrash(); private: QColor COLOR(const QWidget& w) { w.ensurePolished(); @@ -1627,6 +1628,36 @@ void tst_QStyleSheetStyle::changeStyleInChangeEvent() wid.ensurePolished(); } +void tst_QStyleSheetStyle::QTBUG11658_cachecrash() +{ + //should not crash + class Widget : public QWidget + { + public: + Widget(QWidget *parent = 0) + : QWidget(parent) + { + QVBoxLayout* pLayout = new QVBoxLayout(this); + QCheckBox* pCheckBox = new QCheckBox(this); + pLayout->addWidget(pCheckBox); + setLayout(pLayout); + + QString szStyleSheet = QLatin1String("* { color: red; }"); + qApp->setStyleSheet(szStyleSheet); + qApp->setStyle(QStyleFactory::create(QLatin1String("Windows"))); + } + }; + + Widget *w = new Widget(); + delete w; + w = new Widget(); + w->show(); + + QTest::qWaitForWindowShown(w); + delete w; + qApp->setStyleSheet(QString()); +} + void tst_QStyleSheetStyle::QTBUG15910_crashNullWidget() { struct : QWidget { diff --git a/tests/auto/qsvggenerator/qsvggenerator.pro b/tests/auto/qsvggenerator/qsvggenerator.pro index 1ccf8e9..2e899a9 100644 --- a/tests/auto/qsvggenerator/qsvggenerator.pro +++ b/tests/auto/qsvggenerator/qsvggenerator.pro @@ -8,7 +8,7 @@ QT += svg xml SOURCES += tst_qsvggenerator.cpp wince*|symbian { - addFiles.sources = referenceSvgs + addFiles.files = referenceSvgs addFiles.path = . DEPLOYMENT += addFiles } diff --git a/tests/auto/qsvgrenderer/qsvgrenderer.pro b/tests/auto/qsvgrenderer/qsvgrenderer.pro index 9f0f886..fc98776 100644 --- a/tests/auto/qsvgrenderer/qsvgrenderer.pro +++ b/tests/auto/qsvgrenderer/qsvgrenderer.pro @@ -9,7 +9,7 @@ SOURCES += tst_qsvgrenderer.cpp RESOURCES += resources.qrc wince*|symbian { - addFiles.sources = *.svg *.svgz + addFiles.files = *.svg *.svgz addFiles.path = . DEPLOYMENT += addFiles diff --git a/tests/auto/qtabbar/tst_qtabbar.cpp b/tests/auto/qtabbar/tst_qtabbar.cpp index 4e00612..2c5458e 100644 --- a/tests/auto/qtabbar/tst_qtabbar.cpp +++ b/tests/auto/qtabbar/tst_qtabbar.cpp @@ -76,6 +76,7 @@ private slots: void setElideMode_data(); void setElideMode(); + void sizeHints(); void setUsesScrollButtons_data(); void setUsesScrollButtons(); @@ -280,6 +281,46 @@ void tst_QTabBar::setElideMode() QTEST(int(tabBar.elideMode()), "expectedMode"); } +void tst_QTabBar::sizeHints() +{ + QTabBar tabBar; + QSKIP("To be fixed on Mac (font size below not large enough) and Linux QWS (probably too large for the screen).", SkipSingle); + tabBar.setFont(QFont("Arial", 10)); + tabBar.addTab("tab 01"); + tabBar.addTab("tab 02"); + tabBar.addTab("tab 03"); + tabBar.addTab("tab 04"); + tabBar.addTab("tab 05"); + tabBar.addTab("tab 06"); + tabBar.addTab("This is tab7"); + tabBar.addTab("This is tab8"); + tabBar.addTab("This is tab9 with a very long title"); + + // No eliding and no scrolling -> tabbar becomes very wide + tabBar.setUsesScrollButtons(false); + tabBar.setElideMode(Qt::ElideNone); +// qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint(); + QVERIFY(tabBar.minimumSizeHint().width() > 700); + QVERIFY(tabBar.sizeHint().width() > 700); + + // Scrolling enabled -> no reason to become very wide + tabBar.setUsesScrollButtons(true); + // qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint(); + QVERIFY(tabBar.minimumSizeHint().width() < 200); + QVERIFY(tabBar.sizeHint().width() > 700); // unchanged + + // Eliding enabled -> no reason to become very wide + tabBar.setUsesScrollButtons(false); + tabBar.setElideMode(Qt::ElideRight); +// qDebug() << tabBar.minimumSizeHint() << tabBar.sizeHint(); + QVERIFY(tabBar.minimumSizeHint().width() < 500); + QVERIFY(tabBar.sizeHint().width() > 700); // unchanged + + tabBar.addTab("This is tab10 with a very long title"); + QVERIFY(tabBar.minimumSizeHint().width() < 600); + QVERIFY(tabBar.sizeHint().width() > 700); // unchanged +} + void tst_QTabBar::setUsesScrollButtons_data() { QTest::addColumn<int>("usesArrows"); diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index 41cabe8..c6da79a 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -3028,7 +3028,7 @@ void tst_QTableView::spans_data() << 1 << 2; - QTest::newRow("QTBUG-6004: No failing Q_ASSERT, then it passes.") + QTest::newRow("QTBUG-6004: No failing assertion, then it passes.") << 5 << 5 << (SpanList() << QRect(0, 0, 2, 2) << QRect(0, 0, 1, 1)) << false @@ -3036,7 +3036,7 @@ void tst_QTableView::spans_data() << 1 << 1; - QTest::newRow("QTBUG-6004 (follow-up): No failing Q_ASSERT, then it passes.") + QTest::newRow("QTBUG-6004 (follow-up): No failing assertion, then it passes.") << 10 << 10 << (SpanList() << QRect(2, 2, 1, 3) << QRect(2, 2, 1, 1)) << false diff --git a/tests/auto/qtablewidget/tst_qtablewidget.cpp b/tests/auto/qtablewidget/tst_qtablewidget.cpp index cbe38e0..0b66f4d 100644 --- a/tests/auto/qtablewidget/tst_qtablewidget.cpp +++ b/tests/auto/qtablewidget/tst_qtablewidget.cpp @@ -41,6 +41,7 @@ #include <QtTest/QtTest> +#include "../../shared/util.h" #include <qeventloop.h> #include <qlist.h> #include <qpair.h> @@ -1472,7 +1473,7 @@ void tst_QTableWidget::task219380_removeLastRow() testWidget->removeRow(19); //we remove the last row //we make sure the editor is at the cell position - QCOMPARE(testWidget->cellWidget(18, 0)->geometry(), testWidget->visualItemRect(&item)); + QTRY_COMPARE(testWidget->cellWidget(18, 0)->geometry(), testWidget->visualItemRect(&item)); } void tst_QTableWidget::task262056_sortDuplicate() diff --git a/tests/auto/qtabwidget/tst_qtabwidget.cpp b/tests/auto/qtabwidget/tst_qtabwidget.cpp index 0d42cee..cc3dfc1 100644 --- a/tests/auto/qtabwidget/tst_qtabwidget.cpp +++ b/tests/auto/qtabwidget/tst_qtabwidget.cpp @@ -45,6 +45,7 @@ #include <qdebug.h> #include <qapplication.h> #include <qlabel.h> +#include <QtGui/qboxlayout.h> //TESTED_CLASS= //TESTED_FILES= @@ -120,6 +121,9 @@ class tst_QTabWidget:public QObject { void clear(); void keyboardNavigation(); void paintEventCount(); + void minimumSizeHint(); + void heightForWidth_data(); + void heightForWidth(); private: int addPage(); @@ -624,6 +628,74 @@ void tst_QTabWidget::paintEventCount() QCOMPARE(tab2->count, 1); } +void tst_QTabWidget::minimumSizeHint() +{ + QTabWidget tw; + QWidget *page = new QWidget; + QVBoxLayout *lay = new QVBoxLayout; + + QLabel *label = new QLabel(QLatin1String("XXgypq lorem ipsum must be long, must be long. lorem ipsumMMMW")); + lay->addWidget(label); + + page->setLayout(lay); + + tw.addTab(page, QLatin1String("page1")); + + tw.show(); + QTest::qWaitForWindowShown(&tw); + tw.resize(tw.minimumSizeHint()); + + QSize minSize = label->minimumSizeHint(); + QSize actSize = label->geometry().size(); + QVERIFY(minSize.width() <= actSize.width()); + QVERIFY(minSize.height() <= actSize.height()); +} + +void tst_QTabWidget::heightForWidth_data() +{ + QTest::addColumn<int>("tabPosition"); + QTest::newRow("West") << int(QTabWidget::West); + QTest::newRow("North") << int(QTabWidget::North); + QTest::newRow("East") << int(QTabWidget::East); + QTest::newRow("South") << int(QTabWidget::South); +} + +void tst_QTabWidget::heightForWidth() +{ + QFETCH(int, tabPosition); + + QWidget *window = new QWidget; + QVBoxLayout *lay = new QVBoxLayout(window); + lay->setMargin(0); + lay->setSpacing(0); + QTabWidget *tabWid = new QTabWidget(window); + QWidget *w = new QWidget; + tabWid->addTab(w, QLatin1String("HFW page")); + tabWid->setTabPosition(QTabWidget::TabPosition(tabPosition)); + QVBoxLayout *lay2 = new QVBoxLayout(w); + QLabel *label = new QLabel("Label with wordwrap turned on makes it trade height for width." + " Make it a really long text so that it spans on several lines" + " when the label is on its narrowest." + " I don't like to repeat myself." + " I don't like to repeat myself." + " I don't like to repeat myself." + " I don't like to repeat myself." + ); + label->setWordWrap(true); + lay2->addWidget(label); + lay2->setMargin(0); + + lay->addWidget(tabWid); + int h = window->heightForWidth(160); + window->resize(160, h); + window->show(); + + QTest::qWaitForWindowShown(window); + QVERIFY(label->height() >= label->heightForWidth(label->width())); + + delete window; +} + QTEST_MAIN(tst_QTabWidget) #include "tst_qtabwidget.moc" diff --git a/tests/auto/qtconcurrentfilter/qtconcurrentfilter.pro b/tests/auto/qtconcurrentfilter/qtconcurrentfilter.pro index e93c5d2..ee2b77d 100644 --- a/tests/auto/qtconcurrentfilter/qtconcurrentfilter.pro +++ b/tests/auto/qtconcurrentfilter/qtconcurrentfilter.pro @@ -2,3 +2,5 @@ load(qttest_p4) DEFINES += QT_STRICT_ITERATORS SOURCES += tst_qtconcurrentfilter.cpp QT = core +CONFIG += parallel_test +CONFIG += parallel_test diff --git a/tests/auto/qtconcurrentiteratekernel/qtconcurrentiteratekernel.pro b/tests/auto/qtconcurrentiteratekernel/qtconcurrentiteratekernel.pro index 4fdcc22..a61d275 100644 --- a/tests/auto/qtconcurrentiteratekernel/qtconcurrentiteratekernel.pro +++ b/tests/auto/qtconcurrentiteratekernel/qtconcurrentiteratekernel.pro @@ -1,3 +1,5 @@ load(qttest_p4) SOURCES += tst_qtconcurrentiteratekernel.cpp QT = core +CONFIG += parallel_test +CONFIG += parallel_test diff --git a/tests/auto/qtconcurrentmap/qtconcurrentmap.pro b/tests/auto/qtconcurrentmap/qtconcurrentmap.pro index 8cae714..6fc3585 100644 --- a/tests/auto/qtconcurrentmap/qtconcurrentmap.pro +++ b/tests/auto/qtconcurrentmap/qtconcurrentmap.pro @@ -2,3 +2,5 @@ load(qttest_p4) DEFINES += QT_STRICT_ITERATORS SOURCES += tst_qtconcurrentmap.cpp QT = core +CONFIG += parallel_test +CONFIG += parallel_test diff --git a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp index 74ffff2..f4249ab 100644 --- a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -146,6 +146,15 @@ void tst_QtConcurrentMap::map() QCOMPARE(numberList, QList<Number>() << 2 << 4 << 6); QtConcurrent::map(numberList.begin(), numberList.end(), &Number::multiplyBy2).waitForFinished(); QCOMPARE(numberList, QList<Number>() << 4 << 8 << 12); + +#ifdef Q_COMPILER_LAMBDA + // lambda + QtConcurrent::map(list, [](int &x){x *= 2;}).waitForFinished(); + QCOMPARE(list, QList<int>() << 128 << 256 << 384); + QtConcurrent::map(list.begin(), list.end(), [](int &x){x *= 2;}).waitForFinished(); + QCOMPARE(list, QList<int>() << 256 << 512 << 768); +#endif + } // functors don't take arguments by reference, making these no-ops @@ -170,6 +179,14 @@ void tst_QtConcurrentMap::map() QCOMPARE(list, QList<int>() << 1 << 2 << 3); QtConcurrent::map(list.begin(), list.end(), multiplyBy2Immutable).waitForFinished(); QCOMPARE(list, QList<int>() << 1 << 2 << 3); + +#ifdef Q_COMPILER_LAMBDA + // lambda + QtConcurrent::map(list, [](int x){x *= 2;}).waitForFinished(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QtConcurrent::map(list.begin(), list.end(), [](int x){x *= 2;}).waitForFinished(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); +#endif } // Linked lists and forward iterators @@ -2303,6 +2320,10 @@ void tst_QtConcurrentMap::stlContainers() { #ifdef QT_NO_STL QSKIP("Qt compiled without STL support", SkipAll); +#elif defined(Q_COMPILER_RVALUE_REFS) + //mapped uses &Container::push_back, but in c++0x, std::vector has two overload of it + // meaning it is not possible to take the address of that function anymore. + QSKIP("mapped do not work with c++0x stl vector", SkipAll); #else std::vector<int> vector; vector.push_back(1); @@ -2418,6 +2439,7 @@ void tst_QtConcurrentMap::incrementalResults() {} void tst_QtConcurrentMap::stressTest() {} void tst_QtConcurrentMap::throttling() {} void tst_QtConcurrentMap::stlContainers() {} +void tst_QtConcurrentMap::qFutureAssignmentLeak() { } void tst_QtConcurrentMap::noDetatch() {} QTEST_NOOP_MAIN diff --git a/tests/auto/qtconcurrentrun/qtconcurrentrun.pro b/tests/auto/qtconcurrentrun/qtconcurrentrun.pro index ac29dd4..2457604 100644 --- a/tests/auto/qtconcurrentrun/qtconcurrentrun.pro +++ b/tests/auto/qtconcurrentrun/qtconcurrentrun.pro @@ -1,3 +1,5 @@ load(qttest_p4) SOURCES += tst_qtconcurrentrun.cpp QT = core +CONFIG += parallel_test +CONFIG += parallel_test diff --git a/tests/auto/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/qtconcurrentrun/tst_qtconcurrentrun.cpp index 77709a4..cacb09a 100644 --- a/tests/auto/qtconcurrentrun/tst_qtconcurrentrun.cpp +++ b/tests/auto/qtconcurrentrun/tst_qtconcurrentrun.cpp @@ -61,9 +61,14 @@ private slots: void implicitConvertibleTypes(); void runWaitLoop(); void recursive(); +#ifndef QT_NO_EXCEPTIONS + void exceptions(); +#endif #if 0 void createFunctor(); #endif + void functor(); + void lambda(); }; #if 0 @@ -374,6 +379,41 @@ int fn2(double, int *) return 1; } + +#ifndef QT_NO_EXCEPTIONS +void throwFunction() +{ + throw QtConcurrent::Exception(); +} + +int throwFunctionReturn() +{ + throw QtConcurrent::Exception(); + return 0; +} + +void tst_QtConcurrentRun::exceptions() +{ + bool caught = false; + try { + QtConcurrent::run(throwFunction).waitForFinished(); + } catch (Exception &e) { + caught = true; + } + if (!caught) + QFAIL("did not get exception"); + + caught = false; + try { + QtConcurrent::run(throwFunctionReturn).waitForFinished(); + } catch (Exception &e) { + caught = true; + } + if (!caught) + QFAIL("did not get exception"); +} +#endif + #if 0 void tst_QtConcurrentRun::createFunctor() { @@ -406,6 +446,71 @@ void tst_QtConcurrentRun::createFunctor() } #endif +struct Functor { + int operator()() { return 42; } + double operator()(double a, double b) { return a/b; } + int operator()(int a, int b) { return a/b; } + void operator()(int) { } + void operator()(int, int, int) { } + void operator()(int, int, int, int) { } + void operator()(int, int, int, int, int) { } + void operator()(int, int, int, int, int, int) { } +}; + +void tst_QtConcurrentRun::functor() +{ + //this test functor without result_type, decltype need to be supported by the compiler +#ifndef Q_COMPILER_DECLTYPE + QSKIP("Compiler do not suport decltype", SkipAll); +#else + Functor f; + { + QFuture<int> fut = QtConcurrent::run(f); + QCOMPARE(fut.result(), 42); + } + { + QFuture<double> fut = QtConcurrent::run(f, 8.5, 1.8); + QCOMPARE(fut.result(), (8.5/1.8)); + } + { + QFuture<int> fut = QtConcurrent::run(f, 19, 3); + QCOMPARE(fut.result(), int(19/3)); + } + { + QtConcurrent::run(f, 1).waitForFinished(); + QtConcurrent::run(f, 1,2).waitForFinished(); + QtConcurrent::run(f, 1,2,3).waitForFinished(); + QtConcurrent::run(f, 1,2,3,4).waitForFinished(); + QtConcurrent::run(f, 1,2,3,4,5).waitForFinished(); + } +#endif +} + + +void tst_QtConcurrentRun::lambda() +{ +#ifndef Q_COMPILER_LAMBDA + QSKIP("Compiler do not suport lambda", SkipAll); +#else + + QCOMPARE(QtConcurrent::run([](){ return 45; }).result(), 45); + QCOMPARE(QtConcurrent::run([](int a){ return a+15; }, 12).result(), 12+15); + QCOMPARE(QtConcurrent::run([](int a, double b){ return a + b; }, 12, 15).result(), double(12+15)); + QCOMPARE(QtConcurrent::run([](int a , int, int, int, int b){ return a + b; }, 1, 2, 3, 4, 5).result(), 1 + 5); + +#ifdef Q_COMPILER_INITIALIZER_LISTS + { + QString str { "Hello World Foo" }; + QFuture<QStringList> f1 = QtConcurrent::run([&](){ return str.split(' '); }); + auto r = f1.result(); + QCOMPARE(r, QStringList({"Hello", "World", "Foo"})); + } +#endif + +#endif +} + + #include "tst_qtconcurrentrun.moc" #else diff --git a/tests/auto/qtconcurrentthreadengine/qtconcurrentthreadengine.pro b/tests/auto/qtconcurrentthreadengine/qtconcurrentthreadengine.pro index cd8d74e..bbfcf5e 100644 --- a/tests/auto/qtconcurrentthreadengine/qtconcurrentthreadengine.pro +++ b/tests/auto/qtconcurrentthreadengine/qtconcurrentthreadengine.pro @@ -1,3 +1,5 @@ load(qttest_p4) SOURCES += tst_qtconcurrentthreadengine.cpp QT = core +CONFIG += parallel_test +CONFIG += parallel_test diff --git a/tests/auto/qtcpserver/crashingServer/crashingServer.pro b/tests/auto/qtcpserver/crashingServer/crashingServer.pro index 0bea655..700e952 100644 --- a/tests/auto/qtcpserver/crashingServer/crashingServer.pro +++ b/tests/auto/qtcpserver/crashingServer/crashingServer.pro @@ -6,3 +6,4 @@ DESTDIR = ./ # This means the auto test works on some machines for MinGW. No dialog stalls # the application. win32-g++*:CONFIG += console +symbian: TARGET.CAPABILITY += NetworkServices ReadUserData diff --git a/tests/auto/qtcpserver/qtcpserver.pro b/tests/auto/qtcpserver/qtcpserver.pro index a3744a2..e123cfe 100644 --- a/tests/auto/qtcpserver/qtcpserver.pro +++ b/tests/auto/qtcpserver/qtcpserver.pro @@ -1,6 +1,4 @@ TEMPLATE = subdirs SUBDIRS = test crashingServer -symbian: TARGET.CAPABILITY = NetworkServices - diff --git a/tests/auto/qtcpserver/test/test.pro b/tests/auto/qtcpserver/test/test.pro index 123c79e..65e1d82 100644 --- a/tests/auto/qtcpserver/test/test.pro +++ b/tests/auto/qtcpserver/test/test.pro @@ -4,7 +4,7 @@ SOURCES += ../tst_qtcpserver.cpp win32: { wince*: { LIBS += -lws2 - crashApp.sources = ../crashingServer/crashingServer.exe + crashApp.files = ../crashingServer/crashingServer.exe crashApp.path = crashingServer DEPLOYMENT += crashApp } else { @@ -13,9 +13,10 @@ wince*: { } symbian { - crashApp.sources = $$QT_BUILD_TREE/examples/widgets/wiggly/$${BUILD_DIR}/crashingServer.exe - crashApp.path = . - DEPLOYMENT += crashApp + crashApp.files = $$QT_BUILD_TREE/examples/widgets/wiggly/$${BUILD_DIR}/crashingServer.exe + crashApp.path = . + DEPLOYMENT += crashApp + TARGET.CAPABILITY += NetworkServices ReadUserData } TARGET = ../tst_qtcpserver diff --git a/tests/auto/qtcpserver/tst_qtcpserver.cpp b/tests/auto/qtcpserver/tst_qtcpserver.cpp index a63f5ef..a7c2604 100644 --- a/tests/auto/qtcpserver/tst_qtcpserver.cpp +++ b/tests/auto/qtcpserver/tst_qtcpserver.cpp @@ -70,6 +70,9 @@ Q_DECLARE_METATYPE(QNetworkProxy) Q_DECLARE_METATYPE(QList<QNetworkProxy>) +#include <QNetworkSession> +#include <QNetworkConfiguration> +#include <QNetworkConfigurationManager> #include "../network-settings.h" //TESTED_CLASS= @@ -86,6 +89,7 @@ public: public slots: void initTestCase_data(); + void initTestCase(); void init(); void cleanup(); private slots: @@ -93,6 +97,7 @@ private slots: void constructing(); void clientServerLoop(); void ipv6Server(); + void ipv6ServerMapped(); void crashTests(); void maxPendingConnections(); void listenError(); @@ -107,6 +112,12 @@ private slots: void proxyFactory(); void qtbug14268_peek(); + +private: +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkSession *networkSession; + QNetworkConfigurationManager *netConfMan; +#endif }; // Testing get/set functions @@ -141,6 +152,26 @@ void tst_QTcpServer::initTestCase_data() QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy); } +void tst_QTcpServer::initTestCase() +{ +#ifndef QT_NO_BEARERMANAGEMENT + netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QNetworkConfiguration networkConfiguration = netConfMan->defaultConfiguration(); + if (networkConfiguration.isValid()) { + networkSession = new QNetworkSession(networkConfiguration); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); + } +#endif +} + void tst_QTcpServer::init() { QFETCH_GLOBAL(bool, setProxy); @@ -190,7 +221,7 @@ void tst_QTcpServer::clientServerLoop() QTcpSocket client; QHostAddress serverAddress = QHostAddress::LocalHost; - if (!(server.serverAddress() == QHostAddress::Any)) + if (!(server.serverAddress() == QHostAddress::Any) && !(server.serverAddress() == QHostAddress::AnyIPv6)) serverAddress = server.serverAddress(); client.connectToHost(serverAddress, server.serverPort()); @@ -222,9 +253,6 @@ void tst_QTcpServer::clientServerLoop() //---------------------------------------------------------------------------------- void tst_QTcpServer::ipv6Server() { -#if defined(Q_OS_SYMBIAN) - QSKIP("Symbian: IPv6 is not yet supported", SkipAll); -#endif //### need to enter the event loop for the server to get the connection ?? ( windows) QTcpServer server; if (!server.listen(QHostAddress::LocalHostIPv6, 8944)) { @@ -244,6 +272,42 @@ void tst_QTcpServer::ipv6Server() QTcpSocket *serverSocket = 0; QVERIFY((serverSocket = server.nextPendingConnection())); + serverSocket->close(); + delete serverSocket; +} + +//---------------------------------------------------------------------------------- +void tst_QTcpServer::ipv6ServerMapped() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + QTcpServer server; + QVERIFY(server.listen(QHostAddress::LocalHost)); + + // let's try the normal case + QTcpSocket client1; + client1.connectToHost("127.0.0.1", server.serverPort()); + QVERIFY(server.waitForNewConnection(5000)); + delete server.nextPendingConnection(); + + // let's try the mapped one in the nice format + QTcpSocket client2; + client2.connectToHost("::ffff:127.0.0.1", server.serverPort()); + QVERIFY(server.waitForNewConnection(5000)); + delete server.nextPendingConnection(); + + // let's try the mapped in hex format + QTcpSocket client3; + client3.connectToHost("::ffff:7F00:0001", server.serverPort()); + QVERIFY(server.waitForNewConnection(5000)); + delete server.nextPendingConnection(); + + // However connecting to the v6 localhost should not work + QTcpSocket client4; + client4.connectToHost("::1", server.serverPort()); + QVERIFY(!server.waitForNewConnection(5000)); } //---------------------------------------------------------------------------------- @@ -377,9 +441,13 @@ void tst_QTcpServer::waitForConnectionTest() void tst_QTcpServer::setSocketDescriptor() { QTcpServer server; +#ifdef Q_OS_SYMBIAN + QTest::ignoreMessage(QtWarningMsg, "QSymbianSocketEngine::initialize - socket descriptor not found"); +#endif QVERIFY(!server.setSocketDescriptor(42)); QCOMPARE(server.serverError(), QAbstractSocket::UnsupportedSocketOperationError); - +#ifndef Q_OS_SYMBIAN + //adopting Open C sockets is not supported, neither is adopting externally created RSocket #ifdef Q_OS_WIN // ensure winsock is started WSADATA wsaData; @@ -402,6 +470,7 @@ void tst_QTcpServer::setSocketDescriptor() #ifdef Q_OS_WIN WSACleanup(); #endif +#endif } //---------------------------------------------------------------------------------- @@ -493,6 +562,9 @@ void tst_QTcpServer::addressReusable() void tst_QTcpServer::setNewSocketDescriptorBlocking() { +#ifdef Q_OS_SYMBIAN + QSKIP("open C ioctls on Qt sockets not supported", SkipAll); +#else QFETCH_GLOBAL(bool, setProxy); if (setProxy) { QFETCH_GLOBAL(int, proxyType); @@ -507,6 +579,7 @@ void tst_QTcpServer::setNewSocketDescriptorBlocking() socket.connectToHost(QHostAddress::LocalHost, server.serverPort()); QVERIFY(server.waitForNewConnection(5000)); QVERIFY(server.ok); +#endif } void tst_QTcpServer::invalidProxy_data() diff --git a/tests/auto/qtcpsocket/qtcpsocket.pro b/tests/auto/qtcpsocket/qtcpsocket.pro index 8b1f664..5dfff5b 100644 --- a/tests/auto/qtcpsocket/qtcpsocket.pro +++ b/tests/auto/qtcpsocket/qtcpsocket.pro @@ -6,4 +6,3 @@ wince*|symbian|vxworks* : SUBDIRS = test requires(contains(QT_CONFIG,private_tests)) -symbian: TARGET.CAPABILITY = NetworkServices diff --git a/tests/auto/qtcpsocket/stressTest/stressTest.pro b/tests/auto/qtcpsocket/stressTest/stressTest.pro index 9a653c6..adf0217 100644 --- a/tests/auto/qtcpsocket/stressTest/stressTest.pro +++ b/tests/auto/qtcpsocket/stressTest/stressTest.pro @@ -9,4 +9,5 @@ DESTDIR = ./ MOC_DIR = .moc/ TMP_DIR = .tmp/ +symbian: TARGET.CAPABILITY = NetworkServices diff --git a/tests/auto/qtcpsocket/test/test.pro b/tests/auto/qtcpsocket/test/test.pro index c4369df..7bf5ba0 100644 --- a/tests/auto/qtcpsocket/test/test.pro +++ b/tests/auto/qtcpsocket/test/test.pro @@ -11,7 +11,10 @@ wince*: { QT += network vxworks:QT -= gui -symbian: TARGET.EPOCHEAPSIZE="0x100 0x1000000" +symbian: { + TARGET.EPOCHEAPSIZE="0x100 0x3000000" + TARGET.CAPABILITY = NetworkServices ReadUserData +} TARGET = tst_qtcpsocket diff --git a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp index 8a2f1a3..1c33107 100644 --- a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp @@ -106,6 +106,7 @@ Q_DECLARE_METATYPE(QList<QNetworkProxy>) //TESTED_FILES= QT_FORWARD_DECLARE_CLASS(QTcpSocket) +QT_FORWARD_DECLARE_CLASS(SocketPair) class tst_QTcpSocket : public QObject { @@ -138,6 +139,7 @@ public slots: void init(); void cleanup(); private slots: + void socketsConstructedBeforeEventLoop(); void constructing(); void setInvalidSocketDescriptor(); void setSocketDescriptor(); @@ -164,7 +166,9 @@ private slots: void readLineString(); void readChunks(); void waitForBytesWritten(); + void waitForBytesWrittenMinusOne(); void waitForReadyRead(); + void waitForReadyReadMinusOne(); void flush(); void synchronousApi(); void dontCloseOnTimeout(); @@ -221,6 +225,8 @@ protected slots: void abortiveClose_abortSlot(); void remoteCloseErrorSlot(); void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth); + void earlySocketBytesSent(qint64 bytes); + void earlySocketReadyRead(); private: QByteArray expectedReplyIMAP(); @@ -243,6 +249,10 @@ private: bool gotClosedSignal; int numConnections; static int loopLevel; + + SocketPair *earlyConstructedSockets; + int earlyBytesWrittenCount; + int earlyReadyReadCount; }; enum ProxyTests { @@ -296,8 +306,16 @@ public: tst_QTcpSocket::tst_QTcpSocket() { - Q_SET_DEFAULT_IAP tmpSocket = 0; + + //This code relates to the socketsConstructedBeforeEventLoop test case + earlyConstructedSockets = new SocketPair; + QVERIFY(earlyConstructedSockets->create()); + earlyBytesWrittenCount = 0; + earlyReadyReadCount = 0; + connect(earlyConstructedSockets->endPoints[0], SIGNAL(readyRead()), this, SLOT(earlySocketReadyRead())); + connect(earlyConstructedSockets->endPoints[1], SIGNAL(bytesWritten(qint64)), this, SLOT(earlySocketBytesSent(qint64))); + earlyConstructedSockets->endPoints[1]->write("hello work"); } tst_QTcpSocket::~tst_QTcpSocket() @@ -336,7 +354,9 @@ void tst_QTcpSocket::init() QFETCH_GLOBAL(bool, setProxy); if (setProxy) { QFETCH_GLOBAL(int, proxyType); - QString fluke = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(); + QList<QHostAddress> addresses = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses(); + QVERIFY2(addresses.count() > 0, "failed to get ip address for test server"); + QString fluke = addresses.first().toString(); QNetworkProxy proxy; switch (proxyType) { @@ -397,6 +417,33 @@ void tst_QTcpSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthent //---------------------------------------------------------------------------------- +void tst_QTcpSocket::socketsConstructedBeforeEventLoop() +{ + QFETCH_GLOBAL(bool, setProxy); + QFETCH_GLOBAL(bool, ssl); + if (setProxy || ssl) + return; + //This test checks that sockets constructed before QCoreApplication::exec() still emit signals + //see construction code in the tst_QTcpSocket constructor + enterLoop(3); + QCOMPARE(earlyBytesWrittenCount, 1); + QCOMPARE(earlyReadyReadCount, 1); + earlyConstructedSockets->endPoints[0]->close(); + earlyConstructedSockets->endPoints[1]->close(); +} + +void tst_QTcpSocket::earlySocketBytesSent(qint64 bytes) +{ + earlyBytesWrittenCount++; +} + +void tst_QTcpSocket::earlySocketReadyRead() +{ + earlyReadyReadCount++; +} + +//---------------------------------------------------------------------------------- + void tst_QTcpSocket::constructing() { QTcpSocket *socket = newSocket(); @@ -431,6 +478,9 @@ void tst_QTcpSocket::setInvalidSocketDescriptor() { QTcpSocket *socket = newSocket(); QCOMPARE(socket->socketDescriptor(), -1); +#ifdef Q_OS_SYMBIAN + QTest::ignoreMessage(QtWarningMsg, "QSymbianSocketEngine::initialize - socket descriptor not found"); +#endif QVERIFY(!socket->setSocketDescriptor(-5, QTcpSocket::UnconnectedState)); QCOMPARE(socket->socketDescriptor(), -1); @@ -443,6 +493,9 @@ void tst_QTcpSocket::setInvalidSocketDescriptor() void tst_QTcpSocket::setSocketDescriptor() { +#ifdef Q_OS_SYMBIAN + QSKIP("adopting open c socket handles is not supported", SkipAll); +#else QFETCH_GLOBAL(bool, setProxy); if (setProxy) return; // this test doesn't make sense with proxies @@ -483,6 +536,7 @@ void tst_QTcpSocket::setSocketDescriptor() #ifdef Q_OS_WIN delete dummy; #endif +#endif } //---------------------------------------------------------------------------------- @@ -605,14 +659,14 @@ void tst_QTcpSocket::timeoutConnect() // Port 1357 is configured to drop packets on the test server socket->connectToHost(address, 1357); - QVERIFY(timer.elapsed() < 50); - QVERIFY(!socket->waitForConnected(200)); + QVERIFY(timer.elapsed() < 150); + QVERIFY(!socket->waitForConnected(1000)); //200ms is too short when using SOCKS proxy authentication QCOMPARE(socket->state(), QTcpSocket::UnconnectedState); QCOMPARE(int(socket->error()), int(QTcpSocket::SocketTimeoutError)); timer.start(); socket->connectToHost(address, 1357); - QVERIFY(timer.elapsed() < 50); + QVERIFY(timer.elapsed() < 150); QTimer::singleShot(50, &QTestEventLoop::instance(), SLOT(exitLoop())); QTestEventLoop::instance().enterLoop(5); QVERIFY(!QTestEventLoop::instance().timeout()); @@ -975,6 +1029,9 @@ void tst_QTcpSocket::disconnectWhileConnecting_data() void tst_QTcpSocket::disconnectWhileConnecting() { QFETCH(QByteArray, data); + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; //proxy not useful for localhost test case QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost)); @@ -1035,7 +1092,7 @@ public: : server(0), ok(false), quit(false) { } - ~ReceiverThread() { /*delete server;*/ terminate(); wait(); } + ~ReceiverThread() { } bool listen() { @@ -1047,6 +1104,14 @@ public: return true; } + static void cleanup(void *ptr) + { + ReceiverThread* self = reinterpret_cast<ReceiverThread*>(ptr); + self->quit = true; + self->wait(30000); + delete self; + } + protected: void run() { @@ -1092,19 +1157,20 @@ void tst_QTcpSocket::disconnectWhileConnectingNoEventLoop_data() void tst_QTcpSocket::disconnectWhileConnectingNoEventLoop() { QFETCH(QByteArray, data); + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; //proxy not useful for localhost test case - ReceiverThread thread; - QVERIFY(thread.listen()); - thread.start(); + QScopedPointer<ReceiverThread, ReceiverThread> thread (new ReceiverThread); + QVERIFY(thread->listen()); + thread->start(); // proceed to the connect-write-disconnect QTcpSocket *socket = newSocket(); - socket->connectToHost("127.0.0.1", thread.serverPort); + socket->connectToHost("127.0.0.1", thread->serverPort); if (!data.isEmpty()) socket->write(data); if (socket->state() == QAbstractSocket::ConnectedState) { - thread.quit = true; - thread.wait(); QSKIP("localhost connections are immediate, test case is invalid", SkipSingle); } @@ -1130,9 +1196,9 @@ void tst_QTcpSocket::disconnectWhileConnectingNoEventLoop() delete socket; // check if the other side received everything ok - QVERIFY(thread.wait(30000)); - QVERIFY(thread.ok); - QCOMPARE(thread.receivedData, data); + QVERIFY(thread->wait(30000)); + QVERIFY(thread->ok); + QCOMPARE(thread->receivedData, data); } //---------------------------------------------------------------------------------- @@ -1194,6 +1260,7 @@ void tst_QTcpSocket::downloadBigFile() connect(tmpSocket, SIGNAL(connected()), SLOT(exitLoopSlot())); connect(tmpSocket, SIGNAL(readyRead()), SLOT(downloadBigFileSlot())); + connect(tmpSocket, SIGNAL(disconnected()), SLOT(exitLoopSlot())); tmpSocket->connectToHost(QtNetworkSettings::serverName(), 80); @@ -1352,10 +1419,10 @@ void tst_QTcpSocket::readChunks() void tst_QTcpSocket::waitForBytesWritten() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 22); + socket->connectToHost(QtNetworkSettings::serverName(), 80); QVERIFY(socket->waitForConnected(10000)); - socket->write(QByteArray(10000, '@')); + socket->write("GET / HTTP/1.0\r\n\r\n"); qint64 toWrite = socket->bytesToWrite(); QVERIFY(socket->waitForBytesWritten(5000)); QVERIFY(toWrite > socket->bytesToWrite()); @@ -1364,11 +1431,37 @@ void tst_QTcpSocket::waitForBytesWritten() } //---------------------------------------------------------------------------------- +void tst_QTcpSocket::waitForBytesWrittenMinusOne() +{ + QTcpSocket *socket = newSocket(); + socket->connectToHost(QtNetworkSettings::serverName(), 80); + QVERIFY(socket->waitForConnected(10000)); + + socket->write("GET / HTTP/1.0\r\n\r\n"); + qint64 toWrite = socket->bytesToWrite(); + QVERIFY(socket->waitForBytesWritten(-1)); + QVERIFY(toWrite > socket->bytesToWrite()); + + delete socket; +} + +//---------------------------------------------------------------------------------- void tst_QTcpSocket::waitForReadyRead() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 22); - socket->waitForReadyRead(0); + socket->connectToHost(QtNetworkSettings::serverName(), 80); + socket->write("GET / HTTP/1.0\r\n\r\n"); + QVERIFY(socket->waitForReadyRead(5000)); + delete socket; +} + +//---------------------------------------------------------------------------------- +void tst_QTcpSocket::waitForReadyReadMinusOne() +{ + QTcpSocket *socket = newSocket(); + socket->connectToHost(QtNetworkSettings::serverName(), 80); + socket->write("GET / HTTP/1.0\r\n\r\n"); + QVERIFY(socket->waitForReadyRead(-1)); delete socket; } @@ -1380,7 +1473,7 @@ void tst_QTcpSocket::flush() connect(socket, SIGNAL(connected()), SLOT(exitLoopSlot())); socket->connectToHost(QtNetworkSettings::serverName(), 143); - enterLoop(5000); + enterLoop(60); QVERIFY(socket->isOpen()); socket->write("1 LOGOUT\r\n"); @@ -1413,7 +1506,7 @@ void tst_QTcpSocket::dontCloseOnTimeout() QVERIFY(server.listen()); QHostAddress serverAddress = QHostAddress::LocalHost; - if (!(server.serverAddress() == QHostAddress::Any)) + if (!(server.serverAddress() == QHostAddress::Any) && !(server.serverAddress() == QHostAddress::AnyIPv6)) serverAddress = server.serverAddress(); QTcpSocket *socket = newSocket(); @@ -1633,6 +1726,9 @@ private slots: //---------------------------------------------------------------------------------- void tst_QTcpSocket::remoteCloseError() { + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; //proxy not useful for localhost test case RemoteCloseErrorServer server; QVERIFY(server.listen(QHostAddress::LocalHost)); @@ -1943,6 +2039,9 @@ void tst_QTcpSocket::linuxKernelBugLocalSocket() //---------------------------------------------------------------------------------- void tst_QTcpSocket::abortiveClose() { + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; //proxy not useful for localhost test case QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost)); connect(&server, SIGNAL(newConnection()), this, SLOT(exitLoopSlot())); @@ -1981,6 +2080,9 @@ void tst_QTcpSocket::abortiveClose_abortSlot() //---------------------------------------------------------------------------------- void tst_QTcpSocket::localAddressEmptyOnBSD() { + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; //proxy not useful for localhost test case QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost)); @@ -2251,6 +2353,9 @@ void tst_QTcpSocket::moveToThread0() void tst_QTcpSocket::increaseReadBufferSize() { + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; //proxy not useful for localhost test case QTcpServer server; QTcpSocket *active = newSocket(); connect(active, SIGNAL(readyRead()), SLOT(exitLoopSlot())); diff --git a/tests/auto/qtemporaryfile/qtemporaryfile.pro b/tests/auto/qtemporaryfile/qtemporaryfile.pro index c93a2e5..64a043b 100644 --- a/tests/auto/qtemporaryfile/qtemporaryfile.pro +++ b/tests/auto/qtemporaryfile/qtemporaryfile.pro @@ -4,9 +4,11 @@ QT = core symbian { - testData.sources = tst_qtemporaryfile.cpp + testData.files = tst_qtemporaryfile.cpp testData.path = . DEPLOYMENT += testData }else { DEFINES += SRCDIR=\\\"$$PWD/\\\" } + +CONFIG += parallel_test diff --git a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp index 4a9505a..2edb93a 100644 --- a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp @@ -75,6 +75,10 @@ public: public slots: void init(); void cleanup(); + + void initTestCase(); + void cleanupTestCase(); + private slots: void construction(); void fileTemplate(); @@ -97,9 +101,24 @@ private slots: void setTemplateAfterOpen(); void autoRemoveAfterFailedRename(); + void QTBUG_4796_data(); + void QTBUG_4796(); + public: }; +void tst_QTemporaryFile::initTestCase() +{ + // For QTBUG_4796 + QVERIFY(QDir("test-XXXXXX").exists() || QDir().mkdir("test-XXXXXX")); +} + +void tst_QTemporaryFile::cleanupTestCase() +{ + // From QTBUG_4796 + QVERIFY(QDir().rmdir("test-XXXXXX")); +} + void tst_QTemporaryFile::construction() { QTemporaryFile file(0); @@ -144,26 +163,35 @@ void tst_QTemporaryFile::cleanup() void tst_QTemporaryFile::fileTemplate_data() { QTest::addColumn<QString>("constructorTemplate"); + QTest::addColumn<QString>("prefix"); QTest::addColumn<QString>("suffix"); QTest::addColumn<QString>("fileTemplate"); - QTest::newRow("constructor default") << "" << "" << ""; - QTest::newRow("constructor with xxx sufix") << "qt_XXXXXXxxx" << "xxx" << ""; - QTest::newRow("constructor with xXx sufix") << "qt_XXXXXXxXx" << "xXx" << ""; - QTest::newRow("constructor with no sufix") << "qt_XXXXXX" << "" << ""; - QTest::newRow("constructor with >6 X's and xxx suffix") << "qt_XXXXXXXXXXxxx" << "xxx" << ""; - QTest::newRow("constructor with >6 X's, no suffix") << "qt_XXXXXXXXXX" << "" << ""; - - QTest::newRow("set template, no suffix") << "" << "" << "foo"; - QTest::newRow("set template, with lowercase XXXXXX") << "" << "xxxxxx" << "qt_XXXXXXxxxxxx"; - QTest::newRow("set template, with xxx") << "" << ".xxx" << "qt_XXXXXX.xxx"; - QTest::newRow("set template, with >6 X's") << "" << ".xxx" << "qt_XXXXXXXXXXXXXX.xxx"; - QTest::newRow("set template, with >6 X's, no suffix") << "" << "" << "qt_XXXXXXXXXXXXXX"; + QTest::newRow("constructor default") << "" << "." << "" << ""; + QTest::newRow("constructor with xxx sufix") << "qt_XXXXXXxxx" << "qt_" << "xxx" << ""; + QTest::newRow("constructor with xXx sufix") << "qt_XXXXXXxXx" << "qt_" << "xXx" << ""; + QTest::newRow("constructor with no sufix") << "qt_XXXXXX" << "qt_" << "" << ""; + QTest::newRow("constructor with >6 X's and xxx suffix") << "qt_XXXXXXXXXXxxx" << "qt_" << "xxx" << ""; + QTest::newRow("constructor with >6 X's, no suffix") << "qt_XXXXXXXXXX" << "qt_" << "" << ""; + + QTest::newRow("constructor with XXXX suffix") << "qt_XXXXXX_XXXX" << "qt_" << "_XXXX" << ""; + QTest::newRow("constructor with XXXXX suffix") << "qt_XXXXXX_XXXXX" << "qt_" << "_XXXXX" << ""; + QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_XXXX." << "" << ""; + QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_XXXXX." << "" << ""; + QTest::newRow("constructor with XXXX prefix and suffix") << "qt_XXXX_XXXXXX_XXXX" << "qt_XXXX_" << "_XXXX" << ""; + QTest::newRow("constructor with XXXXX prefix and suffix") << "qt_XXXXX_XXXXXX_XXXXX" << "qt_XXXXX_" << "_XXXXX" << ""; + + QTest::newRow("set template, no suffix") << "" << "foo" << "" << "foo"; + QTest::newRow("set template, with lowercase XXXXXX") << "" << "qt_" << "xxxxxx" << "qt_XXXXXXxxxxxx"; + QTest::newRow("set template, with xxx") << "" << "qt_" << ".xxx" << "qt_XXXXXX.xxx"; + QTest::newRow("set template, with >6 X's") << "" << "qt_" << ".xxx" << "qt_XXXXXXXXXXXXXX.xxx"; + QTest::newRow("set template, with >6 X's, no suffix") << "" << "qt_" << "" << "qt_XXXXXXXXXXXXXX"; } void tst_QTemporaryFile::fileTemplate() { QFETCH(QString, constructorTemplate); + QFETCH(QString, prefix); QFETCH(QString, suffix); QFETCH(QString, fileTemplate); @@ -173,8 +201,11 @@ void tst_QTemporaryFile::fileTemplate() QCOMPARE(file.open(), true); - QCOMPARE(file.fileName().right(suffix.length()), suffix); - file.close(); + if (prefix.length()) + QCOMPARE(file.fileName().left(prefix.length()), prefix); + + if (suffix.length()) + QCOMPARE(file.fileName().right(suffix.length()), suffix); } @@ -359,10 +390,7 @@ void tst_QTemporaryFile::stressTest() for (int i = 0; i < iterations; ++i) { QTemporaryFile file; file.setAutoRemove(false); - if (!file.open()) { - qDebug() << "Could not open File:" << file.fileName(); - continue; - } + QVERIFY2(file.open(), qPrintable(file.errorString())); QVERIFY(!names.contains(file.fileName())); names.insert(file.fileName()); } @@ -594,5 +622,108 @@ void tst_QTemporaryFile::autoRemoveAfterFailedRename() cleaner.reset(); } +void tst_QTemporaryFile::QTBUG_4796_data() +{ + QTest::addColumn<QString>("prefix"); + QTest::addColumn<QString>("suffix"); + QTest::addColumn<bool>("openResult"); + + QString unicode = QString::fromUtf8("\xc3\xa5\xc3\xa6\xc3\xb8"); + + QTest::newRow("<empty>") << QString() << QString() << true; + QTest::newRow("blaXXXXXX") << QString("bla") << QString() << true; + QTest::newRow("XXXXXXbla") << QString() << QString("bla") << true; + QTest::newRow("does-not-exist/qt_temp.XXXXXX") << QString("does-not-exist/qt_temp") << QString() << false; + QTest::newRow("XXXXXX<unicode>") << QString() << unicode << true; + QTest::newRow("<unicode>XXXXXX") << unicode << QString() << true; + QTest::newRow("<unicode>XXXXXX<unicode>") << unicode << unicode << true; +} + +void tst_QTemporaryFile::QTBUG_4796() +{ + QVERIFY(QDir("test-XXXXXX").exists()); + + struct CleanOnReturn + { + ~CleanOnReturn() + { + Q_FOREACH(QString tempName, tempNames) + QFile::remove(tempName); + } + + void reset() + { + tempNames.clear(); + } + + QStringList tempNames; + }; + + CleanOnReturn cleaner; + + QFETCH(QString, prefix); + QFETCH(QString, suffix); + QFETCH(bool, openResult); + + { + QString fileTemplate1 = prefix + QString("XX") + suffix; + QString fileTemplate2 = prefix + QString("XXXX") + suffix; + QString fileTemplate3 = prefix + QString("XXXXXX") + suffix; + QString fileTemplate4 = prefix + QString("XXXXXXXX") + suffix; + + QTemporaryFile file1(fileTemplate1); + QTemporaryFile file2(fileTemplate2); + QTemporaryFile file3(fileTemplate3); + QTemporaryFile file4(fileTemplate4); + QTemporaryFile file5("test-XXXXXX/" + fileTemplate1); + QTemporaryFile file6("test-XXXXXX/" + fileTemplate3); + + QCOMPARE(file1.open(), openResult); + QCOMPARE(file2.open(), openResult); + QCOMPARE(file3.open(), openResult); + QCOMPARE(file4.open(), openResult); + QCOMPARE(file5.open(), openResult); + QCOMPARE(file6.open(), openResult); + + QCOMPARE(file1.exists(), openResult); + QCOMPARE(file2.exists(), openResult); + QCOMPARE(file3.exists(), openResult); + QCOMPARE(file4.exists(), openResult); + QCOMPARE(file5.exists(), openResult); + QCOMPARE(file6.exists(), openResult); + + // make sure the file exists under the *correct* name + if (openResult) { + cleaner.tempNames << file1.fileName() + << file2.fileName() + << file3.fileName() + << file4.fileName() + << file5.fileName() + << file6.fileName(); + + QVERIFY(file1.fileName().startsWith(fileTemplate1 + QLatin1Char('.'))); + QVERIFY(file2.fileName().startsWith(fileTemplate2 + QLatin1Char('.'))); + QVERIFY(file5.fileName().startsWith("test-XXXXXX/" + fileTemplate1 + QLatin1Char('.'))); + QVERIFY(file6.fileName().startsWith("test-XXXXXX/" + prefix)); + + if (!prefix.isEmpty()) { + QVERIFY(file3.fileName().startsWith(prefix)); + QVERIFY(file4.fileName().startsWith(prefix)); + } + + if (!suffix.isEmpty()) { + QVERIFY(file3.fileName().endsWith(suffix)); + QVERIFY(file4.fileName().endsWith(suffix)); + QVERIFY(file6.fileName().endsWith(suffix)); + } + } + } + + Q_FOREACH(QString const &tempName, cleaner.tempNames) + QVERIFY( !QFile::exists(tempName) ); + + cleaner.reset(); +} + QTEST_MAIN(tst_QTemporaryFile) #include "tst_qtemporaryfile.moc" diff --git a/tests/auto/qtessellator/dataparser.cpp b/tests/auto/qtessellator/dataparser.cpp index 772f925..8ad7ae8 100644 --- a/tests/auto/qtessellator/dataparser.cpp +++ b/tests/auto/qtessellator/dataparser.cpp @@ -98,8 +98,12 @@ static QList<QPointF> parsePoints(const QByteArray &line) QList<qreal> nums = parseNumbersList(it); QList<qreal>::const_iterator nitr; for (nitr = nums.begin(); nitr != nums.end(); ++nitr) { - qreal x = *nitr; ++nitr; - Q_ASSERT(nitr != nums.end()); + qreal x = *nitr; + ++nitr; + if (nitr == nums.end()) { + qWarning() << "parsePoints: Even number of co-ordinates required, odd number found: skipping last point"; + break; + } qreal y = *nitr; res.append(QPointF(x, y)); } diff --git a/tests/auto/qtessellator/oldtessellator.cpp b/tests/auto/qtessellator/oldtessellator.cpp index 7a76900..fd39d20 100644 --- a/tests/auto/qtessellator/oldtessellator.cpp +++ b/tests/auto/qtessellator/oldtessellator.cpp @@ -80,19 +80,6 @@ struct QEdge { horizontal = p1.y == p2.y; } - inline qreal xAt(const qreal &y) const - { - Q_ASSERT(p1.y != p2.y); - XFixed yf = XDoubleToFixed(y); - - if (yf == p1.y) - return XFixedToDouble(p1.x); - else if (yf == p2.y) - return XFixedToDouble(p2.x); - - return (!vertical) ? (((y - b)*im)) : pf1.x(); - } - QPointF pf1, pf2; XPointFixed p1, p2; qreal m; @@ -218,7 +205,8 @@ void old_tesselate_polygon(QVector<XTrapezoid> *traps, const QPointF *pg, int pg qreal ymax(INT_MIN/256); //painter.begin(pg, pgSize); - Q_ASSERT(pg[0] == pg[pgSize-1]); + if (pg[0] != pg[pgSize-1]) + qWarning() << Q_FUNC_INFO << "Malformed polygon (first and last points must be identical)"; // generate edge table // qDebug() << "POINTS:"; for (int x = 0; x < pgSize-1; ++x) { @@ -383,7 +371,8 @@ void old_tesselate_polygon(QVector<XTrapezoid> *traps, const QPointF *pg, int pg isects[i].edge = edge; } - Q_ASSERT(isects.size()%2 == 1); + if (isects.size()%2 != 1) + qFatal("%s: number of intersection points must be odd", Q_FUNC_INFO); // sort intersection points qSort(&isects[0], &isects[isects.size()-1], compareIntersections); diff --git a/tests/auto/qtessellator/testtessellator.cpp b/tests/auto/qtessellator/testtessellator.cpp index be003b6..c2af1ae 100644 --- a/tests/auto/qtessellator/testtessellator.cpp +++ b/tests/auto/qtessellator/testtessellator.cpp @@ -42,6 +42,7 @@ #include <private/qtessellator_p.h> #include "math.h" +#include <QtCore/QDebug> class TestTessellator : public QTessellator { @@ -91,7 +92,8 @@ void test_tessellate_polygon_rect(QVector<XTrapezoid> *traps, const QPointF *poi bool winding) { // 5 points per rect - Q_ASSERT(nPoints % 5 == 0); + if (nPoints % 5 != 0) + qWarning() << Q_FUNC_INFO << "multiples of 5 points expected"; TestTessellator t; t.traps = traps; diff --git a/tests/auto/qtextboundaryfinder/qtextboundaryfinder.pro b/tests/auto/qtextboundaryfinder/qtextboundaryfinder.pro index aa1fbb5..5f3cb11 100644 --- a/tests/auto/qtextboundaryfinder/qtextboundaryfinder.pro +++ b/tests/auto/qtextboundaryfinder/qtextboundaryfinder.pro @@ -5,7 +5,8 @@ SOURCES += tst_qtextboundaryfinder.cpp !symbian:*:DEFINES += SRCDIR=\\\"$$PWD\\\" wince*|symbian:{ - addFiles.sources = data + addFiles.files = data addFiles.path = . DEPLOYMENT += addFiles } +CONFIG += parallel_test diff --git a/tests/auto/qtextboundaryfinder/tst_qtextboundaryfinder.cpp b/tests/auto/qtextboundaryfinder/tst_qtextboundaryfinder.cpp index 88b725b..3657556 100644 --- a/tests/auto/qtextboundaryfinder/tst_qtextboundaryfinder.cpp +++ b/tests/auto/qtextboundaryfinder/tst_qtextboundaryfinder.cpp @@ -123,14 +123,14 @@ void tst_QTextBoundaryFinder::graphemeBoundaries() if (test.at(pos).unicode() == 0xf7) breakPositions.append(strPos); else - Q_ASSERT(test.at(pos).unicode() == 0xd7); + QVERIFY(test.at(pos).unicode() == 0xd7); ++pos; if (pos < test.length()) { - Q_ASSERT(pos < test.length() - 4); + QVERIFY(pos < test.length() - 4); QString hex = test.mid(pos, 4); bool ok = true; testString.append(QChar(hex.toInt(&ok, 16))); - Q_ASSERT(ok); + QVERIFY(ok); pos += 4; } ++strPos; @@ -176,14 +176,14 @@ void tst_QTextBoundaryFinder::wordBoundaries() if (test.at(pos).unicode() == 0xf7) breakPositions.append(strPos); else - Q_ASSERT(test.at(pos).unicode() == 0xd7); + QVERIFY(test.at(pos).unicode() == 0xd7); ++pos; if (pos < test.length()) { - Q_ASSERT(pos < test.length() - 4); + QVERIFY(pos < test.length() - 4); QString hex = test.mid(pos, 4); bool ok = true; testString.append(QChar(hex.toInt(&ok, 16))); - Q_ASSERT(ok); + QVERIFY(ok); pos += 4; } ++strPos; @@ -228,14 +228,14 @@ void tst_QTextBoundaryFinder::sentenceBoundaries() if (test.at(pos).unicode() == 0xf7) breakPositions.append(strPos); else - Q_ASSERT(test.at(pos).unicode() == 0xd7); + QVERIFY(test.at(pos).unicode() == 0xd7); ++pos; if (pos < test.length()) { - Q_ASSERT(pos < test.length() - 4); + QVERIFY(pos < test.length() - 4); QString hex = test.mid(pos, 4); bool ok = true; testString.append(QChar(hex.toInt(&ok, 16))); - Q_ASSERT(ok); + QVERIFY(ok); pos += 4; } ++strPos; diff --git a/tests/auto/qtextbrowser/qtextbrowser.pro b/tests/auto/qtextbrowser/qtextbrowser.pro index 88061a9..773fb97 100644 --- a/tests/auto/qtextbrowser/qtextbrowser.pro +++ b/tests/auto/qtextbrowser/qtextbrowser.pro @@ -6,9 +6,9 @@ contains(QT_CONFIG, qt3support): QT += qt3support wince*|symbian: { - addFiles.sources = *.html + addFiles.files = *.html addFiles.path = . - addDir.sources = subdir/* + addDir.files = subdir/* addDir.path = subdir DEPLOYMENT += addFiles addDir } diff --git a/tests/auto/qtextcodec/test/test.pro b/tests/auto/qtextcodec/test/test.pro index b85032a..2188d2f 100644 --- a/tests/auto/qtextcodec/test/test.pro +++ b/tests/auto/qtextcodec/test/test.pro @@ -17,7 +17,7 @@ win32: { } wince*|symbian { - addFiles.sources = ../*.txt + addFiles.files = ../*.txt addFiles.path = . DEPLOYMENT += addFiles wince*|qt_not_deployed { diff --git a/tests/auto/qtextcodec/tst_qtextcodec.cpp b/tests/auto/qtextcodec/tst_qtextcodec.cpp index f8e3aec..049af79 100644 --- a/tests/auto/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/qtextcodec/tst_qtextcodec.cpp @@ -106,6 +106,8 @@ private slots: void moreToFromUnicode_data(); void moreToFromUnicode(); + + void shiftJis(); }; void tst_QTextCodec::toUnicode_data() @@ -428,7 +430,7 @@ void tst_QTextCodec::flagCodepointFFFF() const QString input(ch); QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 - Q_ASSERT(codec); + QVERIFY(codec); const QByteArray asDecoded(codec->fromUnicode(input)); QCOMPARE(asDecoded, QByteArray("?")); @@ -465,7 +467,7 @@ void tst_QTextCodec::flagF7808080() const QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 - Q_ASSERT(codec); + QVERIFY(codec); //QVERIFY(!codec->canEncode(QChar(0x1C0000))); @@ -482,7 +484,7 @@ void tst_QTextCodec::flagEFBFBF() const invalidInput[2] = char(0xBF); const QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 - Q_ASSERT(codec); + QVERIFY(codec); { //QVERIFY(!codec->canEncode(QChar(0xFFFF))); @@ -1627,7 +1629,7 @@ void tst_QTextCodec::utf8bom() QFETCH(QString, result); QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 - Q_ASSERT(codec); + QVERIFY(codec); QCOMPARE(codec->toUnicode(data.constData(), data.length(), 0), result); @@ -2236,6 +2238,19 @@ void tst_QTextCodec::moreToFromUnicode() QCOMPARE(testData, cStr); } +void tst_QTextCodec::shiftJis() +{ + QByteArray backslashTilde("\\~"); + QTextCodec* codec = QTextCodec::codecForName("shift_jis"); + QString string = codec->toUnicode(backslashTilde); + QCOMPARE(string.length(), 2); + QCOMPARE(string.at(0), QChar(QLatin1Char('\\'))); + QCOMPARE(string.at(1), QChar(QLatin1Char('~'))); + + QByteArray encoded = codec->fromUnicode(string); + QCOMPARE(encoded, backslashTilde); +} + struct DontCrashAtExit { ~DontCrashAtExit() { QTextCodec *c = QTextCodec::codecForName("utf8"); diff --git a/tests/auto/qtextdocument/tst_qtextdocument.cpp b/tests/auto/qtextdocument/tst_qtextdocument.cpp index 58a2e00..1129219 100644 --- a/tests/auto/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/qtextdocument/tst_qtextdocument.cpp @@ -180,6 +180,8 @@ private slots: void escape_data(); void escape(); + void copiedFontSize(); + private: void backgroundImage_checkExpectedHtml(const QTextDocument &doc); @@ -2734,5 +2736,29 @@ void tst_QTextDocument::escape() QCOMPARE(Qt::escape(original), expected); } +void tst_QTextDocument::copiedFontSize() +{ + QTextDocument documentInput; + QTextDocument documentOutput; + + QFont fontInput; + fontInput.setPixelSize(24); + + QTextCursor cursorInput(&documentInput); + QTextCharFormat formatInput = cursorInput.charFormat(); + formatInput.setFont(fontInput); + cursorInput.insertText("Should be the same font", formatInput); + cursorInput.select(QTextCursor::Document); + + QTextDocumentFragment fragmentInput(cursorInput); + QString html = fragmentInput.toHtml(); + + QTextCursor cursorOutput(&documentOutput); + QTextDocumentFragment fragmentOutput = QTextDocumentFragment::fromHtml(html); + cursorOutput.insertFragment(fragmentOutput); + + QCOMPARE(cursorOutput.charFormat().font().pixelSize(), 24); +} + QTEST_MAIN(tst_QTextDocument) #include "tst_qtextdocument.moc" diff --git a/tests/auto/qtextedit/qtextedit.pro b/tests/auto/qtextedit/qtextedit.pro index 43813da..e7d6c03 100644 --- a/tests/auto/qtextedit/qtextedit.pro +++ b/tests/auto/qtextedit/qtextedit.pro @@ -6,7 +6,7 @@ HEADERS += SOURCES += tst_qtextedit.cpp wince*|symbian: { - addImages.sources = fullWidthSelection/* + addImages.files = fullWidthSelection/* addImages.path = fullWidthSelection DEPLOYMENT += addImages } diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp index 1775c8d..42ea3b1 100644 --- a/tests/auto/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/qtextedit/tst_qtextedit.cpp @@ -42,7 +42,6 @@ #include <QtTest/QtTest> - #include <qtextedit.h> #include <qtextcursor.h> #include <qtextlist.h> @@ -69,6 +68,7 @@ typedef QList<keyPairType> pairListType; Q_DECLARE_METATYPE(pairListType); Q_DECLARE_METATYPE(keyPairType); Q_DECLARE_METATYPE(QList<bool>); +Q_DECLARE_METATYPE(QList<int>); #ifdef Q_WS_MAC #include <Carbon/Carbon.h> @@ -205,6 +205,11 @@ private slots: #ifndef QT_NO_CONTEXTMENU void taskQTBUG_7902_contextMenuCrash(); #endif + void bidiVisualMovement_data(); + void bidiVisualMovement(); + + void bidiLogicalMovement_data(); + void bidiLogicalMovement(); private: void createSelection(); @@ -312,7 +317,7 @@ void tst_QTextEdit::getSetCheck() // void QTextEdit::setFontPointSize(qreal) obj1.setFontPointSize(qreal(1.1)); QCOMPARE(qreal(1.1), obj1.fontPointSize()); - // we currently Q_ASSERT_X in QFont::setPointSizeF for that + // we currently assert in QFont::setPointSizeF for that //obj1.setFontPointSize(0.0); //QCOMPARE(1.1, obj1.fontPointSize()); // Should not accept 0.0 => keep old @@ -322,7 +327,7 @@ void tst_QTextEdit::getSetCheck() QCOMPARE(1, obj1.fontWeight()); // Range<1, 99> obj1.setFontWeight(99); QCOMPARE(99, obj1.fontWeight()); // Range<1, 99> - /* Q_ASSERT_X in qfont.cpp + /* assertion in qfont.cpp obj1.setFontWeight(INT_MIN); QCOMPARE(1, obj1.fontWeight()); // Range<1, 99> obj1.setFontWeight(INT_MAX); @@ -2059,7 +2064,7 @@ void tst_QTextEdit::compareWidgetAndImage(QTextEdit &widget, const QString &imag QCOMPARE(original.isNull(), false); QCOMPARE(original.size(), image.size()); - Q_ASSERT(image.depth() == 32); + QCOMPARE(image.depth(), 32); QCOMPARE(original.depth(), image.depth()); const int bytesPerLine = image.bytesPerLine(); @@ -2235,5 +2240,147 @@ void tst_QTextEdit::taskQTBUG_7902_contextMenuCrash() } #endif +void tst_QTextEdit::bidiVisualMovement_data() +{ + QTest::addColumn<QString>("logical"); + QTest::addColumn<int>("basicDir"); + QTest::addColumn<QList<int> >("positionList"); + + QTest::newRow("Latin text") + << QString::fromUtf8("abc") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text, one item") + << QString::fromUtf8("\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text after Latin text") + << QString::fromUtf8("abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3); + QTest::newRow("Latin text after Hebrew text") + << QString::fromUtf8("\327\220\327\221\327\222abc") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3); + QTest::newRow("LTR, 3 items") + << QString::fromUtf8("abc\327\220\327\221\327\222abc") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9); + QTest::newRow("RTL, 3 items") + << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9); + QTest::newRow("LTR, 4 items") + << QString::fromUtf8("abc\327\220\327\221\327\222abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9); + QTest::newRow("RTL, 4 items") + << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222abc") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9); +} + +void tst_QTextEdit::bidiVisualMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + QFETCH(QList<int>, positionList); + + ed->setText(logical); + + QTextOption option = ed->document()->defaultTextOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + ed->document()->setDefaultTextOption(option); + + ed->document()->setDefaultCursorMoveStyle(Qt::VisualMoveStyle); + ed->moveCursor(QTextCursor::Start); + ed->show(); + + bool moved; + int i = 0, oldPos, newPos = 0; + + do { + oldPos = newPos; + QVERIFY(oldPos == positionList[i]); + if (basicDir == QChar::DirL) { + ed->moveCursor(QTextCursor::Right); + } else + { + ed->moveCursor(QTextCursor::Left); + } + newPos = ed->textCursor().position(); + moved = (oldPos != newPos); + i++; + } while (moved); + + QVERIFY(i == positionList.size()); + + do { + i--; + oldPos = newPos; + QVERIFY(oldPos == positionList[i]); + if (basicDir == QChar::DirL) { + ed->moveCursor(QTextCursor::Left); + } else + { + ed->moveCursor(QTextCursor::Right); + } + newPos = ed->textCursor().position(); + moved = (oldPos != newPos); + } while (moved && i >= 0); +} + +void tst_QTextEdit::bidiLogicalMovement_data() +{ + bidiVisualMovement_data(); +} + +void tst_QTextEdit::bidiLogicalMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + ed->setText(logical); + + QTextOption option = ed->document()->defaultTextOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + ed->document()->setDefaultTextOption(option); + + ed->document()->setDefaultCursorMoveStyle(Qt::LogicalMoveStyle); + ed->moveCursor(QTextCursor::Start); + ed->show(); + + bool moved; + int i = 0, oldPos, newPos = 0; + + do { + oldPos = newPos; + QVERIFY(oldPos == i); + if (basicDir == QChar::DirL) { + ed->moveCursor(QTextCursor::Right); + } else + { + ed->moveCursor(QTextCursor::Left); + } + newPos = ed->textCursor().position(); + moved = (oldPos != newPos); + i++; + } while (moved); + + do { + i--; + oldPos = newPos; + QVERIFY(oldPos == i); + if (basicDir == QChar::DirL) { + ed->moveCursor(QTextCursor::Left); + } else + { + ed->moveCursor(QTextCursor::Right); + } + newPos = ed->textCursor().position(); + moved = (oldPos != newPos); + } while (moved && i >= 0); +} + QTEST_MAIN(tst_QTextEdit) #include "tst_qtextedit.moc" diff --git a/tests/auto/qtextlayout/tst_qtextlayout.cpp b/tests/auto/qtextlayout/tst_qtextlayout.cpp index df84c8f..b6adc2b 100644 --- a/tests/auto/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/qtextlayout/tst_qtextlayout.cpp @@ -85,6 +85,7 @@ private slots: void cursorToXForSetColumns(); void defaultWordSeparators_data(); void defaultWordSeparators(); + void cursorMovementFromInvalidPositions(); void cursorMovementInsideSpaces(); void charWordStopOnLineSeparator(); void xToCursorAtEndOfLine(); @@ -123,11 +124,9 @@ private slots: void testLineBreakingAllSpaces(); void lineWidthFromBOM(); void textWidthVsWIdth(); + void textWithSurrogates_qtbug15679(); void textWidthWithStackedTextEngine(); void textWidthWithLineSeparator(); - void textWithSurrogates_qtbug15679(); - void cursorInLigatureWithMultipleLines(); - void xToCursorForLigatures(); private: QFont testFont; @@ -548,6 +547,10 @@ void tst_QTextLayout::defaultWordSeparators_data() QTest::newRow("lineseparator") << QString::fromLatin1("abcd") + QString(QChar::LineSeparator) + QString::fromLatin1("efgh") << 0 << 5; + + QTest::newRow("empty") + << QString() + << 0 << 0; } void tst_QTextLayout::defaultWordSeparators() @@ -561,12 +564,31 @@ void tst_QTextLayout::defaultWordSeparators() QCOMPARE(layout.previousCursorPosition(endPos, QTextLayout::SkipWords), startPos); } +void tst_QTextLayout::cursorMovementFromInvalidPositions() +{ + int badpos = 10000; + + QTextLayout layout("ABC", testFont); + + QCOMPARE(layout.previousCursorPosition(-badpos, QTextLayout::SkipCharacters), -badpos); + QCOMPARE(layout.nextCursorPosition(-badpos, QTextLayout::SkipCharacters), -badpos); + + QCOMPARE(layout.previousCursorPosition(badpos, QTextLayout::SkipCharacters), badpos); + QCOMPARE(layout.nextCursorPosition(badpos, QTextLayout::SkipCharacters), badpos); +} + void tst_QTextLayout::cursorMovementInsideSpaces() { QTextLayout layout("ABC DEF", testFont); QCOMPARE(layout.previousCursorPosition(6, QTextLayout::SkipWords), 0); QCOMPARE(layout.nextCursorPosition(6, QTextLayout::SkipWords), 15); + + + QTextLayout layout2("ABC\t\t\t\t\t\t\t\t\t\t\t\tDEF", testFont); + + QCOMPARE(layout2.previousCursorPosition(6, QTextLayout::SkipWords), 0); + QCOMPARE(layout2.nextCursorPosition(6, QTextLayout::SkipWords), 15); } void tst_QTextLayout::charWordStopOnLineSeparator() @@ -1392,33 +1414,6 @@ void tst_QTextLayout::textWidthVsWIdth() } } -void tst_QTextLayout::textWidthWithStackedTextEngine() -{ - QString text = QString::fromUtf8("คลิภถัดไป เพื่à¸à¸”ำเนินà¸à¸²à¸£à¸•à¹ˆà¸"); - QTextLayout layout(text); - layout.beginLayout(); - QTextLine line = layout.createLine(); - layout.endLayout(); - QFontMetricsF fm(layout.font()); - QCOMPARE(line.naturalTextWidth(), fm.width(text)); -} - -void tst_QTextLayout::textWidthWithLineSeparator() -{ - QString s1("Save Project"), s2("Save Project\ntest"); - s2.replace('\n', QChar::LineSeparator); - - QTextLayout layout1(s1), layout2(s2); - layout1.beginLayout(); - layout2.beginLayout(); - - QTextLine line1 = layout1.createLine(); - QTextLine line2 = layout2.createLine(); - line1.setLineWidth(0x1000); - line2.setLineWidth(0x1000); - QCOMPARE(line1.naturalTextWidth(), line2.naturalTextWidth()); -} - void tst_QTextLayout::textWithSurrogates_qtbug15679() { QString str = QString::fromUtf8("🀀a🀀"); @@ -1438,44 +1433,31 @@ void tst_QTextLayout::textWithSurrogates_qtbug15679() QCOMPARE(x[2] - x[0], x[5] - x[3]); } -void tst_QTextLayout::cursorInLigatureWithMultipleLines() +void tst_QTextLayout::textWidthWithStackedTextEngine() { -#if !defined(Q_WS_MAC) - QSKIP("This test can only be run on Mac", SkipAll); -#endif - QTextLayout layout("first line finish", QFont("Times", 20)); + QString text = QString::fromUtf8("คลิภถัดไป เพื่à¸à¸”ำเนินà¸à¸²à¸£à¸•à¹ˆà¸"); + QTextLayout layout(text); layout.beginLayout(); QTextLine line = layout.createLine(); - line.setLineWidth(70); - line = layout.createLine(); layout.endLayout(); - - // The second line will be "finish", with "fi" as a ligature - QVERIFY(line.cursorToX(0) != line.cursorToX(1)); + QFontMetricsF fm(layout.font()); + QCOMPARE(line.naturalTextWidth(), fm.width(text)); } -void tst_QTextLayout::xToCursorForLigatures() +void tst_QTextLayout::textWidthWithLineSeparator() { -#if !defined(Q_WS_MAC) - QSKIP("This test can not be run on Mac", SkipAll); -#endif - QTextLayout layout("fi", QFont("Times", 20)); - layout.beginLayout(); - QTextLine line = layout.createLine(); - layout.endLayout(); - - QVERIFY(line.xToCursor(0) != line.xToCursor(line.naturalTextWidth() / 2)); - - // U+0061 U+0308 - QTextLayout layout2(QString::fromUtf8("\x61\xCC\x88"), QFont("Times", 20)); + QString s1("Save Project"), s2("Save Project\ntest"); + s2.replace('\n', QChar::LineSeparator); + QTextLayout layout1(s1), layout2(s2); + layout1.beginLayout(); layout2.beginLayout(); - line = layout2.createLine(); - layout2.endLayout(); - qreal width = line.naturalTextWidth(); - QVERIFY(line.xToCursor(0) == line.xToCursor(width / 2) || - line.xToCursor(width) == line.xToCursor(width / 2)); + QTextLine line1 = layout1.createLine(); + QTextLine line2 = layout2.createLine(); + line1.setLineWidth(0x1000); + line2.setLineWidth(0x1000); + QCOMPARE(line1.naturalTextWidth(), line2.naturalTextWidth()); } QTEST_MAIN(tst_QTextLayout) diff --git a/tests/auto/qtextlist/tst_qtextlist.cpp b/tests/auto/qtextlist/tst_qtextlist.cpp index 262d03a..164dd6f 100644 --- a/tests/auto/qtextlist/tst_qtextlist.cpp +++ b/tests/auto/qtextlist/tst_qtextlist.cpp @@ -67,6 +67,9 @@ private slots: void item(); void autoNumbering(); void autoNumberingRTL(); + void autoNumberingPrefixAndSuffix(); + void autoNumberingPrefixAndSuffixRTL(); + void autoNumberingPrefixAndSuffixHtmlExportImport(); void romanNumbering(); void romanNumberingLimit(); void formatChange(); @@ -128,6 +131,76 @@ void tst_QTextList::autoNumbering() QVERIFY(cursor.currentList()->itemText(cursor.block()) == "ab."); } +void tst_QTextList::autoNumberingPrefixAndSuffix() +{ + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListLowerAlpha); + fmt.setNumberPrefix("-"); + fmt.setNumberSuffix(")"); + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + for (int i = 0; i < 27; ++i) + cursor.insertBlock(); + + QVERIFY(list->count() == 28); + + QVERIFY(cursor.currentList()); + QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 27); + QVERIFY(cursor.currentList()->itemText(cursor.block()) == "-ab)"); +} + +void tst_QTextList::autoNumberingPrefixAndSuffixRTL() +{ + QTextBlockFormat bfmt; + bfmt.setLayoutDirection(Qt::RightToLeft); + cursor.setBlockFormat(bfmt); + + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListUpperAlpha); + fmt.setNumberPrefix("-"); + fmt.setNumberSuffix("*"); + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + cursor.insertBlock(); + + QVERIFY(list->count() == 2); + + QVERIFY(cursor.currentList()->itemText(cursor.block()) == "*B-"); +} + +void tst_QTextList::autoNumberingPrefixAndSuffixHtmlExportImport() +{ + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListLowerAlpha); + fmt.setNumberPrefix("\""); + fmt.setNumberSuffix("#"); + fmt.setIndent(10); + // FIXME: Would like to test "'" but there's a problem in the css parser (Scanner::preprocess + // is called before the values are being parsed), so the quoting does not work. + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + for (int i = 0; i < 27; ++i) + cursor.insertBlock(); + + QVERIFY(list->count() == 28); + + QString htmlExport = doc->toHtml(); + QTextDocument importDoc; + importDoc.setHtml(htmlExport); + + QTextCursor importCursor(&importDoc); + for (int i = 0; i < 27; ++i) + importCursor.movePosition(QTextCursor::NextBlock); + + QVERIFY(importCursor.currentList()); + QVERIFY(importCursor.currentList()->itemNumber(importCursor.block()) == 27); + QVERIFY(importCursor.currentList()->itemText(importCursor.block()) == "\"ab#"); + QVERIFY(importCursor.currentList()->format().indent() == 10); +} + void tst_QTextList::autoNumberingRTL() { QTextBlockFormat bfmt; diff --git a/tests/auto/qtextodfwriter/tst_qtextodfwriter.cpp b/tests/auto/qtextodfwriter/tst_qtextodfwriter.cpp index 0dbcf65..765afce 100644 --- a/tests/auto/qtextodfwriter/tst_qtextodfwriter.cpp +++ b/tests/auto/qtextodfwriter/tst_qtextodfwriter.cpp @@ -114,11 +114,14 @@ QString tst_QTextOdfWriter::getContentFromXml() xmlWriter->writeEndDocument(); buffer->close(); QString stringContent = QString::fromUtf8(buffer->data()); + QString ret; int index = stringContent.indexOf("<dummy"); - Q_ASSERT(index); - index = stringContent.indexOf('>', index); - stringContent = stringContent.mid(index+1, stringContent.length() - index - 10); - return stringContent; + if (index > 0) { + index = stringContent.indexOf('>', index); + if (index > 0) + ret = stringContent.mid(index+1, stringContent.length() - index - 10); + } + return ret; } void tst_QTextOdfWriter::testWriteParagraph_data() diff --git a/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp index 3c26e54..6cbff36 100644 --- a/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp @@ -56,11 +56,14 @@ -#if defined(Q_WS_X11) +#if defined(Q_WS_X11) || defined(Q_WS_MAC) #define private public #include <private/qtextengine_p.h> #include <qtextlayout.h> #undef private +#else +#include <private/qtextengine_p.h> +#include <qtextlayout.h> #endif #include <qfontdatabase.h> @@ -103,6 +106,11 @@ private slots: void khmer(); void linearB(); + void controlInSyllable_qtbug14204(); + void combiningMarks_qtbug15675(); + + void mirroredChars_data(); + void mirroredChars(); }; tst_QTextScriptEngine::tst_QTextScriptEngine() @@ -1111,6 +1119,125 @@ void tst_QTextScriptEngine::greek() #endif } +void tst_QTextScriptEngine::controlInSyllable_qtbug14204() +{ +#if defined(Q_WS_X11) + QString s; + s.append(QChar(0x0915)); + s.append(QChar(0x094d)); + s.append(QChar(0x200d)); + s.append(QChar(0x0915)); + + QTextLayout layout(s); + QTextEngine *e = layout.d; + e->itemize(); + e->shape(0); + + QVERIFY(e->layoutData->items[0].num_glyphs == 2); + QVERIFY(e->layoutData->glyphLayout.advances_x[1] != 0); +#else + QSKIP("X11 specific test", SkipAll); +#endif +} + +void tst_QTextScriptEngine::combiningMarks_qtbug15675() +{ +#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA) + QString s; + s.append(QChar(0x0061)); + s.append(QChar(0x0062)); + s.append(QChar(0x0300)); + s.append(QChar(0x0063)); + + QFont font("Monaco"); + QTextLayout layout(s, font); + QTextEngine *e = layout.d; + e->itemize(); + e->shape(0); + + QVERIFY(e->layoutData->items[0].num_glyphs == 4); + QVERIFY(e->layoutData->glyphLayout.advances_y[2] > 0); +#elif defined(Q_WS_X11) + QFontDatabase db; + + if (!db.families().contains("DejaVu Sans Mono")) { + QSKIP("Required font (DejaVu Sans Mono) doesn't exist, skip test.", SkipAll); + return; + } + + QString s; + s.append(QChar(0x0062)); + s.append(QChar(0x0332)); + s.append(QChar(0x0063)); + + QTextLayout layout(s, QFont("DejaVu Sans Mono")); + QTextEngine *e = layout.d; + e->itemize(); + e->shape(0); + + QVERIFY(e->layoutData->items[0].num_glyphs == 3); + QVERIFY(e->layoutData->glyphLayout.advances_x[1] == 0); +#else + QSKIP("X11/Mac specific test", SkipAll); +#endif +} + +void tst_QTextScriptEngine::mirroredChars_data() +{ + QTest::addColumn<int>("hintingPreference"); + + QTest::newRow("Default hinting") << int(QFont::PreferDefaultHinting); + QTest::newRow("No hinting") << int(QFont::PreferNoHinting); + QTest::newRow("Vertical hinting") << int(QFont::PreferVerticalHinting); + QTest::newRow("Full hinting") << int(QFont::PreferFullHinting); +} + +void tst_QTextScriptEngine::mirroredChars() +{ +#if defined(Q_WS_MAC) + QSKIP("Not supported on Mac", SkipAll); +#endif + QFETCH(int, hintingPreference); + + QFont font; + font.setHintingPreference(QFont::HintingPreference(hintingPreference)); + + QString s; + s.append(QLatin1Char('(')); + s.append(QLatin1Char(')')); + + HB_Glyph leftParenthesis; + HB_Glyph rightParenthesis; + { + QTextLayout layout(s); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QTextEngine *e = layout.engine(); + e->itemize(); + e->shape(0); + QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(2)); + + const QGlyphLayout &glyphLayout = e->layoutData->glyphLayout; + leftParenthesis = glyphLayout.glyphs[0]; + rightParenthesis = glyphLayout.glyphs[1]; + } + + { + QTextLayout layout(s); + layout.setFlags(Qt::TextForceRightToLeft); + + QTextEngine *e = layout.engine(); + e->itemize(); + e->shape(0); + QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(2)); + + const QGlyphLayout &glyphLayout = e->layoutData->glyphLayout; + QCOMPARE(glyphLayout.glyphs[0], rightParenthesis); + QCOMPARE(glyphLayout.glyphs[1], leftParenthesis); + } +} QTEST_MAIN(tst_QTextScriptEngine) #include "tst_qtextscriptengine.moc" diff --git a/tests/auto/qtextstream/test/test.pro b/tests/auto/qtextstream/test/test.pro index 20823de..8805fb9 100644 --- a/tests/auto/qtextstream/test/test.pro +++ b/tests/auto/qtextstream/test/test.pro @@ -18,9 +18,9 @@ QT = core network wince*|symbian: { - addFiles.sources = ../rfc3261.txt ../shift-jis.txt ../task113817.txt ../qtextstream.qrc ../tst_qtextstream.cpp + addFiles.files = ../rfc3261.txt ../shift-jis.txt ../task113817.txt ../qtextstream.qrc ../tst_qtextstream.cpp addFiles.path = . - res.sources = ../resources + res.files = ../resources res.path = . DEPLOYMENT += addFiles } @@ -30,7 +30,7 @@ wince*: { }else:symbian { # Symbian can't define SRCDIR meaningfully here qt_not_deployed { - codecs_plugins.sources = qcncodecs.dll qjpcodecs.dll qtwcodecs.dll qkrcodecs.dll + codecs_plugins.files = qcncodecs.dll qjpcodecs.dll qtwcodecs.dll qkrcodecs.dll codecs_plugins.path = $$QT_PLUGINS_BASE_DIR/codecs DEPLOYMENT += codecs_plugins } diff --git a/tests/auto/qtextstream/tst_qtextstream.cpp b/tests/auto/qtextstream/tst_qtextstream.cpp index 1fd566e..3a2c65c 100644 --- a/tests/auto/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/qtextstream/tst_qtextstream.cpp @@ -208,6 +208,7 @@ private slots: void seek(); void pos(); void pos2(); + void pos3LargeFile(); void readStdin(); void readAllFromStdin(); void readLineFromStdin(); @@ -228,6 +229,7 @@ private slots: void status_real_read(); void status_integer_read(); void status_word_read(); + void status_write_error(); // use case tests void useCase1(); @@ -1501,6 +1503,41 @@ void tst_QTextStream::pos2() } // ------------------------------------------------------------------------------ +void tst_QTextStream::pos3LargeFile() +{ + { + QFile file(TestFileName); + file.open(QIODevice::WriteOnly | QIODevice::Text); + QTextStream out( &file ); + // NOTE: The unusual spacing is to ensure non-1-character whitespace. + QString lineString = " 0 1 2\t3 4\t \t5 6 7 8 9 \n"; + // Approximate 50kb text file + const int NbLines = (50*1024) / lineString.length() + 1; + for (int line = 0; line < NbLines; ++line) + out << lineString; + // File is automatically flushed and closed on destruction. + } + QFile file(TestFileName); + file.open(QIODevice::ReadOnly | QIODevice::Text); + QTextStream in( &file ); + const int testValues[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + int value; + while (true) { + in.pos(); + for ( int i = 0; i < 10; ++i ) { + in >> value; + if (in.status() != QTextStream::Ok) { + // End case, i == 0 && eof reached. + QCOMPARE(i, 0); + QCOMPARE(in.status(), QTextStream::ReadPastEnd); + return; + } + QCOMPARE(value, testValues[i]); + } + } +} + +// ------------------------------------------------------------------------------ void tst_QTextStream::readStdin() { #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) @@ -4176,6 +4213,42 @@ void tst_QTextStream::status_word_read() QCOMPARE(s.status(), QTextStream::ReadPastEnd); } +class FakeBuffer : public QBuffer +{ +protected: + qint64 writeData(const char *c, qint64 i) { return m_lock ? 0 : QBuffer::writeData(c, i); } +public: + FakeBuffer(bool locked = false) : m_lock(locked) {} + void setLocked(bool locked) { m_lock = locked; } +private: + bool m_lock; +}; + +void tst_QTextStream::status_write_error() +{ + FakeBuffer fb(false); + QVERIFY(fb.open(QBuffer::ReadWrite)); + QTextStream fs(&fb); + fs.setCodec(QTextCodec::codecForName("latin1")); + /* first write some initial content */ + fs << "hello"; + fs.flush(); + QCOMPARE(fs.status(), QTextStream::Ok); + QCOMPARE(fb.data(), QByteArray("hello")); + /* then test that writing can cause an error */ + fb.setLocked(true); + fs << "error"; + fs.flush(); + QCOMPARE(fs.status(), QTextStream::WriteFailed); + QCOMPARE(fb.data(), QByteArray("hello")); + /* finally test that writing after an error doesn't change the stream any more */ + fb.setLocked(false); + fs << "can't do that"; + fs.flush(); + QCOMPARE(fs.status(), QTextStream::WriteFailed); + QCOMPARE(fb.data(), QByteArray("hello")); +} + void tst_QTextStream::task180679_alignAccountingStyle() { { diff --git a/tests/auto/qthread/qthread.pro b/tests/auto/qthread/qthread.pro index 0b042ab..d3b1028 100644 --- a/tests/auto/qthread/qthread.pro +++ b/tests/auto/qthread/qthread.pro @@ -2,3 +2,4 @@ load(qttest_p4) SOURCES += tst_qthread.cpp QT = core symbian:LIBS += -llibpthread +CONFIG += parallel_test diff --git a/tests/auto/qthread/tst_qthread.cpp b/tests/auto/qthread/tst_qthread.cpp index 632cd84..3c46212 100644 --- a/tests/auto/qthread/tst_qthread.cpp +++ b/tests/auto/qthread/tst_qthread.cpp @@ -103,11 +103,20 @@ private slots: void adoptedThreadExit(); void adoptedThreadExec(); void adoptedThreadFinished(); + void adoptedThreadExecFinished(); void adoptMultipleThreads(); + void adoptMultipleThreadsOverlap(); void QTBUG13810_exitAndStart(); void QTBUG15378_exitAndExec(); + void connectThreadFinishedSignalToObjectDeleteLaterSlot(); + void wait2(); + void wait3_slowDestructor(); + void destroyFinishRace(); + void startFinishRace(); + void startAndQuitCustomEventLoop(); + void stressTest(); }; @@ -200,7 +209,7 @@ public: cond.wait(&mutex, five_minutes); } setTerminationEnabled(true); - Q_ASSERT_X(false, "tst_QThread", "test case hung"); + qFatal("tst_QThread: test case hung"); } }; @@ -656,7 +665,9 @@ void tst_QThread::usleep() typedef void (*FunctionPointer)(void *); void noop(void*) { } -#ifdef Q_OS_UNIX +#ifdef Q_OS_SYMBIAN +typedef RThread ThreadHandle; +#elif defined Q_OS_UNIX typedef pthread_t ThreadHandle; #elif defined Q_OS_WIN typedef HANDLE ThreadHandle; @@ -687,6 +698,7 @@ public: protected: static void *runUnix(void *data); static unsigned WIN_FIX_STDCALL runWin(void *data); + static int runSymbian(void *data); FunctionPointer functionPointer; void *data; @@ -696,7 +708,10 @@ void NativeThreadWrapper::start(FunctionPointer functionPointer, void *data) { this->functionPointer = functionPointer; this->data = data; -#ifdef Q_OS_UNIX +#ifdef Q_OS_SYMBIAN + qt_symbian_throwIfError(nativeThreadHandle.Create(KNullDesC(), NativeThreadWrapper::runSymbian, 1024, &User::Allocator(), this)); + nativeThreadHandle.Resume(); +#elif defined Q_OS_UNIX const int state = pthread_create(&nativeThreadHandle, 0, NativeThreadWrapper::runUnix, this); Q_UNUSED(state); #elif defined(Q_OS_WINCE) @@ -716,7 +731,12 @@ void NativeThreadWrapper::startAndWait(FunctionPointer functionPointer, void *da void NativeThreadWrapper::join() { -#ifdef Q_OS_UNIX +#ifdef Q_OS_SYMBIAN + TRequestStatus stat; + nativeThreadHandle.Logon(stat); + User::WaitForRequest(stat); + nativeThreadHandle.Close(); +#elif defined Q_OS_UNIX pthread_join(nativeThreadHandle, 0); #elif defined Q_OS_WIN WaitForSingleObject(nativeThreadHandle, INFINITE); @@ -756,6 +776,12 @@ unsigned WIN_FIX_STDCALL NativeThreadWrapper::runWin(void *data) return 0; } +int NativeThreadWrapper::runSymbian(void *data) +{ + runUnix(data); + return 0; +} + void NativeThreadWrapper::stop() { QMutexLocker lock(&mutex); @@ -888,6 +914,21 @@ void tst_QThread::adoptedThreadFinished() QVERIFY(!QTestEventLoop::instance().timeout()); } +void tst_QThread::adoptedThreadExecFinished() +{ + NativeThreadWrapper nativeThread; + nativeThread.setWaitForStop(); + nativeThread.startAndWait(adoptedThreadExecFunction); + + QObject::connect(nativeThread.qthread, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + + nativeThread.stop(); + nativeThread.join(); + + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); +} + void tst_QThread::adoptMultipleThreads() { #if defined(Q_OS_WIN) @@ -917,6 +958,7 @@ void tst_QThread::adoptMultipleThreads() for (int i = 0; i < numThreads; ++i) { nativeThreads.at(i)->stop(); nativeThreads.at(i)->join(); + delete nativeThreads.at(i); } QTestEventLoop::instance().enterLoop(5); @@ -924,6 +966,50 @@ void tst_QThread::adoptMultipleThreads() QCOMPARE(int(recorder.activationCount), numThreads); } +void tst_QThread::adoptMultipleThreadsOverlap() +{ +#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) + const int numThreads = 20; +# else + // need to test lots of threads, so that we exceed MAXIMUM_WAIT_OBJECTS in qt_adopted_thread_watcher() + const int numThreads = 200; +# endif +#elif defined(Q_OS_SYMBIAN) + // stress the monitoring thread's add function + const int numThreads = 100; +#else + const int numThreads = 5; +#endif + QVector<NativeThreadWrapper*> nativeThreads; + + SignalRecorder recorder; + + for (int i = 0; i < numThreads; ++i) { + nativeThreads.append(new NativeThreadWrapper()); + nativeThreads.at(i)->setWaitForStop(); + nativeThreads.at(i)->mutex.lock(); + nativeThreads.at(i)->start(); + } + for (int i = 0; i < numThreads; ++i) { + nativeThreads.at(i)->startCondition.wait(&nativeThreads.at(i)->mutex); + QObject::connect(nativeThreads.at(i)->qthread, SIGNAL(finished()), &recorder, SLOT(slot())); + nativeThreads.at(i)->mutex.unlock(); + } + + QObject::connect(nativeThreads.at(numThreads - 1)->qthread, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + + for (int i = 0; i < numThreads; ++i) { + nativeThreads.at(i)->stop(); + nativeThreads.at(i)->join(); + delete nativeThreads.at(i); + } + + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + QCOMPARE(int(recorder.activationCount), numThreads); +} void tst_QThread::stressTest() { #if defined(Q_OS_WINCE) @@ -976,7 +1062,6 @@ void tst_QThread::QTBUG13810_exitAndStart() QCOMPARE(sync1.m_prop, 89); } - void tst_QThread::QTBUG15378_exitAndExec() { class Thread : public QThread { @@ -999,7 +1084,7 @@ void tst_QThread::QTBUG15378_exitAndExec() thread.sem2.acquire(); int v = thread.value; QCOMPARE(v, 556); - + //test that the thread is running by executing queued connected signal there Syncronizer sync1; sync1.moveToThread(&thread); @@ -1015,6 +1100,149 @@ void tst_QThread::QTBUG15378_exitAndExec() QCOMPARE(sync1.m_prop, 89); } +void tst_QThread::connectThreadFinishedSignalToObjectDeleteLaterSlot() +{ + QThread thread; + QObject *object = new QObject; + QWeakPointer<QObject> p = object; + QVERIFY(!p.isNull()); + connect(&thread, SIGNAL(started()), &thread, SLOT(quit()), Qt::DirectConnection); + connect(&thread, SIGNAL(finished()), object, SLOT(deleteLater())); + object->moveToThread(&thread); + thread.start(); + QVERIFY(thread.wait(30000)); + QVERIFY(p.isNull()); +} + +class Waiting_Thread : public QThread +{ +public: + enum { WaitTime = 800 }; + QMutex mutex; + QWaitCondition cond1; + QWaitCondition cond2; + + void run() + { + QMutexLocker locker(&mutex); + cond1.wait(&mutex); + cond2.wait(&mutex, WaitTime); + } +}; + +void tst_QThread::wait2() +{ + QElapsedTimer timer; + Waiting_Thread thread; + thread.start(); + timer.start(); + QVERIFY(!thread.wait(Waiting_Thread::WaitTime)); + qint64 elapsed = timer.elapsed(); + + QVERIFY(elapsed >= Waiting_Thread::WaitTime); + //QVERIFY(elapsed < Waiting_Thread::WaitTime * 1.4); + + timer.start(); + thread.cond1.wakeOne(); + QVERIFY(thread.wait(/*Waiting_Thread::WaitTime * 1.4*/)); + elapsed = timer.elapsed(); + QVERIFY(elapsed >= Waiting_Thread::WaitTime); + //QVERIFY(elapsed < Waiting_Thread::WaitTime * 1.4); +} + + +class SlowSlotObject : public QObject { + Q_OBJECT +public: + QMutex mutex; + QWaitCondition cond; +public slots: + void slowSlot() { + QMutexLocker locker(&mutex); + cond.wait(&mutex); + } +}; + +void tst_QThread::wait3_slowDestructor() +{ + SlowSlotObject slow; + QThread thread; + QObject::connect(&thread, SIGNAL(finished()), &slow, SLOT(slowSlot()), Qt::DirectConnection); + + enum { WaitTime = 1800 }; + QElapsedTimer timer; + + thread.start(); + thread.quit(); + //the quit function will cause the thread to finish and enter the slowSlot that is blocking + + timer.start(); + QVERIFY(!thread.wait(Waiting_Thread::WaitTime)); + qint64 elapsed = timer.elapsed(); + + QVERIFY(elapsed >= Waiting_Thread::WaitTime); + //QVERIFY(elapsed < Waiting_Thread::WaitTime * 1.4); + + slow.cond.wakeOne(); + //now the thread should finish quickly + QVERIFY(thread.wait(one_minute)); +} + +void tst_QThread::destroyFinishRace() +{ + class Thread : public QThread { void run() {} }; + for (int i = 0; i < 15; i++) { + Thread *thr = new Thread; + connect(thr, SIGNAL(finished()), thr, SLOT(deleteLater())); + QWeakPointer<QThread> weak(static_cast<QThread*>(thr)); + thr->start(); + while (weak) { + qApp->processEvents(); + qApp->processEvents(); + qApp->processEvents(); + qApp->processEvents(); + } + } +} + +void tst_QThread::startFinishRace() +{ + class Thread : public QThread { + public: + Thread() : i (50) {} + void run() { + i--; + if (!i) disconnect(this, SIGNAL(finished()), 0, 0); + } + int i; + }; + for (int i = 0; i < 15; i++) { + Thread thr; + connect(&thr, SIGNAL(finished()), &thr, SLOT(start())); + thr.start(); + while (!thr.isFinished() || thr.i != 0) { + qApp->processEvents(); + qApp->processEvents(); + qApp->processEvents(); + qApp->processEvents(); + } + QCOMPARE(thr.i, 0); + } +} + +void tst_QThread::startAndQuitCustomEventLoop() +{ + struct Thread : QThread { + void run() { QEventLoop().exec(); } + }; + + for (int i = 0; i < 5; i++) { + Thread t; + t.start(); + t.quit(); + t.wait(); + } +} QTEST_MAIN(tst_QThread) diff --git a/tests/auto/qthreadonce/qthreadonce.pro b/tests/auto/qthreadonce/qthreadonce.pro index a672a03..d7ef4d4 100644 --- a/tests/auto/qthreadonce/qthreadonce.pro +++ b/tests/auto/qthreadonce/qthreadonce.pro @@ -10,3 +10,4 @@ QT = core # Temporary: SOURCES += qthreadonce.cpp +CONFIG += parallel_test diff --git a/tests/auto/qthreadpool/qthreadpool.pro b/tests/auto/qthreadpool/qthreadpool.pro index 3f6ea64..dbaeb20 100644 --- a/tests/auto/qthreadpool/qthreadpool.pro +++ b/tests/auto/qthreadpool/qthreadpool.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qthreadpool.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qthreadpool/tst_qthreadpool.cpp b/tests/auto/qthreadpool/tst_qthreadpool.cpp index 9c17948..49c517a 100644 --- a/tests/auto/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/qthreadpool/tst_qthreadpool.cpp @@ -89,6 +89,7 @@ private slots: void tryStartPeakThreadCount(); void tryStartCount(); void waitForDone(); + void waitForDoneTimeout(); void destroyingWaitsForTasksToFinish(); void stressTest(); }; @@ -774,6 +775,32 @@ void tst_QThreadPool::waitForDone() } } +void tst_QThreadPool::waitForDoneTimeout() +{ + class BlockedTask : public QRunnable + { + public: + QMutex mutex; + BlockedTask() { setAutoDelete(false); } + + void run() + { + mutex.lock(); + mutex.unlock(); + QTest::qSleep(50); + } + }; + + QThreadPool threadPool; + + BlockedTask *task = new BlockedTask; + task->mutex.lock(); + threadPool.start(task); + QVERIFY(!threadPool.waitForDone(100)); + task->mutex.unlock(); + QVERIFY(threadPool.waitForDone(400)); +} + void tst_QThreadPool::destroyingWaitsForTasksToFinish() { QTime total, pass; diff --git a/tests/auto/qthreadstorage/qthreadstorage.pro b/tests/auto/qthreadstorage/qthreadstorage.pro index a06f89c..0dc8d08 100644 --- a/tests/auto/qthreadstorage/qthreadstorage.pro +++ b/tests/auto/qthreadstorage/qthreadstorage.pro @@ -2,3 +2,4 @@ TEMPLATE = subdirs SUBDIRS = \ tst_qthreadstorage.pro \ crashOnExit.pro +CONFIG += parallel_test diff --git a/tests/auto/qthreadstorage/tst_qthreadstorage.cpp b/tests/auto/qthreadstorage/tst_qthreadstorage.cpp index ae1e835..307c3ed 100644 --- a/tests/auto/qthreadstorage/tst_qthreadstorage.cpp +++ b/tests/auto/qthreadstorage/tst_qthreadstorage.cpp @@ -77,6 +77,9 @@ private slots: void adoptedThreads(); void ensureCleanupOrder(); void QTBUG13877_crashOnExit(); + void QTBUG14579_leakInDestructor(); + void QTBUG14579_resetInDestructor(); + void valueBased(); }; class Pointer @@ -310,5 +313,191 @@ void tst_QThreadStorage::QTBUG13877_crashOnExit() QVERIFY(process.exitStatus() != QProcess::CrashExit); } +// S stands for thread Safe. +class SPointer +{ +public: + static QBasicAtomicInt count; + inline SPointer() { count.ref(); } + inline ~SPointer() { count.deref(); } + inline SPointer(const SPointer &other) { count.ref(); } +}; +QBasicAtomicInt SPointer::count = Q_BASIC_ATOMIC_INITIALIZER(0); + +Q_GLOBAL_STATIC(QThreadStorage<SPointer *>, QTBUG14579_pointers1) +Q_GLOBAL_STATIC(QThreadStorage<SPointer *>, QTBUG14579_pointers2) + +class QTBUG14579_class +{ +public: + SPointer member; + inline ~QTBUG14579_class() { + QVERIFY(!QTBUG14579_pointers1()->hasLocalData()); + QVERIFY(!QTBUG14579_pointers2()->hasLocalData()); + QTBUG14579_pointers2()->setLocalData(new SPointer); + QTBUG14579_pointers1()->setLocalData(new SPointer); + QVERIFY(QTBUG14579_pointers1()->hasLocalData()); + QVERIFY(QTBUG14579_pointers2()->hasLocalData()); + } +}; + + +void tst_QThreadStorage::QTBUG14579_leakInDestructor() +{ + class Thread : public QThread + { + public: + QThreadStorage<QTBUG14579_class *> &tls; + + Thread(QThreadStorage<QTBUG14579_class *> &t) : tls(t) { } + + void run() + { + QVERIFY(!tls.hasLocalData()); + tls.setLocalData(new QTBUG14579_class); + QVERIFY(tls.hasLocalData()); + } + }; + int c = SPointer::count; + + QThreadStorage<QTBUG14579_class *> tls; + + QVERIFY(!QTBUG14579_pointers1()->hasLocalData()); + QThreadStorage<int *> tls2; //add some more tls to make sure ids are not following each other too much + QThreadStorage<int *> tls3; + QVERIFY(!tls2.hasLocalData()); + QVERIFY(!tls3.hasLocalData()); + QVERIFY(!tls.hasLocalData()); + + Thread t1(tls); + Thread t2(tls); + Thread t3(tls); + + t1.start(); + t2.start(); + t3.start(); + + QVERIFY(t1.wait()); + QVERIFY(t2.wait()); + QVERIFY(t3.wait()); + + //check all the constructed things have been destructed + QCOMPARE(int(SPointer::count), c); +} + +class QTBUG14579_reset { +public: + SPointer member; + ~QTBUG14579_reset(); +}; + +Q_GLOBAL_STATIC(QThreadStorage<QTBUG14579_reset *>, QTBUG14579_resetTls) + +QTBUG14579_reset::~QTBUG14579_reset() { + //Quite stupid, but WTF::ThreadSpecific<T>::destroy does it. + QTBUG14579_resetTls()->setLocalData(this); +} + +void tst_QThreadStorage::QTBUG14579_resetInDestructor() +{ + class Thread : public QThread + { + public: + void run() + { + QVERIFY(!QTBUG14579_resetTls()->hasLocalData()); + QTBUG14579_resetTls()->setLocalData(new QTBUG14579_reset); + QVERIFY(QTBUG14579_resetTls()->hasLocalData()); + } + }; + int c = SPointer::count; + + Thread t1; + Thread t2; + Thread t3; + t1.start(); + t2.start(); + t3.start(); + QVERIFY(t1.wait()); + QVERIFY(t2.wait()); + QVERIFY(t3.wait()); + + //check all the constructed things have been destructed + QCOMPARE(int(SPointer::count), c); +} + + +void tst_QThreadStorage::valueBased() +{ + struct Thread : QThread { + QThreadStorage<SPointer> &tlsSPointer; + QThreadStorage<QString> &tlsString; + QThreadStorage<int> &tlsInt; + + int someNumber; + QString someString; + Thread(QThreadStorage<SPointer> &t1, QThreadStorage<QString> &t2, QThreadStorage<int> &t3) + : tlsSPointer(t1), tlsString(t2), tlsInt(t3) { } + + void run() { + /*QVERIFY(!tlsSPointer.hasLocalData()); + QVERIFY(!tlsString.hasLocalData()); + QVERIFY(!tlsInt.hasLocalData());*/ + SPointer pointercopy = tlsSPointer.localData(); + + //Default constructed values + QVERIFY(tlsString.localData().isNull()); + QCOMPARE(tlsInt.localData(), 0); + + //setting + tlsString.setLocalData(someString); + tlsInt.setLocalData(someNumber); + + QCOMPARE(tlsString.localData(), someString); + QCOMPARE(tlsInt.localData(), someNumber); + + //changing + tlsSPointer.setLocalData(SPointer()); + tlsInt.localData() += 42; + tlsString.localData().append(QLatin1String(" world")); + + QCOMPARE(tlsString.localData(), (someString + QLatin1String(" world"))); + QCOMPARE(tlsInt.localData(), (someNumber + 42)); + + // operator= + tlsString.localData() = QString::number(someNumber); + QCOMPARE(tlsString.localData().toInt(), someNumber); + } + }; + + QThreadStorage<SPointer> tlsSPointer; + QThreadStorage<QString> tlsString; + QThreadStorage<int> tlsInt; + + int c = SPointer::count; + + Thread t1(tlsSPointer, tlsString, tlsInt); + Thread t2(tlsSPointer, tlsString, tlsInt); + Thread t3(tlsSPointer, tlsString, tlsInt); + t1.someNumber = 42; + t2.someNumber = -128; + t3.someNumber = 78; + t1.someString = "hello"; + t2.someString = "trolltech"; + t3.someString = "nokia"; + + t1.start(); + t2.start(); + t3.start(); + + QVERIFY(t1.wait()); + QVERIFY(t2.wait()); + QVERIFY(t3.wait()); + + QCOMPARE(c, int(SPointer::count)); + +} + + QTEST_MAIN(tst_QThreadStorage) #include "tst_qthreadstorage.moc" diff --git a/tests/auto/qtime/qtime.pro b/tests/auto/qtime/qtime.pro index 88277a0..ce4f7ae 100644 --- a/tests/auto/qtime/qtime.pro +++ b/tests/auto/qtime/qtime.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qtime.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qtimeline/qtimeline.pro b/tests/auto/qtimeline/qtimeline.pro index 7820455..9be717d 100644 --- a/tests/auto/qtimeline/qtimeline.pro +++ b/tests/auto/qtimeline/qtimeline.pro @@ -2,3 +2,4 @@ load(qttest_p4) QT = core SOURCES += tst_qtimeline.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qtimer/qtimer.pro b/tests/auto/qtimer/qtimer.pro index 79ae7db..086df1d 100644 --- a/tests/auto/qtimer/qtimer.pro +++ b/tests/auto/qtimer/qtimer.pro @@ -2,3 +2,4 @@ load(qttest_p4) QT = core SOURCES += tst_qtimer.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qtimer/tst_qtimer.cpp b/tests/auto/qtimer/tst_qtimer.cpp index 6252e71..e08c903 100644 --- a/tests/auto/qtimer/tst_qtimer.cpp +++ b/tests/auto/qtimer/tst_qtimer.cpp @@ -50,6 +50,8 @@ #include <unistd.h> #endif +#include "../../shared/util.h" + //TESTED_CLASS= //TESTED_FILES= @@ -272,9 +274,9 @@ void tst_QTimer::livelock() QFETCH(int, interval); LiveLockTester tester(interval); QTest::qWait(180); // we have to use wait here, since we're testing timers with a non-zero timeout - QCOMPARE(tester.timeoutsForFirst, 1); + QTRY_COMPARE(tester.timeoutsForFirst, 1); QCOMPARE(tester.timeoutsForExtra, 0); - QCOMPARE(tester.timeoutsForSecond, 1); + QTRY_COMPARE(tester.timeoutsForSecond, 1); #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) if (QSysInfo::WindowsVersion < QSysInfo::WV_XP) QEXPECT_FAIL("non-zero timer", "Multimedia timers are not available on Windows 2000", Continue); @@ -724,7 +726,7 @@ void tst_QTimer::QTBUG13633_dontBlockEvents() { DontBlockEvents t; QTest::qWait(60); - QVERIFY(t.total > 2); + QTRY_VERIFY(t.total > 2); } class SlotRepeater : public QObject { diff --git a/tests/auto/qtipc/qsharedmemory/src/qsystemlock_unix.cpp b/tests/auto/qtipc/qsharedmemory/src/qsystemlock_unix.cpp index 14ad64e..9843796 100644 --- a/tests/auto/qtipc/qsharedmemory/src/qsystemlock_unix.cpp +++ b/tests/auto/qtipc/qsharedmemory/src/qsystemlock_unix.cpp @@ -207,7 +207,8 @@ bool QSystemLockPrivate::modifySemaphore(QSystemLockPrivate::Operation op, if ((lockCount == 0 && op == Lock) || (lockCount > 0 && op == Unlock)) { if (op == Unlock) { --lockCount; - Q_ASSERT(lockCount >= 0); + if (lockCount < 0) + qFatal("%s: lockCount must not be negative", Q_FUNC_INFO); if (lockCount > 0) return true; } diff --git a/tests/auto/qtipc/qsharedmemory/src/qsystemlock_win.cpp b/tests/auto/qtipc/qsharedmemory/src/qsystemlock_win.cpp index 3e48bb5..c04b596 100644 --- a/tests/auto/qtipc/qsharedmemory/src/qsystemlock_win.cpp +++ b/tests/auto/qtipc/qsharedmemory/src/qsystemlock_win.cpp @@ -157,7 +157,8 @@ bool QSystemLockPrivate::modifySemaphore(QSystemLockPrivate::Operation op, if ((lockCount == 0 && op == Lock) || (lockCount > 0 && op == Unlock)) { if (op == Unlock) { --lockCount; - Q_ASSERT(lockCount >= 0); + if (lockCount < 0) + qFatal("%s: lockCount must not be negative", Q_FUNC_INFO); if (lockCount > 0) return true; } diff --git a/tests/auto/qtipc/qsharedmemory/test/test.pro b/tests/auto/qtipc/qsharedmemory/test/test.pro index 68a5362..50c2669 100644 --- a/tests/auto/qtipc/qsharedmemory/test/test.pro +++ b/tests/auto/qtipc/qsharedmemory/test/test.pro @@ -20,16 +20,16 @@ TARGET = ../tst_qsharedmemory wince*:{ requires(contains(QT_CONFIG,script)) QT += gui script -addFiles.sources = $$OUT_PWD/../../lackey/lackey.exe ../../lackey/scripts +addFiles.files = $$OUT_PWD/../../lackey/lackey.exe ../../lackey/scripts addFiles.path = . DEPLOYMENT += addFiles DEFINES += SRCDIR=\\\".\\\" }else:symbian{ requires(contains(QT_CONFIG,script)) QT += gui script -addFiles.sources = ../../lackey/scripts +addFiles.files = ../../lackey/scripts addFiles.path = /data/qsharedmemorytemp/lackey -addBin.sources = lackey.exe +addBin.files = lackey.exe addBin.path = /sys/bin DEPLOYMENT += addFiles addBin } else { diff --git a/tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp b/tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp index eb3803a..38c6f0e 100644 --- a/tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp +++ b/tests/auto/qtipc/qsharedmemory/tst_qsharedmemory.cpp @@ -107,6 +107,10 @@ private slots: void useTooMuchMemory(); void attachTooMuch(); + // unique keys + void uniqueKey_data(); + void uniqueKey(); + protected: int remove(const QString &key); @@ -225,11 +229,17 @@ void tst_QSharedMemory::key_data() { QTest::addColumn<QString>("constructorKey"); QTest::addColumn<QString>("setKey"); - - QTest::newRow("null, null") << QString() << QString(); - QTest::newRow("null, one") << QString() << QString("one"); - QTest::newRow("one, two") << QString("one") << QString("two"); - QTest::newRow("invalid") << QString("o/e") << QString("t/o"); + QTest::addColumn<QString>("setNativeKey"); + + QTest::newRow("null, null, null") << QString() << QString() << QString(); + QTest::newRow("one, null, null") << QString("one") << QString() << QString(); + QTest::newRow("null, one, null") << QString() << QString("one") << QString(); + QTest::newRow("null, null, one") << QString() << QString() << QString("one"); + QTest::newRow("one, two, null") << QString("one") << QString("two") << QString(); + QTest::newRow("one, null, two") << QString("one") << QString() << QString("two"); + QTest::newRow("null, one, two") << QString() << QString("one") << QString("two"); + QTest::newRow("one, two, three") << QString("one") << QString("two") << QString("three"); + QTest::newRow("invalid") << QString("o/e") << QString("t/o") << QString("|x"); } /*! @@ -239,11 +249,17 @@ void tst_QSharedMemory::key() { QFETCH(QString, constructorKey); QFETCH(QString, setKey); + QFETCH(QString, setNativeKey); QSharedMemory sm(constructorKey); QCOMPARE(sm.key(), constructorKey); + QCOMPARE(sm.nativeKey().isEmpty(), constructorKey.isEmpty()); sm.setKey(setKey); QCOMPARE(sm.key(), setKey); + QCOMPARE(sm.nativeKey().isEmpty(), setKey.isEmpty()); + sm.setNativeKey(setNativeKey); + QVERIFY(sm.key().isNull()); + QCOMPARE(sm.nativeKey(), setNativeKey); QCOMPARE(sm.isAttached(), false); QCOMPARE(sm.error(), QSharedMemory::NoError); @@ -262,7 +278,7 @@ void tst_QSharedMemory::create_data() QTest::addColumn<QSharedMemory::SharedMemoryError>("error"); QTest::newRow("null key") << QString() << 1024 - << false << QSharedMemory::LockError; + << false << QSharedMemory::KeyError; QTest::newRow("-1 size") << QString("negsize") << -1 << false << QSharedMemory::InvalidSize; QTest::newRow("nor size") << QString("norsize") << 1024 @@ -302,7 +318,7 @@ void tst_QSharedMemory::attach_data() QTest::addColumn<bool>("exists"); QTest::addColumn<QSharedMemory::SharedMemoryError>("error"); - QTest::newRow("null key") << QString() << false << QSharedMemory::LockError; + QTest::newRow("null key") << QString() << false << QSharedMemory::KeyError; QTest::newRow("doesn't exists") << QString("doesntexists") << false << QSharedMemory::NotFound; QTest::newRow("already exists") << QString(EXISTING_SHARE) << true << QSharedMemory::NoError; } @@ -786,6 +802,35 @@ void tst_QSharedMemory::simpleProcessProducerConsumer() QCOMPARE(failedProcesses, (unsigned int)(0)); } +void tst_QSharedMemory::uniqueKey_data() +{ + QTest::addColumn<QString>("key1"); + QTest::addColumn<QString>("key2"); + + QTest::newRow("null == null") << QString() << QString(); + QTest::newRow("key == key") << QString("key") << QString("key"); + QTest::newRow("key1 == key1") << QString("key1") << QString("key1"); + QTest::newRow("key != key1") << QString("key") << QString("key1"); + QTest::newRow("ke1y != key1") << QString("ke1y") << QString("key1"); + QTest::newRow("key1 != key2") << QString("key1") << QString("key2"); +} + +void tst_QSharedMemory::uniqueKey() +{ + QFETCH(QString, key1); + QFETCH(QString, key2); + + QSharedMemory sm1(key1); + QSharedMemory sm2(key2); + + bool setEqual = (key1 == key2); + bool keyEqual = (sm1.key() == sm2.key()); + bool nativeEqual = (sm1.nativeKey() == sm2.nativeKey()); + + QCOMPARE(keyEqual, setEqual); + QCOMPARE(nativeEqual, setEqual); +} + QTEST_MAIN(tst_QSharedMemory) #include "tst_qsharedmemory.moc" diff --git a/tests/auto/qtipc/qsystemsemaphore/qsystemsemaphore.pro b/tests/auto/qtipc/qsystemsemaphore/qsystemsemaphore.pro index e21e5df..e05b6b8 100644 --- a/tests/auto/qtipc/qsystemsemaphore/qsystemsemaphore.pro +++ b/tests/auto/qtipc/qsystemsemaphore/qsystemsemaphore.pro @@ -17,7 +17,7 @@ requires(contains(QT_CONFIG,script)) # this test calls lackey, which then again depends on QtScript. # let's add it here so that it gets deployed easily QT += script -lackey.sources = $$OUT_PWD/../lackey/lackey.exe ../lackey/scripts +lackey.files = $$OUT_PWD/../lackey/lackey.exe ../lackey/scripts lackey.path = . DEPLOYMENT += lackey } @@ -28,7 +28,7 @@ requires(contains(QT_CONFIG,script)) # let's add it here so that it gets deployed easily QT += script -lackey.sources = ../lackey/lackey.exe +lackey.files = ../lackey/lackey.exe lackey.path = /sys/bin DEPLOYMENT += lackey diff --git a/tests/auto/qtmd5/qtmd5.pro b/tests/auto/qtmd5/qtmd5.pro index cb4a539..0afc6b1 100644 --- a/tests/auto/qtmd5/qtmd5.pro +++ b/tests/auto/qtmd5/qtmd5.pro @@ -12,3 +12,4 @@ SOURCES += tst_qtmd5.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qtokenautomaton/qtokenautomaton.pro b/tests/auto/qtokenautomaton/qtokenautomaton.pro index 6ebf7c4..5e2e590 100644 --- a/tests/auto/qtokenautomaton/qtokenautomaton.pro +++ b/tests/auto/qtokenautomaton/qtokenautomaton.pro @@ -15,3 +15,4 @@ HEADERS += tokenizers/basic/basic.h \ tokenizers/withNamespace/withNamespace.h QT -= gui +CONFIG += parallel_test diff --git a/tests/auto/qtranslator/qtranslator.pro b/tests/auto/qtranslator/qtranslator.pro index 5b742f7..0001d1c 100644 --- a/tests/auto/qtranslator/qtranslator.pro +++ b/tests/auto/qtranslator/qtranslator.pro @@ -3,7 +3,7 @@ SOURCES += tst_qtranslator.cpp RESOURCES += qtranslator.qrc wince*|symbian: { - addFiles.sources = hellotr_la.qm msgfmt_from_po.qm + addFiles.files = hellotr_la.qm msgfmt_from_po.qm addFiles.path = . DEPLOYMENT += addFiles } diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index c9410b8..b902370 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -277,7 +277,8 @@ public: } int rowCount(const QModelIndex& parent = QModelIndex()) const { - Q_ASSERT(fetched); + if (!fetched) + qFatal("%s: rowCount should not be called before fetching", Q_FUNC_INFO); if ((parent.column() > 0) || (level(parent) > levels)) return 0; return rows; @@ -2536,7 +2537,7 @@ void tst_QTreeView::sortByColumn() /* This is a model that every time kill() is called it will completely change - all of its nodes for new nodes. It then asserts if you later use a dead node. + all of its nodes for new nodes. It then qFatal's if you later use a dead node. */ class EvilModel: public QAbstractItemModel { @@ -2567,7 +2568,8 @@ public: } } if (parent == 0) { - Q_ASSERT(children.isEmpty()); + if (!children.isEmpty()) + qFatal("%s: children should be empty when parent is null", Q_FUNC_INFO); populate(); } else { isDead = true; @@ -2624,7 +2626,8 @@ public: Node *parentNode = root; if (parent.isValid()) { parentNode = static_cast<Node*>(parent.internalPointer()); - Q_ASSERT(!parentNode->isDead); + if (parentNode->isDead) + qFatal("%s: parentNode is dead!", Q_FUNC_INFO); } return parentNode->children.count(); } @@ -2639,9 +2642,11 @@ public: Node *grandparentNode = static_cast<Node*>(parent.internalPointer()); Node *parentNode = root; if (parent.isValid()) { - Q_ASSERT(!grandparentNode->isDead); + if (grandparentNode->isDead) + qFatal("%s: grandparentNode is dead!", Q_FUNC_INFO); parentNode = grandparentNode->children[parent.row()]; - Q_ASSERT(!parentNode->isDead); + if (parentNode->isDead) + qFatal("%s: grandparentNode is dead!", Q_FUNC_INFO); } return createIndex(row, column, parentNode); } @@ -2661,7 +2666,8 @@ public: Node *parentNode = root; if (idx.isValid()) { parentNode = static_cast<Node*>(idx.internalPointer()); - Q_ASSERT(!parentNode->isDead); + if (parentNode->isDead) + qFatal("%s: grandparentNode is dead!", Q_FUNC_INFO); } return QString("[%1,%2,%3]").arg(idx.row()).arg(idx.column()) .arg(parentNode->isDead ? "dead" : "alive"); diff --git a/tests/auto/qudpsocket/clientserver/clientserver.pro b/tests/auto/qudpsocket/clientserver/clientserver.pro index 5fe65b3..6da1486 100644 --- a/tests/auto/qudpsocket/clientserver/clientserver.pro +++ b/tests/auto/qudpsocket/clientserver/clientserver.pro @@ -5,4 +5,4 @@ CONFIG -= app_bundle TARGET = clientserver DESTDIR = ./ - +symbian: TARGET.CAPABILITY += NetworkServices diff --git a/tests/auto/qudpsocket/qudpsocket.pro b/tests/auto/qudpsocket/qudpsocket.pro index 8fd3545..4ddb717 100644 --- a/tests/auto/qudpsocket/qudpsocket.pro +++ b/tests/auto/qudpsocket/qudpsocket.pro @@ -1,6 +1,4 @@ TEMPLATE = subdirs SUBDIRS = test clientserver -symbian: TARGET.CAPABILITY = NetworkServices - diff --git a/tests/auto/qudpsocket/test/test.pro b/tests/auto/qudpsocket/test/test.pro index 9c0d009..b68d30c 100644 --- a/tests/auto/qudpsocket/test/test.pro +++ b/tests/auto/qudpsocket/test/test.pro @@ -15,11 +15,11 @@ win32 { } wince*|symbian: { - addApp.sources = ../clientserver/clientserver.exe + addApp.files = ../clientserver/clientserver.exe addApp.path = clientserver DEPLOYMENT += addApp } TARGET = tst_qudpsocket - +symbian: TARGET.CAPABILITY += NetworkServices diff --git a/tests/auto/qudpsocket/tst_qudpsocket.cpp b/tests/auto/qudpsocket/tst_qudpsocket.cpp index 7cb6933..a38082e 100644 --- a/tests/auto/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/qudpsocket/tst_qudpsocket.cpp @@ -50,12 +50,20 @@ #include <qhostinfo.h> #include <qmap.h> #include <QNetworkProxy> +#include <QNetworkInterface> #include <qstringlist.h> #include "../network-settings.h" -Q_DECLARE_METATYPE(QHostAddress) +#ifndef QT_NO_BEARERMANAGEMENT +#include <QtNetwork/qnetworkconfigmanager.h> +#include <QtNetwork/qnetworkconfiguration.h> +#include <QtNetwork/qnetworksession.h> +#endif +Q_DECLARE_METATYPE(QHostAddress) +Q_DECLARE_METATYPE(QNetworkInterface) +Q_DECLARE_METATYPE(QSharedPointer<QNetworkSession>) //TESTED_CLASS= //TESTED_FILES= @@ -94,10 +102,31 @@ private slots: void outOfProcessConnectedClientServerTest(); void outOfProcessUnconnectedClientServerTest(); void zeroLengthDatagram(); + void multicastTtlOption_data(); + void multicastTtlOption(); + void multicastLoopbackOption_data(); + void multicastLoopbackOption(); + void multicastJoinBeforeBind_data(); + void multicastJoinBeforeBind(); + void multicastLeaveAfterClose_data(); + void multicastLeaveAfterClose(); + void setMulticastInterface_data(); + void setMulticastInterface(); + void multicast_data(); + void multicast(); + void echo_data(); + void echo(); protected slots: void empty_readyReadSlot(); void empty_connectedSlot(); + +private: +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkConfigurationManager *netConfMan; + QNetworkConfiguration networkConfiguration; + QSharedPointer<QNetworkSession> networkSession; +#endif }; tst_QUdpSocket::tst_QUdpSocket() @@ -116,6 +145,23 @@ void tst_QUdpSocket::initTestCase_data() QTest::newRow("WithoutProxy") << false << 0; QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy); + +#ifndef QT_NO_BEARERMANAGEMENT + netConfMan = new QNetworkConfigurationManager(this); + netConfMan->updateConfigurations(); + connect(netConfMan, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + networkConfiguration = netConfMan->defaultConfiguration(); + if (networkConfiguration.isValid()) { + networkSession = QSharedPointer<QNetworkSession>(new QNetworkSession(networkConfiguration)); + if (!networkSession->isOpen()) { + networkSession->open(); + QVERIFY(networkSession->waitForOpened(30000)); + } + } else { + QVERIFY(!(netConfMan->capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)); + } +#endif } void tst_QUdpSocket::init() @@ -140,6 +186,9 @@ void tst_QUdpSocket::cleanup() void tst_QUdpSocket::constructing() { QUdpSocket socket; +#ifdef FORCE_SESSION + socket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QVERIFY(socket.isSequential()); QVERIFY(!socket.isOpen()); @@ -157,6 +206,9 @@ void tst_QUdpSocket::constructing() void tst_QUdpSocket::unconnectedServerAndClientTest() { QUdpSocket serverSocket; +#ifdef FORCE_SESSION + serverSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState"); @@ -167,11 +219,14 @@ void tst_QUdpSocket::unconnectedServerAndClientTest() const char *message[] = {"Yo mista", "Yo", "Wassap"}; QHostAddress serverAddress = QHostAddress::LocalHost; - if (!(serverSocket.localAddress() == QHostAddress::Any)) + if (!(serverSocket.localAddress() == QHostAddress::Any || serverSocket.localAddress() == QHostAddress::AnyIPv6)) serverAddress = serverSocket.localAddress(); for (int i = 0; i < 3; ++i) { QUdpSocket clientSocket; +#ifdef FORCE_SESSION + clientSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QCOMPARE(int(clientSocket.writeDatagram(message[i], strlen(message[i]), serverAddress, serverSocket.localPort())), int(strlen(message[i]))); @@ -202,8 +257,21 @@ void tst_QUdpSocket::broadcasting() #endif const char *message[] = {"Yo mista", "", "Yo", "Wassap"}; + QList<QHostAddress> broadcastAddresses; + foreach (QNetworkInterface iface, QNetworkInterface::allInterfaces()) { + if ((iface.flags() & QNetworkInterface::CanBroadcast) + && iface.flags() & QNetworkInterface::IsUp) { + for (int i=0;i<iface.addressEntries().count();i++) + broadcastAddresses.append(iface.addressEntries().at(i).broadcast()); + } + } + if (broadcastAddresses.isEmpty()) + QSKIP("No interface can broadcast", SkipAll); for (int i = 0; i < 4; ++i) { QUdpSocket serverSocket; +#ifdef FORCE_SESSION + serverSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QVERIFY2(serverSocket.bind(QHostAddress::Any, 5000), serverSocket.errorString().toLatin1().constData()); QCOMPARE(serverSocket.state(), QUdpSocket::BoundState); @@ -211,10 +279,18 @@ void tst_QUdpSocket::broadcasting() connect(&serverSocket, SIGNAL(readyRead()), SLOT(empty_readyReadSlot())); QUdpSocket broadcastSocket; +#ifdef FORCE_SESSION + broadcastSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif + broadcastSocket.bind(); for (int j = 0; j < 100; ++j) { - broadcastSocket.writeDatagram(message[i], strlen(message[i]), - QHostAddress::Broadcast, 5000); + for (int k = 0; k < 4; k++) { + broadcastSocket.writeDatagram(message[i], strlen(message[i]), + QHostAddress::Broadcast, 5000); + foreach (QHostAddress addr, broadcastAddresses) + broadcastSocket.writeDatagram(message[i], strlen(message[i]), addr, 5000); + } QTestEventLoop::instance().enterLoop(15); if (QTestEventLoop::instance().timeout()) { #if defined(Q_OS_FREEBSD) @@ -265,15 +341,19 @@ void tst_QUdpSocket::loop() QUdpSocket peter; QUdpSocket paul; +#ifdef FORCE_SESSION + peter.setProperty("_q_networksession", QVariant::fromValue(networkSession)); + paul.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QVERIFY2(peter.bind(), peter.errorString().toLatin1().constData()); QVERIFY2(paul.bind(), paul.errorString().toLatin1().constData()); QHostAddress peterAddress = QHostAddress::LocalHost; - if (!(peter.localAddress() == QHostAddress::Any)) + if (!(peter.localAddress() == QHostAddress::Any || peter.localAddress() == QHostAddress::AnyIPv6)) peterAddress = peter.localAddress(); QHostAddress pualAddress = QHostAddress::LocalHost; - if (!(paul.localAddress() == QHostAddress::Any)) + if (!(paul.localAddress() == QHostAddress::Any || paul.localAddress() == QHostAddress::AnyIPv6)) pualAddress = paul.localAddress(); QCOMPARE(peter.writeDatagram(peterMessage.data(), peterMessage.length(), @@ -306,8 +386,8 @@ void tst_QUdpSocket::ipv6Loop_data() void tst_QUdpSocket::ipv6Loop() { -#if defined(Q_OS_SYMBIAN) - QSKIP("Symbian IPv6 is not yet supported", SkipAll); +#if defined(QT_NO_IPV6) + QSKIP("IPv6 is not yet supported", SkipAll); #endif QFETCH(QByteArray, peterMessage); QFETCH(QByteArray, paulMessage); @@ -315,6 +395,10 @@ void tst_QUdpSocket::ipv6Loop() QUdpSocket peter; QUdpSocket paul; +#ifdef FORCE_SESSION + peter.setProperty("_q_networksession", QVariant::fromValue(networkSession)); + paul.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif quint16 peterPort = 28124; quint16 paulPort = 28123; @@ -366,9 +450,13 @@ void tst_QUdpSocket::empty_connectedSlot() void tst_QUdpSocket::readLine() { QUdpSocket socket1; + QUdpSocket socket2; +#ifdef FORCE_SESSION + socket1.setProperty("_q_networksession", QVariant::fromValue(networkSession)); + socket2.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QVERIFY2(socket1.bind(), socket1.errorString().toLatin1().constData()); - QUdpSocket socket2; socket2.connectToHost("127.0.0.1", socket1.localPort()); QVERIFY(socket2.waitForConnected(5000)); } @@ -378,13 +466,19 @@ void tst_QUdpSocket::readLine() void tst_QUdpSocket::pendingDatagramSize() { QUdpSocket server; +#ifdef FORCE_SESSION + server.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QVERIFY2(server.bind(), server.errorString().toLatin1().constData()); QHostAddress serverAddress = QHostAddress::LocalHost; - if (!(server.localAddress() == QHostAddress::Any)) + if (!(server.localAddress() == QHostAddress::Any || server.localAddress() == QHostAddress::AnyIPv6)) serverAddress = server.localAddress(); QUdpSocket client; +#ifdef FORCE_SESSION + client.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QVERIFY(client.writeDatagram("this is", 7, serverAddress, server.localPort()) == 7); QVERIFY(client.writeDatagram(0, 0, serverAddress, server.localPort()) == 0); QVERIFY(client.writeDatagram("3 messages", 10, serverAddress, server.localPort()) == 10); @@ -426,13 +520,19 @@ void tst_QUdpSocket::pendingDatagramSize() void tst_QUdpSocket::writeDatagram() { QUdpSocket server; +#ifdef FORCE_SESSION + server.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QVERIFY2(server.bind(), server.errorString().toLatin1().constData()); QHostAddress serverAddress = QHostAddress::LocalHost; - if (!(server.localAddress() == QHostAddress::Any)) + if (!(server.localAddress() == QHostAddress::Any || server.localAddress() == QHostAddress::AnyIPv6)) serverAddress = server.localAddress(); QUdpSocket client; +#ifdef FORCE_SESSION + client.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif qRegisterMetaType<qint64>("qint64"); qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError"); @@ -459,8 +559,16 @@ void tst_QUdpSocket::writeDatagram() QCOMPARE(*static_cast<const qint64 *>(bytesspy.at(0).at(0).constData()), qint64(i * 1024)); QCOMPARE(errorspy.count(), 0); - if (!server.waitForReadyRead(5000)) + if (!server.waitForReadyRead(5000)) { +#ifdef Q_OS_SYMBIAN + //symbian receive buffer for datagrams is ~30k, but it can send datagrams up to the maximum 64k... + if (i > 28) { + i = 64; + continue; + } +#endif QSKIP(QString("UDP packet lost at size %1, unable to complete the test.").arg(i * 1024).toLatin1().data(), SkipSingle); + } QCOMPARE(server.pendingDatagramSize(), qint64(i * 1024)); QCOMPARE(server.readDatagram(0, 0), qint64(0)); } @@ -485,14 +593,21 @@ void tst_QUdpSocket::performance() #endif // Q_OS_SYMBIAN QUdpSocket server; +#ifdef FORCE_SESSION + server.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QVERIFY2(server.bind(), server.errorString().toLatin1().constData()); QHostAddress serverAddress = QHostAddress::LocalHost; - if (!(server.localAddress() == QHostAddress::Any)) + if (!(server.localAddress() == QHostAddress::Any || server.localAddress() == QHostAddress::AnyIPv6)) serverAddress = server.localAddress(); QUdpSocket client; +#ifdef FORCE_SESSION + client.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif client.connectToHost(serverAddress, server.localPort()); + QVERIFY(client.waitForConnected(10000)); QTime stopWatch; stopWatch.start(); @@ -532,8 +647,14 @@ void tst_QUdpSocket::bindMode() } QUdpSocket socket; +#ifdef FORCE_SESSION + socket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QVERIFY2(socket.bind(), socket.errorString().toLatin1().constData()); QUdpSocket socket2; +#ifdef FORCE_SESSION + socket2.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QVERIFY(!socket2.bind(socket.localPort())); #if defined(Q_OS_SYMBIAN) if(RProcess().HasCapability(ECapabilityNetworkControl)) { @@ -603,16 +724,12 @@ void tst_QUdpSocket::writeDatagramToNonExistingPeer_data() QTest::addColumn<bool>("bind"); QTest::addColumn<QHostAddress>("peerAddress"); QHostAddress localhost(QHostAddress::LocalHost); -#if !defined(Q_OS_SYMBIAN) QHostAddress remote = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first(); -#endif QTest::newRow("localhost-unbound") << false << localhost; QTest::newRow("localhost-bound") << true << localhost; -#if !defined(Q_OS_SYMBIAN) QTest::newRow("remote-unbound") << false << remote; QTest::newRow("remote-bound") << true << remote; -#endif } void tst_QUdpSocket::writeDatagramToNonExistingPeer() @@ -623,6 +740,9 @@ void tst_QUdpSocket::writeDatagramToNonExistingPeer() quint16 peerPort = 33533 + int(bind); QUdpSocket sUdp; +#ifdef FORCE_SESSION + sUdp.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QSignalSpy sReadyReadSpy(&sUdp, SIGNAL(readyRead())); if (bind) QVERIFY(sUdp.bind()); @@ -635,14 +755,10 @@ void tst_QUdpSocket::writeToNonExistingPeer_data() { QTest::addColumn<QHostAddress>("peerAddress"); QHostAddress localhost(QHostAddress::LocalHost); -#if !defined(Q_OS_SYMBIAN) QHostAddress remote = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first(); -#endif // write (required to be connected) QTest::newRow("localhost") << localhost; -#if !defined(Q_OS_SYMBIAN) QTest::newRow("remote") << remote; -#endif } void tst_QUdpSocket::writeToNonExistingPeer() @@ -653,9 +769,13 @@ void tst_QUdpSocket::writeToNonExistingPeer() qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError"); QUdpSocket sConnected; +#ifdef FORCE_SESSION + sConnected.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QSignalSpy sConnectedReadyReadSpy(&sConnected, SIGNAL(readyRead())); QSignalSpy sConnectedErrorSpy(&sConnected, SIGNAL(error(QAbstractSocket::SocketError))); sConnected.connectToHost(peerAddress, peerPort, QIODevice::ReadWrite); + QVERIFY(sConnected.waitForConnected(10000)); // the first write succeeds... QCOMPARE(sConnected.write("", 1), qint64(1)); @@ -829,12 +949,18 @@ void tst_QUdpSocket::zeroLengthDatagram() return; QUdpSocket receiver; +#ifdef FORCE_SESSION + receiver.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QVERIFY(receiver.bind()); QVERIFY(!receiver.waitForReadyRead(100)); QVERIFY(!receiver.hasPendingDatagrams()); QUdpSocket sender; +#ifdef FORCE_SESSION + sender.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif QCOMPARE(sender.writeDatagram(QByteArray(), QHostAddress::LocalHost, receiver.localPort()), qint64(0)); QVERIFY(receiver.waitForReadyRead(1000)); @@ -844,5 +970,334 @@ void tst_QUdpSocket::zeroLengthDatagram() QCOMPARE(receiver.readDatagram(&buf, 1), qint64(0)); } +void tst_QUdpSocket::multicastTtlOption_data() +{ + QTest::addColumn<QHostAddress>("bindAddress"); + QTest::addColumn<int>("ttl"); + QTest::addColumn<int>("expected"); + + QList<QHostAddress> addresses; + addresses += QHostAddress(QHostAddress::Any); + addresses += QHostAddress(QHostAddress::AnyIPv6); + + foreach (const QHostAddress &address, addresses) { + QTest::newRow(QString("%1 0").arg(address.toString()).toAscii()) << address << 0 << 0; + QTest::newRow(QString("%1 1").arg(address.toString()).toAscii()) << address << 1 << 1; + QTest::newRow(QString("%1 2").arg(address.toString()).toAscii()) << address << 2 << 2; + QTest::newRow(QString("%1 128").arg(address.toString()).toAscii()) << address << 128 << 128; + QTest::newRow(QString("%1 255").arg(address.toString()).toAscii()) << address << 255 << 255; + QTest::newRow(QString("%1 1024").arg(address.toString()).toAscii()) << address << 1024 << 1; + } +} + +void tst_QUdpSocket::multicastTtlOption() +{ + QFETCH_GLOBAL(bool, setProxy); + QFETCH(QHostAddress, bindAddress); + QFETCH(int, ttl); + QFETCH(int, expected); + if (setProxy) { + // UDP multicast does not work with proxies + expected = 0; + } + + QUdpSocket udpSocket; +#ifdef FORCE_SESSION + udpSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif + // bind, but ignore the result, we are only interested in initializing the socket + (void) udpSocket.bind(bindAddress, 0); + udpSocket.setSocketOption(QUdpSocket::MulticastTtlOption, ttl); + QCOMPARE(udpSocket.socketOption(QUdpSocket::MulticastTtlOption).toInt(), expected); +} + +void tst_QUdpSocket::multicastLoopbackOption_data() +{ + QTest::addColumn<QHostAddress>("bindAddress"); + QTest::addColumn<int>("loopback"); + QTest::addColumn<int>("expected"); + + QList<QHostAddress> addresses; + addresses += QHostAddress(QHostAddress::Any); + addresses += QHostAddress(QHostAddress::AnyIPv6); + + foreach (const QHostAddress &address, addresses) { + QTest::newRow(QString("%1 0").arg(address.toString()).toAscii()) << address << 0 << 0; + QTest::newRow(QString("%1 1").arg(address.toString()).toAscii()) << address << 1 << 1; + QTest::newRow(QString("%1 2").arg(address.toString()).toAscii()) << address << 2 << 1; + QTest::newRow(QString("%1 0 again").arg(address.toString()).toAscii()) << address << 0 << 0; + QTest::newRow(QString("%1 2 again").arg(address.toString()).toAscii()) << address << 2 << 1; + QTest::newRow(QString("%1 0 last time").arg(address.toString()).toAscii()) << address << 0 << 0; + QTest::newRow(QString("%1 1 again").arg(address.toString()).toAscii()) << address << 1 << 1; + } +} + +void tst_QUdpSocket::multicastLoopbackOption() +{ + QFETCH_GLOBAL(bool, setProxy); + QFETCH(QHostAddress, bindAddress); + QFETCH(int, loopback); + QFETCH(int, expected); + if (setProxy) { + // UDP multicast does not work with proxies + expected = 0; + } + + QUdpSocket udpSocket; +#ifdef FORCE_SESSION + udpSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif + // bind, but ignore the result, we are only interested in initializing the socket + (void) udpSocket.bind(bindAddress, 0); + udpSocket.setSocketOption(QUdpSocket::MulticastLoopbackOption, loopback); + QCOMPARE(udpSocket.socketOption(QUdpSocket::MulticastLoopbackOption).toInt(), expected); +} + +void tst_QUdpSocket::multicastJoinBeforeBind_data() +{ + QTest::addColumn<QHostAddress>("groupAddress"); + QTest::newRow("valid ipv4 group address") << QHostAddress("239.255.118.62"); + QTest::newRow("invalid ipv4 group address") << QHostAddress(QHostAddress::Broadcast); + QTest::newRow("valid ipv6 group address") << QHostAddress("FF01::114"); + QTest::newRow("invalid ipv6 group address") << QHostAddress(QHostAddress::AnyIPv6); +} + +void tst_QUdpSocket::multicastJoinBeforeBind() +{ + QFETCH(QHostAddress, groupAddress); + + QUdpSocket udpSocket; +#ifdef FORCE_SESSION + udpSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif + // cannot join group before binding + QTest::ignoreMessage(QtWarningMsg, "QUdpSocket::joinMulticastGroup() called on a QUdpSocket when not in QUdpSocket::BoundState"); + QVERIFY(!udpSocket.joinMulticastGroup(groupAddress)); +} + +void tst_QUdpSocket::multicastLeaveAfterClose_data() +{ + QTest::addColumn<QHostAddress>("groupAddress"); + QTest::newRow("valid ipv4 group address") << QHostAddress("239.255.118.62"); + QTest::newRow("valid ipv6 group address") << QHostAddress("FF01::114"); +} + +void tst_QUdpSocket::multicastLeaveAfterClose() +{ + QFETCH_GLOBAL(bool, setProxy); + QFETCH(QHostAddress, groupAddress); + if (setProxy) { + QSKIP("UDP Multicast does not work with proxies", SkipAll); + } + + QUdpSocket udpSocket; +#ifdef FORCE_SESSION + udpSocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif +#ifdef Q_OS_SYMBIAN + QVERIFY2(udpSocket.bind(), + qPrintable(udpSocket.errorString())); +#else + QVERIFY2(udpSocket.bind(groupAddress, 0), + qPrintable(udpSocket.errorString())); +#endif + QVERIFY2(udpSocket.joinMulticastGroup(groupAddress), + qPrintable(udpSocket.errorString())); + udpSocket.close(); + QTest::ignoreMessage(QtWarningMsg, "QUdpSocket::leaveMulticastGroup() called on a QUdpSocket when not in QUdpSocket::BoundState"); + QVERIFY(!udpSocket.leaveMulticastGroup(groupAddress)); +} + +void tst_QUdpSocket::setMulticastInterface_data() +{ + QTest::addColumn<QNetworkInterface>("iface"); + QTest::addColumn<QHostAddress>("address"); + QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces(); + foreach (const QNetworkInterface &iface, interfaces) { + foreach (const QNetworkAddressEntry &entry, iface.addressEntries()) { + QTest::newRow(QString("%1:%2").arg(iface.name()).arg(entry.ip().toString()).toAscii()) + << iface + << entry.ip(); + } + } +} + +void tst_QUdpSocket::setMulticastInterface() +{ +#ifdef Q_OS_SYMBIAN + QSKIP("Symbian has no IPV6_MULTICAST_IF equivalent", SkipAll); +#else + QFETCH_GLOBAL(bool, setProxy); + QFETCH(QNetworkInterface, iface); + QFETCH(QHostAddress, address); + + QUdpSocket udpSocket; + // bind initializes the socket + bool bound = udpSocket.bind((address.protocol() == QAbstractSocket::IPv6Protocol + ? QHostAddress(QHostAddress::AnyIPv6) + : QHostAddress(QHostAddress::Any)), + 0); + if (!bound) + QTest::ignoreMessage(QtWarningMsg, "QUdpSocket::setMulticastInterface() called on a QUdpSocket when not in QUdpSocket::BoundState"); + udpSocket.setMulticastInterface(iface); + if (!bound) + QTest::ignoreMessage(QtWarningMsg, "QUdpSocket::multicastInterface() called on a QUdpSocket when not in QUdpSocket::BoundState"); + QNetworkInterface iface2 = udpSocket.multicastInterface(); + if (!setProxy) { + QVERIFY(iface2.isValid()); + QCOMPARE(iface.name(), iface2.name()); + } else { + QVERIFY(!iface2.isValid()); + } +#endif +} + +void tst_QUdpSocket::multicast_data() +{ + QHostAddress anyAddress = QHostAddress(QHostAddress::Any); + QHostAddress groupAddress = QHostAddress("239.255.118.62"); + QHostAddress any6Address = QHostAddress(QHostAddress::AnyIPv6); + QHostAddress group6Address = QHostAddress("FF01::114"); + + QTest::addColumn<QHostAddress>("bindAddress"); + QTest::addColumn<bool>("bindResult"); + QTest::addColumn<QHostAddress>("groupAddress"); + QTest::addColumn<bool>("joinResult"); + QTest::newRow("valid bind, group ipv4 address") << anyAddress << true << groupAddress << true; + QTest::newRow("valid bind, invalid group ipv4 address") << anyAddress << true << anyAddress << false; + QTest::newRow("same bind, group ipv4 address") << groupAddress << true << groupAddress << true; + QTest::newRow("valid bind, group ipv6 address") << any6Address << true << group6Address << true; + QTest::newRow("valid bind, invalid group ipv6 address") << any6Address << true << any6Address << false; + QTest::newRow("same bind, group ipv6 address") << group6Address << true << group6Address << true; +} + +void tst_QUdpSocket::multicast() +{ + QFETCH_GLOBAL(bool, setProxy); + QFETCH(QHostAddress, bindAddress); + QFETCH(bool, bindResult); + QFETCH(QHostAddress, groupAddress); + QFETCH(bool, joinResult); + if (setProxy) { + // UDP multicast does not work with proxies + if ((bindAddress.protocol() == QAbstractSocket::IPv4Protocol && (bindAddress.toIPv4Address() & 0xffff0000) == 0xefff0000) + || bindAddress.protocol() == QAbstractSocket::IPv6Protocol) { + // proxy cannot bind to IPv6 or multicast addresses + bindResult = false; + } + joinResult = false; + } + + QUdpSocket receiver; +#ifdef FORCE_SESSION + receiver.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif + + // bind first, then verify that we can join the multicast group +#ifdef Q_OS_SYMBIAN + if (!setProxy) { + QEXPECT_FAIL("same bind, group ipv4 address", "bind to group address not supported on symbian", Abort); + QEXPECT_FAIL("same bind, group ipv6 address", "bind to group address not supported on symbian", Abort); + } +#endif + QVERIFY2(receiver.bind(bindAddress, 0) == bindResult, + qPrintable(receiver.errorString())); + if (!bindResult) + return; + + QVERIFY2(receiver.joinMulticastGroup(groupAddress) == joinResult, + qPrintable(receiver.errorString())); + if (!joinResult) + return; + + QList<QByteArray> datagrams = QList<QByteArray>() + << QByteArray("0123") + << QByteArray("4567") + << QByteArray("89ab") + << QByteArray("cdef"); + + QUdpSocket sender; +#ifdef FORCE_SESSION + sender.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif + sender.bind(); + foreach (const QByteArray &datagram, datagrams) { + QCOMPARE(int(sender.writeDatagram(datagram, groupAddress, receiver.localPort())), + int(datagram.size())); + } + + QVERIFY2(receiver.waitForReadyRead(), + qPrintable(receiver.errorString())); + QVERIFY(receiver.hasPendingDatagrams()); + QList<QByteArray> receivedDatagrams; + while (receiver.hasPendingDatagrams()) { + QByteArray datagram; + datagram.resize(receiver.pendingDatagramSize()); + receiver.readDatagram(datagram.data(), datagram.size(), 0, 0); + receivedDatagrams << datagram; + } +#ifdef Q_OS_SYMBIAN + QEXPECT_FAIL("valid bind, group ipv4 address", "IPv4 multicast not supported on symbian", Abort); +#endif + QCOMPARE(receivedDatagrams, datagrams); + + QVERIFY2(receiver.leaveMulticastGroup(groupAddress), qPrintable(receiver.errorString())); +} + +void tst_QUdpSocket::echo_data() +{ + QTest::addColumn<bool>("connect"); + QTest::newRow("writeDatagram") << false; + QTest::newRow("write") << true; +} + +void tst_QUdpSocket::echo() +{ + QFETCH(bool, connect); + QHostInfo info = QHostInfo::fromName(QtNetworkSettings::serverName()); + QVERIFY(info.addresses().count()); + QHostAddress remote = info.addresses().first(); + + QUdpSocket sock; +#ifdef FORCE_SESSION + sock.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif + if (connect) { + sock.connectToHost(remote, 7); + QVERIFY(sock.waitForConnected(10000)); + } else { + sock.bind(); + } + QByteArray out(30, 'x'); + QByteArray in; + int successes = 0; + for (int i=0;i<10;i++) { + if (connect) { + sock.write(out); + } else { + sock.writeDatagram(out, remote, 7); + } + if (sock.waitForReadyRead(1000)) { + while (sock.hasPendingDatagrams()) { + QHostAddress from; + quint16 port; + if (connect) { + in = sock.read(sock.pendingDatagramSize()); + } else { + in.resize(sock.pendingDatagramSize()); + sock.readDatagram(in.data(), in.length(), &from, &port); + } + if (in==out) + successes++; + } + } + if (!sock.isValid()) + QFAIL(sock.errorString().toLatin1().constData()); + qDebug() << "packets in" << successes << "out" << i; + QTest::qWait(50); //choke to avoid triggering flood/DDoS protections on echo service + } + QVERIFY(successes >= 9); +} + QTEST_MAIN(tst_QUdpSocket) #include "tst_qudpsocket.moc" diff --git a/tests/auto/qundogroup/testdata/qundogroup.ts b/tests/auto/qundogroup/testdata/qundogroup.ts new file mode 100644 index 0000000..a059bcb --- /dev/null +++ b/tests/auto/qundogroup/testdata/qundogroup.ts @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="en"> +<context> + <name>QUndoGroup</name> + <message> + <source>Undo %1</source> + <translation>undo-prefix %1 undo-suffix</translation> + </message> + <message> + <source>Undo</source> + <comment>Default text for undo action</comment> + <translation>Undo-default-text</translation> + </message> + <message> + <source>Redo %1</source> + <translation>redo-prefix %1 redo-suffix</translation> + </message> + <message> + <source>Redo</source> + <comment>Default text for redo action</comment> + <translation>Redo-default-text</translation> + </message> +</context> +</TS> diff --git a/tests/auto/qundogroup/tst_qundogroup.cpp b/tests/auto/qundogroup/tst_qundogroup.cpp index 9bdff34..55aa73b 100644 --- a/tests/auto/qundogroup/tst_qundogroup.cpp +++ b/tests/auto/qundogroup/tst_qundogroup.cpp @@ -201,6 +201,7 @@ private slots: void deleteStack(); void checkSignals(); void addStackAndDie(); + void commandTextFormat(); }; tst_QUndoGroup::tst_QUndoGroup() @@ -604,6 +605,42 @@ void tst_QUndoGroup::addStackAndDie() delete stack; } +void tst_QUndoGroup::commandTextFormat() +{ + QString binDir = QLibraryInfo::location(QLibraryInfo::BinariesPath); + QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/qundogroup.ts")); + + QTranslator translator; + QVERIFY(translator.load("testdata/qundogroup.qm")); + qApp->installTranslator(&translator); + + QUndoGroup group; + QAction *undo_action = group.createUndoAction(0); + QAction *redo_action = group.createRedoAction(0); + + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + QUndoStack stack(&group); + stack.setActive(); + QString str; + + stack.push(new AppendCommand(&str, "foo")); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + stack.push(new InsertCommand(&str, 0, "bar")); + stack.undo(); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("redo-prefix insert redo-suffix")); + + stack.undo(); + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("redo-prefix append redo-suffix")); + + qApp->removeTranslator(&translator); +} + #else class tst_QUndoGroup : public QObject { diff --git a/tests/auto/qundostack/testdata/qundostack.ts b/tests/auto/qundostack/testdata/qundostack.ts new file mode 100644 index 0000000..4584036 --- /dev/null +++ b/tests/auto/qundostack/testdata/qundostack.ts @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="en"> +<context> + <name>QUndoStack</name> + <message> + <source>Undo %1</source> + <translation>undo-prefix %1 undo-suffix</translation> + </message> + <message> + <source>Undo</source> + <comment>Default text for undo action</comment> + <translation>Undo-default-text</translation> + </message> + <message> + <source>Redo %1</source> + <translation>redo-prefix %1 redo-suffix</translation> + </message> + <message> + <source>Redo</source> + <comment>Default text for redo action</comment> + <translation>Redo-default-text</translation> + </message> +</context> +</TS> diff --git a/tests/auto/qundostack/tst_qundostack.cpp b/tests/auto/qundostack/tst_qundostack.cpp index be97b8d..5a09b9a 100644 --- a/tests/auto/qundostack/tst_qundostack.cpp +++ b/tests/auto/qundostack/tst_qundostack.cpp @@ -101,6 +101,16 @@ private: QString m_text; }; +class IdleCommand : public QUndoCommand +{ +public: + IdleCommand(QUndoCommand *parent = 0); + ~IdleCommand(); + + virtual void undo(); + virtual void redo(); +}; + InsertCommand::InsertCommand(QString *str, int idx, const QString &text, QUndoCommand *parent) : QUndoCommand(parent) @@ -201,6 +211,26 @@ bool AppendCommand::mergeWith(const QUndoCommand *other) return true; } +IdleCommand::IdleCommand(QUndoCommand *parent) + : QUndoCommand(parent) +{ + // "idle-item" goes to QUndoStack::{redo,undo}Text + // "idle-action" goes to all other places (e.g. QUndoView) + setText("idle-item\nidle-action"); +} + +IdleCommand::~IdleCommand() +{ +} + +void IdleCommand::redo() +{ +} + +void IdleCommand::undo() +{ +} + /****************************************************************************** ** tst_QUndoStack */ @@ -220,6 +250,8 @@ private slots: void macroBeginEnd(); void compression(); void undoLimit(); + void commandTextFormat(); + void separateUndoText(); }; tst_QUndoStack::tst_QUndoStack() @@ -2935,6 +2967,68 @@ void tst_QUndoStack::undoLimit() true); // redoChanged } +void tst_QUndoStack::commandTextFormat() +{ + QString binDir = QLibraryInfo::location(QLibraryInfo::BinariesPath); + QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/qundostack.ts")); + + QTranslator translator; + QVERIFY(translator.load("testdata/qundostack.qm")); + qApp->installTranslator(&translator); + + QUndoStack stack; + QAction *undo_action = stack.createUndoAction(0); + QAction *redo_action = stack.createRedoAction(0); + + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + QString str; + + stack.push(new AppendCommand(&str, "foo")); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + stack.push(new InsertCommand(&str, 0, "bar")); + stack.undo(); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("redo-prefix insert redo-suffix")); + + stack.undo(); + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("redo-prefix append redo-suffix")); + + qApp->removeTranslator(&translator); +} + +void tst_QUndoStack::separateUndoText() +{ + QUndoStack stack; + QAction *undo_action = stack.createUndoAction(0); + QAction *redo_action = stack.createRedoAction(0); + + QUndoCommand *command1 = new IdleCommand(); + QUndoCommand *command2 = new IdleCommand(); + stack.push(command1); + stack.push(command2); + stack.undo(); + + QCOMPARE(undo_action->text(), QString("Undo idle-action")); + QCOMPARE(redo_action->text(), QString("Redo idle-action")); + QCOMPARE(command1->actionText(), QString("idle-action")); + + QCOMPARE(command1->text(), QString("idle-item")); + QCOMPARE(stack.text(0), QString("idle-item")); + + command1->setText("idle"); + QCOMPARE(command1->actionText(), QString("idle")); + QCOMPARE(command1->text(), QString("idle")); + + command1->setText("idle-item\nidle-action"); + QCOMPARE(command1->actionText(), QString("idle-action")); + QCOMPARE(command1->text(), QString("idle-item")); +} + QTEST_MAIN(tst_QUndoStack) #include "tst_qundostack.moc" diff --git a/tests/auto/qurl/qurl.pro b/tests/auto/qurl/qurl.pro index 018bb38..a5c39a5 100644 --- a/tests/auto/qurl/qurl.pro +++ b/tests/auto/qurl/qurl.pro @@ -2,3 +2,4 @@ load(qttest_p4) SOURCES += tst_qurl.cpp QT = core symbian: TARGET.CAPABILITY = NetworkServices +CONFIG += parallel_test diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index 1601530..ae27c4a 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -49,6 +49,7 @@ #include <qurl.h> #include <qtextcodec.h> #include <qmap.h> +#include "private/qtldurl_p.h" // For testsuites #define IDNA_ACE_PREFIX "xn--" @@ -88,6 +89,8 @@ public slots: void init(); void cleanup(); private slots: + void effectiveTLDs_data(); + void effectiveTLDs(); void getSetCheck(); void constructing(); void assignment(); @@ -132,6 +135,7 @@ private slots: void compat_encode(); void percentEncoding_data(); void percentEncoding(); + void swap(); void symmetry(); void ipv6_data(); void ipv6(); @@ -161,6 +165,8 @@ private slots: void idna_testsuite(); void nameprep_testsuite_data(); void nameprep_testsuite(); + void nameprep_highcodes_data(); + void nameprep_highcodes(); void ace_testsuite_data(); void ace_testsuite(); void std3violations_data(); @@ -315,6 +321,7 @@ void tst_QUrl::constructing() QUrl buildUNC; + buildUNC.setScheme(QString::fromLatin1("file")); buildUNC.setHost(QString::fromLatin1("somehost")); buildUNC.setPath(QString::fromLatin1("somepath")); QCOMPARE(buildUNC.toLocalFile(), QString::fromLatin1("//somehost/somepath")); @@ -1766,7 +1773,15 @@ void tst_QUrl::toLocalFile_data() QTest::newRow("data7") << QString::fromLatin1("file://somehost/") << QString::fromLatin1("//somehost/"); QTest::newRow("data8") << QString::fromLatin1("file://somehost") << QString::fromLatin1("//somehost"); QTest::newRow("data9") << QString::fromLatin1("file:////somehost/somedir/somefile") << QString::fromLatin1("//somehost/somedir/somefile"); + QTest::newRow("data10") << QString::fromLatin1("FILE:/a.txt") << QString::fromLatin1("/a.txt"); + // and some that result in empty (i.e., not local) + QTest::newRow("xdata0") << QString::fromLatin1("/a.txt") << QString(); + QTest::newRow("xdata1") << QString::fromLatin1("//a.txt") << QString(); + QTest::newRow("xdata2") << QString::fromLatin1("///a.txt") << QString(); + QTest::newRow("xdata3") << QString::fromLatin1("foo:/a.txt") << QString(); + QTest::newRow("xdata4") << QString::fromLatin1("foo://a.txt") << QString(); + QTest::newRow("xdata5") << QString::fromLatin1("foo:///a.txt") << QString(); } void tst_QUrl::toLocalFile() @@ -2207,6 +2222,14 @@ void tst_QUrl::toPercentEncoding() QCOMPARE(original, QUrl::fromPercentEncoding(encodedUrl)); } +void tst_QUrl::swap() +{ + QUrl u1(QLatin1String("http://qt.nokia.com")), u2(QLatin1String("http://www.kdab.com")); + u1.swap(u2); + QCOMPARE(u2.host(),QLatin1String("qt.nokia.com")); + QCOMPARE(u1.host(),QLatin1String("www.kdab.com")); +} + void tst_QUrl::symmetry() { QUrl url(QString::fromLatin1("http://www.räksmörgås.se/pub?a=b&a=dø&a=f#vræl")); @@ -2926,7 +2949,6 @@ void tst_QUrl::nameprep_testsuite_data() << QString() << 0 << 0; QTest::newRow("Case folding 8bit U+00DF (german sharp s)") -// << QString::fromUtf8("\xC3\xDF") ### typo in the original testsuite << QString::fromUtf8("\xC3\x9F") << QString("ss") << QString() << 0 << 0; @@ -2957,7 +2979,8 @@ void tst_QUrl::nameprep_testsuite_data() << QString() << 0 << 0; QTest::newRow("Self-reverting case folding U+01F0 and normalization") - << QString::fromUtf8("\xC7\xF0") +// << QString::fromUtf8("\xC7\xF0") ### typo in the original testsuite + << QString::fromUtf8("\xC7\xB0") << QString::fromUtf8("\xC7\xB0") << QString() << 0 << 0; @@ -3132,13 +3155,13 @@ void tst_QUrl::nameprep_testsuite_data() << QString("Nameprep") << STRINGPREP_NO_UNASSIGNED << STRINGPREP_CONTAINS_UNASSIGNED; QTest::newRow("Larger test (shrinking)") - << QString::fromUtf8("X\xC2\xAD\xC3\xDF\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2" + << QString::fromUtf8("X\xC2\xAD\xC3\x9F\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2" "\xaa\xce\xb0\xe2\x80\x80") << QString::fromUtf8("xssi\xcc\x87""tel\xc7\xb0 a\xce\xb0 ") << QString("Nameprep") << 0 << 0; QTest::newRow("Larger test (expanding)") - << QString::fromUtf8("X\xC3\xDF\xe3\x8c\x96\xC4\xB0\xE2\x84\xA1\xE2\x92\x9F\xE3\x8c\x80") + << QString::fromUtf8("X\xC3\x9F\xe3\x8c\x96\xC4\xB0\xE2\x84\xA1\xE2\x92\x9F\xE3\x8c\x80") << QString::fromUtf8("xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88" "\xe3\x83\xab""i\xcc\x87""tel\x28""d\x29\xe3\x82\xa2\xe3\x83\x91" "\xe3\x83\xbc\xe3\x83\x88") @@ -3159,20 +3182,58 @@ void tst_QUrl::nameprep_testsuite() QFETCH(QString, out); QFETCH(QString, profile); - QEXPECT_FAIL("Case folding U+2121 U+33C6 U+1D7BB", - ">0xffff unicode points are not supported", Continue); - QEXPECT_FAIL("Self-reverting case folding U+01F0 and normalization", - "Investigate further", Continue); QEXPECT_FAIL("Left-to-right mark U+200E", "Investigate further", Continue); QEXPECT_FAIL("Deprecated U+202A", "Investigate further", Continue); QEXPECT_FAIL("Language tagging character U+E0001", "Investigate further", Continue); - QEXPECT_FAIL("Larger test (shrinking)", - "Investigate further", Continue); - QEXPECT_FAIL("Larger test (expanding)", - "Investigate further", Continue); + qt_nameprep(&in, 0); + QCOMPARE(in, out); +#endif +} + +void tst_QUrl::nameprep_highcodes_data() +{ + QTest::addColumn<QString>("in"); + QTest::addColumn<QString>("out"); + QTest::addColumn<QString>("profile"); + QTest::addColumn<int>("flags"); + QTest::addColumn<int>("rc"); + + { + QChar st[] = { '-', 0xd801, 0xdc1d, 'a' }; + QChar se[] = { '-', 0xd801, 0xdc45, 'a' }; + QTest::newRow("highcodes (U+1041D)") + << QString(st, sizeof(st)/sizeof(st[0])) + << QString(se, sizeof(se)/sizeof(se[0])) + << QString() << 0 << 0; + } + { + QChar st[] = { 0x011C, 0xd835, 0xdf6e, 0x0110 }; + QChar se[] = { 0x011D, 0x03C9, 0x0111 }; + QTest::newRow("highcodes (U+1D76E)") + << QString(st, sizeof(st)/sizeof(st[0])) + << QString(se, sizeof(se)/sizeof(se[0])) + << QString() << 0 << 0; + } + { + QChar st[] = { 'D', 0xdb40, 0xdc20, 'o', 0xd834, 0xdd7a, '\'', 0x2060, 'h' }; + QChar se[] = { 'd', 'o', '\'', 'h' }; + QTest::newRow("highcodes (D, U+E0020, o, U+1D17A, ', U+2060, h)") + << QString(st, sizeof(st)/sizeof(st[0])) + << QString(se, sizeof(se)/sizeof(se[0])) + << QString() << 0 << 0; + } +} + +void tst_QUrl::nameprep_highcodes() +{ +#ifdef QT_BUILD_INTERNAL + QFETCH(QString, in); + QFETCH(QString, out); + QFETCH(QString, profile); + qt_nameprep(&in, 0); QCOMPARE(in, out); #endif @@ -3947,5 +4008,28 @@ void tst_QUrl::taskQTBUG_8701() QCOMPARE(foo_uni_bar, QUrl(foo_uni_bar, QUrl::StrictMode).toString()); } +void tst_QUrl::effectiveTLDs_data() +{ + QTest::addColumn<QUrl>("domain"); + QTest::addColumn<QString>("TLD"); + + QTest::newRow("yes0") << QUrl::fromEncoded("http://test.co.uk") << ".co.uk"; + QTest::newRow("yes1") << QUrl::fromEncoded("http://test.com") << ".com"; + QTest::newRow("yes2") << QUrl::fromEncoded("http://www.test.de") << ".de"; + QTest::newRow("yes3") << QUrl::fromEncoded("http://test.ulm.museum") << ".ulm.museum"; + QTest::newRow("yes4") << QUrl::fromEncoded("http://www.com.krodsherad.no") << ".krodsherad.no"; + QTest::newRow("yes5") << QUrl::fromEncoded("http://www.co.uk.1.bg") << ".1.bg"; + QTest::newRow("yes6") << QUrl::fromEncoded("http://www.com.com.cn") << ".com.cn"; + QTest::newRow("yes7") << QUrl::fromEncoded("http://www.test.org.ws") << ".org.ws"; + QTest::newRow("yes9") << QUrl::fromEncoded("http://www.com.co.uk.wallonie.museum") << ".wallonie.museum"; +} + +void tst_QUrl::effectiveTLDs() +{ + QFETCH(QUrl, domain); + QFETCH(QString, TLD); + QCOMPARE(domain.topLevelDomain(), TLD); +} + QTEST_MAIN(tst_QUrl) #include "tst_qurl.moc" diff --git a/tests/auto/quuid/quuid.pro b/tests/auto/quuid/quuid.pro index 25e2456..461956f 100644 --- a/tests/auto/quuid/quuid.pro +++ b/tests/auto/quuid/quuid.pro @@ -4,3 +4,4 @@ SUBDIRS = testProcessUniqueness SUBDIRS += test +CONFIG += parallel_test diff --git a/tests/auto/quuid/test/test.pro b/tests/auto/quuid/test/test.pro index 123aa50..06ae3bd 100644 --- a/tests/auto/quuid/test/test.pro +++ b/tests/auto/quuid/test/test.pro @@ -15,14 +15,14 @@ CONFIG(debug_and_release_target) { } wince* { - addFile_processUniqueness.sources = $$OUT_PWD/../testProcessUniqueness/testProcessUniqueness.exe + addFile_processUniqueness.files = $$OUT_PWD/../testProcessUniqueness/testProcessUniqueness.exe addFile_processUniqueness.path = testProcessUniqueness DEPLOYMENT += addFile_processUniqueness } symbian { - binDep.sources = testProcessUniqueness.exe + binDep.files = testProcessUniqueness.exe binDep.path = \\sys\\bin DEPLOYMENT += binDep diff --git a/tests/auto/quuid/tst_quuid.cpp b/tests/auto/quuid/tst_quuid.cpp index 6333e83..4948312 100644 --- a/tests/auto/quuid/tst_quuid.cpp +++ b/tests/auto/quuid/tst_quuid.cpp @@ -60,7 +60,14 @@ public: tst_QUuid(); private slots: + void fromChar(); void toString(); + void fromString(); + void toByteArray(); + void fromByteArray(); + void toRfc4122(); + void fromRfc4122(); + void check_QDataStream(); void isNull(); void equal(); void notEqual(); @@ -83,16 +90,106 @@ public: tst_QUuid::tst_QUuid() { - uuidA = "{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"; - uuidB = "{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"; + //"{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"; + uuidA = QUuid(0xfc69b59e, 0xcc34 ,0x4436 ,0xa4 ,0x3c ,0xee ,0x95 ,0xd1 ,0x28 ,0xb8 ,0xc5); + + //"{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"; + uuidB = QUuid(0x1ab6e93a ,0xb1cb ,0x4a87 ,0xba ,0x47 ,0xec ,0x7e ,0x99 ,0x03 ,0x9a ,0x7b); } +void tst_QUuid::fromChar() +{ + QCOMPARE(uuidA, QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); + QCOMPARE(uuidA, QUuid("fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); + QCOMPARE(uuidA, QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c5")); + QCOMPARE(uuidA, QUuid("fc69b59e-cc34-4436-a43c-ee95d128b8c5")); + QCOMPARE(QUuid(), QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c")); + QCOMPARE(QUuid(), QUuid("{fc69b59e-cc34")); + QCOMPARE(QUuid(), QUuid("fc69b59e-cc34-")); + QCOMPARE(QUuid(), QUuid("fc69b59e-cc34")); + QCOMPARE(QUuid(), QUuid("cc34")); + QCOMPARE(QUuid(), QUuid(NULL)); + + QCOMPARE(uuidB, QUuid(QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"))); +} void tst_QUuid::toString() { QCOMPARE(uuidA.toString(), QString("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); + + QCOMPARE(uuidB.toString(), QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}")); +} + +void tst_QUuid::fromString() +{ + QCOMPARE(uuidA, QUuid(QString("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"))); + QCOMPARE(uuidA, QUuid(QString("fc69b59e-cc34-4436-a43c-ee95d128b8c5}"))); + QCOMPARE(uuidA, QUuid(QString("{fc69b59e-cc34-4436-a43c-ee95d128b8c5"))); + QCOMPARE(uuidA, QUuid(QString("fc69b59e-cc34-4436-a43c-ee95d128b8c5"))); + QCOMPARE(QUuid(), QUuid(QString("{fc69b59e-cc34-4436-a43c-ee95d128b8c"))); + + QCOMPARE(uuidB, QUuid(QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"))); +} + +void tst_QUuid::toByteArray() +{ + QCOMPARE(uuidA.toByteArray(), QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); + + QCOMPARE(uuidB.toByteArray(), QByteArray("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}")); +} + +void tst_QUuid::fromByteArray() +{ + QCOMPARE(uuidA, QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"))); + QCOMPARE(uuidA, QUuid(QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5}"))); + QCOMPARE(uuidA, QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5"))); + QCOMPARE(uuidA, QUuid(QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5"))); + QCOMPARE(QUuid(), QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c"))); + + QCOMPARE(uuidB, QUuid(QByteArray("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"))); +} + +void tst_QUuid::toRfc4122() +{ + QCOMPARE(uuidA.toRfc4122(), QByteArray::fromHex("fc69b59ecc344436a43cee95d128b8c5")); + + QCOMPARE(uuidB.toRfc4122(), QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b")); } +void tst_QUuid::fromRfc4122() +{ + QCOMPARE(uuidA, QUuid::fromRfc4122(QByteArray::fromHex("fc69b59ecc344436a43cee95d128b8c5"))); + + QCOMPARE(uuidB, QUuid::fromRfc4122(QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b"))); +} + +void tst_QUuid::check_QDataStream() +{ + QUuid tmp; + QByteArray ar; + { + QDataStream out(&ar,QIODevice::WriteOnly); + out.setByteOrder(QDataStream::BigEndian); + out << uuidA; + } + { + QDataStream in(&ar,QIODevice::ReadOnly); + in.setByteOrder(QDataStream::BigEndian); + in >> tmp; + QCOMPARE(uuidA, tmp); + } + { + QDataStream out(&ar,QIODevice::WriteOnly); + out.setByteOrder(QDataStream::LittleEndian); + out << uuidA; + } + { + QDataStream in(&ar,QIODevice::ReadOnly); + in.setByteOrder(QDataStream::LittleEndian); + in >> tmp; + QCOMPARE(uuidA, tmp); + } +} void tst_QUuid::isNull() { diff --git a/tests/auto/qvariant/tst_qvariant.cpp b/tests/auto/qvariant/tst_qvariant.cpp index 165207e..d7e9800 100644 --- a/tests/auto/qvariant/tst_qvariant.cpp +++ b/tests/auto/qvariant/tst_qvariant.cpp @@ -100,6 +100,7 @@ private slots: void constructor(); void copy_constructor(); void isNull(); + void swap(); void canConvert_data(); void canConvert(); @@ -274,6 +275,8 @@ private slots: void variantInVariant(); void colorInteger(); + + void forwardDeclare(); }; Q_DECLARE_METATYPE(QDate) @@ -372,6 +375,16 @@ void tst_QVariant::isNull() QVERIFY(var7.isNull()); } +void tst_QVariant::swap() +{ + QVariant v1 = 1, v2 = 2.0; + v1.swap(v2); + QCOMPARE(v1.type(),QVariant::Double); + QCOMPARE(v1.toDouble(),2.0); + QCOMPARE(v2.type(),QVariant::Int); + QCOMPARE(v2.toInt(),1); +} + void tst_QVariant::canConvert_data() { QTest::addColumn<QVariant>("val"); @@ -2637,7 +2650,6 @@ void tst_QVariant::invalidAsByteArray() void tst_QVariant::invalidQColor() const { QVariant va("An invalid QColor::name() value."); - QTest::ignoreMessage(QtWarningMsg, "QColor::setNamedColor: Unknown color name 'An invalid QColor::name() value.'"); QVERIFY(va.canConvert(QVariant::Color)); QVERIFY(!va.convert(QVariant::Color)); @@ -2649,7 +2661,10 @@ void tst_QVariant::qvariant_cast_QObject_data() { QTest::addColumn<QVariant>("data"); QTest::addColumn<bool>("success"); - QTest::newRow("from QObject") << QVariant(QMetaType::QObjectStar, new QObject(this)) << true; + QObject *obj = new QObject(this); + obj->setObjectName(QString::fromLatin1("Hello")); + QTest::newRow("from QObject") << QVariant(QMetaType::QObjectStar, &obj) << true; + QTest::newRow("from QObject2") << QVariant::fromValue(obj) << true; QTest::newRow("from String") << QVariant(QLatin1String("1, 2, 3")) << false; QTest::newRow("from int") << QVariant((int) 123) << false; } @@ -2661,6 +2676,9 @@ void tst_QVariant::qvariant_cast_QObject() { QObject *o = qvariant_cast<QObject *>(data); QCOMPARE(o != 0, success); + if (success) { + QCOMPARE(o->objectName(), QString::fromLatin1("Hello")); + } } Q_DECLARE_METATYPE(qint8); @@ -3221,18 +3239,24 @@ struct MyData { void *ptr; MyData() : ptr(this) {} - ~MyData() { Q_ASSERT(ptr == this); } - MyData(const MyData& o) : ptr(this) { Q_ASSERT(o.ptr == &o); } + ~MyData() + { + if (ptr != this) qWarning("%s: object has moved", Q_FUNC_INFO); + } + MyData(const MyData& o) : ptr(this) + { + if (o.ptr != &o) qWarning("%s: other object has moved", Q_FUNC_INFO); + } MyData &operator=(const MyData &o) { - Q_ASSERT(ptr == this); - Q_ASSERT(o.ptr == &o); + if (ptr != this) qWarning("%s: object has moved", Q_FUNC_INFO); + if (o.ptr != &o) qWarning("%s: other object has moved", Q_FUNC_INFO); return *this; } bool operator==(const MyData &o) const { - Q_ASSERT(ptr == this); - Q_ASSERT(o.ptr == &o); + if (ptr != this) qWarning("%s: object has moved", Q_FUNC_INFO); + if (o.ptr != &o) qWarning("%s: other object has moved", Q_FUNC_INFO); return true; } }; @@ -3422,5 +3446,16 @@ void tst_QVariant::colorInteger() QCOMPARE(v.value<QColor>(), QColor(Qt::yellow)); } +class Forward; +Q_DECLARE_METATYPE(Forward*); + +void tst_QVariant::forwardDeclare() +{ + Forward *f = 0; + QVariant v = QVariant::fromValue(f); + QCOMPARE(qvariant_cast<Forward*>(v), f); +} + + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" diff --git a/tests/auto/qvarlengtharray/qvarlengtharray.pro b/tests/auto/qvarlengtharray/qvarlengtharray.pro index 7a02790..183da1b 100644 --- a/tests/auto/qvarlengtharray/qvarlengtharray.pro +++ b/tests/auto/qvarlengtharray/qvarlengtharray.pro @@ -2,3 +2,4 @@ load(qttest_p4) QT = core SOURCES += tst_qvarlengtharray.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qvector/qvector.pro b/tests/auto/qvector/qvector.pro index 80311b4..a7c3957 100644 --- a/tests/auto/qvector/qvector.pro +++ b/tests/auto/qvector/qvector.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qvector.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qvector/tst_qvector.cpp b/tests/auto/qvector/tst_qvector.cpp index b877684..c6f85d4 100644 --- a/tests/auto/qvector/tst_qvector.cpp +++ b/tests/auto/qvector/tst_qvector.cpp @@ -80,6 +80,7 @@ private slots: void remove() const; void size() const; void startsWith() const; + void swap() const; void toList() const; void toStdVector() const; void value() const; @@ -88,6 +89,7 @@ private slots: void outOfMemory(); void QTBUG6416_reserve(); + void initializeList(); }; void tst_QVector::constructors() const @@ -578,6 +580,17 @@ void tst_QVector::startsWith() const QVERIFY(myvec.startsWith(1)); } +void tst_QVector::swap() const +{ + QVector<int> v1, v2; + v1 << 1 << 2 << 3; + v2 << 4 << 5 << 6; + + v1.swap(v2); + QCOMPARE(v1,QVector<int>() << 4 << 5 << 6); + QCOMPARE(v2,QVector<int>() << 1 << 2 << 3); +} + void tst_QVector::toList() const { QVector<QString> myvec; @@ -834,5 +847,19 @@ void tst_QVector::QTBUG6416_reserve() QCOMPARE(fooCtor, fooDtor); } +void tst_QVector::initializeList() +{ +#ifdef Q_COMPILER_INITIALIZER_LISTS + QVector<int> v1{2,3,4}; + QCOMPARE(v1, QVector<int>() << 2 << 3 << 4); + QCOMPARE(v1, (QVector<int>{2,3,4})); + + QVector<QVector<int>> v2{ v1, {1}, QVector<int>(), {2,3,4} }; + QVector<QVector<int>> v3; + v3 << v1 << (QVector<int>() << 1) << QVector<int>() << v1; + QCOMPARE(v3, v2); +#endif +} + QTEST_APPLESS_MAIN(tst_QVector) #include "tst_qvector.moc" diff --git a/tests/auto/qwaitcondition/qwaitcondition.pro b/tests/auto/qwaitcondition/qwaitcondition.pro index 4d9a082..9af0c71 100644 --- a/tests/auto/qwaitcondition/qwaitcondition.pro +++ b/tests/auto/qwaitcondition/qwaitcondition.pro @@ -3,3 +3,4 @@ SOURCES += tst_qwaitcondition.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index f85d469..5550fe8 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -365,7 +365,7 @@ private slots: void setClearAndResizeMask(); void maskedUpdate(); -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_QPA) void syntheticEnterLeave(); void taskQTBUG_4055_sendSyntheticEnterLeave(); #endif @@ -467,23 +467,15 @@ void tst_QWidget::getSetCheck() QCOMPARE(obj1.minimumWidth(), 0); // A widgets width can never be less than 0 obj1.setMinimumWidth(INT_MAX); #ifndef Q_WS_QWS //QWS doesn't allow toplevels to be bigger than the screen -#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) - QCOMPARE((long)obj1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium -#else QCOMPARE(obj1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium #endif -#endif child1.setMinimumWidth(0); QCOMPARE(child1.minimumWidth(), 0); child1.setMinimumWidth(INT_MIN); QCOMPARE(child1.minimumWidth(), 0); // A widgets width can never be less than 0 child1.setMinimumWidth(INT_MAX); -#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) - QCOMPARE((long)child1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium -#else QCOMPARE(child1.minimumWidth(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium -#endif // int QWidget::minimumHeight() // void QWidget::setMinimumHeight(int) @@ -493,38 +485,24 @@ void tst_QWidget::getSetCheck() QCOMPARE(obj1.minimumHeight(), 0); // A widgets height can never be less than 0 obj1.setMinimumHeight(INT_MAX); #ifndef Q_WS_QWS //QWS doesn't allow toplevels to be bigger than the screen -#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) - QCOMPARE((long)obj1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium -#else QCOMPARE(obj1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium #endif -#endif child1.setMinimumHeight(0); QCOMPARE(child1.minimumHeight(), 0); child1.setMinimumHeight(INT_MIN); QCOMPARE(child1.minimumHeight(), 0); // A widgets height can never be less than 0 child1.setMinimumHeight(INT_MAX); -#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) - QCOMPARE((long)child1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium -#else QCOMPARE(child1.minimumHeight(), QWIDGETSIZE_MAX); // The largest minimum size should only be as big as the maximium -#endif - - -// int QWidget::maximumWidth() + // int QWidget::maximumWidth() // void QWidget::setMaximumWidth(int) obj1.setMaximumWidth(0); QCOMPARE(obj1.maximumWidth(), 0); obj1.setMaximumWidth(INT_MIN); QCOMPARE(obj1.maximumWidth(), 0); // A widgets width can never be less than 0 obj1.setMaximumWidth(INT_MAX); -#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) - QCOMPARE((long)obj1.maximumWidth(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX -#else QCOMPARE(obj1.maximumWidth(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX -#endif // int QWidget::maximumHeight() // void QWidget::setMaximumHeight(int) @@ -533,11 +511,7 @@ void tst_QWidget::getSetCheck() obj1.setMaximumHeight(INT_MIN); QCOMPARE(obj1.maximumHeight(), 0); // A widgets height can never be less than 0 obj1.setMaximumHeight(INT_MAX); -#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) - QCOMPARE((long)obj1.maximumHeight(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX -#else QCOMPARE(obj1.maximumHeight(), QWIDGETSIZE_MAX); // QWIDGETSIZE_MAX is the abs max, not INT_MAX -#endif // back to normal obj1.setMinimumWidth(0); @@ -1993,7 +1967,7 @@ void tst_QWidget::showMaximized() layouted.showNormal(); QVERIFY(!(layouted.windowState() & Qt::WindowMaximized)); -#if !defined(Q_WS_QWS) && !defined(Q_OS_WINCE) && !defined(Q_WS_S60) +#if !defined(Q_WS_QWS) && !defined(Q_OS_WINCE) && !defined(Q_WS_S60) && !defined(Q_WS_QPA) //embedded may choose a different size to fit on the screen. QCOMPARE(layouted.size(), layouted.sizeHint()); #endif @@ -2092,7 +2066,7 @@ void tst_QWidget::showFullScreen() layouted.showNormal(); QVERIFY(!(layouted.windowState() & Qt::WindowFullScreen)); -#if !defined(Q_WS_QWS) && !defined(Q_OS_WINCE) && !defined (Q_WS_S60) +#if !defined(Q_WS_QWS) && !defined(Q_OS_WINCE) && !defined (Q_WS_S60) && !defined(Q_WS_QPA) //embedded may choose a different size to fit on the screen. QCOMPARE(layouted.size(), layouted.sizeHint()); #endif @@ -2181,7 +2155,10 @@ void tst_QWidget::resizeEvent() wParent.show(); QCOMPARE (wChild.m_resizeEventCount, 1); // initial resize event before paint wParent.hide(); - wChild.resize(QSize(640,480)); + QSize safeSize(640,480); + if (wChild.size() == safeSize) + safeSize.setWidth(639); + wChild.resize(safeSize); QCOMPARE (wChild.m_resizeEventCount, 1); wParent.show(); QCOMPARE (wChild.m_resizeEventCount, 2); @@ -2192,7 +2169,10 @@ void tst_QWidget::resizeEvent() wTopLevel.show(); QCOMPARE (wTopLevel.m_resizeEventCount, 1); // initial resize event before paint for toplevels wTopLevel.hide(); - wTopLevel.resize(QSize(640,480)); + QSize safeSize(640,480); + if (wTopLevel.size() == safeSize) + safeSize.setWidth(639); + wTopLevel.resize(safeSize); QCOMPARE (wTopLevel.m_resizeEventCount, 1); wTopLevel.show(); QCOMPARE (wTopLevel.m_resizeEventCount, 2); @@ -2766,9 +2746,6 @@ void tst_QWidget::lostUpdatesOnHide() void tst_QWidget::raise() { -#ifdef QT_MAC_USE_COCOA - QSKIP("Cocoa has no Z-Order for views, we hack it, but it results in paint events.", SkipAll); -#endif QTest::qWait(10); QWidget *parent = new QWidget(0); QList<UpdateWidget *> allChildren; @@ -2793,6 +2770,12 @@ void tst_QWidget::raise() QTest::qWaitForWindowShown(parent); QTest::qWait(10); +#ifdef QT_MAC_USE_COCOA + if (child1->internalWinId()) { + QSKIP("Cocoa has no Z-Order for views, we hack it, but it results in paint events.", SkipAll); + } +#endif + QList<QObject *> list1; list1 << child1 << child2 << child3 << child4; QVERIFY(parent->children() == list1); @@ -2817,6 +2800,9 @@ void tst_QWidget::raise() foreach (UpdateWidget *child, allChildren) { int expectedPaintEvents = child == child2 ? 1 : 0; int expectedZOrderChangeEvents = child == child2 ? 1 : 0; +#ifdef QT_MAC_USE_COCOA + QSKIP("Not yet sure why this fails.", SkipSingle); +#endif QTRY_COMPARE(child->numPaintEvents, expectedPaintEvents); QCOMPARE(child->numZOrderChangeEvents, expectedZOrderChangeEvents); child->reset(); @@ -3067,9 +3053,6 @@ protected: void tst_QWidget::testContentsPropagation() { -#ifdef Q_WS_MAC - QSKIP("Pixmap is not antialiased whereas widget is.", SkipAll); -#endif ContentsPropagationWidget widget; #ifdef Q_WS_QWS widget.resize(500,500); @@ -3389,6 +3372,10 @@ void tst_QWidget::widgetAt() #if defined(Q_OS_SYMBIAN) QEXPECT_FAIL("", "Symbian/S60 does only support rectangular regions", Continue); //See also task 147191 #endif +#if defined(Q_WS_QPA) + QEXPECT_FAIL("", "Window mask not implemented on Lighthouse", Continue); +#endif + QTRY_COMPARE(QApplication::widgetAt(100,100)->objectName(), w1->objectName()); QTRY_COMPARE(QApplication::widgetAt(101,101)->objectName(), w2->objectName()); @@ -3407,6 +3394,9 @@ void tst_QWidget::widgetAt() #if defined(Q_OS_SYMBIAN) QEXPECT_FAIL("", "Symbian/S60 does only support rectangular regions", Continue); //See also task 147191 #endif +#if defined(Q_WS_QPA) + QEXPECT_FAIL("", "Window mask not implemented on Lighthouse", Continue); +#endif QTRY_VERIFY(QApplication::widgetAt(100,100) == w1); QTRY_VERIFY(QApplication::widgetAt(101,101) == w2); @@ -3866,29 +3856,6 @@ void tst_QWidget::testDeletionInEventHandlers() #ifdef Q_WS_MAC -bool testAndRelease(const HIViewRef view) -{ -// qDebug() << CFGetRetainCount(view); - if (CFGetRetainCount(view) != 2) - return false; - CFRelease(view); - CFRelease(view); - return true; -} - -typedef QPair<QWidget *, HIViewRef> WidgetViewPair; - -WidgetViewPair createAndRetain(QWidget * const parent = 0) -{ - QWidget * const widget = new QWidget(parent); - const HIViewRef view = (HIViewRef)widget->winId(); - // Retain twice so we can safely call CFGetRetaintCount even if the retain count - // is off by one because of a double release. - CFRetain(view); - CFRetain(view); - return qMakePair(widget, view); -} - /* Test that retaining and releasing the HIView returned by QWidget::winId() works even if the widget itself is deleted. @@ -4770,12 +4737,10 @@ void tst_QWidget::update() QRegion expectedVisible = QRegion(w.rect()) - child.visibleRegion().translated(childOffset); QCOMPARE(w.visibleRegion(), expectedVisible); -#ifdef QT_MAC_USE_COCOA - QEXPECT_FAIL(0, "Cocoa compositor paints the content view", Continue); -#endif QCOMPARE(w.paintedRegion, expectedVisible); #ifdef QT_MAC_USE_COCOA - QEXPECT_FAIL(0, "Cocoa compositor says to paint this.", Continue); + if (QApplicationPrivate::graphics_system_name != QLatin1String("raster")) + QEXPECT_FAIL(0, "Cocoa compositor says to paint this.", Continue); #endif QCOMPARE(child.numPaintEvents, 0); @@ -4822,14 +4787,8 @@ void tst_QWidget::update() & sibling.visibleRegion().translated(siblingOffset)); QCOMPARE(w.numPaintEvents, 1); -#ifdef QT_MAC_USE_COCOA - QEXPECT_FAIL(0, "Cocoa compositor paints the content view", Continue); -#endif QCOMPARE(w.paintedRegion, w.visibleRegion() & sibling.visibleRegion().translated(siblingOffset)); -#ifdef QT_MAC_USE_COCOA - QEXPECT_FAIL(0, "Cocoa compositor paints the content view", Continue); -#endif QCOMPARE(w.paintedRegion, (w.visibleRegion() - child.visibleRegion().translated(childOffset)) & sibling.visibleRegion().translated(siblingOffset)); @@ -4852,7 +4811,8 @@ void tst_QWidget::update() QCOMPARE(sibling.paintedRegion, sibling.visibleRegion()); #ifdef QT_MAC_USE_COCOA - QEXPECT_FAIL(0, "Cocoa compositor paints child and sibling", Continue); + if (child.internalWinId()) // child is native + QEXPECT_FAIL(0, "Cocoa compositor paints child and sibling", Continue); #endif QCOMPARE(child.numPaintEvents, 0); QCOMPARE(child.visibleRegion(), @@ -5483,10 +5443,14 @@ public: rect.width(), rect.height()); \ QCOMPARE(pixmap.size(), rect.size()); \ QPixmap expectedPixmap(pixmap); /* ensure equal formats */ \ + expectedPixmap.detach(); \ expectedPixmap.fill(color); \ - if (pixmap.toImage().pixel(0,0) != QColor(color).rgb() && t < 4 ) \ + QImage image = pixmap.toImage(); \ + uint alphaCorrection = image.format() == QImage::Format_RGB32 ? 0xff000000 : 0; \ + uint firstPixel = image.pixel(0,0) | alphaCorrection; \ + if ( firstPixel != QColor(color).rgb() && t < 4 ) \ { QTest::qWait(200); continue; } \ - QCOMPARE(pixmap.toImage().pixel(0,0), QColor(color).rgb()); \ + QCOMPARE(firstPixel, QColor(color).rgb()); \ QCOMPARE(pixmap, expectedPixmap); \ break; \ } \ @@ -5526,9 +5490,6 @@ void tst_QWidget::moveChild() QTest::qWait(30); const QPoint tlwOffset = parent.geometry().topLeft(); -#ifdef QT_MAC_USE_COCOA - QEXPECT_FAIL(0, "Cocoa compositor paints the entire content view, even when opaque", Continue); -#endif QTRY_COMPARE(parent.r, QRegion(parent.rect()) - child.geometry()); QTRY_COMPARE(child.r, QRegion(child.rect())); VERIFY_COLOR(child.geometry().translated(tlwOffset), @@ -6377,11 +6338,15 @@ void tst_QWidget::compatibilityChildInsertedEvents() expected = EventRecorder::EventList() << qMakePair(&widget, QEvent::PolishRequest) - << qMakePair(&widget, QEvent::Type(QEvent::User + 1)) -#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_S60) - << qMakePair(&widget, QEvent::UpdateRequest) -#endif - ; + << qMakePair(&widget, QEvent::Type(QEvent::User + 1)); + +#ifndef QT_MAC_USE_CARBON +#ifdef QT_MAC_USE_COCOA + if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) +#endif // QT_MAC_USE_COCOA + expected << qMakePair(&widget, QEvent::UpdateRequest); +#endif // !QT_MAC_USE_CARBON + QCOMPARE(spy.eventList(), expected); } @@ -6473,11 +6438,15 @@ void tst_QWidget::compatibilityChildInsertedEvents() #endif << qMakePair(&widget, QEvent::PolishRequest) << qMakePair(&widget, QEvent::Type(QEvent::User + 1)) - << qMakePair(&widget, QEvent::Type(QEvent::User + 2)) -#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_S60) - << qMakePair(&widget, QEvent::UpdateRequest) -#endif - ; + << qMakePair(&widget, QEvent::Type(QEvent::User + 2)); + +#ifndef QT_MAC_USE_CARBON +#ifdef QT_MAC_USE_COCOA + if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) +#endif // QT_MAC_USE_COCOA + expected << qMakePair(&widget, QEvent::UpdateRequest); +#endif // !QT_MAC_USE_CARBON + QCOMPARE(spy.eventList(), expected); } @@ -6569,11 +6538,15 @@ void tst_QWidget::compatibilityChildInsertedEvents() #endif << qMakePair(&widget, QEvent::PolishRequest) << qMakePair(&widget, QEvent::Type(QEvent::User + 1)) - << qMakePair(&widget, QEvent::Type(QEvent::User + 2)) -#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_S60) - << qMakePair(&widget, QEvent::UpdateRequest) -#endif - ; + << qMakePair(&widget, QEvent::Type(QEvent::User + 2)); + +#ifndef QT_MAC_USE_CARBON +#ifdef QT_MAC_USE_COCOA + if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) +#endif // QT_MAC_USE_COCOA + expected << qMakePair(&widget, QEvent::UpdateRequest); +#endif // !QT_MAC_USE_CARBON + QCOMPARE(spy.eventList(), expected); } } @@ -7261,8 +7234,7 @@ void tst_QWidget::render_systemClip2() QFETCH(bool, usePaintEvent); QFETCH(QColor, expectedColor); - Q_ASSERT_X(expectedColor != QColor(Qt::red), Q_FUNC_INFO, - "Qt::red is the reference color for the image, pick another color"); + QVERIFY2(expectedColor != QColor(Qt::red), "Qt::red is the reference color for the image, pick another color"); class MyWidget : public QWidget { @@ -8951,6 +8923,7 @@ void tst_QWidget::setClearAndResizeMask() UpdateWidget child(&topLevel); child.setAutoFillBackground(true); // NB! Opaque child. + child.setPalette(Qt::red); child.resize(100, 100); child.show(); QTest::qWait(10); @@ -8966,10 +8939,11 @@ void tst_QWidget::setClearAndResizeMask() // and ensure that the child widget doesn't get any update. #ifdef Q_WS_MAC // Mac always issues a full update when calling setMask, and we cannot force it to not do so. - QCOMPARE(child.numPaintEvents, 1); -#else - QCOMPARE(child.numPaintEvents, 0); + if (child.internalWinId()) + QCOMPARE(child.numPaintEvents, 1); + else #endif + QCOMPARE(child.numPaintEvents, 0); // and the parent widget gets an update for the newly exposed area. QTRY_COMPARE(topLevel.numPaintEvents, 1); QRegion expectedParentExpose(child.rect()); @@ -8986,10 +8960,11 @@ void tst_QWidget::setClearAndResizeMask() // and ensure that that the child widget gets an update for the area outside the old mask. QTRY_COMPARE(child.numPaintEvents, 1); outsideOldMask = child.rect(); -#ifndef Q_WS_MAC +#ifdef Q_WS_MAC // Mac always issues a full update when calling setMask, and we cannot force it to not do so. - outsideOldMask -= childMask; + if (!child.internalWinId()) #endif + outsideOldMask -= childMask; QCOMPARE(child.paintedRegion, outsideOldMask); // and the parent widget doesn't get any update. QCOMPARE(topLevel.numPaintEvents, 0); @@ -9002,11 +8977,12 @@ void tst_QWidget::setClearAndResizeMask() QTest::qWait(100); #ifdef Q_WS_MAC // Mac always issues a full update when calling setMask, and we cannot force it to not do so. - QTRY_COMPARE(child.numPaintEvents, 1); -#else + if (child.internalWinId()) + QTRY_COMPARE(child.numPaintEvents, 1); + else +#endif // and ensure that we don't get any updates at all. QTRY_COMPARE(child.numPaintEvents, 0); -#endif QCOMPARE(topLevel.numPaintEvents, 0); // ...and the same applies when clearing the mask. @@ -9014,10 +8990,11 @@ void tst_QWidget::setClearAndResizeMask() QTest::qWait(100); #ifdef Q_WS_MAC // Mac always issues a full update when calling setMask, and we cannot force it to not do so. - QTRY_VERIFY(child.numPaintEvents > 0); -#else - QCOMPARE(child.numPaintEvents, 0); + if (child.internalWinId()) + QTRY_VERIFY(child.numPaintEvents > 0); + else #endif + QCOMPARE(child.numPaintEvents, 0); QCOMPARE(topLevel.numPaintEvents, 0); QWidget resizeParent; @@ -9043,10 +9020,11 @@ void tst_QWidget::setClearAndResizeMask() QTest::qWait(200); #ifdef Q_WS_MAC // Mac always issues a full update when calling setMask, and we cannot force it to not do so. - QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); -#else - QTRY_COMPARE(resizeChild.paintedRegion, QRegion()); + if (child.internalWinId()) + QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); + else #endif + QTRY_COMPARE(resizeChild.paintedRegion, QRegion()); resizeChild.paintedRegion = QRegion(); const QRegion oldMask = resizeChild.mask(); @@ -9054,10 +9032,11 @@ void tst_QWidget::setClearAndResizeMask() QTest::qWait(100); #ifdef Q_WS_MAC // Mac always issues a full update when calling setMask, and we cannot force it to not do so. - QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); -#else - QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask() - oldMask); + if (child.internalWinId()) + QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); + else #endif + QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask() - oldMask); } void tst_QWidget::maskedUpdate() @@ -9207,7 +9186,7 @@ void tst_QWidget::maskedUpdate() QTRY_COMPARE(grandChild.paintedRegion, QRegion(grandChild.rect())); // Full update. } -#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) +#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_QPA) void tst_QWidget::syntheticEnterLeave() { class MyWidget : public QWidget @@ -10442,7 +10421,7 @@ void tst_QWidget::taskQTBUG_7532_tabOrderWithFocusProxy() w.setFocusProxy(fp); QWidget::setTabOrder(&w, fp); - // No Q_ASSERT, then it's allright. + // In debug mode, no assertion failure means it's alright. } void tst_QWidget::movedAndResizedAttributes() @@ -10634,7 +10613,7 @@ void tst_QWidget::nativeChildFocus() QTest::qWaitForWindowShown(&w); QCOMPARE(QApplication::activeWindow(), &w); - QCOMPARE(QApplication::focusWidget(), p1); + QCOMPARE(QApplication::focusWidget(), static_cast<QWidget*>(p1)); } QTEST_MAIN(tst_QWidget) diff --git a/tests/auto/qwidget/tst_qwidget_mac_helpers.h b/tests/auto/qwidget/tst_qwidget_mac_helpers.h index fe1bf1c..97a3a12 100644 --- a/tests/auto/qwidget/tst_qwidget_mac_helpers.h +++ b/tests/auto/qwidget/tst_qwidget_mac_helpers.h @@ -39,9 +39,20 @@ ** ****************************************************************************/ #include <QtCore/QString> -class QWidget; +#include <QtCore/QPair> +#include <QtGui/QWidget> #pragma once // Yeah, it's deprecated in general, but it's standard practive for Mac OS X. QString nativeWindowTitle(QWidget *widget, Qt::WindowState state); bool nativeWindowModified(QWidget *widget); + +#ifndef QT_MAC_USE_COCOA +typedef QPair<QWidget *, HIViewRef> WidgetViewPair; +bool testAndRelease(const HIViewRef view); +WidgetViewPair createAndRetain(QWidget * const parent = 0); +#else +typedef QPair<QWidget *, WId> WidgetViewPair; +bool testAndRelease(const WId); +WidgetViewPair createAndRetain(QWidget * const parent = 0); +#endif diff --git a/tests/auto/qwidget/tst_qwidget_mac_helpers.mm b/tests/auto/qwidget/tst_qwidget_mac_helpers.mm index bfa2489..3bd5db8 100644 --- a/tests/auto/qwidget/tst_qwidget_mac_helpers.mm +++ b/tests/auto/qwidget/tst_qwidget_mac_helpers.mm @@ -72,3 +72,47 @@ bool nativeWindowModified(QWidget *widget) return [qt_mac_window_for(widget) isDocumentEdited]; #endif } + +#ifndef QT_MAC_USE_COCOA +bool testAndRelease(const HIViewRef view) +{ +// qDebug() << CFGetRetainCount(view); + if (CFGetRetainCount(view) != 2) + return false; + CFRelease(view); + CFRelease(view); + return true; +} + +WidgetViewPair createAndRetain(QWidget * const parent) +{ + QWidget * const widget = new QWidget(parent); + const HIViewRef view = (HIViewRef)widget->winId(); + // Retain twice so we can safely call CFGetRetaintCount even if the retain count + // is off by one because of a double release. + CFRetain(view); + CFRetain(view); + return qMakePair(widget, view); +} +#else +bool testAndRelease(const WId view) +{ + if ([id(view) retainCount] != 2) + return false; + [id(view) release]; + [id(view) release]; + return true; +} + +WidgetViewPair createAndRetain(QWidget * const parent) +{ + QWidget * const widget = new QWidget(parent); + const WId view = widget->winId(); + // Retain twice so we can safely call retainCount even if the retain count + // is off by one because of a double release. + [id(view) retain]; + [id(view) retain]; + return qMakePair(widget, view); +} +#endif + diff --git a/tests/auto/qwindowsurface/tst_qwindowsurface.cpp b/tests/auto/qwindowsurface/tst_qwindowsurface.cpp index 3fcf4b4..11f7240 100644 --- a/tests/auto/qwindowsurface/tst_qwindowsurface.cpp +++ b/tests/auto/qwindowsurface/tst_qwindowsurface.cpp @@ -66,7 +66,6 @@ private slots: void getSetWindowSurface(); void flushOutsidePaintEvent(); void grabWidget(); - void staticContentsAndPartialUpdateSupport(); }; class MyWindowSurface : public QWindowSurface @@ -82,8 +81,6 @@ public: /* nothing */ } - using QWindowSurface::setStaticContentsSupport; - using QWindowSurface::setPartialUpdateSupport; private: QImage image; }; @@ -283,51 +280,6 @@ void tst_QWindowSurface::grabWidget() QVERIFY(QColor(childInvalidSubImage.pixel(0, 0)) == QColor(Qt::white)); } -void tst_QWindowSurface::staticContentsAndPartialUpdateSupport() -{ - QWidget widget; - MyWindowSurface surface(&widget); - - // Default values. - QVERIFY(surface.hasPartialUpdateSupport()); - QVERIFY(!surface.hasStaticContentsSupport()); - - // Partial: YES, Static: YES - surface.setStaticContentsSupport(true); - QVERIFY(surface.hasPartialUpdateSupport()); - QVERIFY(surface.hasStaticContentsSupport()); - - // Static contents requires support for partial updates. - // We simply ingore bad combinations and spit out a warning. - - // CONFLICT: Partial: NO, Static: YES - QTest::ignoreMessage(QtWarningMsg, "QWindowSurface::setPartialUpdateSupport: static contents support requires partial update support"); - surface.setPartialUpdateSupport(false); - QVERIFY(surface.hasPartialUpdateSupport()); - QVERIFY(surface.hasStaticContentsSupport()); - - // Partial: YES, Static: NO - surface.setStaticContentsSupport(false); - QVERIFY(surface.hasPartialUpdateSupport()); - QVERIFY(!surface.hasStaticContentsSupport()); - - // Partial: NO, Static: NO - surface.setPartialUpdateSupport(false); - QVERIFY(!surface.hasPartialUpdateSupport()); - QVERIFY(!surface.hasStaticContentsSupport()); - - // CONFLICT: Partial: NO, Static: YES - QTest::ignoreMessage(QtWarningMsg, "QWindowSurface::setStaticContentsSupport: static contents support requires partial update support"); - surface.setStaticContentsSupport(true); - QVERIFY(!surface.hasPartialUpdateSupport()); - QVERIFY(!surface.hasStaticContentsSupport()); - - // Partial: YES, Static: NO - surface.setPartialUpdateSupport(true); - QVERIFY(surface.hasPartialUpdateSupport()); - QVERIFY(!surface.hasStaticContentsSupport()); -} - QTEST_MAIN(tst_QWindowSurface) #else // Q_WS_MAC diff --git a/tests/auto/qwineventnotifier/qwineventnotifier.pro b/tests/auto/qwineventnotifier/qwineventnotifier.pro index 0c8bd2b..62da3a3 100644 --- a/tests/auto/qwineventnotifier/qwineventnotifier.pro +++ b/tests/auto/qwineventnotifier/qwineventnotifier.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qwineventnotifier.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qwizard/tst_qwizard.cpp b/tests/auto/qwizard/tst_qwizard.cpp index 5fcf4ca..b2656db 100644 --- a/tests/auto/qwizard/tst_qwizard.cpp +++ b/tests/auto/qwizard/tst_qwizard.cpp @@ -854,25 +854,26 @@ struct MyPage2 : public QWizardPage public: MyPage2() : init(0), cleanup(0), validate(0) {} - void initializePage() { ++init; QWizardPage::initializePage(); checkInvariant(); } - void cleanupPage() { ++cleanup; QWizardPage::cleanupPage(); checkInvariant(); } + void initializePage() { ++init; QWizardPage::initializePage(); } + void cleanupPage() { ++cleanup; QWizardPage::cleanupPage(); } bool validatePage() { ++validate; return QWizardPage::validatePage(); } - void check(int init, int cleanup) - { Q_ASSERT(init == this->init && cleanup == this->cleanup); Q_UNUSED(init); Q_UNUSED(cleanup); } + bool check(int init, int cleanup) + { + return init == this->init + && cleanup == this->cleanup + && (this->init == this->cleanup || this->init - 1 == this->cleanup); + } int init; int cleanup; int validate; - -private: - void checkInvariant() { Q_ASSERT(init == cleanup || init - 1 == cleanup); } }; #define CHECK_PAGE_INIT(i0, c0, i1, c1, i2, c2) \ - page0->check((i0), (c0)); \ - page1->check((i1), (c1)); \ - page2->check((i2), (c2)); + QVERIFY(page0->check((i0), (c0))); \ + QVERIFY(page1->check((i1), (c1))); \ + QVERIFY(page2->check((i2), (c2))); void tst_QWizard::setOption_IndependentPages() { @@ -1770,8 +1771,11 @@ public: ~TestWizard() { - foreach (int id, pageIds) - delete page(id); + foreach (int id, pageIds) { + QWizardPage *page_to_delete = page(id); + removePage(id); + delete page_to_delete; + } } void applyOperations(const QList<Operation *> &operations) @@ -2548,8 +2552,8 @@ void tst_QWizard::task177022_setFixedSize() QWizard wiz; QWizardPage page1; QWizardPage page2; - wiz.addPage(&page1); - wiz.addPage(&page2); + int page1_id = wiz.addPage(&page1); + int page2_id = wiz.addPage(&page2); wiz.setFixedSize(width, height); if (wiz.wizardStyle() == QWizard::AeroStyle) QEXPECT_FAIL("", "this probably relates to non-client area hack for AeroStyle titlebar " @@ -2576,6 +2580,8 @@ void tst_QWizard::task177022_setFixedSize() QCOMPARE(wiz.maximumWidth(), width); QCOMPARE(wiz.maximumHeight(), height); + wiz.removePage(page1_id); + wiz.removePage(page2_id); } void tst_QWizard::task248107_backButton() diff --git a/tests/auto/qwritelocker/qwritelocker.pro b/tests/auto/qwritelocker/qwritelocker.pro index acae4ef..39a98aa 100644 --- a/tests/auto/qwritelocker/qwritelocker.pro +++ b/tests/auto/qwritelocker/qwritelocker.pro @@ -1,3 +1,4 @@ load(qttest_p4) SOURCES += tst_qwritelocker.cpp QT = core +CONFIG += parallel_test diff --git a/tests/auto/qxml/qxml.pro b/tests/auto/qxml/qxml.pro index 5fb7fe2..c87518a 100644 --- a/tests/auto/qxml/qxml.pro +++ b/tests/auto/qxml/qxml.pro @@ -4,7 +4,7 @@ SOURCES += tst_qxml.cpp QT = core xml wince*|symbian: { - addFiles.sources = 0x010D.xml + addFiles.files = 0x010D.xml addFiles.path = . DEPLOYMENT += addFiles } diff --git a/tests/auto/qxmlformatter/qxmlformatter.pro b/tests/auto/qxmlformatter/qxmlformatter.pro index 339fa55..bcab0b4 100644 --- a/tests/auto/qxmlformatter/qxmlformatter.pro +++ b/tests/auto/qxmlformatter/qxmlformatter.pro @@ -4,7 +4,7 @@ SOURCES += tst_qxmlformatter.cpp include (../xmlpatterns.pri) wince*|symbian:{ - addFiles.sources = baselines input + addFiles.files = baselines input addFiles.path = . DEPLOYMENT += addFiles } diff --git a/tests/auto/qxmlinputsource/tst_qxmlinputsource.cpp b/tests/auto/qxmlinputsource/tst_qxmlinputsource.cpp index 4194568..9d31b34 100644 --- a/tests/auto/qxmlinputsource/tst_qxmlinputsource.cpp +++ b/tests/auto/qxmlinputsource/tst_qxmlinputsource.cpp @@ -181,9 +181,7 @@ private slots: { if(bodyLength == -1) { - Q_ASSERT_X(false, Q_FUNC_INFO, - "No length was specified in the header."); - return; + qFatal("No length was specified in the header."); } QDomDocument domDoc; diff --git a/tests/auto/qxmlquery/MessageValidator.cpp b/tests/auto/qxmlquery/MessageValidator.cpp index b37fba1..0a588f6 100644 --- a/tests/auto/qxmlquery/MessageValidator.cpp +++ b/tests/auto/qxmlquery/MessageValidator.cpp @@ -51,9 +51,8 @@ MessageValidator::MessageValidator() : m_success(false) MessageValidator::~MessageValidator() { - Q_ASSERT_X(m_hasChecked, - Q_FUNC_INFO, - "You must call success()."); + if (!m_hasChecked) + qFatal("%s: You must call success().", Q_FUNC_INFO); } void MessageValidator::handleMessage(QtMsgType type, diff --git a/tests/auto/qxmlquery/NetworkOverrider.h b/tests/auto/qxmlquery/NetworkOverrider.h index 3322054..c64e422 100644 --- a/tests/auto/qxmlquery/NetworkOverrider.h +++ b/tests/auto/qxmlquery/NetworkOverrider.h @@ -70,6 +70,7 @@ public: virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData); + bool isValid() const; private: const QUrl m_rewriteFrom; @@ -77,11 +78,10 @@ private: }; NetworkOverrider::NetworkOverrider(const QUrl &rewriteFrom, - const QUrl &rewriteTo) : m_rewriteFrom(rewriteFrom) - , m_rewriteTo(rewriteTo) + const QUrl &rewriteTo) + : m_rewriteFrom(rewriteFrom) + , m_rewriteTo(rewriteTo) { - Q_ASSERT(m_rewriteFrom.isValid()); - Q_ASSERT(m_rewriteTo.isValid()); } QNetworkReply *NetworkOverrider::createRequest(Operation op, @@ -95,4 +95,9 @@ QNetworkReply *NetworkOverrider::createRequest(Operation op, return QNetworkAccessManager::createRequest(op, newReq, outgoingData); } + +bool NetworkOverrider::isValid() const +{ + return m_rewriteFrom.isValid() && m_rewriteTo.isValid(); +} #endif diff --git a/tests/auto/qxmlquery/PushBaseliner.h b/tests/auto/qxmlquery/PushBaseliner.h index 8d9753c..652d919 100644 --- a/tests/auto/qxmlquery/PushBaseliner.h +++ b/tests/auto/qxmlquery/PushBaseliner.h @@ -65,9 +65,9 @@ public: const QXmlNamePool &namePool) : m_out(out) , m_namePool(namePool) { - Q_ASSERT(m_out.codec()); } + bool isValid() const; virtual void startElement(const QXmlName&); virtual void endElement(); virtual void attribute(const QXmlName&, const QStringRef&); @@ -86,6 +86,11 @@ private: const QXmlNamePool m_namePool; }; +bool PushBaseliner::isValid() const +{ + return m_out.codec(); +} + void PushBaseliner::startElement(const QXmlName &name) { m_out << "startElement(" << name.toClarkName(m_namePool) << ')'<< endl; diff --git a/tests/auto/qxmlquery/qxmlquery.pro b/tests/auto/qxmlquery/qxmlquery.pro index 044b7ce..d5e8228 100644 --- a/tests/auto/qxmlquery/qxmlquery.pro +++ b/tests/auto/qxmlquery/qxmlquery.pro @@ -19,10 +19,10 @@ wince* { include (../xmlpatterns.pri) wince*|symbian: { - addFiles.sources = pushBaselines input.xml + addFiles.files = pushBaselines input.xml addFiles.path = . - patternistFiles.sources = ../xmlpatterns/queries + patternistFiles.files = ../xmlpatterns/queries symbian: { #../xmlpatterns resolves to an illegal path for deployment patternistFiles.path = xmlpatterns diff --git a/tests/auto/qxmlquery/tst_qxmlquery.cpp b/tests/auto/qxmlquery/tst_qxmlquery.cpp index 7cb279e..1d3a0bc 100644 --- a/tests/auto/qxmlquery/tst_qxmlquery.cpp +++ b/tests/auto/qxmlquery/tst_qxmlquery.cpp @@ -455,6 +455,7 @@ void tst_QXmlQuery::assignmentOperator() const class ReturnURI : public QAbstractUriResolver { public: + ReturnURI() {} virtual QUrl resolve(const QUrl &relative, const QUrl &baseURI) const { @@ -966,6 +967,7 @@ void tst_QXmlQuery::evaluateToReceiver() QString produced; QTextStream stream(&produced, QIODevice::WriteOnly); PushBaseliner push(stream, query.namePool()); + QVERIFY(push.isValid()); query.evaluateTo(&push); const QString baselineName(inputFile(QLatin1String(SRCDIR "pushBaselines/") + inputQuery.left(inputQuery.length() - 2) + QString::fromLatin1("ref"))); @@ -1684,6 +1686,7 @@ void tst_QXmlQuery::constCorrectness() const QString dummyString; QTextStream dummyStream(&dummyString); PushBaseliner dummy(dummyStream, query.namePool()); + QVERIFY(dummy.isValid()); query.evaluateTo(&dummy); } } @@ -2871,6 +2874,7 @@ void tst_QXmlQuery::useUriResolver() const , private TestFundament { public: + TestUriResolver() {} virtual QUrl resolve(const QUrl &relative, const QUrl &baseURI) const { @@ -3076,6 +3080,7 @@ void tst_QXmlQuery::setNetworkAccessManager() const { NetworkOverrider networkOverrider(QUrl(QLatin1String("tag:example.com:DOESNOTEXIST")), QUrl(inputFileAsURI(QLatin1String(XMLPATTERNSDIR "/queries/simpleDocument.xml")))); + QVERIFY(networkOverrider.isValid()); QXmlQuery query; query.setNetworkAccessManager(&networkOverrider); @@ -3092,6 +3097,7 @@ void tst_QXmlQuery::setNetworkAccessManager() const { NetworkOverrider networkOverrider(QUrl(QLatin1String("tag:example.com:DOESNOTEXIST")), QUrl(inputFileAsURI(QLatin1String(XMLPATTERNSDIR "/queries/concat.xq")))); + QVERIFY(networkOverrider.isValid()); QXmlQuery query; query.setNetworkAccessManager(&networkOverrider); @@ -3299,7 +3305,7 @@ void tst_QXmlQuery::bindVariableQXmlQueryInvalidate() const QXmlQuery query2; query2.setQuery("'query2'"); - query.bindVariable(QLatin1String("name"), query); + query.bindVariable(QLatin1String("name"), query2); QVERIFY(!query.isValid()); } diff --git a/tests/auto/qxmlsimplereader/qxmlsimplereader.pro b/tests/auto/qxmlsimplereader/qxmlsimplereader.pro index c107470..bc3cbd2 100644 --- a/tests/auto/qxmlsimplereader/qxmlsimplereader.pro +++ b/tests/auto/qxmlsimplereader/qxmlsimplereader.pro @@ -13,7 +13,7 @@ QT -= gui wince*|symbian: { - addFiles.sources = encodings parser xmldocs + addFiles.files = encodings parser xmldocs addFiles.path = . DEPLOYMENT += addFiles } diff --git a/tests/auto/qxmlsimplereader/tst_qxmlsimplereader.cpp b/tests/auto/qxmlsimplereader/tst_qxmlsimplereader.cpp index 3a4e483..f2a973c 100644 --- a/tests/auto/qxmlsimplereader/tst_qxmlsimplereader.cpp +++ b/tests/auto/qxmlsimplereader/tst_qxmlsimplereader.cpp @@ -165,7 +165,7 @@ class tst_QXmlSimpleReader : public QObject void roundtripWithNamespaces() const; private: - static QDomDocument fromByteArray(const QString &title, const QByteArray &ba); + static QDomDocument fromByteArray(const QString &title, const QByteArray &ba, bool *ok); XmlServer *server; }; @@ -730,25 +730,27 @@ void tst_QXmlSimpleReader::reportNamespace_data() const << QString("http://example.com/"); } -QDomDocument tst_QXmlSimpleReader::fromByteArray(const QString &title, const QByteArray &ba) +QDomDocument tst_QXmlSimpleReader::fromByteArray(const QString &title, const QByteArray &ba, bool *ok) { QDomDocument doc(title); - const bool ret = doc.setContent(ba, true); - Q_ASSERT(ret); + *ok = doc.setContent(ba, true); return doc; } void tst_QXmlSimpleReader::roundtripWithNamespaces() const { - QEXPECT_FAIL("", "Known problem, see 154573. The fix happens to break uic.", Abort); - const char *const expected = "<element b:attr=\"value\" xmlns:a=\"http://www.example.com/A\" xmlns:b=\"http://www.example.com/B\" />\n"; + bool ok; { const char *const xml = "<element xmlns:b=\"http://www.example.com/B\" b:attr=\"value\" xmlns:a=\"http://www.example.com/A\"/>"; - const QDomDocument one(fromByteArray("document", xml)); - const QDomDocument two(fromByteArray("document2", one.toByteArray(2))); + const QDomDocument one(fromByteArray("document", xml, &ok)); + QVERIFY(ok); + const QDomDocument two(fromByteArray("document2", one.toByteArray(2), &ok)); + QVERIFY(ok); + + QEXPECT_FAIL("", "Known problem, see 154573. The fix happens to break uic.", Abort); QCOMPARE(expected, one.toByteArray().constData()); QCOMPARE(one.toByteArray(2).constData(), two.toByteArray(2).constData()); @@ -758,8 +760,10 @@ void tst_QXmlSimpleReader::roundtripWithNamespaces() const { const char *const xml = "<element b:attr=\"value\" xmlns:b=\"http://www.example.com/B\" xmlns:a=\"http://www.example.com/A\"/>"; - const QDomDocument one(fromByteArray("document", xml)); - const QDomDocument two(fromByteArray("document2", one.toByteArray(2))); + const QDomDocument one(fromByteArray("document", xml, &ok)); + QVERIFY(ok); + const QDomDocument two(fromByteArray("document2", one.toByteArray(2), &ok)); + QVERIFY(ok); QCOMPARE(expected, one.toByteArray().constData()); QCOMPARE(one.toByteArray(2).constData(), two.toByteArray(2).constData()); diff --git a/tests/auto/qxmlstream/qc14n.h b/tests/auto/qxmlstream/qc14n.h index 7f3aa95..f7c17b5 100644 --- a/tests/auto/qxmlstream/qc14n.h +++ b/tests/auto/qxmlstream/qc14n.h @@ -47,17 +47,9 @@ QT_FORWARD_DECLARE_CLASS(QString) class QC14N { public: - enum Option - { - IgnoreProcessingInstruction, - IgnoreComments - }; - typedef QFlags<Option> Options; - static bool isEqual(QIODevice *const firstDocument, QIODevice *const secondDocument, - QString *const message = 0, - const Options options = Options()); + QString *const message = 0); private: static bool isDifferent(const QXmlStreamReader &r1, @@ -76,20 +68,17 @@ private: */ bool QC14N::isEqual(QIODevice *const firstDocument, QIODevice *const secondDocument, - QString *const message, - const Options options) + QString *const message) { qDebug() << Q_FUNC_INFO; - Q_ASSERT_X(firstDocument, Q_FUNC_INFO, - "A valid QIODevice pointer must be supplied"); - Q_ASSERT_X(secondDocument, Q_FUNC_INFO, - "A valid QIODevice pointer must be supplied"); - Q_ASSERT_X(firstDocument->isReadable(), Q_FUNC_INFO, "The device must be readable."); - Q_ASSERT_X(secondDocument->isReadable(), Q_FUNC_INFO, "The device must be readable."); - - Q_ASSERT_X(options == Options(), Q_FUNC_INFO, - "Not yet implemented."); - Q_UNUSED(options); + if (!firstDocument) + qFatal("%s: A valid firstDocument QIODevice pointer must be supplied", Q_FUNC_INFO); + if (!secondDocument) + qFatal("%s: A valid secondDocument QIODevice pointer must be supplied", Q_FUNC_INFO); + if (!firstDocument->isReadable()) + qFatal("%s: The firstDocument device must be readable.", Q_FUNC_INFO); + if (!secondDocument->isReadable()) + qFatal("%s: The secondDocument device must be readable.", Q_FUNC_INFO); QXmlStreamReader r1(firstDocument); QXmlStreamReader r2(secondDocument); @@ -202,9 +191,9 @@ bool QC14N::isDifferent(const QXmlStreamReader &r1, r2.processingInstructionData() == r2.processingInstructionData(); } + default: + qFatal("%s: Unknown tokenType: %d", Q_FUNC_INFO, static_cast<int>(r1.tokenType())); + return false; } - - Q_ASSERT_X(false, Q_FUNC_INFO, "This line should never be reached"); - return false; } diff --git a/tests/auto/qxmlstream/qxmlstream.pro b/tests/auto/qxmlstream/qxmlstream.pro index 8f076be..894801d 100644 --- a/tests/auto/qxmlstream/qxmlstream.pro +++ b/tests/auto/qxmlstream/qxmlstream.pro @@ -5,10 +5,10 @@ QT = core xml network wince*|symbian: { - addFiles.sources = data XML-Test-Suite + addFiles.files = data XML-Test-Suite addFiles.path = . DEPLOYMENT += addFiles - DEFINES += SRCDIR=\\\"\\\" + wince*:DEFINES += SRCDIR=\\\"\\\" } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" } diff --git a/tests/auto/qxmlstream/tst_qxmlstream.cpp b/tests/auto/qxmlstream/tst_qxmlstream.cpp index 10b9176..0ddbe99 100644 --- a/tests/auto/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/qxmlstream/tst_qxmlstream.cpp @@ -55,6 +55,10 @@ //TESTED_CLASS=QXmlStreamReader QXmlStreamWriter //TESTED_FILES=corelib/xml/stream/qxmlutils.cpp corelib/xml/stream/qxmlstream.cpp corelib/xml/stream/qxmlstream_p.h +#ifdef Q_OS_SYMBIAN +#define SRCDIR "" +#endif + Q_DECLARE_METATYPE(QXmlStreamReader::ReadElementTextBehaviour) static const char *const catalogFile = SRCDIR "XML-Test-Suite/xmlconf/finalCatalog.xml"; @@ -217,8 +221,7 @@ static QString documentElement(const QByteArray &document) reader.readNext(); } - Q_ASSERT_X(false, Q_FUNC_INFO, - qPrintable(QString::fromLatin1("The input %1 didn't contain an element.").arg(QString::fromUtf8(document.constData())))); + qFatal("The input %s didn't contain an element", document.constData()); return QString(); } @@ -261,7 +264,8 @@ public: expected(aExpected), output(aOutput) { - Q_ASSERT(!aId.isEmpty()); + if (aId.isEmpty()) + qFatal("%s: aId must not be an empty string", Q_FUNC_INFO); } QString id; @@ -285,7 +289,8 @@ public: TestSuiteHandler(const QUrl &baseURI) : runCount(0), skipCount(0) { - Q_ASSERT(baseURI.isValid()); + if (!baseURI.isValid()) + qFatal("%s: baseURI must be valid", Q_FUNC_INFO); m_baseURI.push(baseURI); } @@ -457,7 +462,7 @@ public: } else { - Q_ASSERT_X(false, Q_FUNC_INFO, "The input catalog is invalid."); + qFatal("The input catalog is invalid."); return false; } } @@ -477,9 +482,12 @@ public: static bool isWellformed(QIODevice *const inputFile, const ParseMode mode) { - Q_ASSERT(inputFile); - Q_ASSERT_X(inputFile->isOpen(), Q_FUNC_INFO, "The caller is responsible for opening the device."); - Q_ASSERT(mode == ParseIncrementally || mode == ParseSinglePass); + if (!inputFile) + qFatal("%s: inputFile must be a valid QIODevice pointer", Q_FUNC_INFO); + if (!inputFile->isOpen()) + qFatal("%s: inputFile must be opened by the caller", Q_FUNC_INFO); + if (mode != ParseIncrementally && mode != ParseSinglePass) + qFatal("%s: mode must be either ParseIncrementally or ParseSinglePass", Q_FUNC_INFO); if(mode == ParseIncrementally) { @@ -570,6 +578,7 @@ private slots: void checkCommentIndentation() const; void checkCommentIndentation_data() const; void qtbug9196_crash() const; + void hasError() const; private: static QByteArray readFile(const QString &filename); @@ -1556,5 +1565,86 @@ void tst_QXmlStream::qtbug9196_crash() const } } +class FakeBuffer : public QBuffer +{ +protected: + qint64 writeData(const char *c, qint64 i) + { + qint64 ai = qMin(m_capacity, i); + m_capacity -= ai; + return ai ? QBuffer::writeData(c, ai) : 0; + } +public: + void setCapacity(int capacity) { m_capacity = capacity; } +private: + qint64 m_capacity; +}; + +void tst_QXmlStream::hasError() const +{ + { + FakeBuffer fb; + QVERIFY(fb.open(QBuffer::ReadWrite)); + fb.setCapacity(1000); + QXmlStreamWriter writer(&fb); + writer.writeStartDocument(); + writer.writeEndDocument(); + QVERIFY(!writer.hasError()); + QCOMPARE(fb.data(), QByteArray("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")); + } + + { + // Failure caused by write(QString) + FakeBuffer fb; + QVERIFY(fb.open(QBuffer::ReadWrite)); + fb.setCapacity(strlen("<?xml version=\"")); + QXmlStreamWriter writer(&fb); + writer.writeStartDocument(); + QVERIFY(writer.hasError()); + QCOMPARE(fb.data(), QByteArray("<?xml version=\"")); + } + + { + // Failure caused by write(char *) + FakeBuffer fb; + QVERIFY(fb.open(QBuffer::ReadWrite)); + fb.setCapacity(strlen("<?xml version=\"1.0")); + QXmlStreamWriter writer(&fb); + writer.writeStartDocument(); + QVERIFY(writer.hasError()); + QCOMPARE(fb.data(), QByteArray("<?xml version=\"1.0")); + } + + { + // Failure caused by write(QStringRef) + FakeBuffer fb; + QVERIFY(fb.open(QBuffer::ReadWrite)); + fb.setCapacity(strlen("<?xml version=\"1.0\" encoding=\"UTF-8\"?><test xmlns:")); + QXmlStreamWriter writer(&fb); + writer.writeStartDocument(); + writer.writeStartElement("test"); + writer.writeNamespace("http://foo.bar", "foo"); + QVERIFY(writer.hasError()); + QCOMPARE(fb.data(), QByteArray("<?xml version=\"1.0\" encoding=\"UTF-8\"?><test xmlns:")); + } + + { + // Refusal to write after 1st failure + FakeBuffer fb; + QVERIFY(fb.open(QBuffer::ReadWrite)); + fb.setCapacity(10); + QXmlStreamWriter writer(&fb); + writer.writeStartDocument(); + QVERIFY(writer.hasError()); + QCOMPARE(fb.data(), QByteArray("<?xml vers")); + fb.setCapacity(1000); + writer.writeStartElement("test"); // literal & qstring + writer.writeNamespace("http://foo.bar", "foo"); // literal & qstringref + QVERIFY(writer.hasError()); + QCOMPARE(fb.data(), QByteArray("<?xml vers")); + } + +} + #include "tst_qxmlstream.moc" // vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/qzip/qzip.pro b/tests/auto/qzip/qzip.pro index 632c743..683da62 100644 --- a/tests/auto/qzip/qzip.pro +++ b/tests/auto/qzip/qzip.pro @@ -2,7 +2,7 @@ load(qttest_p4) SOURCES += tst_qzip.cpp wince*|symbian: { - addFiles.sources = testdata + addFiles.files = testdata addFiles.path = . DEPLOYMENT += addFiles !symbian:DEFINES += SRCDIR=\\\".\\\" diff --git a/tests/auto/script.pro b/tests/auto/script.pro index 06f51b5..c4d0544 100644 --- a/tests/auto/script.pro +++ b/tests/auto/script.pro @@ -7,10 +7,12 @@ SUBDIRS=\ qscriptengine \ qscriptengineagent \ qscriptenginedebugger \ + qscriptextensionplugin \ qscriptextqobject \ qscriptjstestsuite \ qscriptstring \ qscriptv8testsuite \ qscriptvalue \ + qscriptvaluegenerated \ qscriptvalueiterator \ diff --git a/tests/auto/selftests/alive/qtestalive.cpp b/tests/auto/selftests/alive/qtestalive.cpp index 952058e..dd3d411 100644 --- a/tests/auto/selftests/alive/qtestalive.cpp +++ b/tests/auto/selftests/alive/qtestalive.cpp @@ -78,7 +78,8 @@ private: QTestAlivePinger::QTestAlivePinger(QObject *receiver, QObject *parent) : QObject(parent), rec(receiver), currentSequenceId(0), lastSequenceId(0) { - Q_ASSERT(rec); + if (!rec) + qFatal("Null receiver object passed to QTestAlivePinger::QTestAlivePinger()"); timerId = startTimer(850); } @@ -147,8 +148,8 @@ bool QTestAlive::event(QEvent *e) void QTestAlive::run() { - Q_ASSERT_X(QCoreApplication::instance(), "QTestAlive::run()", - "Cannot start QTestAlive without a QCoreApplication instance."); + if (!QCoreApplication::instance()) + qFatal("QTestAlive::run(): Cannot start QTestAlive without a QCoreApplication instance."); QTestAlivePinger p(this); pinger = &p; diff --git a/tests/auto/selftests/expected_cmptest.txt b/tests/auto/selftests/expected_cmptest.txt index a0d3485..0beb46b 100644 --- a/tests/auto/selftests/expected_cmptest.txt +++ b/tests/auto/selftests/expected_cmptest.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_Cmptest ********* -Config: Using QTest library 4.7.4, Qt 4.7.4 +Config: Using QTest library 4.8.0, Qt 4.8.0 PASS : tst_Cmptest::initTestCase() PASS : tst_Cmptest::compare_boolfuncs() PASS : tst_Cmptest::compare_pointerfuncs() diff --git a/tests/auto/selftests/expected_crashes_3.txt b/tests/auto/selftests/expected_crashes_3.txt index 88ba69f..b7f462a 100644 --- a/tests/auto/selftests/expected_crashes_3.txt +++ b/tests/auto/selftests/expected_crashes_3.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_Crashes ********* -Config: Using QTest library 4.7.4, Qt 4.7.4 +Config: Using QTest library 4.8.0, Qt 4.8.0 PASS : tst_Crashes::initTestCase() QFATAL : tst_Crashes::crash() Received signal 11 FAIL! : tst_Crashes::crash() Received a fatal error. diff --git a/tests/auto/selftests/expected_longstring.txt b/tests/auto/selftests/expected_longstring.txt index 7f50020..99809a8 100644 --- a/tests/auto/selftests/expected_longstring.txt +++ b/tests/auto/selftests/expected_longstring.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_LongString ********* -Config: Using QTest library 4.7.4, Qt 4.7.4 +Config: Using QTest library 4.8.0, Qt 4.8.0 PASS : tst_LongString::initTestCase() FAIL! : tst_LongString::failWithLongString() Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. diff --git a/tests/auto/selftests/expected_maxwarnings.txt b/tests/auto/selftests/expected_maxwarnings.txt index cd80a04..165bdda 100644 --- a/tests/auto/selftests/expected_maxwarnings.txt +++ b/tests/auto/selftests/expected_maxwarnings.txt @@ -1,5 +1,5 @@ ********* Start testing of MaxWarnings ********* -Config: Using QTest library 4.7.4, Qt 4.7.4 +Config: Using QTest library 4.8.0, Qt 4.8.0 PASS : MaxWarnings::initTestCase() QWARN : MaxWarnings::warn() 0 QWARN : MaxWarnings::warn() 1 diff --git a/tests/auto/selftests/expected_skip.txt b/tests/auto/selftests/expected_skip.txt index c259c68..4b53a43 100644 --- a/tests/auto/selftests/expected_skip.txt +++ b/tests/auto/selftests/expected_skip.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_Skip ********* -Config: Using QTest library 4.7.4, Qt 4.7.4 +Config: Using QTest library 4.8.0, Qt 4.8.0 PASS : tst_Skip::initTestCase() SKIP : tst_Skip::test() skipping all Loc: [/home/user/depot/qt-git/mainline/tests/auto/selftests/skip/tst_skip.cpp(68)] diff --git a/tests/auto/selftests/selftests.pro b/tests/auto/selftests/selftests.pro index d854b5e..2f1c327 100644 --- a/tests/auto/selftests/selftests.pro +++ b/tests/auto/selftests/selftests.pro @@ -12,3 +12,4 @@ INSTALLS = QT = core +CONFIG += parallel_test diff --git a/tests/auto/selftests/tst_selftests.cpp b/tests/auto/selftests/tst_selftests.cpp index 39b41fb..1a95420 100644 --- a/tests/auto/selftests/tst_selftests.cpp +++ b/tests/auto/selftests/tst_selftests.cpp @@ -515,8 +515,6 @@ BenchmarkResult BenchmarkResult::parse(QString const& line, QString* error) } bool ok; -#if QT_VERSION >= 0x040700 - // Qt 4.7 uses floating point double total = sTotal.toDouble(&ok); if (!ok) { if (error) *error = sTotal + " is not a valid number"; @@ -527,18 +525,6 @@ BenchmarkResult BenchmarkResult::parse(QString const& line, QString* error) if (error) *error = sIterations + " is not a valid number"; return out; } -#else - qlonglong total = sTotal.toLongLong(&ok); - if (!ok) { - if (error) *error = sTotal + " is not a valid integer"; - return out; - } - qlonglong iterations = sIterations.toLongLong(&ok); - if (!ok) { - if (error) *error = sIterations + " is not a valid integer"; - return out; - } -#endif out.unit = unit; out.total = total; diff --git a/tests/auto/symbols/tst_symbols.cpp b/tests/auto/symbols/tst_symbols.cpp index a1a7b7b..d2c8c24 100644 --- a/tests/auto/symbols/tst_symbols.cpp +++ b/tests/auto/symbols/tst_symbols.cpp @@ -169,11 +169,7 @@ void tst_Symbols::globalObjects() } if (isFailed) { -#if QT_VERSION >= 0x040600 QVERIFY2(!isFailed, "Libraries contain static global objects. See Debug output above."); -#else - QSKIP("Libraries contains static global objects. See Debug output above. [These errors cannot be fixed in 4.5 in time]", SkipSingle); -#endif } } diff --git a/tests/auto/uic/baseline/gridalignment.ui b/tests/auto/uic/baseline/gridalignment.ui new file mode 100644 index 0000000..11c28b1 --- /dev/null +++ b/tests/auto/uic/baseline/gridalignment.ui @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Form</class> + <widget class="QWidget" name="Form"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>279</width> + <height>163</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0" alignment="Qt::AlignLeft"> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>Left</string> + </property> + </widget> + </item> + <item row="0" column="1" alignment="Qt::AlignTop"> + <widget class="QPushButton" name="pushButton_3"> + <property name="text"> + <string>Top</string> + </property> + </widget> + </item> + <item row="1" column="0" alignment="Qt::AlignRight"> + <widget class="QPushButton" name="pushButton_2"> + <property name="text"> + <string>Right</string> + </property> + </widget> + </item> + <item row="1" column="1" alignment="Qt::AlignBottom"> + <widget class="QPushButton" name="pushButton_4"> + <property name="text"> + <string>Bottom</string> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/uic/baseline/gridalignment.ui.h b/tests/auto/uic/baseline/gridalignment.ui.h new file mode 100644 index 0000000..8386190 --- /dev/null +++ b/tests/auto/uic/baseline/gridalignment.ui.h @@ -0,0 +1,83 @@ +/******************************************************************************** +** Form generated from reading UI file 'gridalignment.ui' +** +** Created: Fri Oct 22 14:33:59 2010 +** by: Qt User Interface Compiler version 4.8.0 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef GRIDALIGNMENT_H +#define GRIDALIGNMENT_H + +#include <QtCore/QVariant> +#include <QtGui/QAction> +#include <QtGui/QApplication> +#include <QtGui/QButtonGroup> +#include <QtGui/QGridLayout> +#include <QtGui/QHeaderView> +#include <QtGui/QPushButton> +#include <QtGui/QWidget> + +QT_BEGIN_NAMESPACE + +class Ui_Form +{ +public: + QGridLayout *gridLayout; + QPushButton *pushButton; + QPushButton *pushButton_3; + QPushButton *pushButton_2; + QPushButton *pushButton_4; + + void setupUi(QWidget *Form) + { + if (Form->objectName().isEmpty()) + Form->setObjectName(QString::fromUtf8("Form")); + Form->resize(279, 163); + gridLayout = new QGridLayout(Form); + gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + pushButton = new QPushButton(Form); + pushButton->setObjectName(QString::fromUtf8("pushButton")); + + gridLayout->addWidget(pushButton, 0, 0, 1, 1, Qt::AlignLeft); + + pushButton_3 = new QPushButton(Form); + pushButton_3->setObjectName(QString::fromUtf8("pushButton_3")); + + gridLayout->addWidget(pushButton_3, 0, 1, 1, 1, Qt::AlignTop); + + pushButton_2 = new QPushButton(Form); + pushButton_2->setObjectName(QString::fromUtf8("pushButton_2")); + + gridLayout->addWidget(pushButton_2, 1, 0, 1, 1, Qt::AlignRight); + + pushButton_4 = new QPushButton(Form); + pushButton_4->setObjectName(QString::fromUtf8("pushButton_4")); + + gridLayout->addWidget(pushButton_4, 1, 1, 1, 1, Qt::AlignBottom); + + + retranslateUi(Form); + + QMetaObject::connectSlotsByName(Form); + } // setupUi + + void retranslateUi(QWidget *Form) + { + Form->setWindowTitle(QApplication::translate("Form", "Form", 0, QApplication::UnicodeUTF8)); + pushButton->setText(QApplication::translate("Form", "Left", 0, QApplication::UnicodeUTF8)); + pushButton_3->setText(QApplication::translate("Form", "Top", 0, QApplication::UnicodeUTF8)); + pushButton_2->setText(QApplication::translate("Form", "Right", 0, QApplication::UnicodeUTF8)); + pushButton_4->setText(QApplication::translate("Form", "Bottom", 0, QApplication::UnicodeUTF8)); + } // retranslateUi + +}; + +namespace Ui { + class Form: public Ui_Form {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // GRIDALIGNMENT_H diff --git a/tests/auto/uic/baseline/icontheme.ui b/tests/auto/uic/baseline/icontheme.ui new file mode 100644 index 0000000..a214635 --- /dev/null +++ b/tests/auto/uic/baseline/icontheme.ui @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Form</class> + <widget class="QWidget" name="Form"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>122</width> + <height>117</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPushButton" name="fileicon"> + <property name="text"> + <string>fileicon</string> + </property> + <property name="icon"> + <iconset> + <normaloff>image1.png</normaloff>image1.png</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="fileandthemeicon"> + <property name="text"> + <string>PushButton</string> + </property> + <property name="icon"> + <iconset theme="edit-copy"> + <normaloff>image7.png</normaloff>image7.png</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="themeicon"> + <property name="text"> + <string>PushButton</string> + </property> + <property name="icon"> + <iconset theme="edit-copy"> + <normaloff/> + </iconset> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/uic/baseline/icontheme.ui.h b/tests/auto/uic/baseline/icontheme.ui.h new file mode 100644 index 0000000..946fff9 --- /dev/null +++ b/tests/auto/uic/baseline/icontheme.ui.h @@ -0,0 +1,95 @@ +/******************************************************************************** +** Form generated from reading UI file 'icontheme.ui' +** +** Created: Thu Sep 2 10:28:19 2010 +** by: Qt User Interface Compiler version 4.8.0 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef ICONTHEME_H +#define ICONTHEME_H + +#include <QtCore/QVariant> +#include <QtGui/QAction> +#include <QtGui/QApplication> +#include <QtGui/QButtonGroup> +#include <QtGui/QHeaderView> +#include <QtGui/QPushButton> +#include <QtGui/QVBoxLayout> +#include <QtGui/QWidget> + +QT_BEGIN_NAMESPACE + +class Ui_Form +{ +public: + QVBoxLayout *verticalLayout; + QPushButton *fileicon; + QPushButton *fileandthemeicon; + QPushButton *themeicon; + + void setupUi(QWidget *Form) + { + if (Form->objectName().isEmpty()) + Form->setObjectName(QString::fromUtf8("Form")); + Form->resize(122, 117); + verticalLayout = new QVBoxLayout(Form); + verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + fileicon = new QPushButton(Form); + fileicon->setObjectName(QString::fromUtf8("fileicon")); + QIcon icon; + icon.addFile(QString::fromUtf8("image1.png"), QSize(), QIcon::Normal, QIcon::Off); + fileicon->setIcon(icon); + + verticalLayout->addWidget(fileicon); + + fileandthemeicon = new QPushButton(Form); + fileandthemeicon->setObjectName(QString::fromUtf8("fileandthemeicon")); + QIcon icon1; + QString iconThemeName = QString::fromUtf8("edit-copy"); + if (QIcon::hasThemeIcon(iconThemeName)) { + icon1 = QIcon::fromTheme(iconThemeName); + } else { + icon1.addFile(QString::fromUtf8("image7.png"), QSize(), QIcon::Normal, QIcon::Off); + } + fileandthemeicon->setIcon(icon1); + + verticalLayout->addWidget(fileandthemeicon); + + themeicon = new QPushButton(Form); + themeicon->setObjectName(QString::fromUtf8("themeicon")); + QIcon icon2; + iconThemeName = QString::fromUtf8("edit-copy"); + if (QIcon::hasThemeIcon(iconThemeName)) { + icon2 = QIcon::fromTheme(iconThemeName); + } else { + icon2.addFile(QString::fromUtf8(""), QSize(), QIcon::Normal, QIcon::Off); + } + themeicon->setIcon(icon2); + + verticalLayout->addWidget(themeicon); + + + retranslateUi(Form); + + QMetaObject::connectSlotsByName(Form); + } // setupUi + + void retranslateUi(QWidget *Form) + { + Form->setWindowTitle(QApplication::translate("Form", "Form", 0, QApplication::UnicodeUTF8)); + fileicon->setText(QApplication::translate("Form", "fileicon", 0, QApplication::UnicodeUTF8)); + fileandthemeicon->setText(QApplication::translate("Form", "PushButton", 0, QApplication::UnicodeUTF8)); + themeicon->setText(QApplication::translate("Form", "PushButton", 0, QApplication::UnicodeUTF8)); + } // retranslateUi + +}; + +namespace Ui { + class Form: public Ui_Form {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // ICONTHEME_H diff --git a/tests/auto/uiloader/uiloader/uiloader.pro b/tests/auto/uiloader/uiloader/uiloader.pro index d99df00..4e95956 100644 --- a/tests/auto/uiloader/uiloader/uiloader.pro +++ b/tests/auto/uiloader/uiloader/uiloader.pro @@ -17,10 +17,10 @@ QT += xml svg network contains(QT_CONFIG, qt3support): QT += qt3support wince*|symbian: { - configuration.sources = ../*.ini + configuration.files = ../*.ini configuration.path = . - screenapp.sources = ../tst_screenshot/tst_screenshot.exe + screenapp.files = ../tst_screenshot/tst_screenshot.exe screenapp.path = tst_screenshot DEPLOYMENT += configuration screenapp diff --git a/tests/auto/utf8/tst_utf8.cpp b/tests/auto/utf8/tst_utf8.cpp index 202d102..3031089 100644 --- a/tests/auto/utf8/tst_utf8.cpp +++ b/tests/auto/utf8/tst_utf8.cpp @@ -210,7 +210,9 @@ void tst_Utf8::invalidUtf8_data() QTest::addColumn<QByteArray>("utf8"); QTest::newRow("1char") << QByteArray("\x80"); - QTest::newRow("2chars") << QByteArray("\xC2\xC0"); + QTest::newRow("2chars-1") << QByteArray("\xC2\xC0"); + QTest::newRow("2chars-2") << QByteArray("\xC3\xDF"); + QTest::newRow("2chars-3") << QByteArray("\xC7\xF0"); QTest::newRow("3chars-1") << QByteArray("\xE0\xA0\xC0"); QTest::newRow("3chars-2") << QByteArray("\xE0\xC0\xA0"); QTest::newRow("4chars-1") << QByteArray("\xF0\x90\x80\xC0"); diff --git a/tests/auto/utf8/utf8.pro b/tests/auto/utf8/utf8.pro index 4ec6851..aa133fe 100644 --- a/tests/auto/utf8/utf8.pro +++ b/tests/auto/utf8/utf8.pro @@ -1,3 +1,4 @@ load(qttest_p4) QT -= gui SOURCES += tst_utf8.cpp +CONFIG += parallel_test diff --git a/tests/auto/windowsmobile/test/test.pro b/tests/auto/windowsmobile/test/test.pro index f3124a3..b0536a5 100644 --- a/tests/auto/windowsmobile/test/test.pro +++ b/tests/auto/windowsmobile/test/test.pro @@ -8,7 +8,7 @@ RESOURCES += windowsmobile.qrc TARGET = ../tst_windowsmobile wincewm*: { - addFiles.sources = $$OUT_PWD/../testQMenuBar/*.exe + addFiles.files = $$OUT_PWD/../testQMenuBar/*.exe addFiles.path = "\\Program Files\\tst_windowsmobile" diff --git a/tests/auto/xmlpatterns.pri b/tests/auto/xmlpatterns.pri index 8c8ccad..57b8517 100644 --- a/tests/auto/xmlpatterns.pri +++ b/tests/auto/xmlpatterns.pri @@ -4,9 +4,9 @@ contains(QT_CONFIG,xmlpatterns) { } wince*: { - patternsdk.sources = $$QT_BUILD_TREE/lib/QtXmlPatternsSDK*.dll + patternsdk.files = $$QT_BUILD_TREE/lib/QtXmlPatternsSDK*.dll patternsdk.path = . - basedata.sources = xmlpaternsxqts/Baseline.xml + basedata.files = xmlpaternsxqts/Baseline.xml basedata.path = . DEPLOYMENT += patternsdk QT += network diff --git a/tests/auto/xmlpatterns/stderrBaselines/Passhelp.txt b/tests/auto/xmlpatterns/stderrBaselines/Passhelp.txt index 4e789e7..4a86f75 100644 --- a/tests/auto/xmlpatterns/stderrBaselines/Passhelp.txt +++ b/tests/auto/xmlpatterns/stderrBaselines/Passhelp.txt @@ -1,28 +1,28 @@ xmlpatterns -- A tool for running XQuery queries. - - When appearing, any following options are not + - When appearing, any following options are not interpreted as switches. -help Displays this help. - -initial-template <string> The name of the initial template to call as a + -initial-template <string> The name of the initial template to call as a Clark Name. - -is-uri If specified, all filenames on the command line + -is-uri If specified, all filenames on the command line are interpreted as URIs instead of a local filenames. - -no-format By default output is formatted for readability. + -no-format By default output is formatted for readability. When specified, strict serialization is performed. - -output <local file> A local file to which the output should be + -output <local file> A local file to which the output should be written. The file is overwritten, or if not exist, created. If absent, stdout is used. - -param <name=value> Binds an external variable. The value is + -param <name=value> Binds an external variable. The value is directly available using the variable reference: $name. -version Displays version information. - focus <string> The document to use as focus. Mandatory in case + focus <string> The document to use as focus. Mandatory in case a stylesheet is used. This option is also affected by the is-uris option. - query/stylesheet <string> A local filename pointing to the query to run. + query/stylesheet <string> A local filename pointing to the query to run. If the name ends with .xsl it's assumed to be an XSL-T stylesheet. If it ends with .xq, it's assumed to be an XQuery query. (In other cases diff --git a/tests/auto/xmlpatterns/tst_xmlpatterns.cpp b/tests/auto/xmlpatterns/tst_xmlpatterns.cpp index 3485b8c..9f8de46 100644 --- a/tests/auto/xmlpatterns/tst_xmlpatterns.cpp +++ b/tests/auto/xmlpatterns/tst_xmlpatterns.cpp @@ -107,13 +107,13 @@ tst_XmlPatterns::tst_XmlPatterns() : m_generatedTests(0) , m_dontRun(false) { Q_SET_DEFAULT_IAP - - Q_ASSERT(m_normalizeTestName.isValid()); - Q_ASSERT(m_filenameInStderr.isValid()); } void tst_XmlPatterns::initTestCase() { + QVERIFY(m_normalizeTestName.isValid()); + QVERIFY(m_filenameInStderr.isValid()); + QProcess process; process.start(m_command); @@ -121,7 +121,7 @@ void tst_XmlPatterns::initTestCase() { m_dontRun = true; QEXPECT_FAIL("", "The command line tool is not in the path, most likely because Qt " - "has been partically built, such as only the sub-src rule. No tests will be run.", Abort); + "has been partially built, such as only the sub-src rule. No tests will be run.", Abort); QVERIFY(false); } diff --git a/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro b/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro index 981adab..48c79d5 100644 --- a/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro +++ b/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro @@ -21,7 +21,9 @@ INCLUDEPATH += $$(QTSRCDIR)/tests/auto/xmlpatternssdk \ ../xmlpatternssdk wince*|symbian { - catalog.sources = TestSuite Baseline.xml + catalog.files = TestSuite Baseline.xml catalog.path = . DEPLOYMENT += catalog } + +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro b/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro index f36211e..0fb5fef 100644 --- a/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro +++ b/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro @@ -25,3 +25,5 @@ INCLUDEPATH += $$QT_SOURCE_TREE/tests/auto/xmlpatternssdk/ \ $$QT_SOURCE_TREE/tests/auto/xmlpatternsxqts \ ../xmlpatternsxqts \ ../xmlpatternssdk + +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/xmlpatternsview/xmlpatternsview.pro b/tests/auto/xmlpatternsview/xmlpatternsview.pro index d93cba3..5ab0f0e 100644 --- a/tests/auto/xmlpatternsview/xmlpatternsview.pro +++ b/tests/auto/xmlpatternsview/xmlpatternsview.pro @@ -6,7 +6,7 @@ include (../xmlpatterns.pri) TARGET = tst_xmlpatternsview wince*: { - viewexe.sources = $$QT_BUILD_TREE/xmlpatternsview.exe + viewexe.files = $$QT_BUILD_TREE/xmlpatternsview.exe viewexe.path = . DEPLOYMENT += viewexe } diff --git a/tests/auto/xmlpatternsxqts/tst_suitetest.cpp b/tests/auto/xmlpatternsxqts/tst_suitetest.cpp index 553000e..76b7893 100644 --- a/tests/auto/xmlpatternsxqts/tst_suitetest.cpp +++ b/tests/auto/xmlpatternsxqts/tst_suitetest.cpp @@ -108,7 +108,7 @@ void tst_SuiteTest::runTestSuite() const /* Run the tests, and serialize the result(as according to XQTSResult.xsd) to standard out. */ TestSuiteResult *const result = ts->runSuite(); - Q_ASSERT(result); + QVERIFY(result); QFile out(m_candidateBaseline); QVERIFY(out.open(QIODevice::WriteOnly)); diff --git a/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro b/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro index e81888a..0ced633 100644 --- a/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro +++ b/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro @@ -19,3 +19,5 @@ INCLUDEPATH += $$(QTDIR)/include/QtXmlPatterns/private \ CONFIG += testlib QT += xml TARGET = tst_xmlpatternsxqts + +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro b/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro index 940cc31..44c4754 100644 --- a/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro +++ b/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro @@ -18,7 +18,7 @@ INCLUDEPATH += $$(QTSRCDIR)/tests/auto/xmlpatternssdk \ ../xmlpatternssdk wince*: { - testdata.sources = XSLTS Baseline.xml + testdata.files = XSLTS Baseline.xml testdata.path = . DEPLOYMENT += testdata } |