summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2012-05-30 14:02:55 +0200
committerQt by Nokia <qt-info@nokia.com>2012-06-01 16:04:04 +0200
commit37db43f1c2515002c4ab4493a954d3e8fdd20363 (patch)
treee2c95f696978495495fcaf4e37ea454434a04e3d /tests/auto
parent4189d07c837e66f4cda92820477f5fb0e3d9315c (diff)
Add private API for working with meta-methods in signal index range
Internally, QObject and QMetaObject already leave out non-signal methods when working with signals. This is possible because the signals always come before other types of meta-method in the meta-object data. Ignoring irrelevant methods is faster and can save memory. QMetaObject provides internal indexed-based connect() and disconnect() functions. However, these functions currently take an absolute method index as the signal specifier, instead of an absolute _signal_ index. Hence, QMetaObject and friends must convert from the method index range to the signal index range. By providing an API that only considers signal indices, clients of the index-based QMetaObject::connect()/disconnect() can provide the proper signal index directly. Similarly, for the qtdeclarative integration (QDeclarativeData hooks) the signal index can be passed directly. This will eliminate most of the conversions back and forth between signal index and method index, and some other redundant work done by qtdeclarative's custom connection implementation. There are some places where the behavior can't be changed; for example, QObject::senderSignalIndex() will still need to return an index in the method range, since that function is public API. Changing QMetaObject::connect()/disconnect() to take an index in the signal range will be done in a separate commit; this commit is only an enabler for porting existing usage of those functions to the new behavior. Change-Id: Icb475b6bbdccc74b4e7ee5bf72b944b47159cebd Reviewed-by: Olivier Goffart <ogoffart@woboq.com> Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro2
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp137
2 files changed, 138 insertions, 1 deletions
diff --git a/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro b/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro
index b92c8036b5..a28b8a8d38 100644
--- a/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro
+++ b/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro
@@ -1,5 +1,5 @@
CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qmetaobject
-QT = core gui widgets testlib
+QT = core-private gui widgets testlib
SOURCES = tst_qmetaobject.cpp
diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
index 5cf28b5141..78ca386822 100644
--- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
+++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
@@ -44,6 +44,9 @@
#include <qobject.h>
#include <qmetaobject.h>
#include <qlabel.h>
+#include <private/qmetaobject_p.h>
+
+Q_DECLARE_METATYPE(const QMetaObject *)
struct MyStruct
{
@@ -173,6 +176,15 @@ private slots:
void indexOfMethodPMF();
+ void signalOffset_data();
+ void signalOffset();
+ void signalCount_data();
+ void signalCount();
+ void signal_data();
+ void signal();
+ void signalIndex_data();
+ void signalIndex();
+
signals:
void value6Changed();
void value7Changed(const QString &);
@@ -1151,5 +1163,130 @@ void tst_QMetaObject::indexOfMethodPMF()
INDEXOFMETHODPMF_HELPER(QtTestCustomObject, sig_custom, (const CustomString &))
}
+namespace SignalTestHelper
+{
+// These functions use the public QMetaObject/QMetaMethod API to implement
+// the functionality of the internal API, and are used to check the results.
+
+static int signalCount(const QMetaObject *mo)
+{
+ int n = 0;
+ for (int i = 0; i < mo->methodCount(); ++i) {
+ QMetaMethod mm = mo->method(i);
+ if (mm.methodType() == QMetaMethod::Signal)
+ ++n;
+ }
+ return n;
+}
+
+static int signalOffset(const QMetaObject *mo)
+{
+ return mo->superClass() ? signalCount(mo->superClass()) : 0;
+}
+
+static QMetaMethod signal(const QMetaObject *mo, int index)
+{
+ int k = 0;
+ for (int i = 0; i < mo->methodCount(); ++i) {
+ QMetaMethod mm = mo->method(i);
+ if (mm.methodType() != QMetaMethod::Signal)
+ continue;
+ if (k == index)
+ return mm;
+ ++k;
+ }
+ return QMetaMethod();
+}
+
+static int signalIndex(const QMetaMethod &mm)
+{
+ int k = mm.methodIndex();
+ const QMetaObject *mo = mm.enclosingMetaObject();
+ for (int i = 0; i < mm.methodIndex(); ++i) {
+ if (mo->method(i).methodType() != QMetaMethod::Signal)
+ --k;
+ }
+ return k;
+}
+
+} // namespace SignalTestHelper
+
+void tst_QMetaObject::signalOffset_data()
+{
+ QTest::addColumn<const QMetaObject *>("metaObject");
+
+ QTest::newRow("QObject") << &QObject::staticMetaObject;
+ QTest::newRow("tst_QMetaObject") << &tst_QMetaObject::staticMetaObject;
+ QTest::newRow("QtTestObject") << &QtTestObject::staticMetaObject;
+}
+
+void tst_QMetaObject::signalOffset()
+{
+ QFETCH(const QMetaObject *, metaObject);
+ QCOMPARE(QMetaObjectPrivate::signalOffset(metaObject),
+ SignalTestHelper::signalOffset(metaObject));
+}
+
+void tst_QMetaObject::signalCount_data()
+{
+ signalOffset_data();
+}
+
+void tst_QMetaObject::signalCount()
+{
+ QFETCH(const QMetaObject *, metaObject);
+ QCOMPARE(QMetaObjectPrivate::absoluteSignalCount(metaObject),
+ SignalTestHelper::signalCount(metaObject));
+}
+
+void tst_QMetaObject::signal_data()
+{
+ QTest::addColumn<const QMetaObject *>("metaObject");
+ QTest::addColumn<int>("index");
+
+ struct SignalTestDataHelper
+ {
+ static void addSignals(const QMetaObject *mo)
+ {
+ int count = SignalTestHelper::signalCount(mo);
+ for (int i = 0; i < count; ++i) {
+ QMetaMethod mm = SignalTestHelper::signal(mo, i);
+ QByteArray tag(mo->className());
+ tag.append("::");
+ tag.append(mm.methodSignature());
+ QTest::newRow(tag.constData()) << mo << i;
+ }
+ }
+ };
+
+ SignalTestDataHelper::addSignals(&QObject::staticMetaObject);
+ SignalTestDataHelper::addSignals(&tst_QMetaObject::staticMetaObject);
+ SignalTestDataHelper::addSignals(&QtTestObject::staticMetaObject);
+}
+
+void tst_QMetaObject::signal()
+{
+ QFETCH(const QMetaObject *, metaObject);
+ QFETCH(int, index);
+
+ QCOMPARE(QMetaObjectPrivate::signal(metaObject, index),
+ SignalTestHelper::signal(metaObject, index));
+}
+
+void tst_QMetaObject::signalIndex_data()
+{
+ signal_data();
+}
+
+void tst_QMetaObject::signalIndex()
+{
+ QFETCH(const QMetaObject *, metaObject);
+ QFETCH(int, index);
+
+ QMetaMethod mm = SignalTestHelper::signal(metaObject, index);
+ QCOMPARE(QMetaObjectPrivate::signalIndex(mm),
+ SignalTestHelper::signalIndex(mm));
+}
+
QTEST_MAIN(tst_QMetaObject)
#include "tst_qmetaobject.moc"