--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/auto/moc/tst_moc.cpp Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,1216 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 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 <stdio.h>
+#include <qobject.h>
+
+#include "using-namespaces.h"
+#include "assign-namespace.h"
+#include "no-keywords.h"
+#include "single_function_keyword.h"
+#include "backslash-newlines.h"
+#include "slots-with-void-template.h"
+#include "pure-virtual-signals.h"
+#include "qinvokable.h"
+// msvc and friends crap out on it
+#if !defined(Q_CC_GNU) || defined(Q_OS_IRIX) || defined(Q_OS_WIN)
+#define SKIP_NEWLINE_TEST
+#endif
+#if !defined(SKIP_NEWLINE_TEST)
+#include "os9-newlines.h"
+// msvc and friends crap out on this file too,
+// it seems to contain Mac 9 EOLs, and not windows EOLs.
+#include "win-newlines.h"
+#endif
+#include "escapes-in-string-literals.h"
+#include "cstyle-enums.h"
+
+
+#if defined(PARSE_BOOST)
+#include "parse-boost.h"
+#endif
+
+// No such thing as "long long" in Microsoft's compiler 13.0 and before
+#if defined Q_CC_MSVC && _MSC_VER <= 1310
+# define NOLONGLONG
+#endif
+
+QT_USE_NAMESPACE
+
+struct MyStruct {};
+struct MyStruct2 {};
+
+struct SuperClass {};
+
+// Try to avoid inserting for instance a comment with a quote between the following line and the Q_OBJECT
+// That will make the test give a false positive.
+const char* test_multiple_number_of_escapes = "\\\"";
+namespace MyNamespace
+{
+ class TestSuperClass : public QObject
+ {
+ Q_OBJECT
+ public:
+ inline TestSuperClass() {}
+ };
+}
+
+namespace String
+{
+ typedef QString Type;
+}
+
+namespace Int
+{
+ typedef int Type;
+}
+
+typedef struct {
+ int doNotConfuseMoc;
+} OldStyleCStruct;
+
+class Sender : public QObject
+{
+ Q_OBJECT
+
+public:
+ void sendValue(const String::Type& value)
+ {
+ emit send(value);
+ }
+ void sendValue(const Int::Type& value)
+ {
+ emit send(value);
+ }
+
+signals:
+ void send(const String::Type&);
+ void send(const Int::Type&);
+};
+
+class Receiver : public QObject
+{
+ Q_OBJECT
+public:
+ Receiver() : stringCallCount(0), intCallCount(0) {}
+
+ int stringCallCount;
+ int intCallCount;
+
+public slots:
+ void receive(const String::Type&) { stringCallCount++; }
+ void receive(const Int::Type&) { intCallCount++; }
+};
+
+#define MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES
+
+#define DONT_CONFUSE_MOC(klass) klass
+#define DONT_CONFUSE_MOC_EVEN_MORE(klass, dummy, dummy2) klass
+
+Q_DECLARE_METATYPE(MyStruct)
+Q_DECLARE_METATYPE(MyStruct*)
+
+namespace myNS {
+ struct Points
+ {
+ Points() : p1(0xBEEF), p2(0xBABE) { }
+ int p1, p2;
+ };
+}
+
+Q_DECLARE_METATYPE(myNS::Points)
+
+class TestClassinfoWithEscapes: public QObject
+{
+ Q_OBJECT
+ Q_CLASSINFO("escaped", "\"bar\"")
+ Q_CLASSINFO("\"escaped\"", "foo")
+public slots:
+ void slotWithAReallyLongName(int)
+ { }
+};
+
+struct ForwardDeclaredStruct;
+
+struct StructQObject : public QObject
+{
+ Q_OBJECT
+public:
+ void foo(struct ForwardDeclaredStruct *);
+};
+
+void StructQObject::foo(struct ForwardDeclaredStruct *)
+{
+ struct Inner {
+ bool field;
+ };
+
+ struct Inner unusedVariable;
+}
+
+class TestClass : public MyNamespace::TestSuperClass, public DONT_CONFUSE_MOC(MyStruct),
+ public DONT_CONFUSE_MOC_EVEN_MORE(MyStruct2, dummy, ignored)
+{
+ Q_OBJECT
+ Q_CLASSINFO("help", QT_TR_NOOP("Opening this will let you configure something"))
+ Q_PROPERTY(short int shortIntProperty READ shortIntProperty)
+ Q_PROPERTY(unsigned short int unsignedShortIntProperty READ unsignedShortIntProperty)
+ Q_PROPERTY(signed short int signedShortIntProperty READ signedShortIntProperty)
+ Q_PROPERTY(long int longIntProperty READ longIntProperty)
+ Q_PROPERTY(unsigned long int unsignedLongIntProperty READ unsignedLongIntProperty)
+ Q_PROPERTY(signed long int signedLongIntProperty READ signedLongIntProperty)
+ Q_PROPERTY(long double longDoubleProperty READ longDoubleProperty)
+ Q_PROPERTY(myNS::Points points READ points WRITE setPoints)
+
+ Q_CLASSINFO("Multi"
+ "line",
+ ""
+ "This is a "
+ "multiline Q_CLASSINFO"
+ "")
+
+ // a really really long string that we have to cut into pieces in the generated stringdata
+ // table, otherwise msvc craps out
+ Q_CLASSINFO("D-Bus Introspection", ""
+" <interface name=\"org.kde.KCookieServer\" >\n"
+" <method name=\"findCookies\" >\n"
+" <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
+" <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
+" <arg direction=\"out\" type=\"s\" name=\"cookies\" />\n"
+" </method>\n"
+" <method name=\"findDomains\" >\n"
+" <arg direction=\"out\" type=\"as\" name=\"domains\" />\n"
+" </method>\n"
+" <method name=\"findCookies\" >\n"
+" <arg direction=\"in\" type=\"ai\" name=\"fields\" />\n"
+" <arg direction=\"in\" type=\"s\" name=\"domain\" />\n"
+" <arg direction=\"in\" type=\"s\" name=\"fqdn\" />\n"
+" <arg direction=\"in\" type=\"s\" name=\"path\" />\n"
+" <arg direction=\"in\" type=\"s\" name=\"name\" />\n"
+" <arg direction=\"out\" type=\"as\" name=\"cookies\" />\n"
+" <annotation value=\"QList<int>\" name=\"com.trolltech.QtDBus.QtTypeName.In0\" />\n"
+" </method>\n"
+" <method name=\"findDOMCookies\" >\n"
+" <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
+" <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
+" <arg direction=\"out\" type=\"s\" name=\"cookies\" />\n"
+" </method>\n"
+" <method name=\"addCookies\" >\n"
+" <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
+" <arg direction=\"in\" type=\"ay\" name=\"cookieHeader\" />\n"
+" <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
+" </method>\n"
+" <method name=\"deleteCookie\" >\n"
+" <arg direction=\"in\" type=\"s\" name=\"domain\" />\n"
+" <arg direction=\"in\" type=\"s\" name=\"fqdn\" />\n"
+" <arg direction=\"in\" type=\"s\" name=\"path\" />\n"
+" <arg direction=\"in\" type=\"s\" name=\"name\" />\n"
+" </method>\n"
+" <method name=\"deleteCookiesFromDomain\" >\n"
+" <arg direction=\"in\" type=\"s\" name=\"domain\" />\n"
+" </method>\n"
+" <method name=\"deleteSessionCookies\" >\n"
+" <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
+" </method>\n"
+" <method name=\"deleteSessionCookiesFor\" >\n"
+" <arg direction=\"in\" type=\"s\" name=\"fqdn\" />\n"
+" <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
+" </method>\n"
+" <method name=\"deleteAllCookies\" />\n"
+" <method name=\"addDOMCookies\" >\n"
+" <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
+" <arg direction=\"in\" type=\"ay\" name=\"cookieHeader\" />\n"
+" <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
+" </method>\n"
+" <method name=\"setDomainAdvice\" >\n"
+" <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
+" <arg direction=\"in\" type=\"s\" name=\"advice\" />\n"
+" </method>\n"
+" <method name=\"getDomainAdvice\" >\n"
+" <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
+" <arg direction=\"out\" type=\"s\" name=\"advice\" />\n"
+" </method>\n"
+" <method name=\"reloadPolicy\" />\n"
+" <method name=\"shutdown\" />\n"
+" </interface>\n"
+ "")
+
+public:
+ inline TestClass() {}
+
+private slots:
+ inline void dummy1() MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES {}
+ inline void dummy2() MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES const {}
+ inline void dummy3() const MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES {}
+
+#ifndef NOLONGLONG
+ void slotWithULongLong(unsigned long long) {}
+ void slotWithULongLongP(unsigned long long*) {}
+ void slotWithULong(unsigned long) {}
+ void slotWithLongLong(long long) {}
+ void slotWithLong(long) {}
+#endif
+
+ void slotWithColonColonType(::Int::Type) {}
+
+ TestClass &slotWithReferenceReturnType() { return *this; }
+
+#if (0 && 1) || 1
+ void expressionEvaluationShortcut1() {}
+#endif
+#if (1 || 0) && 0
+#else
+ void expressionEvaluationShortcut2() {}
+#endif
+
+public slots:
+ void slotWithArray(const double[3]) {}
+ void slotWithNamedArray(const double namedArray[3]) {}
+ void slotWithMultiArray(const double[3][4]) {}
+
+ short int shortIntProperty() { return 0; }
+ unsigned short int unsignedShortIntProperty() { return 0; }
+ signed short int signedShortIntProperty() { return 0; }
+ long int longIntProperty() { return 0; }
+ unsigned long int unsignedLongIntProperty() { return 0; }
+ signed long int signedLongIntProperty() { return 0; }
+ long double longDoubleProperty() { return 0.0; }
+
+ myNS::Points points() { return m_points; }
+ void setPoints(myNS::Points points) { m_points = points; }
+
+signals:
+ void signalWithArray(const double[3]);
+ void signalWithNamedArray(const double namedArray[3]);
+
+private slots:
+ // for tst_Moc::preprocessorConditionals
+#if 0
+ void invalidSlot() {}
+#else
+ void slotInElse() {}
+#endif
+
+#if 1
+ void slotInIf() {}
+#else
+ void invalidSlot() {}
+#endif
+
+#if 0
+ void invalidSlot() {}
+#elif 0
+#else
+ void slotInLastElse() {}
+#endif
+
+#if 0
+ void invalidSlot() {}
+#elif 1
+ void slotInElif() {}
+#else
+ void invalidSlot() {}
+#endif
+
+
+ friend class Receiver; // task #85783
+signals:
+ friend class Sender; // task #85783
+
+public slots:
+ void const slotWithSillyConst() {}
+
+public:
+ Q_INVOKABLE void const slotWithSillyConst2() {}
+
+ // that one however should be fine
+public slots:
+ void slotWithVoidStar(void *) {}
+
+private:
+ myNS::Points m_points;
+
+private slots:
+ inline virtual void blub1() {}
+ virtual inline void blub2() {}
+};
+
+class PropertyTestClass : public QObject
+{
+ Q_OBJECT
+public:
+
+ enum TestEnum { One, Two, Three };
+
+ Q_ENUMS(TestEnum)
+};
+
+class PropertyUseClass : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(PropertyTestClass::TestEnum foo READ foo)
+public:
+
+ inline PropertyTestClass::TestEnum foo() const { return PropertyTestClass::One; }
+};
+
+#if defined(Q_MOC_RUN)
+// Task #119503
+#define _TASK_119503
+#if !_TASK_119503
+#endif
+#endif
+
+static QString srcify(const char *path)
+{
+#ifndef Q_OS_IRIX
+ return QString(SRCDIR) + QLatin1Char('/') + QLatin1String(path);
+#else
+ return QString(QLatin1String(path));
+#endif
+}
+
+class CtorTestClass : public QObject
+{
+ Q_OBJECT
+public:
+ Q_INVOKABLE CtorTestClass(QObject *parent = 0);
+
+ CtorTestClass(int foo);
+
+ inline Q_INVOKABLE CtorTestClass(const QString &str)
+ { m_str = str; }
+
+ QString m_str;
+
+protected:
+ CtorTestClass(int foo, int bar, int baz);
+private:
+ CtorTestClass(float, float) {}
+};
+
+CtorTestClass::CtorTestClass(QObject *parent)
+ : QObject(parent) {}
+
+CtorTestClass::CtorTestClass(int, int, int) {}
+
+
+class tst_Moc : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool user1 READ user1 USER true )
+ Q_PROPERTY(bool user2 READ user2 USER false)
+ Q_PROPERTY(bool user3 READ user3 USER userFunction())
+
+public:
+ inline tst_Moc() {}
+
+private slots:
+ void initTestCase();
+
+ void slotWithException() throw(MyStruct);
+ void dontStripNamespaces();
+ void oldStyleCasts();
+ void warnOnExtraSignalSlotQualifiaction();
+ void uLongLong();
+ void inputFileNameWithDotsButNoExtension();
+ void userProperties();
+ void supportConstSignals();
+ void task87883();
+ void multilineComments();
+ void classinfoWithEscapes();
+ void trNoopInClassInfo();
+ void ppExpressionEvaluation();
+ void arrayArguments();
+ void preprocessorConditionals();
+ void blackslashNewlines();
+ void slotWithSillyConst();
+ void testExtraData();
+ void namespaceTypeProperty();
+ void slotsWithVoidTemplate();
+ void structQObject();
+ void namespacedFlags();
+ void warnOnMultipleInheritance();
+ void forgottenQInterface();
+ void os9Newline();
+ void winNewline();
+ void escapesInStringLiterals();
+ void frameworkSearchPath();
+ void cstyleEnums();
+ void defineMacroViaCmdline();
+ void invokable();
+ void singleFunctionKeywordSignalAndSlot();
+ void templateGtGt();
+ void qprivateslots();
+ void inlineSlotsWithThrowDeclaration();
+ void warnOnPropertyWithoutREAD();
+ void constructors();
+ void typenameWithUnsigned();
+ void warnOnVirtualSignal();
+
+signals:
+ void sigWithUnsignedArg(unsigned foo);
+ void sigWithSignedArg(signed foo);
+ void sigWithConstSignedArg(const signed foo);
+ void sigWithVolatileConstSignedArg(volatile const signed foo);
+ void sigWithCustomType(const MyStruct);
+ void constSignal1() const;
+ void constSignal2(int arg) const;
+
+private:
+ bool user1() { return true; };
+ bool user2() { return false; };
+ bool user3() { return false; };
+ bool userFunction(){ return false; };
+
+private:
+ QString qtIncludePath;
+};
+
+void tst_Moc::initTestCase()
+{
+#if defined(Q_OS_UNIX) && !defined(QT_NO_PROCESS)
+ QProcess proc;
+ proc.start("qmake", QStringList() << "-query" << "QT_INSTALL_HEADERS");
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(proc.exitCode(), 0);
+ QByteArray output = proc.readAllStandardOutput();
+ QVERIFY(!output.isEmpty());
+ QCOMPARE(proc.readAllStandardError(), QByteArray());
+ qtIncludePath = QString::fromLocal8Bit(output).trimmed();
+ QFileInfo fi(qtIncludePath);
+ QVERIFY(fi.exists());
+ QVERIFY(fi.isDir());
+#endif
+}
+
+void tst_Moc::slotWithException() throw(MyStruct)
+{
+ // be happy
+ QVERIFY(true);
+}
+
+void tst_Moc::dontStripNamespaces()
+{
+ Sender sender;
+ Receiver receiver;
+
+ connect(&sender, SIGNAL(send(const String::Type &)),
+ &receiver, SLOT(receive(const String::Type &)));
+ connect(&sender, SIGNAL(send(const Int::Type &)),
+ &receiver, SLOT(receive(const Int::Type &)));
+
+ sender.sendValue(String::Type("Hello"));
+ QCOMPARE(receiver.stringCallCount, 1);
+ QCOMPARE(receiver.intCallCount, 0);
+ sender.sendValue(Int::Type(42));
+ QCOMPARE(receiver.stringCallCount, 1);
+ QCOMPARE(receiver.intCallCount, 1);
+}
+
+
+void tst_Moc::oldStyleCasts()
+{
+#ifdef MOC_CROSS_COMPILED
+ QSKIP("Not tested when cross-compiled", SkipAll);
+#endif
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
+ QProcess proc;
+ proc.start("moc", QStringList(srcify("/oldstyle-casts.h")));
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(proc.exitCode(), 0);
+ QByteArray mocOut = proc.readAllStandardOutput();
+ QVERIFY(!mocOut.isEmpty());
+ QCOMPARE(proc.readAllStandardError(), QByteArray());
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "."
+ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+ proc.closeWriteChannel();
+
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(proc.exitCode(), 0);
+ QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString());
+#else
+ QSKIP("Only tested on linux/gcc", SkipAll);
+#endif
+}
+
+void tst_Moc::warnOnExtraSignalSlotQualifiaction()
+{
+#ifdef MOC_CROSS_COMPILED
+ QSKIP("Not tested when cross-compiled", SkipAll);
+#endif
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
+ QProcess proc;
+ proc.start("moc", QStringList(srcify("extraqualification.h")));
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(proc.exitCode(), 0);
+ QByteArray mocOut = proc.readAllStandardOutput();
+ QVERIFY(!mocOut.isEmpty());
+ QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
+ QCOMPARE(mocWarning, QString(SRCDIR) +
+ QString("/extraqualification.h:53: Warning: Function declaration Test::badFunctionDeclaration contains extra qualification. Ignoring as signal or slot.\n") +
+ QString(SRCDIR) + QString("/extraqualification.h:56: Warning: parsemaybe: Function declaration Test::anotherOne contains extra qualification. Ignoring as signal or slot.\n"));
+#else
+ QSKIP("Only tested on linux/gcc", SkipAll);
+#endif
+}
+
+void tst_Moc::uLongLong()
+{
+#ifndef NOLONGLONG
+ TestClass tst;
+ const QMetaObject *mobj = tst.metaObject();
+ int idx = mobj->indexOfSlot("slotWithULong(ulong)");
+ QVERIFY(idx != -1);
+ idx = mobj->indexOfSlot("slotWithULongLong(unsigned long long)");
+ QVERIFY(idx != -1);
+ idx = mobj->indexOfSlot("slotWithULongLongP(unsigned long long*)");
+ QVERIFY(idx != -1);
+
+ idx = mobj->indexOfSlot("slotWithLong(long)");
+ QVERIFY(idx != -1);
+ idx = mobj->indexOfSlot("slotWithLongLong(long long)");
+ QVERIFY(idx != -1);
+#else
+ QSKIP("long long doesn't work on MSVC6 & .NET 2002, also skipped on 2003 due to compiler version issue with moc", SkipAll);
+#endif
+}
+
+void tst_Moc::inputFileNameWithDotsButNoExtension()
+{
+#ifdef MOC_CROSS_COMPILED
+ QSKIP("Not tested when cross-compiled", SkipAll);
+#endif
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
+ QProcess proc;
+ proc.setWorkingDirectory(QString(SRCDIR) + "/task71021");
+ proc.start("moc", QStringList("../Header"));
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(proc.exitCode(), 0);
+ QByteArray mocOut = proc.readAllStandardOutput();
+ QVERIFY(!mocOut.isEmpty());
+ QCOMPARE(proc.readAllStandardError(), QByteArray());
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << ".."
+ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+ proc.closeWriteChannel();
+
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString());
+ QCOMPARE(proc.exitCode(), 0);
+#else
+ QSKIP("Only tested on linux/gcc", SkipAll);
+#endif
+}
+
+void tst_Moc::userProperties()
+{
+ const QMetaObject *mobj = metaObject();
+ QMetaProperty property = mobj->property(mobj->indexOfProperty("user1"));
+ QVERIFY(property.isValid());
+ QVERIFY(property.isUser());
+
+ property = mobj->property(mobj->indexOfProperty("user2"));
+ QVERIFY(property.isValid());
+ QVERIFY(!property.isUser());
+
+ property = mobj->property(mobj->indexOfProperty("user3"));
+ QVERIFY(property.isValid());
+ QVERIFY(!property.isUser(this));
+}
+
+void tst_Moc::supportConstSignals()
+{
+ QSignalSpy spy1(this, SIGNAL(constSignal1()));
+ QVERIFY(spy1.isEmpty());
+ emit constSignal1();
+ QCOMPARE(spy1.count(), 1);
+
+ QSignalSpy spy2(this, SIGNAL(constSignal2(int)));
+ QVERIFY(spy2.isEmpty());
+ emit constSignal2(42);
+ QCOMPARE(spy2.count(), 1);
+ QCOMPARE(spy2.at(0).at(0).toInt(), 42);
+}
+
+#include "task87883.h"
+
+void tst_Moc::task87883()
+{
+ QVERIFY(Task87883::staticMetaObject.className());
+}
+
+#include "c-comments.h"
+
+void tst_Moc::multilineComments()
+{
+ QVERIFY(IfdefedClass::staticMetaObject.className());
+}
+
+void tst_Moc::classinfoWithEscapes()
+{
+ const QMetaObject *mobj = &TestClassinfoWithEscapes::staticMetaObject;
+ QCOMPARE(mobj->methodCount() - mobj->methodOffset(), 1);
+
+ QMetaMethod mm = mobj->method(mobj->methodOffset());
+ QCOMPARE(mm.signature(), "slotWithAReallyLongName(int)");
+}
+
+void tst_Moc::trNoopInClassInfo()
+{
+ TestClass t;
+ const QMetaObject *mobj = t.metaObject();
+ QVERIFY(mobj);
+ QCOMPARE(mobj->classInfoCount(), 3);
+ QCOMPARE(mobj->indexOfClassInfo("help"), 0);
+ QCOMPARE(QString(mobj->classInfo(0).value()), QString("Opening this will let you configure something"));
+}
+
+void tst_Moc::ppExpressionEvaluation()
+{
+ TestClass tst;
+ const QMetaObject *mobj = tst.metaObject();
+ int idx = mobj->indexOfSlot("expressionEvaluationShortcut1()");
+ QVERIFY(idx != -1);
+
+ idx = mobj->indexOfSlot("expressionEvaluationShortcut2()");
+ QVERIFY(idx != -1);
+}
+
+void tst_Moc::arrayArguments()
+{
+ TestClass tst;
+ const QMetaObject *mobj = tst.metaObject();
+ QVERIFY(mobj->indexOfSlot("slotWithArray(const double[3])") != -1);
+ QVERIFY(mobj->indexOfSlot("slotWithNamedArray(const double[3])") != -1);
+ QVERIFY(mobj->indexOfSlot("slotWithMultiArray(const double[3][4])") != -1);
+ QVERIFY(mobj->indexOfSignal("signalWithArray(const double[3])") != -1);
+ QVERIFY(mobj->indexOfSignal("signalWithNamedArray(const double[3])") != -1);
+}
+
+void tst_Moc::preprocessorConditionals()
+{
+ TestClass tst;
+ const QMetaObject *mobj = tst.metaObject();
+ QVERIFY(mobj->indexOfSlot("slotInElse()") != -1);
+ QVERIFY(mobj->indexOfSlot("slotInIf()") != -1);
+ QVERIFY(mobj->indexOfSlot("slotInLastElse()") != -1);
+ QVERIFY(mobj->indexOfSlot("slotInElif()") != -1);
+}
+
+void tst_Moc::blackslashNewlines()
+{
+ BackslashNewlines tst;
+ const QMetaObject *mobj = tst.metaObject();
+ QVERIFY(mobj->indexOfSlot("works()") != -1);
+ QVERIFY(mobj->indexOfSlot("buggy()") == -1);
+}
+
+void tst_Moc::slotWithSillyConst()
+{
+ TestClass tst;
+ const QMetaObject *mobj = tst.metaObject();
+ QVERIFY(mobj->indexOfSlot("slotWithSillyConst()") != -1);
+ QVERIFY(mobj->indexOfMethod("slotWithSillyConst2()") != -1);
+ QVERIFY(mobj->indexOfSlot("slotWithVoidStar(void*)") != -1);
+}
+
+void tst_Moc::testExtraData()
+{
+ const QMetaObject *mobj = &PropertyTestClass::staticMetaObject;
+ QCOMPARE(mobj->enumeratorCount(), 1);
+ QCOMPARE(QByteArray(mobj->enumerator(0).name()), QByteArray("TestEnum"));
+
+ mobj = &PropertyUseClass::staticMetaObject;
+ const int idx = mobj->indexOfProperty("foo");
+ QVERIFY(idx != -1);
+ const QMetaProperty prop = mobj->property(idx);
+ QVERIFY(prop.isValid());
+ QVERIFY(prop.isEnumType());
+ const QMetaEnum en = prop.enumerator();
+ QCOMPARE(QByteArray(en.name()), QByteArray("TestEnum"));
+}
+
+void tst_Moc::namespaceTypeProperty()
+{
+ qRegisterMetaType<myNS::Points>("myNS::Points");
+ TestClass tst;
+ QByteArray ba = QByteArray("points");
+ QVariant v = tst.property(ba);
+ QVERIFY(v.isValid());
+ myNS::Points p = qVariantValue<myNS::Points>(v);
+ QCOMPARE(p.p1, 0xBEEF);
+ QCOMPARE(p.p2, 0xBABE);
+ p.p1 = 0xCAFE;
+ p.p2 = 0x1EE7;
+ QVERIFY(tst.setProperty(ba, qVariantFromValue(p)));
+ myNS::Points pp = qVariantValue<myNS::Points>(tst.property(ba));
+ QCOMPARE(p.p1, pp.p1);
+ QCOMPARE(p.p2, pp.p2);
+}
+
+void tst_Moc::slotsWithVoidTemplate()
+{
+ SlotsWithVoidTemplateTest test;
+ QVERIFY(QObject::connect(&test, SIGNAL(myVoidSignal(void)),
+ &test, SLOT(dummySlot(void))));
+ QVERIFY(QObject::connect(&test, SIGNAL(mySignal(const TestTemplate<void> &)),
+ &test, SLOT(anotherSlot(const TestTemplate<void> &))));
+}
+
+void tst_Moc::structQObject()
+{
+ StructQObject o;
+ QCOMPARE(QByteArray(o.metaObject()->className()), QByteArray("StructQObject"));
+}
+
+#include "namespaced-flags.h"
+
+void tst_Moc::namespacedFlags()
+{
+ Foo::Baz baz;
+ Foo::Bar bar;
+
+ bar.setFlags(Foo::Bar::Read | Foo::Bar::Write);
+ QVERIFY(baz.flags() != bar.flags());
+
+ const QVariant v = bar.property("flags");
+ QVERIFY(v.isValid());
+ QVERIFY(baz.setProperty("flags", v));
+ QVERIFY(baz.flags() == bar.flags());
+}
+
+void tst_Moc::warnOnMultipleInheritance()
+{
+#ifdef MOC_CROSS_COMPILED
+ QSKIP("Not tested when cross-compiled", SkipAll);
+#endif
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
+ QProcess proc;
+ QStringList args;
+ args << "-I" << qtIncludePath + "/QtGui"
+ << srcify("warn-on-multiple-qobject-subclasses.h");
+ proc.start("moc", args);
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(proc.exitCode(), 0);
+ QByteArray mocOut = proc.readAllStandardOutput();
+ QVERIFY(!mocOut.isEmpty());
+ QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
+ QCOMPARE(mocWarning, QString(SRCDIR) +
+ QString("/warn-on-multiple-qobject-subclasses.h:53: Warning: Class Bar inherits from two QObject subclasses QWidget and Foo. This is not supported!\n"));
+#else
+ QSKIP("Only tested on linux/gcc", SkipAll);
+#endif
+}
+
+void tst_Moc::forgottenQInterface()
+{
+#ifdef MOC_CROSS_COMPILED
+ QSKIP("Not tested when cross-compiled", SkipAll);
+#endif
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
+ QProcess proc;
+ QStringList args;
+ args << "-I" << qtIncludePath + "/QtCore"
+ << srcify("forgotten-qinterface.h");
+ proc.start("moc", args);
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(proc.exitCode(), 0);
+ QByteArray mocOut = proc.readAllStandardOutput();
+ QVERIFY(!mocOut.isEmpty());
+ QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
+ QCOMPARE(mocWarning, QString(SRCDIR) +
+ QString("/forgotten-qinterface.h:55: Warning: Class Test implements the interface MyInterface but does not list it in Q_INTERFACES. qobject_cast to MyInterface will not work!\n"));
+#else
+ QSKIP("Only tested on linux/gcc", SkipAll);
+#endif
+}
+
+void tst_Moc::os9Newline()
+{
+#if !defined(SKIP_NEWLINE_TEST)
+ const QMetaObject &mo = Os9Newlines::staticMetaObject;
+ QVERIFY(mo.indexOfSlot("testSlot()") != -1);
+ QFile f(srcify("os9-newlines.h"));
+ QVERIFY(f.open(QIODevice::ReadOnly)); // no QIODevice::Text!
+ QByteArray data = f.readAll();
+ f.close();
+ QVERIFY(!data.contains('\n'));
+ QVERIFY(data.contains('\r'));
+#endif
+}
+
+void tst_Moc::winNewline()
+{
+#if !defined(SKIP_NEWLINE_TEST)
+ const QMetaObject &mo = WinNewlines::staticMetaObject;
+ QVERIFY(mo.indexOfSlot("testSlot()") != -1);
+ QFile f(srcify("win-newlines.h"));
+ QVERIFY(f.open(QIODevice::ReadOnly)); // no QIODevice::Text!
+ QByteArray data = f.readAll();
+ f.close();
+ for (int i = 0; i < data.count(); ++i) {
+ if (data.at(i) == QLatin1Char('\r')) {
+ QVERIFY(i < data.count() - 1);
+ ++i;
+ QVERIFY(data.at(i) == '\n');
+ } else {
+ QVERIFY(data.at(i) != '\n');
+ }
+ }
+#endif
+}
+
+void tst_Moc::escapesInStringLiterals()
+{
+ const QMetaObject &mo = StringLiterals::staticMetaObject;
+ QCOMPARE(mo.classInfoCount(), 3);
+
+ int idx = mo.indexOfClassInfo("Test");
+ QVERIFY(idx != -1);
+ QMetaClassInfo info = mo.classInfo(idx);
+ QCOMPARE(QByteArray(info.value()),
+ QByteArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\x53"));
+
+ QVERIFY(idx != -1);
+ idx = mo.indexOfClassInfo("Test2");
+ info = mo.classInfo(idx);
+ QCOMPARE(QByteArray(info.value()),
+ QByteArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\123"));
+
+ QVERIFY(idx != -1);
+ idx = mo.indexOfClassInfo("Test3");
+ info = mo.classInfo(idx);
+ QCOMPARE(QByteArray(info.value()),
+ QByteArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nb"));
+}
+
+void tst_Moc::frameworkSearchPath()
+{
+#ifdef MOC_CROSS_COMPILED
+ QSKIP("Not tested when cross-compiled", SkipAll);
+#endif
+#if defined(Q_OS_UNIX) && !defined(QT_NO_PROCESS)
+ QStringList args;
+ args << "-F" << srcify(".")
+ << srcify("interface-from-framework.h")
+ ;
+
+ QProcess proc;
+ proc.start("moc", args);
+ bool finished = proc.waitForFinished();
+ if (!finished)
+ qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error());
+ QVERIFY(finished);
+ if (proc.exitCode() != 0) {
+ qDebug() << proc.readAllStandardError();
+ }
+ QCOMPARE(proc.exitCode(), 0);
+ QCOMPARE(proc.readAllStandardError(), QByteArray());
+#else
+ QSKIP("Only tested/relevant on unixy platforms", SkipAll);
+#endif
+}
+
+void tst_Moc::cstyleEnums()
+{
+ const QMetaObject &obj = CStyleEnums::staticMetaObject;
+ QCOMPARE(obj.enumeratorCount(), 1);
+ QMetaEnum metaEnum = obj.enumerator(0);
+ QCOMPARE(metaEnum.name(), "Baz");
+ QCOMPARE(metaEnum.keyCount(), 2);
+ QCOMPARE(metaEnum.key(0), "Foo");
+ QCOMPARE(metaEnum.key(1), "Bar");
+}
+
+void tst_Moc::templateGtGt()
+{
+#ifdef MOC_CROSS_COMPILED
+ QSKIP("Not tested when cross-compiled", SkipAll);
+#endif
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
+ QProcess proc;
+ proc.start("moc", QStringList(srcify("template-gtgt.h")));
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(proc.exitCode(), 0);
+ QByteArray mocOut = proc.readAllStandardOutput();
+ QVERIFY(!mocOut.isEmpty());
+ QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
+ QVERIFY(mocWarning.isEmpty());
+#else
+ QSKIP("Only tested on linux/gcc", SkipAll);
+#endif
+}
+
+void tst_Moc::defineMacroViaCmdline()
+{
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
+ QProcess proc;
+
+ QStringList args;
+ args << "-DFOO";
+ args << srcify("macro-on-cmdline.h");
+
+ proc.start("moc", args);
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(proc.exitCode(), 0);
+ QCOMPARE(proc.readAllStandardError(), QByteArray());
+ QByteArray mocOut = proc.readAllStandardOutput();
+ QVERIFY(!mocOut.isEmpty());
+#else
+ QSKIP("Only tested on linux/gcc", SkipAll);
+#endif
+}
+
+void tst_Moc::invokable()
+{
+ {
+ const QMetaObject &mobj = InvokableBeforeReturnType::staticMetaObject;
+ QCOMPARE(mobj.methodCount(), 5);
+ QVERIFY(mobj.method(4).signature() == QByteArray("foo()"));
+ }
+
+ {
+ const QMetaObject &mobj = InvokableBeforeInline::staticMetaObject;
+ QCOMPARE(mobj.methodCount(), 6);
+ QVERIFY(mobj.method(4).signature() == QByteArray("foo()"));
+ QVERIFY(mobj.method(5).signature() == QByteArray("bar()"));
+ }
+}
+
+void tst_Moc::singleFunctionKeywordSignalAndSlot()
+{
+ {
+ const QMetaObject &mobj = SingleFunctionKeywordBeforeReturnType::staticMetaObject;
+ QCOMPARE(mobj.methodCount(), 6);
+ QVERIFY(mobj.method(4).signature() == QByteArray("mySignal()"));
+ QVERIFY(mobj.method(5).signature() == QByteArray("mySlot()"));
+ }
+
+ {
+ const QMetaObject &mobj = SingleFunctionKeywordBeforeInline::staticMetaObject;
+ QCOMPARE(mobj.methodCount(), 6);
+ QVERIFY(mobj.method(4).signature() == QByteArray("mySignal()"));
+ QVERIFY(mobj.method(5).signature() == QByteArray("mySlot()"));
+ }
+
+ {
+ const QMetaObject &mobj = SingleFunctionKeywordAfterInline::staticMetaObject;
+ QCOMPARE(mobj.methodCount(), 6);
+ QVERIFY(mobj.method(4).signature() == QByteArray("mySignal()"));
+ QVERIFY(mobj.method(5).signature() == QByteArray("mySlot()"));
+ }
+}
+
+#include "qprivateslots.h"
+
+void tst_Moc::qprivateslots()
+{
+ TestQPrivateSlots tst;
+ const QMetaObject *mobj = tst.metaObject();
+ QVERIFY(mobj->indexOfSlot("_q_privateslot()") != -1);
+ QVERIFY(mobj->indexOfMethod("method1()") != -1); //tast204730
+}
+
+#include "task189996.h"
+
+void InlineSlotsWithThrowDeclaration::c() throw() {}
+
+void tst_Moc::inlineSlotsWithThrowDeclaration()
+{
+ InlineSlotsWithThrowDeclaration tst;
+ const QMetaObject *mobj = tst.metaObject();
+ QVERIFY(mobj->indexOfSlot("a()") != -1);
+ QVERIFY(mobj->indexOfSlot("b()") != -1);
+ QVERIFY(mobj->indexOfSlot("c()") != -1);
+ QVERIFY(mobj->indexOfSlot("d()") != -1);
+ QVERIFY(mobj->indexOfSlot("e()") != -1);
+}
+
+void tst_Moc::warnOnPropertyWithoutREAD()
+{
+#ifdef MOC_CROSS_COMPILED
+ QSKIP("Not tested when cross-compiled", SkipAll);
+#endif
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
+ QProcess proc;
+ proc.start("moc", QStringList(srcify("warn-on-property-without-read.h")));
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(proc.exitCode(), 0);
+ QByteArray mocOut = proc.readAllStandardOutput();
+ QVERIFY(!mocOut.isEmpty());
+ QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
+ QCOMPARE(mocWarning, QString(SRCDIR) +
+ QString("/warn-on-property-without-read.h:46: Warning: Property declaration foo has no READ accessor function. The property will be invalid.\n"));
+#else
+ QSKIP("Only tested on linux/gcc", SkipAll);
+#endif
+}
+
+void tst_Moc::constructors()
+{
+ const QMetaObject *mo = &CtorTestClass::staticMetaObject;
+ QCOMPARE(mo->constructorCount(), 3);
+ {
+ QMetaMethod mm = mo->constructor(0);
+ QCOMPARE(mm.access(), QMetaMethod::Public);
+ QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
+ QCOMPARE(mm.signature(), "CtorTestClass(QObject*)");
+ QCOMPARE(mm.typeName(), "");
+ QList<QByteArray> paramNames = mm.parameterNames();
+ QCOMPARE(paramNames.size(), 1);
+ QCOMPARE(paramNames.at(0), QByteArray("parent"));
+ QList<QByteArray> paramTypes = mm.parameterTypes();
+ QCOMPARE(paramTypes.size(), 1);
+ QCOMPARE(paramTypes.at(0), QByteArray("QObject*"));
+ }
+ {
+ QMetaMethod mm = mo->constructor(1);
+ QCOMPARE(mm.access(), QMetaMethod::Public);
+ QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
+ QCOMPARE(mm.signature(), "CtorTestClass()");
+ QCOMPARE(mm.typeName(), "");
+ QCOMPARE(mm.parameterNames().size(), 0);
+ QCOMPARE(mm.parameterTypes().size(), 0);
+ }
+ {
+ QMetaMethod mm = mo->constructor(2);
+ QCOMPARE(mm.access(), QMetaMethod::Public);
+ QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
+ QCOMPARE(mm.signature(), "CtorTestClass(QString)");
+ QCOMPARE(mm.typeName(), "");
+ QList<QByteArray> paramNames = mm.parameterNames();
+ QCOMPARE(paramNames.size(), 1);
+ QCOMPARE(paramNames.at(0), QByteArray("str"));
+ QList<QByteArray> paramTypes = mm.parameterTypes();
+ QCOMPARE(paramTypes.size(), 1);
+ QCOMPARE(paramTypes.at(0), QByteArray("QString"));
+ }
+
+ QCOMPARE(mo->indexOfConstructor("CtorTestClass(QObject*)"), 0);
+ QCOMPARE(mo->indexOfConstructor("CtorTestClass()"), 1);
+ QCOMPARE(mo->indexOfConstructor("CtorTestClass(QString)"), 2);
+ QCOMPARE(mo->indexOfConstructor("CtorTestClass2(QObject*)"), -1);
+ QCOMPARE(mo->indexOfConstructor("CtorTestClass(float,float)"), -1);
+
+ QObject *o1 = mo->newInstance();
+ QVERIFY(o1 != 0);
+ QCOMPARE(o1->parent(), (QObject*)0);
+ QVERIFY(qobject_cast<CtorTestClass*>(o1) != 0);
+
+ QObject *o2 = mo->newInstance(Q_ARG(QObject*, o1));
+ QVERIFY(o2 != 0);
+ QCOMPARE(o2->parent(), o1);
+
+ QString str = QString::fromLatin1("hello");
+ QObject *o3 = mo->newInstance(Q_ARG(QString, str));
+ QVERIFY(o3 != 0);
+ QCOMPARE(qobject_cast<CtorTestClass*>(o3)->m_str, str);
+
+ {
+ //explicit constructor
+ QObject *o = QObject::staticMetaObject.newInstance();
+ QVERIFY(o);
+ delete o;
+ }
+}
+
+#include "task234909.h"
+
+#include "task240368.h"
+
+void tst_Moc::typenameWithUnsigned()
+{
+ TypenameWithUnsigned tst;
+ const QMetaObject *mobj = tst.metaObject();
+ QVERIFY(mobj->indexOfSlot("a(uint)") != -1);
+ QVERIFY(mobj->indexOfSlot("b(uint)") != -1);
+ QVERIFY(mobj->indexOfSlot("c(uint*)") != -1);
+ QVERIFY(mobj->indexOfSlot("d(uint*)") != -1);
+ QVERIFY(mobj->indexOfSlot("e(uint&)") != -1);
+ QVERIFY(mobj->indexOfSlot("f(uint&)") != -1);
+ QVERIFY(mobj->indexOfSlot("g(unsigned1)") != -1);
+ QVERIFY(mobj->indexOfSlot("h(unsigned1)") != -1);
+ QVERIFY(mobj->indexOfSlot("i(uint,unsigned1)") != -1);
+ QVERIFY(mobj->indexOfSlot("j(unsigned1,uint)") != -1);
+ QVERIFY(mobj->indexOfSlot("k(unsignedQImage)") != -1);
+ QVERIFY(mobj->indexOfSlot("l(unsignedQImage)") != -1);
+}
+
+
+void tst_Moc::warnOnVirtualSignal()
+{
+#ifdef MOC_CROSS_COMPILED
+ QSKIP("Not tested when cross-compiled", SkipAll);
+#endif
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
+ QProcess proc;
+ proc.start("moc", QStringList(srcify("pure-virtual-signals.h")));
+ QVERIFY(proc.waitForFinished());
+ QCOMPARE(proc.exitCode(), 0);
+ QByteArray mocOut = proc.readAllStandardOutput();
+ QVERIFY(!mocOut.isEmpty());
+ QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
+ QCOMPARE(mocWarning, QString(SRCDIR) + QString("/pure-virtual-signals.h:48: Warning: Signals cannot be declared virtual\n") +
+ QString(SRCDIR) + QString("/pure-virtual-signals.h:50: Warning: Signals cannot be declared virtual\n"));
+#else
+ QSKIP("Only tested on linux/gcc", SkipAll);
+#endif
+}
+
+QTEST_APPLESS_MAIN(tst_Moc)
+#include "tst_moc.moc"
+
+
+