1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSIGNALSPY_H
#define QSIGNALSPY_H
#include <QtCore/qbytearray.h>
#include <QtCore/qlist.h>
#include <QtCore/qobject.h>
#include <QtCore/qmetaobject.h>
#include <QtTest/qtesteventloop.h>
#include <QtCore/qvariant.h>
#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
class QVariant;
class QSignalSpy: public QObject, public QList<QList<QVariant> >
{
struct ObjectSignal {
const QObject *obj;
QMetaMethod sig;
};
public:
explicit QSignalSpy(const QObject *obj, const char *aSignal)
: QSignalSpy(verify(obj, aSignal)) {}
#ifdef Q_QDOC
template <typename PointerToMemberFunction>
QSignalSpy(const QObject *object, PointerToMemberFunction signal);
#else
template <typename Func>
QSignalSpy(const typename QtPrivate::FunctionPointer<Func>::Object *obj, Func signal0)
: QSignalSpy(verify(obj, QMetaMethod::fromSignal(signal0))) {}
#endif // Q_QDOC
QSignalSpy(const QObject *obj, QMetaMethod signal)
: QSignalSpy(verify(obj, signal)) {}
inline bool isValid() const { return !sig.isEmpty(); }
inline QByteArray signal() const { return sig; }
bool wait(int timeout)
{ return wait(std::chrono::milliseconds{timeout}); }
Q_TESTLIB_EXPORT bool wait(std::chrono::milliseconds timeout = std::chrono::seconds{5});
int qt_metacall(QMetaObject::Call call, int methodId, void **a) override
{
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:
explicit QSignalSpy(ObjectSignal os)
: args(os.obj ? makeArgs(os.sig, os.obj) : QList<int>{})
{
if (!os.obj)
return;
if (!connectToSignal(os.obj, os.sig.methodIndex()))
return;
sig = os.sig.methodSignature();
}
Q_TESTLIB_EXPORT static ObjectSignal verify(const QObject *obj, QMetaMethod signal);
Q_TESTLIB_EXPORT static ObjectSignal verify(const QObject *obj, const char *aSignal);
Q_TESTLIB_EXPORT bool connectToSignal(const QObject *sender, int sigIndex);
Q_TESTLIB_EXPORT static QList<int> makeArgs(const QMetaMethod &member, const QObject *obj);
Q_TESTLIB_EXPORT void appendArgs(void **a);
// the full, normalized signal name
QByteArray sig;
// holds the QMetaType types for the argument list of the signal
const QList<int> args;
QTestEventLoop m_loop;
bool m_waiting = false;
QMutex m_mutex; // protects m_waiting and the QList base class, between appendArgs() and wait()
};
QT_END_NAMESPACE
#endif
|