1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 #include <QtTest/QtTest>
48 #include "using-namespaces.h"
49 #include "assign-namespace.h"
50 #include "no-keywords.h"
51 #include "single_function_keyword.h"
52 #include "backslash-newlines.h"
53 #include "slots-with-void-template.h"
54 #include "pure-virtual-signals.h"
55 #include "qinvokable.h"
56 // msvc and friends crap out on it
57 #if !defined(Q_CC_GNU) || defined(Q_OS_IRIX) || defined(Q_OS_WIN)
58 #define SKIP_NEWLINE_TEST
60 #if !defined(SKIP_NEWLINE_TEST)
61 #include "os9-newlines.h"
62 // msvc and friends crap out on this file too,
63 // it seems to contain Mac 9 EOLs, and not windows EOLs.
64 #include "win-newlines.h"
66 #include "escapes-in-string-literals.h"
67 #include "cstyle-enums.h"
69 #if defined(PARSE_BOOST)
70 #include "parse-boost.h"
72 #include "cxx11-enums.h"
81 // Try to avoid inserting for instance a comment with a quote between the following line and the Q_OBJECT
82 // That will make the test give a false positive.
83 const char* test_multiple_number_of_escapes = "\\\"";
86 class TestSuperClass : public QObject
90 inline TestSuperClass() {}
108 class Sender : public QObject
113 void sendValue(const String::Type& value)
117 void sendValue(const Int::Type& value)
123 void send(const String::Type&);
124 void send(const Int::Type&);
127 class Receiver : public QObject
131 Receiver() : stringCallCount(0), intCallCount(0) {}
137 void receive(const String::Type&) { stringCallCount++; }
138 void receive(const Int::Type&) { intCallCount++; }
141 #define MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES
143 #define DONT_CONFUSE_MOC(klass) klass
144 #define DONT_CONFUSE_MOC_EVEN_MORE(klass, dummy, dummy2) klass
146 Q_DECLARE_METATYPE(MyStruct)
147 Q_DECLARE_METATYPE(MyStruct*)
152 Points() : p1(0xBEEF), p2(0xBABE) { }
157 Q_DECLARE_METATYPE(myNS::Points)
159 class TestClassinfoWithEscapes: public QObject
162 Q_CLASSINFO("escaped", "\"bar\"")
163 Q_CLASSINFO("\"escaped\"", "foo")
165 void slotWithAReallyLongName(int)
169 struct ForwardDeclaredStruct;
171 struct StructQObject : public QObject
175 void foo(struct ForwardDeclaredStruct *);
178 void StructQObject::foo(struct ForwardDeclaredStruct *)
184 struct Inner unusedVariable;
187 class TestClass : public MyNamespace::TestSuperClass, public DONT_CONFUSE_MOC(MyStruct),
188 public DONT_CONFUSE_MOC_EVEN_MORE(MyStruct2, dummy, ignored)
191 Q_CLASSINFO("help", QT_TR_NOOP("Opening this will let you configure something"))
192 Q_PROPERTY(short int shortIntProperty READ shortIntProperty)
193 Q_PROPERTY(unsigned short int unsignedShortIntProperty READ unsignedShortIntProperty)
194 Q_PROPERTY(signed short int signedShortIntProperty READ signedShortIntProperty)
195 Q_PROPERTY(long int longIntProperty READ longIntProperty)
196 Q_PROPERTY(unsigned long int unsignedLongIntProperty READ unsignedLongIntProperty)
197 Q_PROPERTY(signed long int signedLongIntProperty READ signedLongIntProperty)
198 Q_PROPERTY(long double longDoubleProperty READ longDoubleProperty)
199 Q_PROPERTY(myNS::Points points READ points WRITE setPoints)
205 "multiline Q_CLASSINFO"
208 // a really really long string that we have to cut into pieces in the generated stringdata
209 // table, otherwise msvc craps out
210 Q_CLASSINFO("D-Bus Introspection", ""
211 " <interface name=\"org.kde.KCookieServer\" >\n"
212 " <method name=\"findCookies\" >\n"
213 " <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
214 " <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
215 " <arg direction=\"out\" type=\"s\" name=\"cookies\" />\n"
217 " <method name=\"findDomains\" >\n"
218 " <arg direction=\"out\" type=\"as\" name=\"domains\" />\n"
220 " <method name=\"findCookies\" >\n"
221 " <arg direction=\"in\" type=\"ai\" name=\"fields\" />\n"
222 " <arg direction=\"in\" type=\"s\" name=\"domain\" />\n"
223 " <arg direction=\"in\" type=\"s\" name=\"fqdn\" />\n"
224 " <arg direction=\"in\" type=\"s\" name=\"path\" />\n"
225 " <arg direction=\"in\" type=\"s\" name=\"name\" />\n"
226 " <arg direction=\"out\" type=\"as\" name=\"cookies\" />\n"
227 " <annotation value=\"QList<int>\" name=\"com.trolltech.QtDBus.QtTypeName.In0\" />\n"
229 " <method name=\"findDOMCookies\" >\n"
230 " <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
231 " <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
232 " <arg direction=\"out\" type=\"s\" name=\"cookies\" />\n"
234 " <method name=\"addCookies\" >\n"
235 " <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
236 " <arg direction=\"in\" type=\"ay\" name=\"cookieHeader\" />\n"
237 " <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
239 " <method name=\"deleteCookie\" >\n"
240 " <arg direction=\"in\" type=\"s\" name=\"domain\" />\n"
241 " <arg direction=\"in\" type=\"s\" name=\"fqdn\" />\n"
242 " <arg direction=\"in\" type=\"s\" name=\"path\" />\n"
243 " <arg direction=\"in\" type=\"s\" name=\"name\" />\n"
245 " <method name=\"deleteCookiesFromDomain\" >\n"
246 " <arg direction=\"in\" type=\"s\" name=\"domain\" />\n"
248 " <method name=\"deleteSessionCookies\" >\n"
249 " <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
251 " <method name=\"deleteSessionCookiesFor\" >\n"
252 " <arg direction=\"in\" type=\"s\" name=\"fqdn\" />\n"
253 " <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
255 " <method name=\"deleteAllCookies\" />\n"
256 " <method name=\"addDOMCookies\" >\n"
257 " <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
258 " <arg direction=\"in\" type=\"ay\" name=\"cookieHeader\" />\n"
259 " <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
261 " <method name=\"setDomainAdvice\" >\n"
262 " <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
263 " <arg direction=\"in\" type=\"s\" name=\"advice\" />\n"
265 " <method name=\"getDomainAdvice\" >\n"
266 " <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
267 " <arg direction=\"out\" type=\"s\" name=\"advice\" />\n"
269 " <method name=\"reloadPolicy\" />\n"
270 " <method name=\"shutdown\" />\n"
275 inline TestClass() {}
278 inline void dummy1() MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES {}
279 inline void dummy2() MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES const {}
280 inline void dummy3() const MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES {}
282 void slotWithULongLong(unsigned long long) {}
283 void slotWithULongLongP(unsigned long long*) {}
284 void slotWithULong(unsigned long) {}
285 void slotWithLongLong(long long) {}
286 void slotWithLong(long) {}
288 void slotWithColonColonType(::Int::Type) {}
290 TestClass &slotWithReferenceReturnType() { return *this; }
293 void expressionEvaluationShortcut1() {}
297 void expressionEvaluationShortcut2() {}
301 void slotWithArray(const double[3]) {}
302 void slotWithNamedArray(const double namedArray[3]) { Q_UNUSED(namedArray); }
303 void slotWithMultiArray(const double[3][4]) {}
305 short int shortIntProperty() { return 0; }
306 unsigned short int unsignedShortIntProperty() { return 0; }
307 signed short int signedShortIntProperty() { return 0; }
308 long int longIntProperty() { return 0; }
309 unsigned long int unsignedLongIntProperty() { return 0; }
310 signed long int signedLongIntProperty() { return 0; }
311 long double longDoubleProperty() { return 0.0; }
313 myNS::Points points() { return m_points; }
314 void setPoints(myNS::Points points) { m_points = points; }
317 void signalWithArray(const double[3]);
318 void signalWithNamedArray(const double namedArray[3]);
321 // for tst_Moc::preprocessorConditionals
323 void invalidSlot() {}
331 void invalidSlot() {}
335 void invalidSlot() {}
338 void slotInLastElse() {}
342 void invalidSlot() {}
346 void invalidSlot() {}
349 friend class Receiver; // task #85783
351 friend class Sender; // task #85783
353 #define MACRO_DEFINED
355 #if !(defined MACRO_UNDEF || defined MACRO_DEFINED) || 1
360 #if !(!defined MACRO_UNDEF || !defined MACRO_DEFINED) && 1
365 #if !(!defined (MACRO_DEFINED) || !defined (MACRO_UNDEF)) && 1
379 void const slotWithSillyConst() {}
382 Q_INVOKABLE void const slotWithSillyConst2() {}
383 Q_INVOKABLE QObject& myInvokableReturningRef()
385 Q_INVOKABLE const QObject& myInvokableReturningConstRef() const
389 // that one however should be fine
391 void slotWithVoidStar(void *) {}
394 myNS::Points m_points;
397 inline virtual void blub1() {}
398 virtual inline void blub2() {}
401 class PropertyTestClass : public QObject
406 enum TestEnum { One, Two, Three };
411 class PropertyUseClass : public QObject
414 Q_PROPERTY(PropertyTestClass::TestEnum foo READ foo)
417 inline PropertyTestClass::TestEnum foo() const { return PropertyTestClass::One; }
420 class EnumSourceClass : public QObject
425 enum TestEnum { Value = 37 };
430 class EnumUserClass : public QObject
435 Q_ENUMS(EnumSourceClass::TestEnum)
438 #if defined(Q_MOC_RUN)
445 static QString srcify(const char *path)
448 return QString(SRCDIR) + QLatin1Char('/') + QLatin1String(path);
450 return QString(QLatin1String(path));
454 class CtorTestClass : public QObject
458 Q_INVOKABLE CtorTestClass(QObject *parent = 0);
460 CtorTestClass(int foo);
462 inline Q_INVOKABLE CtorTestClass(const QString &str)
468 CtorTestClass(int foo, int bar, int baz);
470 CtorTestClass(float, float) {}
473 CtorTestClass::CtorTestClass(QObject *parent)
476 CtorTestClass::CtorTestClass(int, int, int) {}
479 class tst_Moc : public QObject
483 Q_PROPERTY(bool user1 READ user1 USER true )
484 Q_PROPERTY(bool user2 READ user2 USER false)
485 Q_PROPERTY(bool user3 READ user3 USER userFunction())
493 void slotWithException() throw(MyStruct);
494 void dontStripNamespaces();
495 void oldStyleCasts();
496 void warnOnExtraSignalSlotQualifiaction();
498 void inputFileNameWithDotsButNoExtension();
499 void userProperties();
500 void supportConstSignals();
502 void multilineComments();
503 void classinfoWithEscapes();
504 void trNoopInClassInfo();
505 void ppExpressionEvaluation();
506 void arrayArguments();
507 void preprocessorConditionals();
508 void blackslashNewlines();
509 void slotWithSillyConst();
510 void testExtraData();
511 void testExtraDataForEnum();
512 void namespaceTypeProperty();
513 void slotsWithVoidTemplate();
514 void structQObject();
515 void namespacedFlags();
516 void warnOnMultipleInheritance();
517 void forgottenQInterface();
520 void escapesInStringLiterals();
521 void frameworkSearchPath();
523 void defineMacroViaCmdline();
525 void singleFunctionKeywordSignalAndSlot();
527 void qprivateslots();
528 void qprivateproperties();
529 void inlineSlotsWithThrowDeclaration();
530 void warnOnPropertyWithoutREAD();
532 void typenameWithUnsigned();
533 void warnOnVirtualSignal();
534 void QTBUG5590_dummyProperty();
535 void QTBUG12260_defaultTemplate();
537 void QTBUG17635_invokableAndProperty();
539 void warnings_data();
542 void cxx11Enums_data();
547 void sigWithUnsignedArg(unsigned foo);
548 void sigWithSignedArg(signed foo);
549 void sigWithConstSignedArg(const signed foo);
550 void sigWithVolatileConstSignedArg(volatile const signed foo);
551 void sigWithCustomType(const MyStruct);
552 void constSignal1() const;
553 void constSignal2(int arg) const;
556 bool user1() { return true; };
557 bool user2() { return false; };
558 bool user3() { return false; };
559 bool userFunction(){ return false; };
560 template <class T> void revisions_T();
563 QString qtIncludePath;
567 void tst_Moc::initTestCase()
569 #if defined(Q_OS_UNIX) && !defined(QT_NO_PROCESS)
571 proc.start("qmake", QStringList() << "-query" << "QT_INSTALL_HEADERS");
572 QVERIFY(proc.waitForFinished());
573 QCOMPARE(proc.exitCode(), 0);
574 QByteArray output = proc.readAllStandardOutput();
575 QVERIFY(!output.isEmpty());
576 QCOMPARE(proc.readAllStandardError(), QByteArray());
577 qtIncludePath = QString::fromLocal8Bit(output).trimmed();
578 QFileInfo fi(qtIncludePath);
579 QVERIFY(fi.exists());
584 void tst_Moc::slotWithException() throw(MyStruct)
590 void tst_Moc::dontStripNamespaces()
595 connect(&sender, SIGNAL(send(const String::Type &)),
596 &receiver, SLOT(receive(const String::Type &)));
597 connect(&sender, SIGNAL(send(const Int::Type &)),
598 &receiver, SLOT(receive(const Int::Type &)));
600 sender.sendValue(String::Type("Hello"));
601 QCOMPARE(receiver.stringCallCount, 1);
602 QCOMPARE(receiver.intCallCount, 0);
603 sender.sendValue(Int::Type(42));
604 QCOMPARE(receiver.stringCallCount, 1);
605 QCOMPARE(receiver.intCallCount, 1);
608 void tst_Moc::oldStyleCasts()
610 #ifdef MOC_CROSS_COMPILED
611 QSKIP("Not tested when cross-compiled");
613 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
615 proc.start("moc", QStringList(srcify("/oldstyle-casts.h")));
616 QVERIFY(proc.waitForFinished());
617 QCOMPARE(proc.exitCode(), 0);
618 QByteArray mocOut = proc.readAllStandardOutput();
619 QVERIFY(!mocOut.isEmpty());
620 QCOMPARE(proc.readAllStandardError(), QByteArray());
623 args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "."
624 << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIE" << "-";
625 proc.start("gcc", args);
626 QVERIFY(proc.waitForStarted());
628 proc.closeWriteChannel();
630 QVERIFY(proc.waitForFinished());
631 QCOMPARE(proc.exitCode(), 0);
632 QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString());
634 QSKIP("Only tested on linux/gcc");
638 void tst_Moc::warnOnExtraSignalSlotQualifiaction()
640 #ifdef MOC_CROSS_COMPILED
641 QSKIP("Not tested when cross-compiled");
643 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
645 proc.start("moc", QStringList(srcify("extraqualification.h")));
646 QVERIFY(proc.waitForFinished());
647 QCOMPARE(proc.exitCode(), 0);
648 QByteArray mocOut = proc.readAllStandardOutput();
649 QVERIFY(!mocOut.isEmpty());
650 QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
651 QCOMPARE(mocWarning, QString(SRCDIR) +
652 QString("/extraqualification.h:53: Warning: Function declaration Test::badFunctionDeclaration contains extra qualification. Ignoring as signal or slot.\n") +
653 QString(SRCDIR) + QString("/extraqualification.h:56: Warning: parsemaybe: Function declaration Test::anotherOne contains extra qualification. Ignoring as signal or slot.\n"));
655 QSKIP("Only tested on linux/gcc");
659 void tst_Moc::uLongLong()
662 const QMetaObject *mobj = tst.metaObject();
663 int idx = mobj->indexOfSlot("slotWithULong(ulong)");
665 idx = mobj->indexOfSlot("slotWithULongLong(unsigned long long)");
667 idx = mobj->indexOfSlot("slotWithULongLongP(unsigned long long*)");
670 idx = mobj->indexOfSlot("slotWithLong(long)");
672 idx = mobj->indexOfSlot("slotWithLongLong(long long)");
676 void tst_Moc::inputFileNameWithDotsButNoExtension()
678 #ifdef MOC_CROSS_COMPILED
679 QSKIP("Not tested when cross-compiled");
681 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
683 proc.setWorkingDirectory(QString(SRCDIR) + "/task71021");
684 proc.start("moc", QStringList("../Header"));
685 QVERIFY(proc.waitForFinished());
686 QCOMPARE(proc.exitCode(), 0);
687 QByteArray mocOut = proc.readAllStandardOutput();
688 QVERIFY(!mocOut.isEmpty());
689 QCOMPARE(proc.readAllStandardError(), QByteArray());
692 args << "-c" << "-x" << "c++" << "-I" << ".."
693 << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIE" << "-";
694 proc.start("gcc", args);
695 QVERIFY(proc.waitForStarted());
697 proc.closeWriteChannel();
699 QVERIFY(proc.waitForFinished());
700 QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString());
701 QCOMPARE(proc.exitCode(), 0);
703 QSKIP("Only tested on linux/gcc");
707 void tst_Moc::userProperties()
709 const QMetaObject *mobj = metaObject();
710 QMetaProperty property = mobj->property(mobj->indexOfProperty("user1"));
711 QVERIFY(property.isValid());
712 QVERIFY(property.isUser());
714 property = mobj->property(mobj->indexOfProperty("user2"));
715 QVERIFY(property.isValid());
716 QVERIFY(!property.isUser());
718 property = mobj->property(mobj->indexOfProperty("user3"));
719 QVERIFY(property.isValid());
720 QVERIFY(!property.isUser(this));
723 void tst_Moc::supportConstSignals()
725 QSignalSpy spy1(this, SIGNAL(constSignal1()));
726 QVERIFY(spy1.isEmpty());
728 QCOMPARE(spy1.count(), 1);
730 QSignalSpy spy2(this, SIGNAL(constSignal2(int)));
731 QVERIFY(spy2.isEmpty());
732 emit constSignal2(42);
733 QCOMPARE(spy2.count(), 1);
734 QCOMPARE(spy2.at(0).at(0).toInt(), 42);
737 #include "task87883.h"
739 void tst_Moc::task87883()
741 QVERIFY(Task87883::staticMetaObject.className());
744 #include "c-comments.h"
746 void tst_Moc::multilineComments()
748 QVERIFY(IfdefedClass::staticMetaObject.className());
751 void tst_Moc::classinfoWithEscapes()
753 const QMetaObject *mobj = &TestClassinfoWithEscapes::staticMetaObject;
754 QCOMPARE(mobj->methodCount() - mobj->methodOffset(), 1);
756 QMetaMethod mm = mobj->method(mobj->methodOffset());
757 QCOMPARE(mm.methodSignature(), QByteArray("slotWithAReallyLongName(int)"));
760 void tst_Moc::trNoopInClassInfo()
763 const QMetaObject *mobj = t.metaObject();
765 QCOMPARE(mobj->classInfoCount(), 3);
766 QCOMPARE(mobj->indexOfClassInfo("help"), 0);
767 QCOMPARE(QString(mobj->classInfo(0).value()), QString("Opening this will let you configure something"));
770 void tst_Moc::ppExpressionEvaluation()
773 const QMetaObject *mobj = tst.metaObject();
774 int idx = mobj->indexOfSlot("expressionEvaluationShortcut1()");
777 idx = mobj->indexOfSlot("expressionEvaluationShortcut2()");
781 void tst_Moc::arrayArguments()
784 const QMetaObject *mobj = tst.metaObject();
785 QVERIFY(mobj->indexOfSlot("slotWithArray(const double[3])") != -1);
786 QVERIFY(mobj->indexOfSlot("slotWithNamedArray(const double[3])") != -1);
787 QVERIFY(mobj->indexOfSlot("slotWithMultiArray(const double[3][4])") != -1);
788 QVERIFY(mobj->indexOfSignal("signalWithArray(const double[3])") != -1);
789 QVERIFY(mobj->indexOfSignal("signalWithNamedArray(const double[3])") != -1);
792 void tst_Moc::preprocessorConditionals()
795 const QMetaObject *mobj = tst.metaObject();
796 QVERIFY(mobj->indexOfSlot("slotInElse()") != -1);
797 QVERIFY(mobj->indexOfSlot("slotInIf()") != -1);
798 QVERIFY(mobj->indexOfSlot("slotInLastElse()") != -1);
799 QVERIFY(mobj->indexOfSlot("slotInElif()") != -1);
800 QVERIFY(mobj->indexOfSignal("signalInIf1()") != -1);
801 QVERIFY(mobj->indexOfSignal("signalInIf2()") != -1);
802 QVERIFY(mobj->indexOfSignal("signalInIf3()") != -1);
803 QVERIFY(mobj->indexOfSignal("doNotExist()") == -1);
806 void tst_Moc::blackslashNewlines()
808 BackslashNewlines tst;
809 const QMetaObject *mobj = tst.metaObject();
810 QVERIFY(mobj->indexOfSlot("works()") != -1);
811 QVERIFY(mobj->indexOfSlot("buggy()") == -1);
814 void tst_Moc::slotWithSillyConst()
817 const QMetaObject *mobj = tst.metaObject();
818 QVERIFY(mobj->indexOfSlot("slotWithSillyConst()") != -1);
819 QVERIFY(mobj->indexOfMethod("slotWithSillyConst2()") != -1);
820 QVERIFY(mobj->indexOfSlot("slotWithVoidStar(void*)") != -1);
823 void tst_Moc::testExtraData()
825 const QMetaObject *mobj = &PropertyTestClass::staticMetaObject;
826 QCOMPARE(mobj->enumeratorCount(), 1);
827 QCOMPARE(QByteArray(mobj->enumerator(0).name()), QByteArray("TestEnum"));
829 mobj = &PropertyUseClass::staticMetaObject;
830 const int idx = mobj->indexOfProperty("foo");
832 const QMetaProperty prop = mobj->property(idx);
833 QVERIFY(prop.isValid());
834 QVERIFY(prop.isEnumType());
835 const QMetaEnum en = prop.enumerator();
836 QCOMPARE(QByteArray(en.name()), QByteArray("TestEnum"));
839 // QTBUG-20639 - Accept non-local enums for QML signal/slot parameters.
840 void tst_Moc::testExtraDataForEnum()
842 const QMetaObject *mobjSource = &EnumSourceClass::staticMetaObject;
843 QCOMPARE(mobjSource->enumeratorCount(), 1);
844 QCOMPARE(QByteArray(mobjSource->enumerator(0).name()), QByteArray("TestEnum"));
846 const QMetaObject *mobjUser = &EnumUserClass::staticMetaObject;
847 QCOMPARE(mobjUser->enumeratorCount(), 0);
849 const QMetaObject **objects = mobjUser->d.relatedMetaObjects;
851 QVERIFY(objects[0] == mobjSource);
852 QVERIFY(objects[1] == 0);
855 void tst_Moc::namespaceTypeProperty()
857 qRegisterMetaType<myNS::Points>("myNS::Points");
859 QByteArray ba = QByteArray("points");
860 QVariant v = tst.property(ba);
861 QVERIFY(v.isValid());
862 myNS::Points p = qvariant_cast<myNS::Points>(v);
863 QCOMPARE(p.p1, 0xBEEF);
864 QCOMPARE(p.p2, 0xBABE);
867 QVERIFY(tst.setProperty(ba, QVariant::fromValue(p)));
868 myNS::Points pp = qvariant_cast<myNS::Points>(tst.property(ba));
869 QCOMPARE(p.p1, pp.p1);
870 QCOMPARE(p.p2, pp.p2);
873 void tst_Moc::slotsWithVoidTemplate()
875 SlotsWithVoidTemplateTest test;
876 QVERIFY(QObject::connect(&test, SIGNAL(myVoidSignal(void)),
877 &test, SLOT(dummySlot(void))));
878 QVERIFY(QObject::connect(&test, SIGNAL(mySignal(const TestTemplate<void> &)),
879 &test, SLOT(anotherSlot(const TestTemplate<void> &))));
880 QVERIFY(QObject::connect(&test, SIGNAL(myVoidSignal2()),
881 &test, SLOT(dummySlot2())));
884 void tst_Moc::structQObject()
887 QCOMPARE(QByteArray(o.metaObject()->className()), QByteArray("StructQObject"));
890 #include "namespaced-flags.h"
892 Q_DECLARE_METATYPE(QList<Foo::Bar::Flags>);
894 void tst_Moc::namespacedFlags()
899 bar.setFlags(Foo::Bar::Read | Foo::Bar::Write);
900 QVERIFY(baz.flags() != bar.flags());
902 const QVariant v = bar.property("flags");
903 QVERIFY(v.isValid());
904 QVERIFY(baz.setProperty("flags", v));
905 QVERIFY(baz.flags() == bar.flags());
907 QList<Foo::Bar::Flags> l;
909 QVariant v2 = baz.setProperty("flagsList", QVariant::fromValue(l));
910 QCOMPARE(l, baz.flagsList());
911 QCOMPARE(l, qvariant_cast<QList<Foo::Bar::Flags> >(baz.property("flagsList")));
914 void tst_Moc::warnOnMultipleInheritance()
916 #ifdef MOC_CROSS_COMPILED
917 QSKIP("Not tested when cross-compiled");
919 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
922 args << "-I" << qtIncludePath + "/QtGui"
923 << srcify("warn-on-multiple-qobject-subclasses.h");
924 proc.start("moc", args);
925 QVERIFY(proc.waitForFinished());
926 QCOMPARE(proc.exitCode(), 0);
927 QByteArray mocOut = proc.readAllStandardOutput();
928 QVERIFY(!mocOut.isEmpty());
929 QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
930 QCOMPARE(mocWarning, QString(SRCDIR) +
931 QString("/warn-on-multiple-qobject-subclasses.h:53: Warning: Class Bar inherits from two QObject subclasses QWindow and Foo. This is not supported!\n"));
933 QSKIP("Only tested on linux/gcc");
937 void tst_Moc::forgottenQInterface()
939 #ifdef MOC_CROSS_COMPILED
940 QSKIP("Not tested when cross-compiled");
942 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
945 args << "-I" << qtIncludePath + "/QtCore"
946 << srcify("forgotten-qinterface.h");
947 proc.start("moc", args);
948 QVERIFY(proc.waitForFinished());
949 QCOMPARE(proc.exitCode(), 0);
950 QByteArray mocOut = proc.readAllStandardOutput();
951 QVERIFY(!mocOut.isEmpty());
952 QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
953 QCOMPARE(mocWarning, QString(SRCDIR) +
954 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"));
956 QSKIP("Only tested on linux/gcc");
960 void tst_Moc::os9Newline()
962 #if !defined(SKIP_NEWLINE_TEST)
963 const QMetaObject &mo = Os9Newlines::staticMetaObject;
964 QVERIFY(mo.indexOfSlot("testSlot()") != -1);
965 QFile f(srcify("os9-newlines.h"));
966 QVERIFY(f.open(QIODevice::ReadOnly)); // no QIODevice::Text!
967 QByteArray data = f.readAll();
969 QVERIFY(!data.contains('\n'));
970 QVERIFY(data.contains('\r'));
974 void tst_Moc::winNewline()
976 #if !defined(SKIP_NEWLINE_TEST)
977 const QMetaObject &mo = WinNewlines::staticMetaObject;
978 QVERIFY(mo.indexOfSlot("testSlot()") != -1);
979 QFile f(srcify("win-newlines.h"));
980 QVERIFY(f.open(QIODevice::ReadOnly)); // no QIODevice::Text!
981 QByteArray data = f.readAll();
983 for (int i = 0; i < data.count(); ++i) {
984 if (data.at(i) == QLatin1Char('\r')) {
985 QVERIFY(i < data.count() - 1);
987 QVERIFY(data.at(i) == '\n');
989 QVERIFY(data.at(i) != '\n');
995 void tst_Moc::escapesInStringLiterals()
997 const QMetaObject &mo = StringLiterals::staticMetaObject;
998 QCOMPARE(mo.classInfoCount(), 3);
1000 int idx = mo.indexOfClassInfo("Test");
1002 QMetaClassInfo info = mo.classInfo(idx);
1003 QCOMPARE(QByteArray(info.value()),
1004 QByteArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\x53"));
1007 idx = mo.indexOfClassInfo("Test2");
1008 info = mo.classInfo(idx);
1009 QCOMPARE(QByteArray(info.value()),
1010 QByteArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\123"));
1013 idx = mo.indexOfClassInfo("Test3");
1014 info = mo.classInfo(idx);
1015 QCOMPARE(QByteArray(info.value()),
1016 QByteArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nb"));
1019 void tst_Moc::frameworkSearchPath()
1021 #ifdef MOC_CROSS_COMPILED
1022 QSKIP("Not tested when cross-compiled");
1024 #if defined(Q_OS_UNIX) && !defined(QT_NO_PROCESS)
1026 args << "-F" << srcify(".")
1027 << srcify("interface-from-framework.h")
1031 proc.start("moc", args);
1032 bool finished = proc.waitForFinished();
1034 qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error());
1036 if (proc.exitCode() != 0) {
1037 qDebug() << proc.readAllStandardError();
1039 QCOMPARE(proc.exitCode(), 0);
1040 QCOMPARE(proc.readAllStandardError(), QByteArray());
1042 QSKIP("Only tested/relevant on unixy platforms");
1046 void tst_Moc::cstyleEnums()
1048 const QMetaObject &obj = CStyleEnums::staticMetaObject;
1049 QCOMPARE(obj.enumeratorCount(), 1);
1050 QMetaEnum metaEnum = obj.enumerator(0);
1051 QCOMPARE(metaEnum.name(), "Baz");
1052 QCOMPARE(metaEnum.keyCount(), 2);
1053 QCOMPARE(metaEnum.key(0), "Foo");
1054 QCOMPARE(metaEnum.key(1), "Bar");
1057 void tst_Moc::templateGtGt()
1059 #ifdef MOC_CROSS_COMPILED
1060 QSKIP("Not tested when cross-compiled");
1062 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
1064 proc.start("moc", QStringList(srcify("template-gtgt.h")));
1065 QVERIFY(proc.waitForFinished());
1066 QCOMPARE(proc.exitCode(), 0);
1067 QByteArray mocOut = proc.readAllStandardOutput();
1068 QVERIFY(!mocOut.isEmpty());
1069 QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
1070 QVERIFY(mocWarning.isEmpty());
1072 QSKIP("Only tested on linux/gcc");
1076 void tst_Moc::defineMacroViaCmdline()
1078 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
1083 args << srcify("macro-on-cmdline.h");
1085 proc.start("moc", args);
1086 QVERIFY(proc.waitForFinished());
1087 QCOMPARE(proc.exitCode(), 0);
1088 QCOMPARE(proc.readAllStandardError(), QByteArray());
1089 QByteArray mocOut = proc.readAllStandardOutput();
1090 QVERIFY(!mocOut.isEmpty());
1092 QSKIP("Only tested on linux/gcc");
1096 void tst_Moc::invokable()
1099 const QMetaObject &mobj = InvokableBeforeReturnType::staticMetaObject;
1100 QCOMPARE(mobj.methodCount(), 6);
1101 QVERIFY(mobj.method(5).methodSignature() == QByteArray("foo()"));
1105 const QMetaObject &mobj = InvokableBeforeInline::staticMetaObject;
1106 QCOMPARE(mobj.methodCount(), 7);
1107 QVERIFY(mobj.method(5).methodSignature() == QByteArray("foo()"));
1108 QVERIFY(mobj.method(6).methodSignature() == QByteArray("bar()"));
1112 void tst_Moc::singleFunctionKeywordSignalAndSlot()
1115 const QMetaObject &mobj = SingleFunctionKeywordBeforeReturnType::staticMetaObject;
1116 QCOMPARE(mobj.methodCount(), 7);
1117 QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()"));
1118 QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()"));
1122 const QMetaObject &mobj = SingleFunctionKeywordBeforeInline::staticMetaObject;
1123 QCOMPARE(mobj.methodCount(), 7);
1124 QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()"));
1125 QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()"));
1129 const QMetaObject &mobj = SingleFunctionKeywordAfterInline::staticMetaObject;
1130 QCOMPARE(mobj.methodCount(), 7);
1131 QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()"));
1132 QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()"));
1136 #include "qprivateslots.h"
1138 void tst_Moc::qprivateslots()
1140 TestQPrivateSlots tst;
1141 const QMetaObject *mobj = tst.metaObject();
1142 QVERIFY(mobj->indexOfSlot("_q_privateslot()") != -1);
1143 QVERIFY(mobj->indexOfMethod("method1()") != -1); //tast204730
1146 class PrivatePropertyTest : public QObject
1149 Q_PROPERTY(int foo READ foo WRITE setFoo)
1150 Q_PRIVATE_PROPERTY(d, int bar READ bar WRITE setBar)
1151 Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, int plop READ plop WRITE setPlop)
1152 Q_PRIVATE_PROPERTY(PrivatePropertyTest::d_func(), int baz READ baz WRITE setBaz)
1155 MyDPointer() : mBar(0), mPlop(0) {}
1156 int bar() { return mBar ; }
1157 void setBar(int value) { mBar = value; }
1158 int plop() { return mPlop ; }
1159 void setPlop(int value) { mPlop = value; }
1160 int baz() { return mBaz ; }
1161 void setBaz(int value) { mBaz = value; }
1168 PrivatePropertyTest() : mFoo(0), d (new MyDPointer) {}
1169 int foo() { return mFoo ; }
1170 void setFoo(int value) { mFoo = value; }
1171 MyDPointer *d_func() {return d;}
1178 void tst_Moc::qprivateproperties()
1180 PrivatePropertyTest test;
1182 test.setProperty("foo", 1);
1183 QCOMPARE(test.property("foo"), QVariant::fromValue(1));
1185 test.setProperty("bar", 2);
1186 QCOMPARE(test.property("bar"), QVariant::fromValue(2));
1188 test.setProperty("plop", 3);
1189 QCOMPARE(test.property("plop"), QVariant::fromValue(3));
1191 test.setProperty("baz", 4);
1192 QCOMPARE(test.property("baz"), QVariant::fromValue(4));
1196 #include "task189996.h"
1198 void InlineSlotsWithThrowDeclaration::c() throw() {}
1200 void tst_Moc::inlineSlotsWithThrowDeclaration()
1202 InlineSlotsWithThrowDeclaration tst;
1203 const QMetaObject *mobj = tst.metaObject();
1204 QVERIFY(mobj->indexOfSlot("a()") != -1);
1205 QVERIFY(mobj->indexOfSlot("b()") != -1);
1206 QVERIFY(mobj->indexOfSlot("c()") != -1);
1207 QVERIFY(mobj->indexOfSlot("d()") != -1);
1208 QVERIFY(mobj->indexOfSlot("e()") != -1);
1211 void tst_Moc::warnOnPropertyWithoutREAD()
1213 #ifdef MOC_CROSS_COMPILED
1214 QSKIP("Not tested when cross-compiled");
1216 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
1218 proc.start("moc", QStringList(srcify("warn-on-property-without-read.h")));
1219 QVERIFY(proc.waitForFinished());
1220 QCOMPARE(proc.exitCode(), 0);
1221 QByteArray mocOut = proc.readAllStandardOutput();
1222 QVERIFY(!mocOut.isEmpty());
1223 QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
1224 QCOMPARE(mocWarning, QString(SRCDIR) +
1225 QString("/warn-on-property-without-read.h:46: Warning: Property declaration foo has no READ accessor function. The property will be invalid.\n"));
1227 QSKIP("Only tested on linux/gcc");
1231 void tst_Moc::constructors()
1233 const QMetaObject *mo = &CtorTestClass::staticMetaObject;
1234 QCOMPARE(mo->constructorCount(), 3);
1236 QMetaMethod mm = mo->constructor(0);
1237 QCOMPARE(mm.access(), QMetaMethod::Public);
1238 QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
1239 QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass(QObject*)"));
1240 QCOMPARE(mm.typeName(), "");
1241 QList<QByteArray> paramNames = mm.parameterNames();
1242 QCOMPARE(paramNames.size(), 1);
1243 QCOMPARE(paramNames.at(0), QByteArray("parent"));
1244 QList<QByteArray> paramTypes = mm.parameterTypes();
1245 QCOMPARE(paramTypes.size(), 1);
1246 QCOMPARE(paramTypes.at(0), QByteArray("QObject*"));
1249 QMetaMethod mm = mo->constructor(1);
1250 QCOMPARE(mm.access(), QMetaMethod::Public);
1251 QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
1252 QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass()"));
1253 QCOMPARE(mm.typeName(), "");
1254 QCOMPARE(mm.parameterNames().size(), 0);
1255 QCOMPARE(mm.parameterTypes().size(), 0);
1258 QMetaMethod mm = mo->constructor(2);
1259 QCOMPARE(mm.access(), QMetaMethod::Public);
1260 QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
1261 QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass(QString)"));
1262 QCOMPARE(mm.typeName(), "");
1263 QList<QByteArray> paramNames = mm.parameterNames();
1264 QCOMPARE(paramNames.size(), 1);
1265 QCOMPARE(paramNames.at(0), QByteArray("str"));
1266 QList<QByteArray> paramTypes = mm.parameterTypes();
1267 QCOMPARE(paramTypes.size(), 1);
1268 QCOMPARE(paramTypes.at(0), QByteArray("QString"));
1271 QCOMPARE(mo->indexOfConstructor("CtorTestClass(QObject*)"), 0);
1272 QCOMPARE(mo->indexOfConstructor("CtorTestClass()"), 1);
1273 QCOMPARE(mo->indexOfConstructor("CtorTestClass(QString)"), 2);
1274 QCOMPARE(mo->indexOfConstructor("CtorTestClass2(QObject*)"), -1);
1275 QCOMPARE(mo->indexOfConstructor("CtorTestClass(float,float)"), -1);
1277 QObject *o1 = mo->newInstance();
1279 QCOMPARE(o1->parent(), (QObject*)0);
1280 QVERIFY(qobject_cast<CtorTestClass*>(o1) != 0);
1282 QObject *o2 = mo->newInstance(Q_ARG(QObject*, o1));
1284 QCOMPARE(o2->parent(), o1);
1286 QString str = QString::fromLatin1("hello");
1287 QObject *o3 = mo->newInstance(Q_ARG(QString, str));
1289 QCOMPARE(qobject_cast<CtorTestClass*>(o3)->m_str, str);
1292 //explicit constructor
1293 QObject *o = QObject::staticMetaObject.newInstance();
1299 #include "task234909.h"
1301 #include "task240368.h"
1303 void tst_Moc::typenameWithUnsigned()
1305 TypenameWithUnsigned tst;
1306 const QMetaObject *mobj = tst.metaObject();
1307 QVERIFY(mobj->indexOfSlot("a(uint)") != -1);
1308 QVERIFY(mobj->indexOfSlot("b(uint)") != -1);
1309 QVERIFY(mobj->indexOfSlot("c(uint*)") != -1);
1310 QVERIFY(mobj->indexOfSlot("d(uint*)") != -1);
1311 QVERIFY(mobj->indexOfSlot("e(uint&)") != -1);
1312 QVERIFY(mobj->indexOfSlot("f(uint&)") != -1);
1313 QVERIFY(mobj->indexOfSlot("g(unsigned1)") != -1);
1314 QVERIFY(mobj->indexOfSlot("h(unsigned1)") != -1);
1315 QVERIFY(mobj->indexOfSlot("i(uint,unsigned1)") != -1);
1316 QVERIFY(mobj->indexOfSlot("j(unsigned1,uint)") != -1);
1317 QVERIFY(mobj->indexOfSlot("k(unsignedQImage)") != -1);
1318 QVERIFY(mobj->indexOfSlot("l(unsignedQImage)") != -1);
1321 void tst_Moc::warnOnVirtualSignal()
1323 #ifdef MOC_CROSS_COMPILED
1324 QSKIP("Not tested when cross-compiled");
1326 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
1328 proc.start("moc", QStringList(srcify("pure-virtual-signals.h")));
1329 QVERIFY(proc.waitForFinished());
1330 QCOMPARE(proc.exitCode(), 0);
1331 QByteArray mocOut = proc.readAllStandardOutput();
1332 QVERIFY(!mocOut.isEmpty());
1333 QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
1334 QCOMPARE(mocWarning, QString(SRCDIR) + QString("/pure-virtual-signals.h:48: Warning: Signals cannot be declared virtual\n") +
1335 QString(SRCDIR) + QString("/pure-virtual-signals.h:50: Warning: Signals cannot be declared virtual\n"));
1337 QSKIP("Only tested on linux/gcc");
1341 class QTBUG5590_DummyObject: public QObject
1344 Q_PROPERTY(bool dummy)
1347 class QTBUG5590_PropertyObject: public QTBUG5590_DummyObject
1350 Q_PROPERTY(int value READ value WRITE setValue)
1351 Q_PROPERTY(int value2 READ value2 WRITE setValue2)
1354 QTBUG5590_PropertyObject() : m_value(85), m_value2(40) { }
1355 int value() const { return m_value; }
1356 void setValue(int value) { m_value = value; }
1357 int value2() const { return m_value2; }
1358 void setValue2(int value) { m_value2 = value; }
1360 int m_value, m_value2;
1363 void tst_Moc::QTBUG5590_dummyProperty()
1365 QTBUG5590_PropertyObject o;
1366 QCOMPARE(o.property("value").toInt(), 85);
1367 QCOMPARE(o.property("value2").toInt(), 40);
1368 o.setProperty("value", 32);
1369 QCOMPARE(o.value(), 32);
1370 o.setProperty("value2", 82);
1371 QCOMPARE(o.value2(), 82);
1374 class QTBUG7421_ReturnConstTemplate: public QObject
1377 const QList<int> returnConstTemplate1() { return QList<int>(); }
1378 QList<int> const returnConstTemplate2() { return QList<int>(); }
1379 const int returnConstInt() { return 0; }
1380 const QString returnConstString(const QString s) { return s; }
1381 QString const returnConstString2( QString const s) { return s; }
1384 class QTBUG9354_constInName: public QObject
1387 void slotChooseScientificConst0(struct science_constant const &) {};
1388 void foo(struct science_const const &) {};
1389 void foo(struct constconst const &) {};
1390 void foo(struct constconst *) {};
1391 void foo(struct const_ *) {};
1395 template<typename T1, typename T2>
1400 class QTBUG11647_constInTemplateParameter : public QObject
1403 void testSlot(TestTemplate2<const int, const short*>) {}
1404 void testSlot2(TestTemplate2<int, short const * const >) {}
1405 void testSlot3(TestTemplate2<TestTemplate2 < const int, const short* > const *,
1406 TestTemplate2< TestTemplate2 < void, int > , unsigned char *> > ) {}
1409 void testSignal(TestTemplate2<const int, const short*>);
1412 class QTBUG12260_defaultTemplate_Object : public QObject
1415 #if !(defined(Q_CC_GNU) && __GNUC__ == 4 && __GNUC_MINOR__ <= 3) || defined(Q_MOC_RUN)
1416 void doSomething(QHash<QString, QVariant> values = QHash<QString, QVariant>() ) { Q_UNUSED(values); }
1418 // we want to test the previous function, but gcc < 4.4 seemed to have a bug similar to the one moc has.
1419 typedef QHash<QString, QVariant> WorkaroundGCCBug;
1420 void doSomething(QHash<QString, QVariant> values = WorkaroundGCCBug() ) { Q_UNUSED(values); }
1423 void doAnotherThing(bool a = (1 < 3), bool b = (1 > 4)) { Q_UNUSED(a); Q_UNUSED(b); }
1427 void tst_Moc::QTBUG12260_defaultTemplate()
1429 QVERIFY(QTBUG12260_defaultTemplate_Object::staticMetaObject.indexOfSlot("doSomething(QHash<QString,QVariant>)") != -1);
1430 QVERIFY(QTBUG12260_defaultTemplate_Object::staticMetaObject.indexOfSlot("doAnotherThing(bool,bool)") != -1);
1433 void tst_Moc::notifyError()
1435 #ifdef MOC_CROSS_COMPILED
1436 QSKIP("Not tested when cross-compiled");
1438 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS)
1440 proc.start("moc", QStringList(srcify("error-on-wrong-notify.h")));
1441 QVERIFY(proc.waitForFinished());
1442 QCOMPARE(proc.exitCode(), 1);
1443 QCOMPARE(proc.exitStatus(), QProcess::NormalExit);
1444 QByteArray mocOut = proc.readAllStandardOutput();
1445 QVERIFY(mocOut.isEmpty());
1446 QString mocError = QString::fromLocal8Bit(proc.readAllStandardError());
1447 QCOMPARE(mocError, QString(SRCDIR) +
1448 QString("/error-on-wrong-notify.h:52: Error: NOTIFY signal 'fooChanged' of property 'foo' does not exist in class ClassWithWrongNOTIFY.\n"));
1450 QSKIP("Only tested on linux/gcc");
1454 class QTBUG_17635_InvokableAndProperty : public QObject
1458 Q_PROPERTY(int numberOfEggs READ numberOfEggs)
1459 Q_PROPERTY(int numberOfChickens READ numberOfChickens)
1460 Q_INVOKABLE QString getEgg(int index) { Q_UNUSED(index); return QString::fromLatin1("Egg"); }
1461 Q_INVOKABLE QString getChicken(int index) { Q_UNUSED(index); return QString::fromLatin1("Chicken"); }
1462 int numberOfEggs() { return 2; }
1463 int numberOfChickens() { return 4; }
1466 void tst_Moc::QTBUG17635_invokableAndProperty()
1468 //Moc used to fail parsing Q_INVOKABLE if they were dirrectly following a Q_PROPERTY;
1469 QTBUG_17635_InvokableAndProperty mc;
1471 QMetaObject::invokeMethod(&mc, "getEgg", Q_RETURN_ARG(QString, val), Q_ARG(int, 10));
1472 QCOMPARE(val, QString::fromLatin1("Egg"));
1473 QMetaObject::invokeMethod(&mc, "getChicken", Q_RETURN_ARG(QString, val), Q_ARG(int, 10));
1474 QCOMPARE(val, QString::fromLatin1("Chicken"));
1475 QVERIFY(mc.metaObject()->indexOfProperty("numberOfEggs") != -1);
1476 QVERIFY(mc.metaObject()->indexOfProperty("numberOfChickens") != -1);
1479 // If changed, update VersionTestNotify below
1480 class VersionTest : public QObject
1483 Q_PROPERTY(int prop1 READ foo)
1484 Q_PROPERTY(int prop2 READ foo REVISION 2)
1488 int foo() const { return 0; }
1490 Q_INVOKABLE void method1() {}
1491 Q_INVOKABLE Q_REVISION(4) void method2() {}
1493 enum TestEnum { One, Two };
1497 Q_REVISION(3) void slot2() {}
1501 Q_REVISION(5) void signal2();
1503 public slots Q_REVISION(6):
1507 signals Q_REVISION(7):
1512 // If changed, update VersionTest above
1513 class VersionTestNotify : public QObject
1516 Q_PROPERTY(int prop1 READ foo NOTIFY fooChanged)
1517 Q_PROPERTY(int prop2 READ foo REVISION 2)
1521 int foo() const { return 0; }
1523 Q_INVOKABLE void method1() {}
1524 Q_INVOKABLE Q_REVISION(4) void method2() {}
1526 enum TestEnum { One, Two };
1530 Q_REVISION(3) void slot2() {}
1535 Q_REVISION(5) void signal2();
1537 public slots Q_REVISION(6):
1541 signals Q_REVISION(7):
1547 void tst_Moc::revisions_T()
1549 int idx = T::staticMetaObject.indexOfProperty("prop1");
1550 QVERIFY(T::staticMetaObject.property(idx).revision() == 0);
1551 idx = T::staticMetaObject.indexOfProperty("prop2");
1552 QVERIFY(T::staticMetaObject.property(idx).revision() == 2);
1554 idx = T::staticMetaObject.indexOfMethod("method1()");
1555 QVERIFY(T::staticMetaObject.method(idx).revision() == 0);
1556 idx = T::staticMetaObject.indexOfMethod("method2()");
1557 QVERIFY(T::staticMetaObject.method(idx).revision() == 4);
1559 idx = T::staticMetaObject.indexOfSlot("slot1()");
1560 QVERIFY(T::staticMetaObject.method(idx).revision() == 0);
1561 idx = T::staticMetaObject.indexOfSlot("slot2()");
1562 QVERIFY(T::staticMetaObject.method(idx).revision() == 3);
1564 idx = T::staticMetaObject.indexOfSlot("slot3()");
1565 QVERIFY(T::staticMetaObject.method(idx).revision() == 6);
1566 idx = T::staticMetaObject.indexOfSlot("slot4()");
1567 QVERIFY(T::staticMetaObject.method(idx).revision() == 6);
1569 idx = T::staticMetaObject.indexOfSignal("signal1()");
1570 QVERIFY(T::staticMetaObject.method(idx).revision() == 0);
1571 idx = T::staticMetaObject.indexOfSignal("signal2()");
1572 QVERIFY(T::staticMetaObject.method(idx).revision() == 5);
1574 idx = T::staticMetaObject.indexOfSignal("signal3()");
1575 QVERIFY(T::staticMetaObject.method(idx).revision() == 7);
1576 idx = T::staticMetaObject.indexOfSignal("signal4()");
1577 QVERIFY(T::staticMetaObject.method(idx).revision() == 7);
1579 idx = T::staticMetaObject.indexOfEnumerator("TestEnum");
1580 QCOMPARE(T::staticMetaObject.enumerator(idx).keyCount(), 2);
1581 QCOMPARE(T::staticMetaObject.enumerator(idx).key(0), "One");
1584 // test using both class that has properties with and without NOTIFY signals
1585 void tst_Moc::revisions()
1587 revisions_T<VersionTest>();
1588 revisions_T<VersionTestNotify>();
1591 void tst_Moc::warnings_data()
1593 QTest::addColumn<QByteArray>("input");
1594 QTest::addColumn<QStringList>("args");
1595 QTest::addColumn<int>("exitCode");
1596 QTest::addColumn<QString>("expectedStdOut");
1597 QTest::addColumn<QString>("expectedStdErr");
1599 // empty input should result in "no relevant classes" note
1600 QTest::newRow("No relevant classes")
1605 << QString("standard input:0: Note: No relevant classes found. No output generated.");
1607 // passing "-nn" should suppress "no relevant classes" note
1608 QTest::newRow("-nn")
1610 << (QStringList() << "-nn")
1615 // passing "-nw" should also suppress "no relevant classes" note
1616 QTest::newRow("-nw")
1618 << (QStringList() << "-nw")
1623 // This should output a warning
1624 QTest::newRow("Invalid property warning")
1625 << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };")
1628 << QString("IGNORE_ALL_STDOUT")
1629 << QString("standard input:1: Warning: Property declaration x has no READ accessor function. The property will be invalid.");
1631 // Passing "-nn" should NOT suppress the warning
1632 QTest::newRow("Invalid property warning with -nn")
1633 << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };")
1634 << (QStringList() << "-nn")
1636 << QString("IGNORE_ALL_STDOUT")
1637 << QString("standard input:1: Warning: Property declaration x has no READ accessor function. The property will be invalid.");
1639 // Passing "-nw" should suppress the warning
1640 QTest::newRow("Invalid property warning with -nw")
1641 << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };")
1642 << (QStringList() << "-nw")
1644 << QString("IGNORE_ALL_STDOUT")
1647 // This should output an error
1648 QTest::newRow("Does not inherit QObject")
1649 << QByteArray("class X { Q_OBJECT };")
1653 << QString("standard input:1: Error: Class contains Q_OBJECT macro but does not inherit from QObject");
1655 // "-nn" should not suppress the error
1656 QTest::newRow("Does not inherit QObject with -nn")
1657 << QByteArray("class X { Q_OBJECT };")
1658 << (QStringList() << "-nn")
1661 << QString("standard input:1: Error: Class contains Q_OBJECT macro but does not inherit from QObject");
1663 // "-nw" should not suppress the error
1664 QTest::newRow("Does not inherit QObject with -nw")
1665 << QByteArray("class X { Q_OBJECT };")
1666 << (QStringList() << "-nw")
1669 << QString("standard input:1: Error: Class contains Q_OBJECT macro but does not inherit from QObject");
1672 void tst_Moc::warnings()
1674 #ifdef MOC_CROSS_COMPILED
1675 QSKIP("Not tested when cross-compiled");
1677 QFETCH(QByteArray, input);
1678 QFETCH(QStringList, args);
1679 QFETCH(int, exitCode);
1680 QFETCH(QString, expectedStdOut);
1681 QFETCH(QString, expectedStdErr);
1684 // for some reasons, moc compiled with MSVC uses a different output format
1685 QRegExp lineNumberRe(":(\\d+):");
1686 lineNumberRe.setMinimal(true);
1687 expectedStdErr.replace(lineNumberRe, "(\\1):");
1691 proc.start("moc", args);
1692 QVERIFY(proc.waitForStarted());
1694 QCOMPARE(proc.write(input), qint64(input.size()));
1696 proc.closeWriteChannel();
1698 QVERIFY(proc.waitForFinished());
1700 QCOMPARE(proc.exitCode(), exitCode);
1701 QCOMPARE(proc.exitStatus(), QProcess::NormalExit);
1703 // magic value "IGNORE_ALL_STDOUT" ignores stdout
1704 if (expectedStdOut != "IGNORE_ALL_STDOUT")
1705 QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardOutput()).trimmed(), expectedStdOut);
1706 QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()).trimmed(), expectedStdErr);
1709 class tst_Moc::PrivateClass : public QObject {
1710 Q_PROPERTY(int someProperty READ someSlot WRITE someSlot2)
1715 int someSlot() { return 1; }
1716 void someSlot2(int) {}
1718 Q_INVOKABLE PrivateClass() {}
1721 void tst_Moc::privateClass()
1723 QVERIFY(PrivateClass::staticMetaObject.indexOfConstructor("PrivateClass()") == 0);
1724 QVERIFY(PrivateClass::staticMetaObject.indexOfSignal("someSignal()") > 0);
1727 void tst_Moc::cxx11Enums_data()
1729 QTest::addColumn<QByteArray>("enumName");
1730 QTest::addColumn<char>("prefix");
1732 QTest::newRow("EnumClass") << QByteArray("EnumClass") << 'A';
1733 QTest::newRow("TypedEnum") << QByteArray("TypedEnum") << 'B';
1734 QTest::newRow("TypedEnumClass") << QByteArray("TypedEnumClass") << 'C';
1735 QTest::newRow("NormalEnum") << QByteArray("NormalEnum") << 'D';
1739 void tst_Moc::cxx11Enums()
1741 const QMetaObject *meta = &CXX11Enums::staticMetaObject;
1742 QCOMPARE(meta->enumeratorOffset(), 0);
1744 QFETCH(QByteArray, enumName);
1745 QFETCH(char, prefix);
1748 idx = meta->indexOfEnumerator(enumName);
1750 QCOMPARE(meta->enumerator(idx).enclosingMetaObject(), meta);
1751 QCOMPARE(meta->enumerator(idx).isValid(), true);
1752 QCOMPARE(meta->enumerator(idx).keyCount(), 4);
1753 QCOMPARE(meta->enumerator(idx).name(), enumName.constData());
1754 for (int i = 0; i < 4; i++) {
1755 QByteArray v = prefix + QByteArray::number(i);
1756 QCOMPARE(meta->enumerator(idx).keyToValue(v), i);
1757 QCOMPARE(meta->enumerator(idx).valueToKey(i), v.constData());
1761 void tst_Moc::returnRefs()
1764 const QMetaObject *mobj = tst.metaObject();
1765 QVERIFY(mobj->indexOfMethod("myInvokableReturningRef()") != -1);
1766 QVERIFY(mobj->indexOfMethod("myInvokableReturningConstRef()") != -1);
1767 // Those two functions are copied from the qscriptextqobject test in qtscript
1768 // they used to cause miscompilation of the moc generated file.
1772 #include "tst_moc.moc"