summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/dbus.pro2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/signalAssignment.2.qml2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/signalParameterTypes.qml8
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/testtypes.h2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp46
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp42
-rw-r--r--tests/auto/gui.pro1
-rw-r--r--tests/auto/qbuttongroup/tst_qbuttongroup.cpp10
-rw-r--r--tests/auto/qdbusabstractadaptor/myobject.h286
-rw-r--r--tests/auto/qdbusabstractadaptor/qdbusabstractadaptor.pro9
-rw-r--r--tests/auto/qdbusabstractadaptor/qmyserver/qmyserver.cpp167
-rw-r--r--tests/auto/qdbusabstractadaptor/qmyserver/qmyserver.pro5
-rw-r--r--tests/auto/qdbusabstractadaptor/test/test.pro7
-rw-r--r--tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp985
-rw-r--r--tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml2
-rw-r--r--tests/auto/qdbusabstractinterface/interface.h1
-rw-r--r--tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro17
-rw-r--r--tests/auto/qdbusabstractinterface/qpinger/qpinger.cpp (renamed from tests/auto/qdbusperformance/server/server.cpp)75
-rw-r--r--tests/auto/qdbusabstractinterface/qpinger/qpinger.pro5
-rw-r--r--tests/auto/qdbusabstractinterface/test/test.pro13
-rw-r--r--tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp573
-rw-r--r--tests/auto/qdbusconnection/tst_qdbusconnection.cpp382
-rw-r--r--tests/auto/qdbusinterface/myobject.h164
-rw-r--r--tests/auto/qdbusinterface/qdbusinterface.pro7
-rw-r--r--tests/auto/qdbusinterface/qmyserver/qmyserver.cpp155
-rw-r--r--tests/auto/qdbusinterface/qmyserver/qmyserver.pro5
-rw-r--r--tests/auto/qdbusinterface/test/test.pro7
-rw-r--r--tests/auto/qdbusinterface/tst_qdbusinterface.cpp629
-rw-r--r--tests/auto/qdbusmarshall/common.h69
-rw-r--r--tests/auto/qdbusmarshall/qdbusmarshall.pro2
-rw-r--r--tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp94
-rw-r--r--tests/auto/qdbusperformance/.gitignore2
-rw-r--r--tests/auto/qdbusperformance/qdbusperformance.pro8
-rw-r--r--tests/auto/qdbusperformance/server/server.pro5
-rw-r--r--tests/auto/qdbusperformance/serverobject.h115
-rw-r--r--tests/auto/qdbusperformance/test/test.pro7
-rw-r--r--tests/auto/qdbusperformance/tst_qdbusperformance.cpp230
-rw-r--r--tests/auto/qdbustype/qdbustype.pro10
-rw-r--r--tests/auto/qdbustype/tst_qdbustype.cpp273
-rw-r--r--tests/auto/qeasingcurve/tst_qeasingcurve.cpp6
-rw-r--r--tests/auto/qglyphs/tst_qglyphs.cpp21
-rw-r--r--tests/auto/qrawfont/qrawfont.pro13
-rw-r--r--tests/auto/qrawfont/testfont.ttfbin0 -> 63212 bytes
-rw-r--r--tests/auto/qrawfont/testfont_bold_italic.ttfbin0 -> 49760 bytes
-rw-r--r--tests/auto/qrawfont/tst_qrawfont.cpp814
-rw-r--r--tests/auto/qsharedpointer/tst_qsharedpointer.cpp4
-rw-r--r--tests/auto/qsslkey/tst_qsslkey.cpp4
-rw-r--r--tests/auto/qstringbuilder1/stringbuilder.cpp3
-rw-r--r--tests/auto/qtextblock/tst_qtextblock.cpp12
-rw-r--r--tests/auto/selftests/tst_selftests.cpp14
-rw-r--r--tests/auto/symbols/tst_symbols.cpp4
52 files changed, 4461 insertions, 858 deletions
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/qdeclarativeecmascript/data/signalAssignment.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/signalAssignment.2.qml
index 8addcb9..6467c42 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/signalAssignment.2.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/signalAssignment.2.qml
@@ -1,5 +1,5 @@
import Qt.test 1.0
MyQmlObject {
- onArgumentSignal: setString('pass ' + a + ' ' + b + ' ' + c)
+ onArgumentSignal: setString('pass ' + a + ' ' + b + ' ' + c + ' ' + d + ' ' + e)
}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/signalParameterTypes.qml b/tests/auto/declarative/qdeclarativeecmascript/data/signalParameterTypes.qml
index ffbe317..4fc2dab 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/signalParameterTypes.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/signalParameterTypes.qml
@@ -7,10 +7,12 @@ MyQmlObject
property real realProperty
property color colorProperty
property variant variantProperty
+ property int enumProperty
+ property int qtEnumProperty
- signal mySignal(int a, real b, color c, variant d)
+ signal mySignal(int a, real b, color c, variant d, int e, int f)
- onMySignal: { intProperty = a; realProperty = b; colorProperty = c; variantProperty = d; }
+ onMySignal: { intProperty = a; realProperty = b; colorProperty = c; variantProperty = d; enumProperty = e; qtEnumProperty = f; }
- onBasicSignal: root.mySignal(10, 19.2, Qt.rgba(1, 1, 0, 1), Qt.rgba(1, 0, 1, 1))
+ onBasicSignal: root.mySignal(10, 19.2, Qt.rgba(1, 1, 0, 1), Qt.rgba(1, 0, 1, 1), MyQmlObject.EnumValue3, Qt.LeftButton)
}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
index 7e63bd5..1d65b15 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
@@ -127,6 +127,8 @@ void registerTypes()
qmlRegisterType<QPlainTextEdit>("Qt.test",1,0,"QPlainTextEdit");
qRegisterMetaType<MyQmlObject::MyType>("MyQmlObject::MyType");
+ qRegisterMetaType<MyQmlObject::MyType>("MyEnum2");
+ qRegisterMetaType<Qt::MouseButtons>("Qt::MouseButtons");
}
#include "testtypes.moc"
diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
index 081cc4c..94cec3f 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
+++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
@@ -159,7 +159,7 @@ public:
signals:
void basicSignal();
- void argumentSignal(int a, QString b, qreal c);
+ void argumentSignal(int a, QString b, qreal c, MyEnum2 d, Qt::MouseButtons e);
void stringChanged();
void objectChanged();
void anotherBasicSignal();
diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
index 48466d5..7876671 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
@@ -304,8 +304,8 @@ void tst_qdeclarativeecmascript::signalAssignment()
MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
QVERIFY(object != 0);
QCOMPARE(object->string(), QString());
- emit object->argumentSignal(19, "Hello world!", 10.25);
- QCOMPARE(object->string(), QString("pass 19 Hello world! 10.25"));
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
+ QCOMPARE(object->string(), QString("pass 19 Hello world! 10.25 3 2"));
}
}
@@ -870,7 +870,7 @@ void tst_qdeclarativeecmascript::scope()
QCOMPARE(object->property("test").toInt(), 0);
QCOMPARE(object->property("test2").toString(), QString());
- emit object->argumentSignal(13, "Argument Scope", 9);
+ emit object->argumentSignal(13, "Argument Scope", 9, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 13);
QCOMPARE(object->property("test2").toString(), QString("Argument Scope"));
@@ -895,6 +895,8 @@ void tst_qdeclarativeecmascript::signalParameterTypes()
QCOMPARE(object->property("realProperty").toReal(), 19.2);
QVERIFY(object->property("colorProperty").value<QColor>() == QColor(255, 255, 0, 255));
QVERIFY(object->property("variantProperty") == QVariant::fromValue(QColor(255, 0, 255, 255)));
+ QVERIFY(object->property("enumProperty") == MyQmlObject::EnumValue3);
+ QVERIFY(object->property("qtEnumProperty") == Qt::LeftButton);
}
/*
@@ -1139,7 +1141,7 @@ void tst_qdeclarativeecmascript::signalTriggeredBindings()
QCOMPARE(object->property("test1").toReal(), 200.);
QCOMPARE(object->property("test2").toReal(), 200.);
- object->argumentSignal(10, QString(), 10);
+ object->argumentSignal(10, QString(), 10, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("base").toReal(), 400.);
QCOMPARE(object->property("test1").toReal(), 400.);
@@ -1940,7 +1942,7 @@ void tst_qdeclarativeecmascript::scriptConnect()
QVERIFY(object != 0);
QCOMPARE(object->property("test").toBool(), false);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toBool(), true);
delete object;
@@ -1953,7 +1955,7 @@ void tst_qdeclarativeecmascript::scriptConnect()
QVERIFY(object != 0);
QCOMPARE(object->property("test").toBool(), false);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toBool(), true);
delete object;
@@ -1966,7 +1968,7 @@ void tst_qdeclarativeecmascript::scriptConnect()
QVERIFY(object != 0);
QCOMPARE(object->property("test").toBool(), false);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toBool(), true);
delete object;
@@ -1979,7 +1981,7 @@ void tst_qdeclarativeecmascript::scriptConnect()
QVERIFY(object != 0);
QCOMPARE(object->methodCalled(), false);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->methodCalled(), true);
delete object;
@@ -1992,7 +1994,7 @@ void tst_qdeclarativeecmascript::scriptConnect()
QVERIFY(object != 0);
QCOMPARE(object->methodCalled(), false);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->methodCalled(), true);
delete object;
@@ -2005,7 +2007,7 @@ void tst_qdeclarativeecmascript::scriptConnect()
QVERIFY(object != 0);
QCOMPARE(object->property("test").toInt(), 0);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 2);
delete object;
@@ -2021,13 +2023,13 @@ void tst_qdeclarativeecmascript::scriptDisconnect()
QVERIFY(object != 0);
QCOMPARE(object->property("test").toInt(), 0);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 1);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 2);
emit object->basicSignal();
QCOMPARE(object->property("test").toInt(), 2);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 2);
delete object;
@@ -2040,13 +2042,13 @@ void tst_qdeclarativeecmascript::scriptDisconnect()
QVERIFY(object != 0);
QCOMPARE(object->property("test").toInt(), 0);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 1);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 2);
emit object->basicSignal();
QCOMPARE(object->property("test").toInt(), 2);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 2);
delete object;
@@ -2059,13 +2061,13 @@ void tst_qdeclarativeecmascript::scriptDisconnect()
QVERIFY(object != 0);
QCOMPARE(object->property("test").toInt(), 0);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 1);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 2);
emit object->basicSignal();
QCOMPARE(object->property("test").toInt(), 2);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 3);
delete object;
@@ -2077,13 +2079,13 @@ void tst_qdeclarativeecmascript::scriptDisconnect()
QVERIFY(object != 0);
QCOMPARE(object->property("test").toInt(), 0);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 1);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 2);
emit object->basicSignal();
QCOMPARE(object->property("test").toInt(), 2);
- emit object->argumentSignal(19, "Hello world!", 10.25);
+ emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->property("test").toInt(), 3);
delete object;
diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
index 45072f3..2f7513f 100644
--- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
+++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
@@ -106,6 +106,7 @@ private slots:
void property_changes_data();
void property_changes_worker();
void property_changes_worker_data();
+ void clear();
};
int tst_qdeclarativelistmodel::roleFromName(const QDeclarativeListModel *model, const QString &roleName)
{
@@ -1091,6 +1092,47 @@ void tst_qdeclarativelistmodel::property_changes_worker_data()
property_changes_data();
}
+void tst_qdeclarativelistmodel::clear()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeListModel model;
+ QDeclarativeEngine::setContextForObject(&model, engine.rootContext());
+ engine.rootContext()->setContextObject(&model);
+
+ QScriptEngine *seng = QDeclarativeEnginePrivate::getScriptEngine(&engine);
+ QScriptValue sv = seng->newObject();
+ QVariant result;
+
+ model.clear();
+ QCOMPARE(model.count(), 0);
+
+ sv.setProperty("propertyA", "value a");
+ sv.setProperty("propertyB", "value b");
+ model.append(sv);
+ QCOMPARE(model.count(), 1);
+
+ model.clear();
+ QCOMPARE(model.count(), 0);
+
+ model.append(sv);
+ model.append(sv);
+ QCOMPARE(model.count(), 2);
+
+ model.clear();
+ QCOMPARE(model.count(), 0);
+
+ // clearing does not remove the roles
+ sv.setProperty("propertyC", "value c");
+ model.append(sv);
+ QList<int> roles = model.roles();
+ model.clear();
+ QCOMPARE(model.count(), 0);
+ QCOMPARE(model.roles(), roles);
+ QCOMPARE(model.toString(roles[0]), QString("propertyA"));
+ QCOMPARE(model.toString(roles[1]), QString("propertyB"));
+ QCOMPARE(model.toString(roles[2]), QString("propertyC"));
+}
+
QTEST_MAIN(tst_qdeclarativelistmodel)
#include "tst_qdeclarativelistmodel.moc"
diff --git a/tests/auto/gui.pro b/tests/auto/gui.pro
index 8dc7b5f..0d77fff 100644
--- a/tests/auto/gui.pro
+++ b/tests/auto/gui.pro
@@ -136,6 +136,7 @@ SUBDIRS=\
qpushbutton \
qquaternion \
qradiobutton \
+ qrawfont \
qregexpvalidator \
qregion \
qscrollarea \
diff --git a/tests/auto/qbuttongroup/tst_qbuttongroup.cpp b/tests/auto/qbuttongroup/tst_qbuttongroup.cpp
index a809101..34be20c 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/qdbusabstractadaptor/myobject.h b/tests/auto/qdbusabstractadaptor/myobject.h
new file mode 100644
index 0000000..7353fa6
--- /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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef 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..238bc38
--- /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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <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 a64b3d2..9250350 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 &parameter)
+{
+ 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 9a14222..62f81af 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/qdbusperformance/server/server.cpp b/tests/auto/qdbusabstractinterface/qpinger/qpinger.cpp
index 3bd5efc..3b605c8 100644
--- a/tests/auto/qdbusperformance/server/server.cpp
+++ b/tests/auto/qdbusabstractinterface/qpinger/qpinger.cpp
@@ -40,16 +40,79 @@
****************************************************************************/
#include <QtCore/QtCore>
#include <QtDBus/QtDBus>
+#include "../interface.h"
-#include "../serverobject.h"
+static const char serviceName[] = "com.trolltech.autotests.qpinger";
+static const char objectPath[] = "/com/trolltech/qpinger";
+//static const char *interfaceName = serviceName;
-static const char serviceName[] = "com.trolltech.autotests.performance";
-static const char objectPath[] = "/";
+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);
@@ -57,8 +120,12 @@ int main(int argc, char *argv[])
if (!con.registerService(serviceName))
exit(2);
- ServerObject obj(objectPath, con);
+ 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 e8ce1f9..6f93d8a 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 8e3a44b..d4a9dab 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..68b8d1a
--- /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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef 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&lt;int&gt;\"/>\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&lt;int&gt;\"/>\n"
+" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QList&lt;int&gt;\"/>\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&lt;int&gt;\"/>\n"
+" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QList&lt;int&gt;\"/>\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..c68f7bf
--- /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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <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 39f0677..04b3d72 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&lt;int&gt;\"/>\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&lt;int&gt;\"/>\n"
-" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QList&lt;int&gt;\"/>\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&lt;int&gt;\"/>\n"
-" <annotation name=\"com.trolltech.QtDBus.QtTypeName.Out0\" value=\"QList&lt;int&gt;\"/>\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 532394a..8f7f3c3 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 9bae6af..737f0cf 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/serverobject.h b/tests/auto/qdbusperformance/serverobject.h
deleted file mode 100644
index 6f85bb4..0000000
--- a/tests/auto/qdbusperformance/serverobject.h
+++ /dev/null
@@ -1,115 +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$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef SERVEROBJECT_H
-#define SERVEROBJECT_H
-
-#include <QObject>
-#include <QtDBus/QtDBus>
-
-class ServerObject: public QObject
-{
- 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);
- }
-
-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)
- {
- 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();
- }
- }
-
- QByteArray echo(const QByteArray &data)
- {
- return data;
- }
- QString echo(const QString &data)
- {
- return data;
- }
- QDBusVariant echo(const QDBusVariant &data)
- {
- return data;
- }
-
- void nothing()
- {
- }
-};
-
-#endif
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 a5b4b98..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$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <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/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..676a904
--- /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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp
index 327b6f3..f10d35b 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/qglyphs/tst_qglyphs.cpp b/tests/auto/qglyphs/tst_qglyphs.cpp
index 1c0aa9e..ffa0d00 100644
--- a/tests/auto/qglyphs/tst_qglyphs.cpp
+++ b/tests/auto/qglyphs/tst_qglyphs.cpp
@@ -52,6 +52,7 @@ class tst_QGlyphs: public QObject
{
Q_OBJECT
+#if !defined(QT_NO_RAWFONT)
private slots:
void initTestCase();
void cleanupTestCase();
@@ -75,8 +76,12 @@ private slots:
private:
int m_testFontId;
QFont m_testFont;
+#endif // QT_NO_RAWFONT
+
};
+#if !defined(QT_NO_RAWFONT)
+
Q_DECLARE_METATYPE(QGlyphs);
void tst_QGlyphs::initTestCase()
@@ -116,7 +121,7 @@ static QGlyphs make_dummy_indexes()
positions.append(QPointF(3, 4));
positions.append(QPointF(5, 6));
- glyphs.setFont(font);
+ glyphs.setFont(QRawFont::fromFont(font));
glyphs.setGlyphIndexes(glyphIndexes);
glyphs.setPositions(positions);
@@ -141,7 +146,7 @@ void tst_QGlyphs::copyConstructor()
positions.append(QPointF(3, 4));
positions.append(QPointF(5, 6));
- glyphs.setFont(font);
+ glyphs.setFont(QRawFont::fromFont(font));
glyphs.setGlyphIndexes(glyphIndexes);
glyphs.setPositions(positions);
}
@@ -180,14 +185,16 @@ void tst_QGlyphs::equalsOperator_data()
positions[2] += QPointF(1, 1);
busted.setPositions(positions);
+
QTest::newRow("Different positions") << one << busted << false;
}
{
QGlyphs busted(two);
- QFont font = busted.font();
- font.setPointSize(font.pointSize() * 2);
- busted.setFont(font);
+
+ QFont font;
+ font.setPixelSize(busted.font().pixelSize() * 2);
+ busted.setFont(QRawFont::fromFont(font));
QTest::newRow("Different fonts") << one << busted << false;
}
@@ -288,7 +295,7 @@ void tst_QGlyphs::drawNonExistentGlyphs()
QGlyphs glyphs;
glyphs.setGlyphIndexes(glyphIndexes);
glyphs.setPositions(glyphPositions);
- glyphs.setFont(m_testFont);
+ glyphs.setFont(QRawFont::fromFont(m_testFont));
QPixmap image(1000, 1000);
image.fill(Qt::white);
@@ -568,6 +575,8 @@ void tst_QGlyphs::drawRightToLeft()
}
+#endif // QT_NO_RAWFONT
+
QTEST_MAIN(tst_QGlyphs)
#include "tst_qglyphs.moc"
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
new file mode 100644
index 0000000..d6042d2
--- /dev/null
+++ b/tests/auto/qrawfont/testfont.ttf
Binary files differ
diff --git a/tests/auto/qrawfont/testfont_bold_italic.ttf b/tests/auto/qrawfont/testfont_bold_italic.ttf
new file mode 100644
index 0000000..9f65ac8
--- /dev/null
+++ b/tests/auto/qrawfont/testfont_bold_italic.ttf
Binary files differ
diff --git a/tests/auto/qrawfont/tst_qrawfont.cpp b/tests/auto/qrawfont/tst_qrawfont.cpp
new file mode 100644
index 0000000..3aa4006
--- /dev/null
+++ b/tests/auto/qrawfont/tst_qrawfont.cpp
@@ -0,0 +1,814 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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();
+#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(), -1);
+ 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<int>("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;
+
+ 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;
+
+ ++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(int, 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);
+ QCOMPARE(QFontInfo(font).family(), familyName);
+
+ QTextLayout layout(QLatin1String("Foobar"));
+ layout.setFont(font);
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QList<QGlyphs> glyphss = layout.glyphs();
+ QCOMPARE(glyphss.size(), 1);
+
+ QGlyphs glyphs = glyphss.at(0);
+
+ QRawFont rawFont = glyphs.font();
+ QVERIFY(rawFont.isValid());
+ QCOMPARE(rawFont.familyName(), familyName);
+ QCOMPARE(rawFont.pixelSize(), 18);
+
+ 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);
+
+ QRawFont rawFont = QRawFont::fromFont(font, writingSystem);
+ QVERIFY(rawFont.isValid());
+ QCOMPARE(rawFont.familyName(), familyName);
+ QCOMPARE(rawFont.pixelSize(), 26);
+
+ 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;
+ int 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;
+ int 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);
+
+ QRawFont rawFont = QRawFont::fromFont(font, QFontDatabase::Any);
+ QCOMPARE(rawFont.familyName(), QString::fromLatin1("QtBidiTestFont"));
+ QCOMPARE(rawFont.pixelSize(), 12);
+
+ rawFont = QRawFont::fromFont(font, QFontDatabase::Hebrew);
+ QCOMPARE(rawFont.familyName(), QString::fromLatin1("QtBidiTestFont"));
+ QCOMPARE(rawFont.pixelSize(), 12);
+
+ QString arabicText = QFontDatabase::writingSystemSample(QFontDatabase::Arabic);
+
+ QTextLayout layout;
+ layout.setFont(font);
+ layout.setText(arabicText);
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QList<QGlyphs> glyphss = layout.glyphs();
+ QCOMPARE(glyphss.size(), 1);
+
+ QGlyphs glyphs = glyphss.at(0);
+ QRawFont layoutFont = glyphs.font();
+ QVERIFY(layoutFont.familyName() != QString::fromLatin1("QtBidiTestFont"));
+ QCOMPARE(layoutFont.pixelSize(), 12);
+
+ rawFont = QRawFont::fromFont(font, QFontDatabase::Arabic);
+ QCOMPARE(rawFont.familyName(), layoutFont.familyName());
+ QCOMPARE(rawFont.pixelSize(), 12);
+
+ fontDatabase.removeApplicationFont(id);
+}
+
+#endif // QT_NO_RAWFONT
+
+QTEST_MAIN(tst_QRawFont)
+#include "tst_qrawfont.moc"
+
diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp
index e7c8175..bb04621 100644
--- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp
+++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp
@@ -698,7 +698,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()
@@ -1747,7 +1747,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
@@ -1761,7 +1760,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/qsslkey/tst_qsslkey.cpp b/tests/auto/qsslkey/tst_qsslkey.cpp
index e7b4740..86da09e 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/qstringbuilder1/stringbuilder.cpp b/tests/auto/qstringbuilder1/stringbuilder.cpp
index 035a1f4..d7a32bf 100644
--- a/tests/auto/qstringbuilder1/stringbuilder.cpp
+++ b/tests/auto/qstringbuilder1/stringbuilder.cpp
@@ -190,9 +190,6 @@ void runScenario()
ba2 = (ba += QLatin1String(LITERAL) + QString::fromUtf8(UTF8_LITERAL));
QCOMPARE(ba2, ba);
QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL));
- ba = UTF8_LITERAL;
- ba += QLatin1String(LITERAL) P withZero;
- QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL + withZero));
#endif
}
diff --git a/tests/auto/qtextblock/tst_qtextblock.cpp b/tests/auto/qtextblock/tst_qtextblock.cpp
index cec3a6a..748d921 100644
--- a/tests/auto/qtextblock/tst_qtextblock.cpp
+++ b/tests/auto/qtextblock/tst_qtextblock.cpp
@@ -76,6 +76,7 @@ private slots:
void excludeParagraphSeparatorFragment();
void backwardsBlockIterator();
void previousBlock_qtbug18026();
+ void removedBlock_qtbug18500();
private:
QTextDocument *doc;
@@ -181,5 +182,16 @@ void tst_QTextBlock::previousBlock_qtbug18026()
QVERIFY(last.isValid());
}
+void tst_QTextBlock::removedBlock_qtbug18500()
+{
+ cursor.insertText("line 1\nline 2\nline 3 \nline 4\n");
+ cursor.setPosition(7);
+ QTextBlock block = cursor.block();
+ cursor.setPosition(21, QTextCursor::KeepAnchor);
+
+ cursor.removeSelectedText();
+ QVERIFY(!block.isValid());
+}
+
QTEST_MAIN(tst_QTextBlock)
#include "tst_qtextblock.moc"
diff --git a/tests/auto/selftests/tst_selftests.cpp b/tests/auto/selftests/tst_selftests.cpp
index 0d27d38..1c01c5f 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 db1cbea..6f21c71 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
}
}