LCOV - code coverage report
Current view: top level - usr/include/x86_64-linux-gnu/qt5/QtTest - qsignalspy.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 44 69 63.8 %
Date: 2016-12-01 18:45:36 Functions: 6 7 85.7 %

          Line data    Source code
       1             : /****************************************************************************
       2             : **
       3             : ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
       4             : ** Contact: http://www.qt-project.org/legal
       5             : **
       6             : ** This file is part of the QtTest module of the Qt Toolkit.
       7             : **
       8             : ** $QT_BEGIN_LICENSE:LGPL$
       9             : ** Commercial License Usage
      10             : ** Licensees holding valid commercial Qt licenses may use this file in
      11             : ** accordance with the commercial license agreement provided with the
      12             : ** Software or, alternatively, in accordance with the terms contained in
      13             : ** a written agreement between you and Digia.  For licensing terms and
      14             : ** conditions see http://qt.digia.com/licensing.  For further information
      15             : ** use the contact form at http://qt.digia.com/contact-us.
      16             : **
      17             : ** GNU Lesser General Public License Usage
      18             : ** Alternatively, this file may be used under the terms of the GNU Lesser
      19             : ** General Public License version 2.1 as published by the Free Software
      20             : ** Foundation and appearing in the file LICENSE.LGPL included in the
      21             : ** packaging of this file.  Please review the following information to
      22             : ** ensure the GNU Lesser General Public License version 2.1 requirements
      23             : ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
      24             : **
      25             : ** In addition, as a special exception, Digia gives you certain additional
      26             : ** rights.  These rights are described in the Digia Qt LGPL Exception
      27             : ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
      28             : **
      29             : ** GNU General Public License Usage
      30             : ** Alternatively, this file may be used under the terms of the GNU
      31             : ** General Public License version 3.0 as published by the Free Software
      32             : ** Foundation and appearing in the file LICENSE.GPL included in the
      33             : ** packaging of this file.  Please review the following information to
      34             : ** ensure the GNU General Public License version 3.0 requirements will be
      35             : ** met: http://www.gnu.org/copyleft/gpl.html.
      36             : **
      37             : **
      38             : ** $QT_END_LICENSE$
      39             : **
      40             : ****************************************************************************/
      41             : 
      42             : #ifndef QSIGNALSPY_H
      43             : #define QSIGNALSPY_H
      44             : 
      45             : #include <QtCore/qbytearray.h>
      46             : #include <QtCore/qlist.h>
      47             : #include <QtCore/qobject.h>
      48             : #include <QtCore/qmetaobject.h>
      49             : #include <QtCore/qvariant.h>
      50             : #include <QtCore/qvector.h>
      51             : #include <QtTest/qtesteventloop.h>
      52             : 
      53             : QT_BEGIN_NAMESPACE
      54             : 
      55             : 
      56             : class QVariant;
      57             : 
      58           4 : class QSignalSpy: public QObject, public QList<QList<QVariant> >
      59             : {
      60             : public:
      61           4 :     explicit QSignalSpy(const QObject *obj, const char *aSignal)
      62           4 :         : m_waiting(false)
      63             :     {
      64             : #ifdef Q_CC_BOR
      65             :         const int memberOffset = QObject::staticMetaObject.methodCount();
      66             : #else
      67           4 :         static const int memberOffset = QObject::staticMetaObject.methodCount();
      68             : #endif
      69           4 :         if (!obj) {
      70           0 :             qWarning("QSignalSpy: Cannot spy on a null object");
      71           0 :             return;
      72             :         }
      73             : 
      74           4 :         if (!aSignal) {
      75           0 :             qWarning("QSignalSpy: Null signal name is not valid");
      76           0 :             return;
      77             :         }
      78             : 
      79           4 :         if (((aSignal[0] - '0') & 0x03) != QSIGNAL_CODE) {
      80           0 :             qWarning("QSignalSpy: Not a valid signal, use the SIGNAL macro");
      81           0 :             return;
      82             :         }
      83             : 
      84           4 :         const QByteArray ba = QMetaObject::normalizedSignature(aSignal + 1);
      85           4 :         const QMetaObject * const mo = obj->metaObject();
      86           4 :         const int sigIndex = mo->indexOfMethod(ba.constData());
      87           4 :         if (sigIndex < 0) {
      88           0 :             qWarning("QSignalSpy: No such signal: '%s'", ba.constData());
      89           0 :             return;
      90             :         }
      91             : 
      92           8 :         if (!QMetaObject::connect(obj, sigIndex, this, memberOffset,
      93           8 :                     Qt::DirectConnection, 0)) {
      94           0 :             qWarning("QSignalSpy: QMetaObject::connect returned false. Unable to connect.");
      95           0 :             return;
      96             :         }
      97           4 :         sig = ba;
      98           4 :         initArgs(mo->method(sigIndex), obj);
      99             :     }
     100             : 
     101             :     inline bool isValid() const { return !sig.isEmpty(); }
     102             :     inline QByteArray signal() const { return sig; }
     103             : 
     104           5 :     bool wait(int timeout = 5000)
     105             :     {
     106           5 :         Q_ASSERT(!m_waiting);
     107           5 :         const int origCount = count();
     108           5 :         m_waiting = true;
     109           5 :         m_loop.enterLoopMSecs(timeout);
     110           5 :         m_waiting = false;
     111           5 :         return count() > origCount;
     112             :     }
     113             : 
     114           5 :     int qt_metacall(QMetaObject::Call call, int methodId, void **a) Q_DECL_OVERRIDE
     115             :     {
     116           5 :         methodId = QObject::qt_metacall(call, methodId, a);
     117           5 :         if (methodId < 0)
     118           0 :             return methodId;
     119             : 
     120           5 :         if (call == QMetaObject::InvokeMetaMethod) {
     121           5 :             if (methodId == 0) {
     122           5 :                 appendArgs(a);
     123             :             }
     124           5 :             --methodId;
     125             :         }
     126           5 :         return methodId;
     127             :     }
     128             : 
     129             : private:
     130             :     void initArgs(const QMetaMethod &member)
     131             :     {
     132             :         initArgs(member, 0);
     133             :     }
     134             : 
     135           4 :     void initArgs(const QMetaMethod &member, const QObject *obj)
     136             :     {
     137           4 :         const QList<QByteArray> params = member.parameterTypes();
     138           4 :         args.reserve(params.size());
     139           4 :         for (int i = 0; i < params.count(); ++i) {
     140           0 :             int tp = QMetaType::type(params.at(i).constData());
     141           0 :             if (tp == QMetaType::UnknownType && obj) {
     142           0 :                 void *argv[] = { &tp, &i };
     143             :                 QMetaObject::metacall(const_cast<QObject*>(obj),
     144             :                                       QMetaObject::RegisterMethodArgumentMetaType,
     145           0 :                                       member.methodIndex(), argv);
     146           0 :                 if (tp == -1)
     147           0 :                     tp = QMetaType::UnknownType;
     148             :             }
     149           0 :             if (tp == QMetaType::UnknownType) {
     150           0 :                 Q_ASSERT(tp != QMetaType::Void); // void parameter => metaobject is corrupt
     151             :                 qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.",
     152           0 :                          params.at(i).constData());
     153             :             }
     154           0 :             args << tp;
     155           4 :         }
     156           4 :     }
     157             : 
     158           5 :     void appendArgs(void **a)
     159             :     {
     160           5 :         QList<QVariant> list;
     161           5 :         list.reserve(args.count());
     162           5 :         for (int i = 0; i < args.count(); ++i) {
     163           0 :             const QMetaType::Type type = static_cast<QMetaType::Type>(args.at(i));
     164           0 :             if (type == QMetaType::QVariant)
     165           0 :                 list << *reinterpret_cast<QVariant *>(a[i + 1]);
     166             :             else
     167           0 :                 list << QVariant(type, a[i + 1]);
     168             :         }
     169           5 :         append(list);
     170             : 
     171           5 :         if (m_waiting)
     172           5 :             m_loop.exitLoop();
     173           5 :     }
     174             : 
     175             :     // the full, normalized signal name
     176             :     QByteArray sig;
     177             :     // holds the QMetaType types for the argument list of the signal
     178             :     QVector<int> args;
     179             : 
     180             :     QTestEventLoop m_loop;
     181             :     bool m_waiting;
     182             : };
     183             : 
     184             : QT_END_NAMESPACE
     185             : 
     186             : #endif

Generated by: LCOV version 1.11