From 6cc6bbcdfa94760157e7d989f519fe008cfe4d81 Mon Sep 17 00:00:00 2001 From: hensels Date: Mon, 8 May 2023 12:07:45 +0200 Subject: [PATCH] chore: update class interfaces to support Qt5 and Qt6 while dropping support for Qt4 all tests checked against RabbitMQ 3.11.13 with Erlang 25.3 with following kits: Qt 5.6.3 32Bit MSVC2017 Qt 5.15.2 32Bit Clang 15.0.1 Qt 5.15.2 32,64Bit MSVC2019 Qt 5.15.2 32Bit MSVC2022 Qt 6.5.0 64Bit MinGW 11.2.0 Qt 6.5.0 64Bit MSVC2019 Qt 6.5.0 64Bit MSVC2022 --- .travis.yml | 2 +- README.md | 12 +- qamqp.pri | 4 +- src/qamqpclient.cpp | 37 +-- src/qamqpclient.h | 2 +- src/qamqpexchange.h | 8 +- src/qamqpframe.cpp | 11 +- src/qamqpglobal.h | 4 +- src/qamqpmessage.cpp | 7 - src/qamqpmessage.h | 15 -- src/qamqpqueue.h | 253 ++++++++++----------- src/qamqptable.cpp | 1 + src/src.pro | 16 +- tests/auto/qamqpclient/tst_qamqpclient.cpp | 6 +- tests/auto/qamqpqueue/tst_qamqpqueue.cpp | 17 +- tests/common/signalspy.h | 123 ---------- 16 files changed, 202 insertions(+), 316 deletions(-) diff --git a/.travis.yml b/.travis.yml index ee641ec..f4324d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ language: cpp cache: apt env: - - QT_SELECT=qt4 - QT_SELECT=qt5 + - QT_SELECT=qt6 services: - rabbitmq before_install: diff --git a/README.md b/README.md index 426a315..530fac8 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ QAMQP ============= -A Qt4/Qt5 implementation of AMQP 0.9.1, focusing primarily on RabbitMQ support. +A Qt5/Qt6 implementation of AMQP 0.9.1, focusing primarily on RabbitMQ support. Usage ------------ @@ -16,8 +16,16 @@ Usage Documentation ------------ -Coming soon! +Tests checked and integrated against rabbitmq 3.11 (August 1, 2022) +Qt5.6.3 (MSVC2017) 32Bit +Qt5.15.2 (MSVC2019, MSVC2022, MinGW, Clang) 32 and 64Bit +Qt6.5 (MSVC2019, MSVC2022) 64Bit +A good starting point is: +* running a local RabbitMQ, +* browse to http://localhost:15672/#/queues (guest/guest) +* Start the "receive" sample and see in your browser the "hello" queue appear +* publish a message there AMQP Support ------------ diff --git a/qamqp.pri b/qamqp.pri index 0e7a383..01de98b 100644 --- a/qamqp.pri +++ b/qamqp.pri @@ -1,4 +1,4 @@ -QAMQP_VERSION = 0.5.0 +QAMQP_VERSION = 0.6.0 isEmpty(QAMQP_LIBRARY_TYPE) { QAMQP_LIBRARY_TYPE = shared @@ -7,6 +7,7 @@ isEmpty(QAMQP_LIBRARY_TYPE) { QT += network QAMQP_INCLUDEPATH = $${PWD}/src QAMQP_LIBS = -lqamqp + CONFIG(debug, debug|release){ QAMQP_LIBS = -lqamqpd } @@ -14,7 +15,6 @@ contains(QAMQP_LIBRARY_TYPE, staticlib) { DEFINES += QAMQP_STATIC } else { DEFINES += QAMQP_SHARED - win32:QAMQP_LIBS = -lqamqp0 } isEmpty(PREFIX) { diff --git a/src/qamqpclient.cpp b/src/qamqpclient.cpp index 41a0a17..2b26464 100644 --- a/src/qamqpclient.cpp +++ b/src/qamqpclient.cpp @@ -62,10 +62,25 @@ void QAmqpClientPrivate::initSocket() QObject::connect(socket, SIGNAL(connected()), q, SLOT(_q_socketConnected())); QObject::connect(socket, SIGNAL(disconnected()), q, SLOT(_q_socketDisconnected())); QObject::connect(socket, SIGNAL(readyRead()), q, SLOT(_q_readyRead())); - QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), - q, SLOT(_q_socketError(QAbstractSocket::SocketError))); - QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), - q, SIGNAL(socketError(QAbstractSocket::SocketError))); +#if QT_VERSION >= 0x060000 + QObject::connect(socket, + SIGNAL(errorOccurred(QAbstractSocket::SocketError)), + q, + SLOT(_q_socketError(QAbstractSocket::SocketError))); + QObject::connect(socket, + SIGNAL(errorOccurred(QAbstractSocket::SocketError)), + q, + SIGNAL(socketErrorOccurred(QAbstractSocket::SocketError))); +#else + QObject::connect(socket, + SIGNAL(error(QAbstractSocket::SocketError)), + q, + SLOT(_q_socketError(QAbstractSocket::SocketError))); + QObject::connect(socket, + SIGNAL(error(QAbstractSocket::SocketError)), + q, + SIGNAL(socketErrorOccurred(QAbstractSocket::SocketError))); +#endif QObject::connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), q, SIGNAL(socketStateChanged(QAbstractSocket::SocketState))); QObject::connect(socket, SIGNAL(sslErrors(QList)), @@ -107,11 +122,7 @@ void QAmqpClientPrivate::setPassword(const QString &password) void QAmqpClientPrivate::parseConnectionString(const QString &uri) { -#if QT_VERSION > 0x040801 QUrl connectionString = QUrl::fromUserInput(uri); -#else - QUrl connectionString(uri, QUrl::TolerantMode); -#endif if (connectionString.scheme() != AMQP_SCHEME && connectionString.scheme() != AMQP_SSL_SCHEME) { @@ -126,15 +137,9 @@ void QAmqpClientPrivate::parseConnectionString(const QString &uri) QString vhost = connectionString.path(); if (vhost.startsWith("/") && vhost.size() > 1) vhost = vhost.mid(1); -#if QT_VERSION <= 0x050200 - virtualHost = QUrl::fromPercentEncoding(vhost.toUtf8()); - setPassword(QUrl::fromPercentEncoding(connectionString.password().toUtf8())); - setUsername(QUrl::fromPercentEncoding(connectionString.userName().toUtf8())); -#else virtualHost = vhost; setPassword(connectionString.password()); setUsername(connectionString.userName()); -#endif } void QAmqpClientPrivate::_q_connect() @@ -531,7 +536,11 @@ void QAmqpClientPrivate::startOk() clientProperties["version"] = QString(QAMQP_VERSION); clientProperties["platform"] = QString("Qt %1").arg(qVersion()); clientProperties["product"] = QString("QAMQP"); +#if QT_VERSION >= 0x060000 + clientProperties.insert(customProperties); +#else clientProperties.unite(customProperties); +#endif stream << clientProperties; authenticator->write(stream); diff --git a/src/qamqpclient.h b/src/qamqpclient.h index 8b2aa86..62c6cc4 100644 --- a/src/qamqpclient.h +++ b/src/qamqpclient.h @@ -115,7 +115,7 @@ Q_SIGNALS: void disconnected(); void heartbeat(); void error(QAMQP::Error error); - void socketError(QAbstractSocket::SocketError error); + void socketErrorOccurred(QAbstractSocket::SocketError error); void socketStateChanged(QAbstractSocket::SocketState state); void sslErrors(const QList &errors); diff --git a/src/qamqpexchange.h b/src/qamqpexchange.h index da16aff..8247913 100644 --- a/src/qamqpexchange.h +++ b/src/qamqpexchange.h @@ -31,7 +31,6 @@ class QAMQP_EXPORT QAmqpExchange : public QAmqpChannel Q_OBJECT Q_PROPERTY(QString type READ type CONSTANT) Q_PROPERTY(ExchangeOptions options READ options CONSTANT) - Q_ENUMS(ExchangeOptions) public: virtual ~QAmqpExchange(); @@ -68,6 +67,7 @@ public: }; Q_DECLARE_FLAGS(ExchangeOptions, ExchangeOption) ExchangeOptions options() const; + Q_ENUM(ExchangeOptions) bool isDeclared() const; @@ -83,11 +83,11 @@ Q_SIGNALS: public Q_SLOTS: // AMQP Exchange - void declare(ExchangeType type = Direct, - ExchangeOptions options = NoOptions, + void declare(QAmqpExchange::ExchangeType type = Direct, + QAmqpExchange::ExchangeOptions options = NoOptions, const QAmqpTable &args = QAmqpTable()); void declare(const QString &type, - ExchangeOptions options = NoOptions, + QAmqpExchange::ExchangeOptions options = NoOptions, const QAmqpTable &args = QAmqpTable()); void remove(int options = roIfUnused|roNoWait); diff --git a/src/qamqpframe.cpp b/src/qamqpframe.cpp index 2c4bf10..13cdf5c 100644 --- a/src/qamqpframe.cpp +++ b/src/qamqpframe.cpp @@ -1,6 +1,7 @@ #include -#include #include +#include +#include #include "qamqptable.h" #include "qamqpglobal.h" @@ -208,7 +209,11 @@ QVariant QAmqpFrame::readAmqpField(QDataStream &s, QAmqpMetaType::ValueType type { qulonglong tmp_value; s >> tmp_value; +#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) + return QDateTime::fromSecsSinceEpoch(tmp_value); +#else return QDateTime::fromTime_t(tmp_value); +#endif } case QAmqpMetaType::Hash: { @@ -262,7 +267,11 @@ void QAmqpFrame::writeAmqpField(QDataStream &s, QAmqpMetaType::ValueType type, c } break; case QAmqpMetaType::Timestamp: +#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) + s << qulonglong(value.toDateTime().toSecsSinceEpoch()); +#else s << qulonglong(value.toDateTime().toTime_t()); +#endif break; case QAmqpMetaType::Hash: { diff --git a/src/qamqpglobal.h b/src/qamqpglobal.h index 138e8c8..54abf52 100644 --- a/src/qamqpglobal.h +++ b/src/qamqpglobal.h @@ -47,7 +47,7 @@ #define AMQP_BASIC_APP_ID_FLAG (1 << 3) #define AMQP_BASIC_CLUSTER_ID_FLAG (1 << 2) -#define QAMQP_VERSION "0.5.0" +#define QAMQP_VERSION "0.6.0" #define AMQP_CONNECTION_FORCED 320 @@ -61,7 +61,7 @@ # define QAMQP_EXPORT #endif -#define qAmqpDebug if (qgetenv("QAMQP_DEBUG").isEmpty()); else qDebug +#define qAmqpDebug if (qEnvironmentVariableIsEmpty("QAMQP_DEBUG")); else qDebug namespace QAmqpMetaType { diff --git a/src/qamqpmessage.cpp b/src/qamqpmessage.cpp index c9d6349..82a1432 100644 --- a/src/qamqpmessage.cpp +++ b/src/qamqpmessage.cpp @@ -113,13 +113,6 @@ QHash QAmqpMessage::headers() const return d->headers; } -#if QT_VERSION < 0x050000 -bool QAmqpMessage::isDetached() const -{ - return d && d->ref == 1; -} -#endif - uint qHash(const QAmqpMessage &message, uint seed) { Q_UNUSED(seed); diff --git a/src/qamqpmessage.h b/src/qamqpmessage.h index 43350ac..74960a5 100644 --- a/src/qamqpmessage.h +++ b/src/qamqpmessage.h @@ -34,9 +34,7 @@ public: QAmqpMessage &operator=(const QAmqpMessage &other); ~QAmqpMessage(); -#if QT_VERSION >= 0x050000 inline void swap(QAmqpMessage &other) { qSwap(d, other.d); } -#endif bool operator==(const QAmqpMessage &message) const; inline bool operator!=(const QAmqpMessage &message) const { return !(operator==(message)); } @@ -80,22 +78,9 @@ private: QSharedDataPointer d; friend class QAmqpQueuePrivate; friend class QAmqpQueue; - -#if QT_VERSION < 0x050000 -public: - typedef QSharedDataPointer DataPtr; - inline DataPtr &data_ptr() { return d; } - - // internal - bool isDetached() const; -#endif }; Q_DECLARE_METATYPE(QAmqpMessage::PropertyHash) - -#if QT_VERSION < 0x050000 -Q_DECLARE_TYPEINFO(QAmqpMessage, Q_MOVABLE_TYPE); -#endif Q_DECLARE_SHARED(QAmqpMessage) // NOTE: needed only for MSVC support, don't depend on this hash diff --git a/src/qamqpqueue.h b/src/qamqpqueue.h index 324030c..b8a8dc6 100644 --- a/src/qamqpqueue.h +++ b/src/qamqpqueue.h @@ -1,127 +1,126 @@ -/* - * Copyright (C) 2012-2014 Alexey Shcherbakov - * Copyright (C) 2014-2015 Matt Broadstone - * Contact: https://github.com/mbroadst/qamqp - * - * This file is part of the QAMQP Library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -#ifndef QAMQPQUEUE_H -#define QAMQPQUEUE_H - -#include - -#include "qamqpchannel.h" -#include "qamqpmessage.h" -#include "qamqpglobal.h" -#include "qamqptable.h" - -class QAmqpClient; -class QAmqpClientPrivate; -class QAmqpExchange; -class QAmqpQueuePrivate; -class QAMQP_EXPORT QAmqpQueue : public QAmqpChannel, public QQueue -{ - Q_OBJECT - Q_ENUMS(QueueOptions) - Q_PROPERTY(int options READ options CONSTANT) - Q_PROPERTY(QString consumerTag READ consumerTag WRITE setConsumerTag) - Q_ENUMS(QueueOption) - Q_ENUMS(ConsumeOption) - Q_ENUMS(RemoveOption) - -public: - enum QueueOption { - NoOptions = 0x0, - Passive = 0x01, - Durable = 0x02, - Exclusive = 0x04, - AutoDelete = 0x08, - NoWait = 0x10 - }; - Q_DECLARE_FLAGS(QueueOptions, QueueOption) - int options() const; - - enum ConsumeOption { - coNoLocal = 0x01, - coNoAck = 0x02, - coExclusive = 0x04, - coNoWait = 0x08 - }; - Q_DECLARE_FLAGS(ConsumeOptions, ConsumeOption) - - enum RemoveOption { - roForce = 0x0, - roIfUnused = 0x01, - roIfEmpty = 0x02, - roNoWait = 0x04 - }; - Q_DECLARE_FLAGS(RemoveOptions, RemoveOption) - - ~QAmqpQueue(); - - bool isConsuming() const; - bool isDeclared() const; - - void setConsumerTag(const QString &consumerTag); - QString consumerTag() const; - - qint32 messageCount() const; - qint32 consumerCount() const; - -Q_SIGNALS: - void declared(); - void bound(); - void unbound(); - void removed(); - void purged(int messageCount); - - void messageReceived(); - void empty(); - void consuming(const QString &consumerTag); - void cancelled(const QString &consumerTag); - -public Q_SLOTS: - // AMQP Queue - void declare(int options = Durable|AutoDelete, const QAmqpTable &arguments = QAmqpTable()); - void bind(const QString &exchangeName, const QString &key); - void bind(QAmqpExchange *exchange, const QString &key); - void unbind(const QString &exchangeName, const QString &key); - void unbind(QAmqpExchange *exchange, const QString &key); - void purge(); - void remove(int options = roIfUnused|roIfEmpty|roNoWait); - - // AMQP Basic - bool consume(int options = NoOptions); - void get(bool noAck = true); - bool cancel(bool noWait = false); - void ack(const QAmqpMessage &message); - void ack(qlonglong deliveryTag, bool multiple); - void reject(const QAmqpMessage &message, bool requeue); - void reject(qlonglong deliveryTag, bool requeue); - -protected: - // reimp Channel - virtual void channelOpened(); - virtual void channelClosed(); - -private: - explicit QAmqpQueue(int channelNumber = -1, QAmqpClient *parent = 0); - - Q_DISABLE_COPY(QAmqpQueue) - Q_DECLARE_PRIVATE(QAmqpQueue) - friend class QAmqpClient; - friend class QAmqpClientPrivate; - -}; - -#endif // QAMQPQUEUE_H +/* + * Copyright (C) 2012-2014 Alexey Shcherbakov + * Copyright (C) 2014-2015 Matt Broadstone + * Contact: https://github.com/mbroadst/qamqp + * + * This file is part of the QAMQP Library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +#ifndef QAMQPQUEUE_H +#define QAMQPQUEUE_H + +#include + +#include "qamqpchannel.h" +#include "qamqpmessage.h" +#include "qamqpglobal.h" +#include "qamqptable.h" + +class QAmqpClient; +class QAmqpClientPrivate; +class QAmqpExchange; +class QAmqpQueuePrivate; +class QAMQP_EXPORT QAmqpQueue : public QAmqpChannel, public QQueue +{ + Q_OBJECT + Q_PROPERTY(int options READ options CONSTANT) + Q_PROPERTY(QString consumerTag READ consumerTag WRITE setConsumerTag) + +public: + enum QueueOption { + NoOptions = 0x0, + Passive = 0x01, + Durable = 0x02, + Exclusive = 0x04, + AutoDelete = 0x08, + NoWait = 0x10 + }; + Q_DECLARE_FLAGS(QueueOptions, QueueOption) + Q_ENUM(QueueOption) + Q_ENUM(QueueOptions) int options() const; + + enum ConsumeOption { + coNoLocal = 0x01, + coNoAck = 0x02, + coExclusive = 0x04, + coNoWait = 0x08 + }; + Q_DECLARE_FLAGS(ConsumeOptions, ConsumeOption) + Q_ENUM(ConsumeOption) + + enum RemoveOption { + roForce = 0x0, + roIfUnused = 0x01, + roIfEmpty = 0x02, + roNoWait = 0x04 + }; + Q_DECLARE_FLAGS(RemoveOptions, RemoveOption) + Q_ENUM(RemoveOption) + + ~QAmqpQueue(); + + bool isConsuming() const; + bool isDeclared() const; + + void setConsumerTag(const QString &consumerTag); + QString consumerTag() const; + + qint32 messageCount() const; + qint32 consumerCount() const; + +Q_SIGNALS: + void declared(); + void bound(); + void unbound(); + void removed(); + void purged(int messageCount); + + void messageReceived(); + void empty(); + void consuming(const QString &consumerTag); + void cancelled(const QString &consumerTag); + +public Q_SLOTS: + // AMQP Queue + void declare(int options = Durable|AutoDelete, const QAmqpTable &arguments = QAmqpTable()); + void bind(const QString &exchangeName, const QString &key); + void bind(QAmqpExchange *exchange, const QString &key); + void unbind(const QString &exchangeName, const QString &key); + void unbind(QAmqpExchange *exchange, const QString &key); + void purge(); + void remove(int options = roIfUnused|roIfEmpty|roNoWait); + + // AMQP Basic + bool consume(int options = NoOptions); + void get(bool noAck = true); + bool cancel(bool noWait = false); + void ack(const QAmqpMessage &message); + void ack(qlonglong deliveryTag, bool multiple); + void reject(const QAmqpMessage &message, bool requeue); + void reject(qlonglong deliveryTag, bool requeue); + +protected: + // reimp Channel + virtual void channelOpened(); + virtual void channelClosed(); + +private: + explicit QAmqpQueue(int channelNumber = -1, QAmqpClient *parent = 0); + + Q_DISABLE_COPY(QAmqpQueue) + Q_DECLARE_PRIVATE(QAmqpQueue) + friend class QAmqpClient; + friend class QAmqpClientPrivate; + +}; + +#endif // QAMQPQUEUE_H diff --git a/src/qamqptable.cpp b/src/qamqptable.cpp index 6a63873..3ec9470 100644 --- a/src/qamqptable.cpp +++ b/src/qamqptable.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "qamqpframe_p.h" #include "qamqptable.h" diff --git a/src/src.pro b/src/src.pro index 6795364..34f91ae 100644 --- a/src/src.pro +++ b/src/src.pro @@ -64,16 +64,12 @@ HEADERS += \ $${INSTALL_HEADERS} \ $${PRIVATE_HEADERS} -SOURCES += \ - qamqpauthenticator.cpp \ - qamqpchannel.cpp \ - qamqpchannelhash.cpp \ - qamqpclient.cpp \ - qamqpexchange.cpp \ - qamqpframe.cpp \ - qamqpmessage.cpp \ - qamqpqueue.cpp \ - qamqptable.cpp +SOURCES += $$files($$PWD/*.cpp) + +DISTFILES += \ + ../.travis.yml \ + ../LICENSE \ + ../README.md # install headers.files = $${INSTALL_HEADERS} diff --git a/tests/auto/qamqpclient/tst_qamqpclient.cpp b/tests/auto/qamqpclient/tst_qamqpclient.cpp index 67ccf6f..9dc76c8 100644 --- a/tests/auto/qamqpclient/tst_qamqpclient.cpp +++ b/tests/auto/qamqpclient/tst_qamqpclient.cpp @@ -179,7 +179,7 @@ void tst_QAMQPClient::tune() client.connectToHost(); QVERIFY(waitForSignal(&client, SIGNAL(connected()))); - QCOMPARE((int)client.channelMax(), 15); + QCOMPARE((int) client.channelMax(), 2047); QCOMPARE((int)client.heartbeatDelay(), 600); QCOMPARE((int)client.frameMax(), 5000); @@ -191,7 +191,7 @@ void tst_QAMQPClient::socketError() { QAmqpClient client; client.connectToHost("amqp://127.0.0.1:56725/"); - QVERIFY(waitForSignal(&client, SIGNAL(socketError(QAbstractSocket::SocketError)))); + QVERIFY(waitForSignal(&client, SIGNAL(socketErrorOccurred(QAbstractSocket::SocketError)))); QCOMPARE(client.socketError(), QAbstractSocket::ConnectionRefusedError); } @@ -208,10 +208,8 @@ void tst_QAMQPClient::validateUri_data() << "guest" << "guest" << "192.168.1.10" << quint16(5672) << "/"; QTest::newRow("standard") << "amqp://user:pass@host:10000/vhost" << "user" << "pass" << "host" << quint16(10000) << "vhost"; -#if QT_VERSION >= 0x040806 QTest::newRow("urlencoded") << "amqp://user%61:%61pass@ho%61st:10000/v%2fhost" << "usera" << "apass" << "hoast" << quint16(10000) << "v/host"; -#endif QTest::newRow("empty") << "amqp://" << "" << "" << "" << quint16(AMQP_PORT) << ""; QTest::newRow("empty2") << "amqp://:@/" << "" << "" << "" << quint16(AMQP_PORT) << "/"; QTest::newRow("onlyuser") << "amqp://user@" << "user" << "" << "" << quint16(AMQP_PORT) << ""; diff --git a/tests/auto/qamqpqueue/tst_qamqpqueue.cpp b/tests/auto/qamqpqueue/tst_qamqpqueue.cpp index 2cdfc1a..e61c3a4 100644 --- a/tests/auto/qamqpqueue/tst_qamqpqueue.cpp +++ b/tests/auto/qamqpqueue/tst_qamqpqueue.cpp @@ -356,7 +356,7 @@ void tst_QAMQPQueue::canOnlyStartConsumingOnce() void tst_QAMQPQueue::ensureConsumeOnlySentOnce() { QAmqpQueue *queue = client->createQueue("test-single-consumer"); - SignalSpy spy(queue, SIGNAL(consuming(QString))); + QSignalSpy spy(queue, SIGNAL(consuming(QString))); queue->declare(); QVERIFY(waitForSignal(queue, SIGNAL(declared()))); @@ -601,8 +601,13 @@ void tst_QAMQPQueue::tableFieldDataTypes() QCOMPARE(message.header("double").toDouble(), double(FLT_MAX)); QCOMPARE(message.header("short-string").toString(), QLatin1String("test")); QCOMPARE(message.header("long-string").toString(), QLatin1String("test")); - QCOMPARE(message.header("timestamp").toDateTime().toTime_t(), timestamp.toTime_t()); QCOMPARE(message.header("bytes").toByteArray(), QByteArray("abcdefg1234567")); +#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) + QCOMPARE(message.header("timestamp").toDateTime().toSecsSinceEpoch(), + timestamp.toSecsSinceEpoch()); +#else + QCOMPARE(message.header("timestamp").toDateTime().toTime_t(), timestamp.toTime_t()); +#endif QVERIFY(message.hasHeader("nested-table")); QAmqpTable compareTable(message.header("nested-table").toHash()); @@ -654,11 +659,17 @@ void tst_QAMQPQueue::messageProperties() QCOMPARE(message.property(QAmqpMessage::ReplyTo).toString(), QLatin1String("another-queue")); QCOMPARE(message.property(QAmqpMessage::MessageId).toString(), QLatin1String("some-message-id")); QCOMPARE(message.property(QAmqpMessage::Expiration).toString(), QLatin1String("60000")); - QCOMPARE(message.property(QAmqpMessage::Timestamp).toDateTime().toTime_t(), timestamp.toTime_t()); QCOMPARE(message.property(QAmqpMessage::Type).toString(), QLatin1String("some-message-type")); QCOMPARE(message.property(QAmqpMessage::UserId).toString(), QLatin1String("guest")); QCOMPARE(message.property(QAmqpMessage::AppId).toString(), QLatin1String("some-app-id")); QCOMPARE(message.property(QAmqpMessage::ClusterID).toString(), QLatin1String("some-cluster-id")); +#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) + QCOMPARE(message.property(QAmqpMessage::Timestamp).toDateTime().toSecsSinceEpoch(), + timestamp.toSecsSinceEpoch()); +#else + QCOMPARE(message.property(QAmqpMessage::Timestamp).toDateTime().toTime_t(), + timestamp.toTime_t()); +#endif } void tst_QAMQPQueue::emptyMessage() diff --git a/tests/common/signalspy.h b/tests/common/signalspy.h index eaa1698..ae81728 100644 --- a/tests/common/signalspy.h +++ b/tests/common/signalspy.h @@ -17,127 +17,4 @@ bool waitForSignal(QObject *obj, const char *signal, int delay) } // namespace Test } // namespace QAMQP - - - -#if QT_VERSION >= 0x050000 -typedef QSignalSpy SignalSpy; -#else -#include -#include -#include -#include -#include -#include -#include - -class QVariant; -class SignalSpy: public QObject, public QList > -{ -public: - explicit SignalSpy(const QObject *obj, const char *aSignal) - : m_waiting(false) - { - static const int memberOffset = QObject::staticMetaObject.methodCount(); - if (!obj) { - qWarning("SignalSpy: Cannot spy on a null object"); - return; - } - - if (!aSignal) { - qWarning("SignalSpy: Null signal name is not valid"); - return; - } - - if (((aSignal[0] - '0') & 0x03) != QSIGNAL_CODE) { - qWarning("SignalSpy: Not a valid signal, use the SIGNAL macro"); - return; - } - - const QByteArray ba = QMetaObject::normalizedSignature(aSignal + 1); - const QMetaObject * const mo = obj->metaObject(); - const int sigIndex = mo->indexOfMethod(ba.constData()); - if (sigIndex < 0) { - qWarning("SignalSpy: No such signal: '%s'", ba.constData()); - return; - } - - if (!QMetaObject::connect(obj, sigIndex, this, memberOffset, - Qt::DirectConnection, 0)) { - qWarning("SignalSpy: QMetaObject::connect returned false. Unable to connect."); - return; - } - sig = ba; - initArgs(mo->method(sigIndex), obj); - } - - inline bool isValid() const { return !sig.isEmpty(); } - inline QByteArray signal() const { return sig; } - - bool wait(int timeout = 5) - { - Q_ASSERT(!m_waiting); - const int origCount = count(); - m_waiting = true; - m_loop.enterLoop(timeout); - m_waiting = false; - return count() > origCount; - } - - int qt_metacall(QMetaObject::Call call, int methodId, void **a) - { - methodId = QObject::qt_metacall(call, methodId, a); - if (methodId < 0) - return methodId; - - if (call == QMetaObject::InvokeMetaMethod) { - if (methodId == 0) { - appendArgs(a); - } - --methodId; - } - return methodId; - } - -private: - void initArgs(const QMetaMethod &member) - { - initArgs(member, 0); - } - - void initArgs(const QMetaMethod &member, const QObject *obj) - { - Q_UNUSED(obj) - QList params = member.parameterTypes(); - for (int i = 0; i < params.count(); ++i) { - int tp = QMetaType::type(params.at(i).constData()); - if (tp == QMetaType::Void) - qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.", - params.at(i).constData()); - args << tp; - } - } - - void appendArgs(void **a) - { - QList list; - for (int i = 0; i < args.count(); ++i) { - QMetaType::Type type = static_cast(args.at(i)); - list << QVariant(type, a[i + 1]); - } - append(list); - - if (m_waiting) - m_loop.exitLoop(); - } - - // the full, normalized signal name - QByteArray sig; - // holds the QMetaType types for the argument list of the signal - QVector args; - - QTestEventLoop m_loop; - bool m_waiting; -}; -#endif #endif