QtBase  v6.3.1
tst_moc.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2020 The Qt Company Ltd.
4 ** Copyright (C) 2020 Olivier Goffart <ogoffart@woboq.com>
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
22 ** included in the packaging of this file. Please review the following
23 ** information to ensure the GNU General Public License requirements will
24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 **
26 ** $QT_END_LICENSE$
27 **
28 ****************************************************************************/
29 
30 #include <QTest>
31 #include <QSignalSpy>
32 #include <stdio.h>
33 #include <qobject.h>
34 #include <qmetaobject.h>
35 #include <qjsondocument.h>
36 #include <qversionnumber.h>
37 #include <qregularexpression.h>
38 
39 #include "using-namespaces.h"
40 #include "assign-namespace.h"
41 #include "no-keywords.h"
43 #include "backslash-newlines.h"
45 #include "qinvokable.h"
46 // msvc and friends crap out on it
47 #if !defined(Q_CC_GNU) || defined(Q_OS_WIN)
48 #define SKIP_NEWLINE_TEST
49 #endif
50 #if !defined(SKIP_NEWLINE_TEST)
51 #include "os9-newlines.h"
52 // msvc and friends crap out on this file too,
53 // it seems to contain Mac 9 EOLs, and not windows EOLs.
54 #include "win-newlines.h"
55 #endif
57 #include "cstyle-enums.h"
58 
59 #if defined(PARSE_BOOST)
60 #include "parse-boost.h"
61 #endif
62 #include "cxx11-enums.h"
63 #include "cxx11-final-classes.h"
65 #include "cxx11-trailing-return.h"
66 
67 #include "parse-defines.h"
71 
74 #include "namespace.h"
75 #include "cxx17-namespaces.h"
76 #include "cxx-attributes.h"
77 
78 #include "moc_include.h"
79 #include "pointery_to_incomplete.h"
80 #include "fwdclass1.h"
81 #include "fwdclass2.h"
82 #include "fwdclass3.h"
83 
84 #ifdef Q_MOC_RUN
85 // check that moc can parse these constructs, they are being used in Windows winsock2.h header
86 #define STRING_HASH_HASH(x) ("foo" ## x ## "bar")
87 const char *string_hash_hash = STRING_HASH_HASH("baz");
88 #endif
89 
90 Q_DECLARE_METATYPE(const QMetaObject*);
91 
92 #define TESTEXPORTMACRO Q_DECL_EXPORT
93 
94 namespace TestNonQNamespace {
95 
96 struct TestGadget {
97  Q_GADGET
98  Q_CLASSINFO("key", "value")
99 public:
100  enum class TestGEnum1 {
101  Key1 = 11,
102  Key2
103  };
105 
106  enum class TestGEnum2 {
107  Key1 = 17,
108  Key2
109  };
111 };
112 
113 }
114 
115 namespace TestQNamespace {
117  enum class TestEnum1 {
118  Key1 = 11,
119  Key2
120  };
122 
123  enum class TestEnum2 {
124  Key1 = 17,
125  Key2
126  };
128 
129  // try to dizzy moc by adding a struct in between
130  struct TestGadget {
131  Q_GADGET
132  public:
133  enum class TestGEnum1 {
134  Key1 = 13,
135  Key2
136  };
137  enum class TestGEnum2 {
138  Key1 = 23,
139  Key2
140  };
141  Q_ENUM(TestGEnum1)
142  Q_ENUM(TestGEnum2)
143  };
144 
147  Q_CLASSINFO("key", "exported")
148  public:
149  enum class TestGeEnum1 {
150  Key1 = 20,
151  Key2
152  };
154  enum class TestGeEnum2 {
155  Key1 = 23,
156  Key2
157  };
159  };
160 
161  enum class TestFlag1 {
162  None = 0,
163  Flag1 = 1,
164  Flag2 = 2,
165  Any = Flag1 | Flag2
166  };
168 
169  enum class TestFlag2 {
170  None = 0,
171  Flag1 = 4,
172  Flag2 = 8,
173  Any = Flag1 | Flag2
174  };
176 }
177 
178 
181  enum class MyEnum {
182  Key1, Key2
183  };
185 }
186 
188 
189 template <bool b> struct QTBUG_31218 {};
190 struct QTBUG_31218_Derived : QTBUG_31218<-1<0> {};
191 
192 #if defined(Q_MOC_RUN)
193  class QTBUG_45790 : Bug() { };
194 #endif
195 
196 class CreatableGadget
197 {
198  Q_GADGET
199 public:
200  Q_INVOKABLE CreatableGadget()
201  {
202  CreatableGadget::qt_static_metacall((QObject*)this, QMetaObject::ReadProperty, -1, nullptr);
203  }
204 };
205 
206 CreatableGadget creatableGadget; // Force the compiler to use the constructor
207 
208 struct MyStruct {};
209 struct MyStruct2 {};
210 
211 struct SuperClass {};
212 
213 // Try to avoid inserting for instance a comment with a quote between the following line and the Q_OBJECT
214 // That will make the test give a false positive.
215 const char* test_multiple_number_of_escapes = "\\\"";
216 namespace MyNamespace
217 {
218  class TestSuperClass : public QObject
219  {
220  Q_OBJECT
221  public:
222  inline TestSuperClass() {}
223  };
224 }
225 
226 namespace String
227 {
228  typedef QString Type;
229 }
230 
231 namespace Int
232 {
233  typedef int Type;
234 }
235 
236 typedef struct {
237  int doNotConfuseMoc;
238 } OldStyleCStruct;
239 
240 namespace {
241 
242  class GadgetInUnnamedNS
243  {
244  Q_GADGET
245  Q_PROPERTY(int x READ x WRITE setX)
246  Q_PROPERTY(int y READ y WRITE setY)
247  public:
248  explicit GadgetInUnnamedNS(int x, int y) : m_x(x), m_y(y) {}
249  int x() const { return m_x; }
250  int y() const { return m_y; }
251  void setX(int x) { m_x = x; }
252  void setY(int y) { m_y = y; }
253 
254  private:
255  int m_x, m_y;
256  };
257 
258  class ObjectInUnnamedNS : public QObject
259  {
260  Q_OBJECT
261  public:
262  explicit ObjectInUnnamedNS(QObject *parent = nullptr) : QObject(parent) {}
263  };
264 
265 }
266 
267 class Sender : public QObject
268 {
269  Q_OBJECT
270 
271 public:
272  void sendValue(const String::Type& value)
273  {
274  emit send(value);
275  }
276  void sendValue(const Int::Type& value)
277  {
278  emit send(value);
279  }
280 
281  bool operator< ( const Sender & ) const { /* QTBUG-36834 */ return true;}
282 signals:
283  void send(const String::Type&);
284  void send(const Int::Type&);
285 };
286 
287 class Receiver : public QObject
288 {
289  Q_OBJECT
290 public:
291  Receiver() : stringCallCount(0), intCallCount(0) {}
292 
293  int stringCallCount;
294  int intCallCount;
295 
296 public slots:
297  void receive(const String::Type&) { stringCallCount++; }
298  void receive(const Int::Type&) { intCallCount++; }
299 };
300 
301 #define MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES
302 
303 #define DONT_CONFUSE_MOC(klass) klass
304 #define DONT_CONFUSE_MOC_EVEN_MORE(klass, dummy, dummy2) klass
305 
306 Q_DECLARE_METATYPE(MyStruct)
307 Q_DECLARE_METATYPE(MyStruct*)
308 
309 namespace myNS {
310  struct Points
311  {
312  Points() : p1(0xBEEF), p2(0xBABE) { }
313  int p1, p2;
314  };
315 }
316 
317 Q_DECLARE_METATYPE(myNS::Points)
318 
319 class TestClassinfoWithEscapes: public QObject
320 {
321  Q_OBJECT
322  Q_CLASSINFO("escaped", "\"bar\"")
323  Q_CLASSINFO("\"escaped\"", "foo")
324  Q_CLASSINFO("cpp c*/omment", "f/*oo")
325  Q_CLASSINFO("endswith\\", "Or?\?/")
326  Q_CLASSINFO("newline\n inside\n", "Or \r")
327 public slots:
328  void slotWithAReallyLongName(int)
329  { }
330 };
331 
332 #define CLASSINFO_VAARGS(...) Q_CLASSINFO("classinfo_va_args", #__VA_ARGS__)
333 class TestClassinfoFromVaArgs : public QObject
334 {
335  Q_OBJECT
336  CLASSINFO_VAARGS(a, b, c, d)
337 };
338 #undef CLASSINFO_VAARGS
339 
340 struct ForwardDeclaredStruct;
341 
342 struct StructQObject : public QObject
343 {
344  Q_OBJECT
345 public:
346  void foo(struct ForwardDeclaredStruct *);
347 };
348 
349 QT_WARNING_PUSH
350 QT_WARNING_DISABLE_GCC("-Wunused-variable")
351 void StructQObject::foo(struct ForwardDeclaredStruct *)
352 {
353  struct Inner {
354  bool field;
355  };
356 
357  Q_DECL_UNUSED_MEMBER struct Inner unusedVariable;
358 }
359 QT_WARNING_POP
360 
361 QT_WARNING_PUSH
362 QT_WARNING_DISABLE_CLANG("-Wignored-qualifiers")
363 QT_WARNING_DISABLE_GCC("-Wignored-qualifiers")
364 
365 using ObjectCRef = const QObject &;
366 
367 class TestClass : public MyNamespace::TestSuperClass, public DONT_CONFUSE_MOC(MyStruct),
368  public DONT_CONFUSE_MOC_EVEN_MORE(MyStruct2, dummy, ignored)
369 {
370  Q_OBJECT
371  Q_CLASSINFO("help", QT_TR_NOOP("Opening this will let you configure something"))
372  Q_PROPERTY(short int shortIntProperty READ shortIntProperty)
373  Q_PROPERTY(unsigned short int unsignedShortIntProperty READ unsignedShortIntProperty)
374  Q_PROPERTY(signed short int signedShortIntProperty READ signedShortIntProperty)
375  Q_PROPERTY(long int longIntProperty READ longIntProperty)
376  Q_PROPERTY(unsigned long int unsignedLongIntProperty READ unsignedLongIntProperty)
377  Q_PROPERTY(signed long int signedLongIntProperty READ signedLongIntProperty)
378  Q_PROPERTY(long double longDoubleProperty READ longDoubleProperty)
379  Q_PROPERTY(myNS::Points points READ points WRITE setPoints)
380 
381  Q_CLASSINFO("Multi"
382  "line",
383  ""
384  "This is a "
385  "multiline Q_CLASSINFO"
386  "")
387 
388  // a really really long string that we have to cut into pieces in the generated stringdata
389  // table, otherwise msvc craps out
390  Q_CLASSINFO("D-Bus Introspection", ""
391 " <interface name=\"org.kde.KCookieServer\" >\n"
392 " <method name=\"findCookies\" >\n"
393 " <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
394 " <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
395 " <arg direction=\"out\" type=\"s\" name=\"cookies\" />\n"
396 " </method>\n"
397 " <method name=\"findDomains\" >\n"
398 " <arg direction=\"out\" type=\"as\" name=\"domains\" />\n"
399 " </method>\n"
400 " <method name=\"findCookies\" >\n"
401 " <arg direction=\"in\" type=\"ai\" name=\"fields\" />\n"
402 " <arg direction=\"in\" type=\"s\" name=\"domain\" />\n"
403 " <arg direction=\"in\" type=\"s\" name=\"fqdn\" />\n"
404 " <arg direction=\"in\" type=\"s\" name=\"path\" />\n"
405 " <arg direction=\"in\" type=\"s\" name=\"name\" />\n"
406 " <arg direction=\"out\" type=\"as\" name=\"cookies\" />\n"
407 " <annotation value=\"QList&lt;int>\" name=\"com.trolltech.QtDBus.QtTypeName.In0\" />\n"
408 " </method>\n"
409 " <method name=\"findDOMCookies\" >\n"
410 " <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
411 " <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
412 " <arg direction=\"out\" type=\"s\" name=\"cookies\" />\n"
413 " </method>\n"
414 " <method name=\"addCookies\" >\n"
415 " <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
416 " <arg direction=\"in\" type=\"ay\" name=\"cookieHeader\" />\n"
417 " <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
418 " </method>\n"
419 " <method name=\"deleteCookie\" >\n"
420 " <arg direction=\"in\" type=\"s\" name=\"domain\" />\n"
421 " <arg direction=\"in\" type=\"s\" name=\"fqdn\" />\n"
422 " <arg direction=\"in\" type=\"s\" name=\"path\" />\n"
423 " <arg direction=\"in\" type=\"s\" name=\"name\" />\n"
424 " </method>\n"
425 " <method name=\"deleteCookiesFromDomain\" >\n"
426 " <arg direction=\"in\" type=\"s\" name=\"domain\" />\n"
427 " </method>\n"
428 " <method name=\"deleteSessionCookies\" >\n"
429 " <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
430 " </method>\n"
431 " <method name=\"deleteSessionCookiesFor\" >\n"
432 " <arg direction=\"in\" type=\"s\" name=\"fqdn\" />\n"
433 " <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
434 " </method>\n"
435 " <method name=\"deleteAllCookies\" />\n"
436 " <method name=\"addDOMCookies\" >\n"
437 " <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
438 " <arg direction=\"in\" type=\"ay\" name=\"cookieHeader\" />\n"
439 " <arg direction=\"in\" type=\"x\" name=\"windowId\" />\n"
440 " </method>\n"
441 " <method name=\"setDomainAdvice\" >\n"
442 " <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
443 " <arg direction=\"in\" type=\"s\" name=\"advice\" />\n"
444 " </method>\n"
445 " <method name=\"getDomainAdvice\" >\n"
446 " <arg direction=\"in\" type=\"s\" name=\"url\" />\n"
447 " <arg direction=\"out\" type=\"s\" name=\"advice\" />\n"
448 " </method>\n"
449 " <method name=\"reloadPolicy\" />\n"
450 " <method name=\"shutdown\" />\n"
451 " </interface>\n"
452  "")
453 
454 public:
455  inline TestClass() {}
456 
457 private slots:
458  inline void dummy1() MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES {}
459  inline void dummy2() MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES const {}
460  inline void dummy3() const MACRO_WITH_POSSIBLE_COMPILER_SPECIFIC_ATTRIBUTES {}
461 
462  void slotWithULongLong(unsigned long long) {}
463  void slotWithULongLongP(unsigned long long*) {}
464  void slotWithULong(unsigned long) {}
465  void slotWithLongLong(long long) {}
466  void slotWithLong(long) {}
467 
468  void slotWithColonColonType(::Int::Type) {}
469 
470  TestClass &slotWithReferenceReturnType() { return *this; }
471 
472 #if (0 && 1) || 1
473  void expressionEvaluationShortcut1() {}
474 #endif
475 #if (1 || 0) && 0
476 #else
477  void expressionEvaluationShortcut2() {}
478 #endif
479 
480 public slots:
481  void slotWithArray(const double[3]) {}
482  void slotWithNamedArray(const double namedArray[3]) { Q_UNUSED(namedArray); }
483  void slotWithMultiArray(const double[3][4]) {}
484 
485  short int shortIntProperty() { return 0; }
486  unsigned short int unsignedShortIntProperty() { return 0; }
487  signed short int signedShortIntProperty() { return 0; }
488  long int longIntProperty() { return 0; }
489  unsigned long int unsignedLongIntProperty() { return 0; }
490  signed long int signedLongIntProperty() { return 0; }
491  long double longDoubleProperty() { return 0.0; }
492 
493  myNS::Points points() { return m_points; }
494  void setPoints(myNS::Points points) { m_points = points; }
495 
496 signals:
497  void signalWithArray(const double[3]);
498  void signalWithNamedArray(const double namedArray[3]);
499  void signalWithIterator(QList<QUrl>::iterator);
500  void signalWithListPointer(QList<QUrl>*); //QTBUG-31002
501 
502 private slots:
503  // for tst_Moc::preprocessorConditionals
504 #if 0
505  void invalidSlot() {}
506 #else
507  void slotInElse() {}
508 #endif
509 
510 #if 1
511  void slotInIf() {}
512 #else
513  void invalidSlot() {}
514 #endif
515 
516 #if 0
517  void invalidSlot() {}
518 #elif 0
519 #else
520  void slotInLastElse() {}
521 #endif
522 
523 #if 0
524  void invalidSlot() {}
525 #elif 1
526  void slotInElif() {}
527 #else
528  void invalidSlot() {}
529 #endif
530 
531  friend class Receiver; // task #85783
532 signals:
533  friend class Sender; // task #85783
534 
535 #define MACRO_DEFINED
536 
537 #if !(defined MACRO_UNDEF || defined MACRO_DEFINED) || 1
538  void signalInIf1();
539 #else
540  void doNotExist();
541 #endif
542 #if !(!defined MACRO_UNDEF || !defined MACRO_DEFINED) && 1
543  void doNotExist();
544 #else
545  void signalInIf2();
546 #endif
547 #if !(!defined (MACRO_DEFINED) || !defined (MACRO_UNDEF)) && 1
548  void doNotExist();
549 #else
550  void signalInIf3();
551 #endif
552 
553 # //QTBUG-22717
554  # /* */
555 #
556 
557  # \
558 
559 //
560 public slots:
561  void const slotWithSillyConst() {}
562  void slotTakingCRefViaTypedef(ObjectCRef o) { this->setObjectName(o.objectName()); }
563 
564 public:
565  Q_INVOKABLE void const slotWithSillyConst2() {}
566  Q_INVOKABLE QObject& myInvokableReturningRef()
567  { return *this; }
568  Q_INVOKABLE const QObject& myInvokableReturningConstRef() const
569  { return *this; }
570 
571 
572  // that one however should be fine
573 public slots:
574  void slotWithVoidStar(void *) {}
575 
576 private:
577  myNS::Points m_points;
578 
579 #ifdef Q_MOC_RUN
580  int xx = 11'11; // digit separator must not confuse moc (QTBUG-59351)
581  int xx = 0b11'11; // digit separator in a binary literal must not confuse moc (QTBUG-75656)
582 #endif
583 
584 private slots:
585  inline virtual void blub1() {}
586  virtual inline void blub2() {}
587 };
588 
589 QT_WARNING_POP
590 
591 class PropertyTestClass : public QObject
592 {
593  Q_OBJECT
594 public:
595 
596  enum TestEnum { One, Two, Three };
597 
598  Q_ENUM(TestEnum)
599 };
600 
601 class PropertyUseClass : public QObject
602 {
603  Q_OBJECT
604  Q_PROPERTY(PropertyTestClass::TestEnum foo READ foo)
605 public:
606 
607  inline PropertyTestClass::TestEnum foo() const { return PropertyTestClass::One; }
608 };
609 
610 class EnumSourceClass : public QObject
611 {
612  Q_OBJECT
613 
614 public:
615  enum TestEnum { Value = 37 };
616 
617  Q_ENUM(TestEnum)
618 };
619 
620 class EnumUserClass : public QObject
621 {
622  Q_OBJECT
623 
624 public:
625  Q_ENUMS(EnumSourceClass::TestEnum)
626 };
627 
628 class CtorTestClass : public QObject
629 {
630  Q_OBJECT
631 public:
632  Q_INVOKABLE CtorTestClass(QObject *parent = nullptr);
633 
634  CtorTestClass(int foo);
635 
636  inline Q_INVOKABLE CtorTestClass(const QString &str)
637  { m_str = str; }
638 
639  QString m_str;
640 
641 protected:
642  CtorTestClass(int foo, int bar, int baz);
643 private:
644  CtorTestClass(float, float) {}
645 };
646 
647 CtorTestClass::CtorTestClass(QObject *parent)
648  : QObject(parent) {}
649 
650 CtorTestClass::CtorTestClass(int, int, int) {}
651 
652 class PrivatePropertyTest;
653 
654 class tst_Moc : public QObject
655 {
656  Q_OBJECT
657 
658  Q_PROPERTY(bool user1 READ user1 USER true )
659  Q_PROPERTY(bool user2 READ user2 USER false)
660  Q_PROPERTY(QString member1 MEMBER sMember)
661  Q_PROPERTY(QString member2 MEMBER sMember READ member2)
662  Q_PROPERTY(QString member3 MEMBER sMember WRITE setMember3)
663  Q_PROPERTY(QString member4 MEMBER sMember NOTIFY member4Changed)
664  Q_PROPERTY(QString member5 MEMBER sMember NOTIFY member5Changed)
665  Q_PROPERTY(QString member6 MEMBER sConst CONSTANT)
666  Q_PROPERTY(QString sub1 MEMBER (sub.m_string))
667  Q_PROPERTY(QString sub2 READ (sub.string) WRITE (sub.setString))
668 
669 public:
670  inline tst_Moc() : sConst("const") {}
671 
672 private slots:
673  void initTestCase();
674 
675  void dontStripNamespaces();
676  void oldStyleCasts();
677  void warnOnExtraSignalSlotQualifiaction();
678  void uLongLong();
679  void inputFileNameWithDotsButNoExtension();
680  void userProperties();
681  void supportConstSignals();
682  void task87883();
683  void multilineComments();
684  void classinfoWithEscapes();
685  void classinfoFromVaArgs();
686  void trNoopInClassInfo();
687  void ppExpressionEvaluation();
688  void arrayArguments();
689  void preprocessorConditionals();
690  void blackslashNewlines();
691  void slotWithSillyConst();
692  void slotTakingCRefViaTypedef();
693  void testExtraData();
694  void testExtraDataForEnum();
695  void namespaceTypeProperty();
696  void slotsWithVoidTemplate();
697  void structQObject();
698  void namespacedFlags();
699  void warnOnMultipleInheritance();
700  void ignoreOptionClashes();
701  void forgottenQInterface();
702  void os9Newline();
703  void winNewline();
704  void escapesInStringLiterals();
705  void frameworkSearchPath();
706  void cstyleEnums();
707  void defineMacroViaCmdline();
708  void defineMacroViaForcedInclude();
709  void defineMacroViaForcedIncludeRelative();
710  void environmentIncludePaths_data();
711  void environmentIncludePaths();
712  void specifyMetaTagsFromCmdline();
713  void invokable();
714  void singleFunctionKeywordSignalAndSlot();
715  void templateGtGt();
716  void qprivateslots();
717  void qprivateproperties();
718  void warnOnPropertyWithoutREAD();
719  void constructors();
720  void typenameWithUnsigned();
721  void warnOnVirtualSignal();
722  void QTBUG5590_dummyProperty();
723  void QTBUG12260_defaultTemplate();
724  void notifyError();
725  void QTBUG17635_invokableAndProperty();
726  void revisions();
727  void warnings_data();
728  void warnings();
729  void privateClass();
730  void cxx11Enums_data();
731  void cxx11Enums();
732  void cxx11TrailingReturn();
733  void returnRefs();
734  void memberProperties_data();
735  void memberProperties();
736  void memberProperties2();
737  void privateSignalConnection();
738  void finalClasses_data();
739  void finalClasses();
740  void explicitOverrideControl_data();
741  void explicitOverrideControl();
742  void overloadedAddressOperator();
743  void autoPropertyMetaTypeRegistration();
744  void autoMethodArgumentMetaTypeRegistration();
745  void autoSignalSpyMetaTypeRegistration();
746  void parseDefines();
747  void preprocessorOnly();
748  void unterminatedFunctionMacro();
749  void QTBUG32933_relatedObjectsDontIncludeItself();
750  void writeEnumFromUnrelatedClass();
751  void relatedMetaObjectsWithinNamespaces();
752  void relatedMetaObjectsInGadget();
753  void relatedMetaObjectsNameConflict_data();
754  void relatedMetaObjectsNameConflict();
755  void strignLiteralsInMacroExtension();
756  void unnamedNamespaceObjectsAndGadgets();
757  void veryLongStringData();
758  void gadgetHierarchy();
759  void optionsFileError_data();
760  void optionsFileError();
761  void testQNamespace();
762  void cxx17Namespaces();
763  void cxxAttributes();
764  void mocJsonOutput();
765  void mocInclude();
766  void requiredProperties();
767  void qpropertyMembers();
768  void observerMetaCall();
769  void setQPRopertyBinding();
770  void privateQPropertyShim();
771 
772 signals:
773  void sigWithUnsignedArg(unsigned foo);
774  void sigWithSignedArg(signed foo);
775  void sigWithConstSignedArg(const signed foo);
776  void sigWithVolatileConstSignedArg(volatile const signed foo);
777  void sigWithCustomType(const MyStruct);
778  void constSignal1() const;
779  void constSignal2(int arg) const;
780  void member4Changed();
781  void member5Changed(const QString &newVal);
782 
783 private:
784  bool user1() { return true; };
785  bool user2() { return false; };
786  template <class T> void revisions_T();
787  QString member2() const { return sMember; }
788  void setMember3( const QString &sVal ) { sMember = sVal; }
789 
790 private:
791  QString m_moc;
792  QString m_sourceDirectory;
793  QString qtIncludePath;
794  class PrivateClass;
795  QString sMember;
796  const QString sConst;
797  PrivatePropertyTest *pPPTest;
798 
799  struct {
800  QString m_string;
801  void setString(const QString &s) { m_string = s; }
802  QString string() { return m_string; }
803  } sub;
804 
805 };
806 
807 void tst_Moc::initTestCase()
808 {
809  QString binpath = QLibraryInfo::path(QLibraryInfo::BinariesPath);
810  QString qtpaths = QString("%1/qtpaths").arg(binpath);
811  QString libexecPath = QLibraryInfo::path(QLibraryInfo::LibraryExecutablesPath);
812  m_moc = QString("%1/moc").arg(libexecPath);
813 
814  const QString testHeader = QFINDTESTDATA("backslash-newlines.h");
815  QVERIFY(!testHeader.isEmpty());
816  m_sourceDirectory = QFileInfo(testHeader).absolutePath();
817 #if defined(Q_OS_UNIX) && QT_CONFIG(process)
818  QProcess proc;
819  proc.start(qtpaths, QStringList() << "-query" << "QT_INSTALL_HEADERS");
820  QVERIFY(proc.waitForFinished());
821  QCOMPARE(proc.exitCode(), 0);
822  QByteArray output = proc.readAllStandardOutput();
823  QVERIFY(!output.isEmpty());
824  QCOMPARE(proc.readAllStandardError(), QByteArray());
825  qtIncludePath = QString::fromLocal8Bit(output).trimmed();
826  QFileInfo fi(qtIncludePath);
827  QVERIFY(fi.exists());
828  QVERIFY(fi.isDir());
829 #endif
830 }
831 
832 void tst_Moc::dontStripNamespaces()
833 {
834  Sender sender;
835  Receiver receiver;
836 
837  connect(&sender, SIGNAL(send(const String::Type &)),
838  &receiver, SLOT(receive(const String::Type &)));
839  connect(&sender, SIGNAL(send(const Int::Type &)),
840  &receiver, SLOT(receive(const Int::Type &)));
841 
842  sender.sendValue(String::Type("Hello"));
843  QCOMPARE(receiver.stringCallCount, 1);
844  QCOMPARE(receiver.intCallCount, 0);
845  sender.sendValue(Int::Type(42));
846  QCOMPARE(receiver.stringCallCount, 1);
847  QCOMPARE(receiver.intCallCount, 1);
848 }
849 
850 void tst_Moc::oldStyleCasts()
851 {
852 #ifdef MOC_CROSS_COMPILED
853  QSKIP("Not tested when cross-compiled");
854 #endif
855 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && QT_CONFIG(process)
856  QProcess proc;
857  proc.start(m_moc, QStringList(m_sourceDirectory + QStringLiteral("/oldstyle-casts.h")));
858  QVERIFY(proc.waitForFinished());
859  QCOMPARE(proc.exitCode(), 0);
860  QByteArray mocOut = proc.readAllStandardOutput();
861  QVERIFY(!mocOut.isEmpty());
862  QCOMPARE(proc.readAllStandardError(), QByteArray());
863 
864  QStringList args;
865  args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "."
866  << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
867  proc.start("gcc", args);
868  QVERIFY(proc.waitForStarted());
869  proc.write(mocOut);
870  proc.closeWriteChannel();
871 
872  QVERIFY(proc.waitForFinished());
873  QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString());
874  QCOMPARE(proc.exitCode(), 0);
875 #else
876  QSKIP("Only tested on linux/gcc");
877 #endif
878 }
879 
880 void tst_Moc::warnOnExtraSignalSlotQualifiaction()
881 {
882 #ifdef MOC_CROSS_COMPILED
883  QSKIP("Not tested when cross-compiled");
884 #endif
885 #if defined(Q_OS_UNIX) && defined(Q_CC_GNU) && QT_CONFIG(process)
886  QProcess proc;
887  const QString header = m_sourceDirectory + QStringLiteral("/extraqualification.h");
888  proc.start(m_moc, QStringList(header));
889  QVERIFY(proc.waitForFinished());
890  QCOMPARE(proc.exitCode(), 0);
891  QByteArray mocOut = proc.readAllStandardOutput();
892  QVERIFY(!mocOut.isEmpty());
893  QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
894  QCOMPARE(mocWarning, header +
895  QString(":43:1: warning: Function declaration Test::badFunctionDeclaration contains extra qualification. Ignoring as signal or slot.\n") +
896  header + QString(":46:1: warning: parsemaybe: Function declaration Test::anotherOne contains extra qualification. Ignoring as signal or slot.\n"));
897 #else
898  QSKIP("Only tested on unix/gcc");
899 #endif
900 }
901 
902 void tst_Moc::uLongLong()
903 {
904  TestClass tst;
905  const QMetaObject *mobj = tst.metaObject();
906  int idx = mobj->indexOfSlot("slotWithULong(ulong)");
907  QVERIFY(idx != -1);
908  idx = mobj->indexOfSlot("slotWithULongLong(unsigned long long)");
909  QVERIFY(idx != -1);
910  idx = mobj->indexOfSlot("slotWithULongLong(qulonglong)");
911  QVERIFY(idx != -1);
912  idx = mobj->indexOfSlot("slotWithULongLongP(qulonglong*)");
913  QVERIFY(idx != -1);
914 
915  idx = mobj->indexOfSlot("slotWithLong(long)");
916  QVERIFY(idx != -1);
917  idx = mobj->indexOfSlot("slotWithLongLong(long long)");
918  QVERIFY(idx != -1);
919 }
920 
921 void tst_Moc::inputFileNameWithDotsButNoExtension()
922 {
923 #ifdef MOC_CROSS_COMPILED
924  QSKIP("Not tested when cross-compiled");
925 #endif
926 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && QT_CONFIG(process)
927  QProcess proc;
928  proc.setWorkingDirectory(m_sourceDirectory + QStringLiteral("/task71021"));
929  proc.start(m_moc, QStringList("../Header"));
930  QVERIFY(proc.waitForFinished());
931  QCOMPARE(proc.exitCode(), 0);
932  QByteArray mocOut = proc.readAllStandardOutput();
933  QVERIFY(!mocOut.isEmpty());
934  QCOMPARE(proc.readAllStandardError(), QByteArray());
935 
936  QStringList args;
937  args << "-c" << "-x" << "c++" << "-I" << ".."
938  << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
939  proc.start("gcc", args);
940  QVERIFY(proc.waitForStarted());
941  proc.write(mocOut);
942  proc.closeWriteChannel();
943 
944  QVERIFY(proc.waitForFinished());
945  QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString());
946  QCOMPARE(proc.exitCode(), 0);
947 #else
948  QSKIP("Only tested on linux/gcc");
949 #endif
950 }
951 
952 void tst_Moc::userProperties()
953 {
954  const QMetaObject *mobj = metaObject();
955  QMetaProperty property = mobj->property(mobj->indexOfProperty("user1"));
956  QVERIFY(property.isValid());
957  QVERIFY(property.isUser());
958 
959  property = mobj->property(mobj->indexOfProperty("user2"));
960  QVERIFY(property.isValid());
961  QVERIFY(!property.isUser());
962 }
963 
964 void tst_Moc::supportConstSignals()
965 {
966  QSignalSpy spy1(this, SIGNAL(constSignal1()));
967  QVERIFY(spy1.isEmpty());
968  emit constSignal1();
969  QCOMPARE(spy1.count(), 1);
970 
971  QSignalSpy spy2(this, SIGNAL(constSignal2(int)));
972  QVERIFY(spy2.isEmpty());
973  emit constSignal2(42);
974  QCOMPARE(spy2.count(), 1);
975  QCOMPARE(spy2.at(0).at(0).toInt(), 42);
976 }
977 
978 #include "task87883.h"
979 
980 void tst_Moc::task87883()
981 {
982  QVERIFY(Task87883::staticMetaObject.className());
983 }
984 
985 #include "c-comments.h"
986 
987 void tst_Moc::multilineComments()
988 {
989  QVERIFY(IfdefedClass::staticMetaObject.className());
990 }
991 
992 void tst_Moc::classinfoWithEscapes()
993 {
994  const QMetaObject *mobj = &TestClassinfoWithEscapes::staticMetaObject;
995  QCOMPARE(mobj->methodCount() - mobj->methodOffset(), 1);
996 
997  QCOMPARE(mobj->classInfoCount(), 5);
998  QCOMPARE(mobj->classInfo(2).name(), "cpp c*/omment");
999  QCOMPARE(mobj->classInfo(2).value(), "f/*oo");
1000  QCOMPARE(mobj->classInfo(3).name(), "endswith\\");
1001  QCOMPARE(mobj->classInfo(3).value(), "Or?\?/");
1002  QCOMPARE(mobj->classInfo(4).name(), "newline\n inside\n");
1003  QCOMPARE(mobj->classInfo(4).value(), "Or \r");
1004 
1005  QMetaMethod mm = mobj->method(mobj->methodOffset());
1006  QCOMPARE(mm.methodSignature(), QByteArray("slotWithAReallyLongName(int)"));
1007 }
1008 
1009 void tst_Moc::classinfoFromVaArgs()
1010 {
1011  const QMetaObject *mobj = &TestClassinfoFromVaArgs::staticMetaObject;
1012 
1013  QCOMPARE(mobj->classInfoCount(), 1);
1014  QCOMPARE(mobj->classInfo(0).name(), "classinfo_va_args");
1015  QCOMPARE(mobj->classInfo(0).value(), "a,b,c,d");
1016 }
1017 
1018 void tst_Moc::trNoopInClassInfo()
1019 {
1020  TestClass t;
1021  const QMetaObject *mobj = t.metaObject();
1022  QVERIFY(mobj);
1023  QCOMPARE(mobj->classInfoCount(), 3);
1024  QCOMPARE(mobj->indexOfClassInfo("help"), 0);
1025  QCOMPARE(QString(mobj->classInfo(0).value()), QString("Opening this will let you configure something"));
1026 }
1027 
1028 void tst_Moc::ppExpressionEvaluation()
1029 {
1030  TestClass tst;
1031  const QMetaObject *mobj = tst.metaObject();
1032  int idx = mobj->indexOfSlot("expressionEvaluationShortcut1()");
1033  QVERIFY(idx != -1);
1034 
1035  idx = mobj->indexOfSlot("expressionEvaluationShortcut2()");
1036  QVERIFY(idx != -1);
1037 }
1038 
1039 void tst_Moc::arrayArguments()
1040 {
1041  TestClass tst;
1042  const QMetaObject *mobj = tst.metaObject();
1043  QVERIFY(mobj->indexOfSlot("slotWithArray(const double[3])") != -1);
1044  QVERIFY(mobj->indexOfSlot("slotWithNamedArray(const double[3])") != -1);
1045  QVERIFY(mobj->indexOfSlot("slotWithMultiArray(const double[3][4])") != -1);
1046  QVERIFY(mobj->indexOfSignal("signalWithArray(const double[3])") != -1);
1047  QVERIFY(mobj->indexOfSignal("signalWithNamedArray(const double[3])") != -1);
1048 }
1049 
1050 void tst_Moc::preprocessorConditionals()
1051 {
1052  TestClass tst;
1053  const QMetaObject *mobj = tst.metaObject();
1054  QVERIFY(mobj->indexOfSlot("slotInElse()") != -1);
1055  QVERIFY(mobj->indexOfSlot("slotInIf()") != -1);
1056  QVERIFY(mobj->indexOfSlot("slotInLastElse()") != -1);
1057  QVERIFY(mobj->indexOfSlot("slotInElif()") != -1);
1058  QVERIFY(mobj->indexOfSignal("signalInIf1()") != -1);
1059  QVERIFY(mobj->indexOfSignal("signalInIf2()") != -1);
1060  QVERIFY(mobj->indexOfSignal("signalInIf3()") != -1);
1061  QCOMPARE(mobj->indexOfSignal("doNotExist()"), -1);
1062 }
1063 
1064 void tst_Moc::blackslashNewlines()
1065 {
1066  BackslashNewlines tst;
1067  const QMetaObject *mobj = tst.metaObject();
1068  QVERIFY(mobj->indexOfSlot("works()") != -1);
1069  QCOMPARE(mobj->indexOfSlot("buggy()"), -1);
1070 }
1071 
1072 void tst_Moc::slotWithSillyConst()
1073 {
1074  TestClass tst;
1075  const QMetaObject *mobj = tst.metaObject();
1076  QVERIFY(mobj->indexOfSlot("slotWithSillyConst()") != -1);
1077  QVERIFY(mobj->indexOfMethod("slotWithSillyConst2()") != -1);
1078  QVERIFY(mobj->indexOfSlot("slotWithVoidStar(void*)") != -1);
1079 }
1080 
1081 void tst_Moc::slotTakingCRefViaTypedef()
1082 {
1083  TestClass tst;
1084  QObject obj;
1085  obj.setObjectName("works");
1086  QMetaObject::invokeMethod(&tst, "slotTakingCRefViaTypedef", Q_ARG(ObjectCRef, obj));
1087  QCOMPARE(obj.objectName(), "works");
1088 }
1089 
1090 void tst_Moc::testExtraData()
1091 {
1092  const QMetaObject *mobj = &PropertyTestClass::staticMetaObject;
1093  QCOMPARE(mobj->enumeratorCount(), 1);
1094  QCOMPARE(QByteArray(mobj->enumerator(0).name()), QByteArray("TestEnum"));
1095 
1096  mobj = &PropertyUseClass::staticMetaObject;
1097  const int idx = mobj->indexOfProperty("foo");
1098  QVERIFY(idx != -1);
1099  const QMetaProperty prop = mobj->property(idx);
1100  QVERIFY(prop.isValid());
1101  QVERIFY(prop.isEnumType());
1102  const QMetaEnum en = prop.enumerator();
1103  QCOMPARE(QByteArray(en.name()), QByteArray("TestEnum"));
1104 }
1105 
1106 // QTBUG-20639 - Accept non-local enums for QML signal/slot parameters.
1107 void tst_Moc::testExtraDataForEnum()
1108 {
1109  const QMetaObject *mobjSource = &EnumSourceClass::staticMetaObject;
1110  QCOMPARE(mobjSource->enumeratorCount(), 1);
1111  QCOMPARE(QByteArray(mobjSource->enumerator(0).name()), QByteArray("TestEnum"));
1112 
1113  const QMetaObject *mobjUser = &EnumUserClass::staticMetaObject;
1114  QCOMPARE(mobjUser->enumeratorCount(), 0);
1115 
1116  const auto *objects = mobjUser->d.relatedMetaObjects;
1117  QVERIFY(objects);
1118  QCOMPARE(objects[0], mobjSource);
1119  QVERIFY(!objects[1]);
1120 }
1121 
1122 void tst_Moc::namespaceTypeProperty()
1123 {
1124  qRegisterMetaType<myNS::Points>("myNS::Points");
1125  TestClass tst;
1126  QByteArray ba = QByteArray("points");
1127  QVariant v = tst.property(ba);
1128  QVERIFY(v.isValid());
1129  myNS::Points p = qvariant_cast<myNS::Points>(v);
1130  QCOMPARE(p.p1, 0xBEEF);
1131  QCOMPARE(p.p2, 0xBABE);
1132  p.p1 = 0xCAFE;
1133  p.p2 = 0x1EE7;
1134  QVERIFY(tst.setProperty(ba, QVariant::fromValue(p)));
1135  myNS::Points pp = qvariant_cast<myNS::Points>(tst.property(ba));
1136  QCOMPARE(p.p1, pp.p1);
1137  QCOMPARE(p.p2, pp.p2);
1138 }
1139 
1140 void tst_Moc::slotsWithVoidTemplate()
1141 {
1143  QVERIFY(QObject::connect(&test, SIGNAL(myVoidSignal(void)),
1144  &test, SLOT(dummySlot(void))));
1145  QVERIFY(QObject::connect(&test, SIGNAL(mySignal(const TestTemplate<void> &)),
1146  &test, SLOT(anotherSlot(const TestTemplate<void> &))));
1147  QVERIFY(QObject::connect(&test, SIGNAL(myVoidSignal2()),
1148  &test, SLOT(dummySlot2())));
1149 }
1150 
1151 void tst_Moc::structQObject()
1152 {
1153  StructQObject o;
1154  QCOMPARE(QByteArray(o.metaObject()->className()), QByteArray("StructQObject"));
1155 }
1156 
1157 #include "namespaced-flags.h"
1158 
1160 
1161 void tst_Moc::namespacedFlags()
1162 {
1163  Foo::Baz baz;
1164  Foo::Bar bar;
1165 
1167  QVERIFY(baz.flags() != bar.flags());
1168 
1169  const QVariant v = bar.property("flags");
1170  QVERIFY(v.isValid());
1171  QVERIFY(baz.setProperty("flags", v));
1172  QCOMPARE(baz.flags(), bar.flags());
1173 
1175  l << baz.flags();
1176  QVariant v2 = baz.setProperty("flagsList", QVariant::fromValue(l));
1177  QCOMPARE(l, baz.flagsList());
1178  QCOMPARE(l, qvariant_cast<QList<Foo::Bar::Flags> >(baz.property("flagsList")));
1179 }
1180 
1181 void tst_Moc::warnOnMultipleInheritance()
1182 {
1183 #ifdef MOC_CROSS_COMPILED
1184  QSKIP("Not tested when cross-compiled");
1185 #endif
1186 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && QT_CONFIG(process)
1187  QProcess proc;
1188  QStringList args;
1189  const QString header = m_sourceDirectory + QStringLiteral("/warn-on-multiple-qobject-subclasses.h");
1190  args << "-I" << qtIncludePath + "/QtGui" << header;
1191  proc.start(m_moc, args);
1192  QVERIFY(proc.waitForFinished());
1193  QCOMPARE(proc.exitCode(), 0);
1194  QByteArray mocOut = proc.readAllStandardOutput();
1195  QVERIFY(!mocOut.isEmpty());
1196  QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
1197  QCOMPARE(mocWarning, header +
1198  QString(":43:1: warning: Class Bar inherits from two QObject subclasses QWindow and Foo. This is not supported!\n"));
1199 #else
1200  QSKIP("Only tested on linux/gcc");
1201 #endif
1202 }
1203 
1204 void tst_Moc::ignoreOptionClashes()
1205 {
1206 #ifdef MOC_CROSS_COMPILED
1207  QSKIP("Not tested when cross-compiled");
1208 #endif
1209 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && QT_CONFIG(process)
1210  QProcess proc;
1211  QStringList args;
1212  const QString header = m_sourceDirectory + QStringLiteral("/interface-from-include.h");
1213  const QString includeDir = m_sourceDirectory + "/Test.framework/Headers";
1214  // given --ignore-option-clashes, -pthread should be ignored, but the -I path should not be.
1215  args << "--ignore-option-clashes" << "-pthread" << "-I" << includeDir << "-fno-builtin" << header;
1216  proc.start(m_moc, args);
1217  bool finished = proc.waitForFinished();
1218  if (!finished)
1219  qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error());
1220  QVERIFY(finished);
1221  if (proc.exitCode() != 0) {
1222  qDebug() << proc.readAllStandardError();
1223  }
1224  QCOMPARE(proc.exitCode(), 0);
1225  QCOMPARE(proc.readAllStandardError(), QByteArray());
1226  QByteArray mocOut = proc.readAllStandardOutput();
1227 
1228  // If -pthread wasn't ignored, it was parsed as a prefix of "thread/", which breaks compilation.
1229  QStringList gccArgs;
1230  gccArgs << "-c" << "-x" << "c++" << "-I" << ".."
1231  << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null"
1232  << "-fPIC" << "-std=c++1z" << "-";
1233  proc.start("gcc", gccArgs);
1234  QVERIFY(proc.waitForStarted());
1235  proc.write(mocOut);
1236  proc.closeWriteChannel();
1237 
1238  QVERIFY(proc.waitForFinished());
1239  QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString());
1240 #else
1241  QSKIP("Only tested on linux/gcc");
1242 #endif
1243 }
1244 
1245 void tst_Moc::forgottenQInterface()
1246 {
1247 #ifdef MOC_CROSS_COMPILED
1248  QSKIP("Not tested when cross-compiled");
1249 #endif
1250 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && QT_CONFIG(process)
1251  QProcess proc;
1252  QStringList args;
1253  const QString header = m_sourceDirectory + QStringLiteral("/forgotten-qinterface.h");
1254  args << "-I" << qtIncludePath + "/QtCore" << header;
1255  proc.start(m_moc, args);
1256  QVERIFY(proc.waitForFinished());
1257  QCOMPARE(proc.exitCode(), 0);
1258  QByteArray mocOut = proc.readAllStandardOutput();
1259  QVERIFY(!mocOut.isEmpty());
1260  QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
1261  QCOMPARE(mocWarning, header +
1262  QString(":45:1: warning: Class Test implements the interface MyInterface but does not list it in Q_INTERFACES. qobject_cast to MyInterface will not work!\n"));
1263 #else
1264  QSKIP("Only tested on linux/gcc");
1265 #endif
1266 }
1267 
1268 void tst_Moc::os9Newline()
1269 {
1270 #if !defined(SKIP_NEWLINE_TEST)
1271  const QMetaObject &mo = Os9Newlines::staticMetaObject;
1272  QVERIFY(mo.indexOfSlot("testSlot()") != -1);
1273  QFile f(m_sourceDirectory + QStringLiteral("/os9-newlines.h"));
1274  QVERIFY(f.open(QIODevice::ReadOnly)); // no QIODevice::Text!
1275  QByteArray data = f.readAll();
1276  f.close();
1277  QVERIFY(!data.contains('\n'));
1278  QVERIFY(data.contains('\r'));
1279 #endif
1280 }
1281 
1282 void tst_Moc::winNewline()
1283 {
1284 #if !defined(SKIP_NEWLINE_TEST)
1285  const QMetaObject &mo = WinNewlines::staticMetaObject;
1286  QVERIFY(mo.indexOfSlot("testSlot()") != -1);
1287  QFile f(m_sourceDirectory + QStringLiteral("/win-newlines.h"));
1288  QVERIFY(f.open(QIODevice::ReadOnly)); // no QIODevice::Text!
1289  QByteArray data = f.readAll();
1290  f.close();
1291  for (int i = 0; i < data.count(); ++i) {
1292  if (data.at(i) == QLatin1Char('\r')) {
1293  QVERIFY(i < data.count() - 1);
1294  ++i;
1295  QCOMPARE(data.at(i), '\n');
1296  } else {
1297  QVERIFY(data.at(i) != '\n');
1298  }
1299  }
1300 #endif
1301 }
1302 
1303 void tst_Moc::escapesInStringLiterals()
1304 {
1305  const QMetaObject &mo = StringLiterals::staticMetaObject;
1306  QCOMPARE(mo.classInfoCount(), 3);
1307 
1308  int idx = mo.indexOfClassInfo("Test");
1309  QVERIFY(idx != -1);
1310  QMetaClassInfo info = mo.classInfo(idx);
1311  QCOMPARE(QByteArray(info.value()),
1312  QByteArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\x53"));
1313 
1314  QVERIFY(idx != -1);
1315  idx = mo.indexOfClassInfo("Test2");
1316  info = mo.classInfo(idx);
1317  QCOMPARE(QByteArray(info.value()),
1318  QByteArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\123"));
1319 
1320  QVERIFY(idx != -1);
1321  idx = mo.indexOfClassInfo("Test3");
1322  info = mo.classInfo(idx);
1323  QCOMPARE(QByteArray(info.value()),
1324  QByteArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nb"));
1325 }
1326 
1327 void tst_Moc::frameworkSearchPath()
1328 {
1329 #ifdef MOC_CROSS_COMPILED
1330  QSKIP("Not tested when cross-compiled");
1331 #endif
1332 #if defined(Q_OS_UNIX) && QT_CONFIG(process)
1333  QStringList args;
1334  args << "-F" << m_sourceDirectory + QStringLiteral("/.")
1335  << m_sourceDirectory + QStringLiteral("/interface-from-framework.h")
1336  ;
1337 
1338  QProcess proc;
1339  proc.start(m_moc, args);
1340  bool finished = proc.waitForFinished();
1341  if (!finished)
1342  qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error());
1343  QVERIFY(finished);
1344  if (proc.exitCode() != 0) {
1345  qDebug() << proc.readAllStandardError();
1346  }
1347  QCOMPARE(proc.exitCode(), 0);
1348  QCOMPARE(proc.readAllStandardError(), QByteArray());
1349 #else
1350  QSKIP("Only tested/relevant on unixy platforms");
1351 #endif
1352 }
1353 
1354 void tst_Moc::cstyleEnums()
1355 {
1356  const QMetaObject &obj = CStyleEnums::staticMetaObject;
1357  QCOMPARE(obj.enumeratorCount(), 2);
1358  QMetaEnum metaEnum = obj.enumerator(0);
1359  QCOMPARE(metaEnum.name(), "Baz");
1360  QCOMPARE(metaEnum.keyCount(), 2);
1361  QCOMPARE(metaEnum.key(0), "Foo");
1362  QCOMPARE(metaEnum.key(1), "Bar");
1363 
1364  QMetaEnum metaEnum2 = obj.enumerator(1);
1365  QCOMPARE(metaEnum2.name(), "Baz2");
1366  QCOMPARE(metaEnum2.keyCount(), 2);
1367  QCOMPARE(metaEnum2.key(0), "Foo2");
1368  QCOMPARE(metaEnum2.key(1), "Bar2");
1369 }
1370 
1371 void tst_Moc::templateGtGt()
1372 {
1373 #ifdef MOC_CROSS_COMPILED
1374  QSKIP("Not tested when cross-compiled");
1375 #endif
1376 #if defined(Q_OS_UNIX) && defined(Q_CC_GNU) && QT_CONFIG(process)
1377  QProcess proc;
1378  proc.start(m_moc, QStringList(m_sourceDirectory + QStringLiteral("/template-gtgt.h")));
1379  QVERIFY(proc.waitForFinished());
1380  QCOMPARE(proc.exitCode(), 0);
1381  QByteArray mocOut = proc.readAllStandardOutput();
1382  QVERIFY(!mocOut.isEmpty());
1383  QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
1384  QVERIFY(mocWarning.isEmpty());
1385 #else
1386  QSKIP("Only tested on unix/gcc");
1387 #endif
1388 }
1389 
1390 void tst_Moc::defineMacroViaCmdline()
1391 {
1392 #if defined(Q_OS_UNIX) && defined(Q_CC_GNU) && QT_CONFIG(process)
1393  QProcess proc;
1394 
1395  QStringList args;
1396  args << "-DFOO";
1397  args << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h");
1398 
1399  proc.start(m_moc, args);
1400  QVERIFY(proc.waitForFinished());
1401  QCOMPARE(proc.exitCode(), 0);
1402  QCOMPARE(proc.readAllStandardError(), QByteArray());
1403  QByteArray mocOut = proc.readAllStandardOutput();
1404  QVERIFY(!mocOut.isEmpty());
1405 #else
1406  QSKIP("Only tested on unix/gcc");
1407 #endif
1408 }
1409 
1410 void tst_Moc::defineMacroViaForcedInclude()
1411 {
1412 #if defined(Q_OS_UNIX) && defined(Q_CC_GNU) && QT_CONFIG(process)
1413  QProcess proc;
1414 
1415  QStringList args;
1416  args << "--include" << m_sourceDirectory + QLatin1String("/subdir/extradefines.h");
1417  args << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h");
1418 
1419  proc.start(m_moc, args);
1420  QVERIFY(proc.waitForFinished());
1421  QCOMPARE(proc.exitCode(), 0);
1422  QCOMPARE(proc.readAllStandardError(), QByteArray());
1423  QByteArray mocOut = proc.readAllStandardOutput();
1424  QVERIFY(!mocOut.isEmpty());
1425 #else
1426  QSKIP("Only tested on unix/gcc");
1427 #endif
1428 }
1429 
1430 void tst_Moc::defineMacroViaForcedIncludeRelative()
1431 {
1432 #if defined(Q_OS_UNIX) && defined(Q_CC_GNU) && QT_CONFIG(process)
1433  QProcess proc;
1434 
1435  QStringList args;
1436  args << "--include" << QStringLiteral("extradefines.h") << "-I" + m_sourceDirectory + "/subdir";
1437  args << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h");
1438 
1439  proc.start(m_moc, args);
1440  QVERIFY(proc.waitForFinished());
1441  QCOMPARE(proc.exitCode(), 0);
1442  QCOMPARE(proc.readAllStandardError(), QByteArray());
1443  QByteArray mocOut = proc.readAllStandardOutput();
1444  QVERIFY(!mocOut.isEmpty());
1445 #else
1446  QSKIP("Only tested on unix/gcc");
1447 #endif
1448 }
1449 
1450 
1451 void tst_Moc::environmentIncludePaths_data()
1452 {
1453 #if defined(Q_OS_UNIX) && defined(Q_CC_GNU) && QT_CONFIG(process)
1454  QTest::addColumn<QString>("cmdline");
1455  QTest::addColumn<QString>("varname");
1456 
1457  QTest::newRow("INCLUDE") << "--compiler-flavor=msvc" << "INCLUDE";
1458  QTest::newRow("CPATH1") << QString() << "CPATH";
1459  QTest::newRow("CPATH2") << "--compiler-flavor=unix" << "CPATH";
1460  QTest::newRow("CPLUS_INCLUDE_PATH1") << QString() << "CPLUS_INCLUDE_PATH";
1461  QTest::newRow("CPLUS_INCLUDE_PATH2") << "--compiler-flavor=unix" << "CPLUS_INCLUDE_PATH";
1462 #endif
1463 }
1464 
1465 void tst_Moc::environmentIncludePaths()
1466 {
1467 #if defined(Q_OS_UNIX) && defined(Q_CC_GNU) && QT_CONFIG(process)
1468  QFETCH(QString, cmdline);
1469  QFETCH(QString, varname);
1470 
1471  QStringList args;
1472  if (!cmdline.isEmpty())
1473  args << cmdline;
1474  args << "--include" << QStringLiteral("extradefines.h")
1475  << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h");
1476 
1478  env.remove("INCLUDE");
1479  env.remove("CPATH");
1480  env.remove("CPLUS_INCLUDE_PATH");
1481  env.insert(varname, m_sourceDirectory + "/subdir");
1482 
1483  QProcess proc;
1484  proc.setProcessEnvironment(env);
1485  proc.start(m_moc, args);
1486  QVERIFY(proc.waitForFinished());
1487  QCOMPARE(proc.exitCode(), 0);
1488  QCOMPARE(proc.readAllStandardError(), QByteArray());
1489  QByteArray mocOut = proc.readAllStandardOutput();
1490  QVERIFY(!mocOut.isEmpty());
1491 #else
1492  QSKIP("Only tested on unix/gcc");
1493 #endif
1494 }
1495 
1496 // tst_Moc::specifyMetaTagsFromCmdline()
1497 // plugin_metadata.h contains a plugin which we register here. Since we're not building this
1498 // application as a plugin, we need top copy some of the initializer code found in qplugin.h:
1499 extern "C" QObject *qt_plugin_instance();
1502 public:
1506  }
1507 };
1508 static StaticPluginInstance staticInstance;
1509 
1510 void tst_Moc::specifyMetaTagsFromCmdline() {
1511  foreach (const QStaticPlugin &plugin, QPluginLoader::staticPlugins()) {
1512  const QString iid = plugin.metaData().value(QLatin1String("IID")).toString();
1513  if (iid == QLatin1String("test.meta.tags")) {
1514  const QJsonArray metaTagsUriList = plugin.metaData().value("uri").toArray();
1515  QCOMPARE(metaTagsUriList.size(), 2);
1516 
1517  // The following uri-s are set in the pro file using
1518  // -Muri=com.company.app -Muri=com.company.app.private
1519  QCOMPARE(metaTagsUriList[0].toString(), QLatin1String("com.company.app"));
1520  QCOMPARE(metaTagsUriList[1].toString(), QLatin1String("com.company.app.private"));
1521  return;
1522  }
1523  }
1524  QFAIL("Could not find plugin with IID 'test.meta.tags'");
1525 }
1526 
1527 void tst_Moc::invokable()
1528 {
1529  {
1530  const QMetaObject &mobj = InvokableBeforeReturnType::staticMetaObject;
1531  QCOMPARE(mobj.methodCount(), 6);
1532  QCOMPARE(mobj.method(5).methodSignature(), QByteArray("foo()"));
1533  }
1534 
1535  {
1536  const QMetaObject &mobj = InvokableBeforeInline::staticMetaObject;
1537  QCOMPARE(mobj.methodCount(), 7);
1538  QCOMPARE(mobj.method(5).methodSignature(), QByteArray("foo()"));
1539  QCOMPARE(mobj.method(6).methodSignature(), QByteArray("bar()"));
1540  }
1541 }
1542 
1543 void tst_Moc::singleFunctionKeywordSignalAndSlot()
1544 {
1545  {
1546  const QMetaObject &mobj = SingleFunctionKeywordBeforeReturnType::staticMetaObject;
1547  QCOMPARE(mobj.methodCount(), 7);
1548  QCOMPARE(mobj.method(5).methodSignature(), QByteArray("mySignal()"));
1549  QCOMPARE(mobj.method(6).methodSignature(), QByteArray("mySlot()"));
1550  }
1551 
1552  {
1553  const QMetaObject &mobj = SingleFunctionKeywordBeforeInline::staticMetaObject;
1554  QCOMPARE(mobj.methodCount(), 7);
1555  QCOMPARE(mobj.method(5).methodSignature(), QByteArray("mySignal()"));
1556  QCOMPARE(mobj.method(6).methodSignature(), QByteArray("mySlot()"));
1557  }
1558 
1559  {
1560  const QMetaObject &mobj = SingleFunctionKeywordAfterInline::staticMetaObject;
1561  QCOMPARE(mobj.methodCount(), 7);
1562  QCOMPARE(mobj.method(5).methodSignature(), QByteArray("mySignal()"));
1563  QCOMPARE(mobj.method(6).methodSignature(), QByteArray("mySlot()"));
1564  }
1565 }
1566 
1567 #include "qprivateslots.h"
1568 
1569 void tst_Moc::qprivateslots()
1570 {
1571  TestQPrivateSlots tst;
1572  const QMetaObject *mobj = tst.metaObject();
1573  QVERIFY(mobj->indexOfSlot("_q_privateslot()") != -1);
1574  QVERIFY(mobj->indexOfMethod("method1()") != -1); //tast204730
1575 }
1576 
1577 class PrivatePropertyTest : public QObject
1578 {
1579  Q_OBJECT
1580  Q_PROPERTY(int foo READ foo WRITE setFoo)
1581  Q_PRIVATE_PROPERTY(d, int bar READ bar WRITE setBar)
1582  Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, int plop READ plop WRITE setPlop)
1583  Q_PRIVATE_PROPERTY(PrivatePropertyTest::d_func(), int baz READ baz WRITE setBaz)
1584  Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, QString blub MEMBER mBlub)
1585  Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, QString blub2 MEMBER mBlub READ blub)
1586  Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, QString blub3 MEMBER mBlub WRITE setBlub)
1587  Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, QString blub4 MEMBER mBlub NOTIFY blub4Changed)
1588  Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, QString blub5 MEMBER mBlub NOTIFY blub5Changed)
1589  Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, QString blub6 MEMBER mConst CONSTANT)
1590  Q_PRIVATE_PROPERTY(PrivatePropertyTest::d, int zap READ zap WRITE setZap BINDABLE bindableZap)
1591  class MyDPointer {
1592  public:
1593  MyDPointer() : mConst("const"), mBar(0), mPlop(0) {}
1594  int bar() { return mBar ; }
1595  void setBar(int value) { mBar = value; }
1596  int plop() { return mPlop ; }
1597  void setPlop(int value) { mPlop = value; }
1598  int baz() { return mBaz ; }
1599  void setBaz(int value) { mBaz = value; }
1600  QString blub() const { return mBlub; }
1601  void setBlub(const QString &value) { mBlub = value; }
1602  int zap() { return mZap; }
1603  void setZap(int zap) { mZap = zap; }
1604  QBindable<int> bindableZap() { return QBindable<int>(&mZap); }
1605  QString mBlub;
1606  const QString mConst;
1607  private:
1608  int mBar;
1609  int mPlop;
1610  int mBaz;
1612  };
1613 public:
1614  PrivatePropertyTest(QObject *parent = nullptr) : QObject(parent), mFoo(0), d (new MyDPointer) {}
1615  int foo() { return mFoo ; }
1616  void setFoo(int value) { mFoo = value; }
1617  MyDPointer *d_func() {return d.data();}
1618  const MyDPointer *d_func() const {return d.data();}
1619 signals:
1621  void blub5Changed(const QString &newBlub);
1622 private:
1623  int mFoo;
1625 };
1626 
1627 
1628 void tst_Moc::qprivateproperties()
1629 {
1630  PrivatePropertyTest test;
1631 
1632  test.setProperty("foo", 1);
1633  QCOMPARE(test.property("foo"), QVariant::fromValue(1));
1634 
1635  test.setProperty("bar", 2);
1636  QCOMPARE(test.property("bar"), QVariant::fromValue(2));
1637 
1638  test.setProperty("plop", 3);
1639  QCOMPARE(test.property("plop"), QVariant::fromValue(3));
1640 
1641  test.setProperty("baz", 4);
1642  QCOMPARE(test.property("baz"), QVariant::fromValue(4));
1643 
1644  QMetaProperty zap = test.metaObject()->property(test.metaObject()->indexOfProperty("zap"));
1645  QVERIFY(zap.isValid());
1646  QVERIFY(zap.isBindable());
1647  auto zapBindable = zap.bindable(&test);
1648  QVERIFY(zapBindable.isBindable());
1649 }
1650 
1651 void tst_Moc::warnOnPropertyWithoutREAD()
1652 {
1653 #ifdef MOC_CROSS_COMPILED
1654  QSKIP("Not tested when cross-compiled");
1655 #endif
1656 #if defined(Q_OS_UNIX) && defined(Q_CC_GNU) && QT_CONFIG(process)
1657  QProcess proc;
1658  const QString header = m_sourceDirectory + QStringLiteral("/warn-on-property-without-read.h");
1659  proc.start(m_moc, QStringList(header));
1660  QVERIFY(proc.waitForFinished());
1661  QCOMPARE(proc.exitCode(), 0);
1662  QByteArray mocOut = proc.readAllStandardOutput();
1663  QVERIFY(!mocOut.isEmpty());
1664  QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
1665  QCOMPARE(mocWarning, header +
1666  QString(":36:1: warning: Property declaration foo has neither an associated QProperty<> member, nor a READ accessor function nor an associated MEMBER variable. The property will be invalid.\n"));
1667 #else
1668  QSKIP("Only tested on unix/gcc");
1669 #endif
1670 }
1671 
1672 void tst_Moc::constructors()
1673 {
1674  const QMetaObject *mo = &CtorTestClass::staticMetaObject;
1675  QCOMPARE(mo->constructorCount(), 3);
1676  {
1677  QMetaMethod mm = mo->constructor(0);
1680  QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass(QObject*)"));
1681  QCOMPARE(mm.typeName(), "");
1682  QList<QByteArray> paramNames = mm.parameterNames();
1683  QCOMPARE(paramNames.size(), 1);
1684  QCOMPARE(paramNames.at(0), QByteArray("parent"));
1685  QList<QByteArray> paramTypes = mm.parameterTypes();
1686  QCOMPARE(paramTypes.size(), 1);
1687  QCOMPARE(paramTypes.at(0), QByteArray("QObject*"));
1688  }
1689  {
1690  QMetaMethod mm = mo->constructor(1);
1693  QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass()"));
1694  QCOMPARE(mm.typeName(), "");
1695  QCOMPARE(mm.parameterNames().size(), 0);
1696  QCOMPARE(mm.parameterTypes().size(), 0);
1697  }
1698  {
1699  QMetaMethod mm = mo->constructor(2);
1702  QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass(QString)"));
1703  QCOMPARE(mm.typeName(), "");
1704  QList<QByteArray> paramNames = mm.parameterNames();
1705  QCOMPARE(paramNames.size(), 1);
1706  QCOMPARE(paramNames.at(0), QByteArray("str"));
1707  QList<QByteArray> paramTypes = mm.parameterTypes();
1708  QCOMPARE(paramTypes.size(), 1);
1709  QCOMPARE(paramTypes.at(0), QByteArray("QString"));
1710  }
1711 
1712  QCOMPARE(mo->indexOfConstructor("CtorTestClass(QObject*)"), 0);
1713  QCOMPARE(mo->indexOfConstructor("CtorTestClass()"), 1);
1714  QCOMPARE(mo->indexOfConstructor("CtorTestClass(QString)"), 2);
1715  QCOMPARE(mo->indexOfConstructor("CtorTestClass2(QObject*)"), -1);
1716  QCOMPARE(mo->indexOfConstructor("CtorTestClass(float,float)"), -1);
1717 
1718  QScopedPointer<QObject> o1(mo->newInstance());
1719  QVERIFY(o1 != 0);
1720  QCOMPARE(o1->parent(), (QObject*)0);
1721  QVERIFY(qobject_cast<CtorTestClass*>(o1.data()) != 0);
1722 
1723  QObject *o2 = mo->newInstance(Q_ARG(QObject*, o1.data()));
1724  QVERIFY(o2 != 0);
1725  QCOMPARE(o2->parent(), o1.data());
1726 
1727  QString str = QString::fromLatin1("hello");
1728  QScopedPointer<QObject> o3(mo->newInstance(Q_ARG(QString, str)));
1729  QVERIFY(o3 != 0);
1730  QCOMPARE(qobject_cast<CtorTestClass*>(o3.data())->m_str, str);
1731 
1732  {
1733  //explicit constructor
1734  QObject *o = QObject::staticMetaObject.newInstance();
1735  QVERIFY(o);
1736  delete o;
1737  }
1738 }
1739 
1740 #include "task234909.h"
1741 
1742 #include "task240368.h"
1743 
1744 void tst_Moc::typenameWithUnsigned()
1745 {
1747  const QMetaObject *mobj = tst.metaObject();
1748  QVERIFY(mobj->indexOfSlot("a(uint)") != -1);
1749  QVERIFY(mobj->indexOfSlot("b(uint)") != -1);
1750  QVERIFY(mobj->indexOfSlot("c(uint*)") != -1);
1751  QVERIFY(mobj->indexOfSlot("d(uint*)") != -1);
1752  QVERIFY(mobj->indexOfSlot("e(uint&)") != -1);
1753  QVERIFY(mobj->indexOfSlot("f(uint&)") != -1);
1754  QVERIFY(mobj->indexOfSlot("g(unsigned1)") != -1);
1755  QVERIFY(mobj->indexOfSlot("h(unsigned1)") != -1);
1756  QVERIFY(mobj->indexOfSlot("i(uint,unsigned1)") != -1);
1757  QVERIFY(mobj->indexOfSlot("j(unsigned1,uint)") != -1);
1758  QVERIFY(mobj->indexOfSlot("k(unsignedQImage)") != -1);
1759  QVERIFY(mobj->indexOfSlot("l(unsignedQImage)") != -1);
1760 }
1761 
1762 void tst_Moc::warnOnVirtualSignal()
1763 {
1764 #ifdef MOC_CROSS_COMPILED
1765  QSKIP("Not tested when cross-compiled");
1766 #endif
1767 #if defined(Q_OS_UNIX) && defined(Q_CC_GNU) && QT_CONFIG(process)
1768  QProcess proc;
1769  const QString header = m_sourceDirectory + QStringLiteral("/pure-virtual-signals.h");
1770  proc.start(m_moc, QStringList(header));
1771  QVERIFY(proc.waitForFinished());
1772  QCOMPARE(proc.exitCode(), 0);
1773  QByteArray mocOut = proc.readAllStandardOutput();
1774  QVERIFY(!mocOut.isEmpty());
1775  QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
1776  QCOMPARE(mocWarning, header + QString(":38:1: warning: Signals cannot be declared virtual\n") +
1777  header + QString(":40:1: warning: Signals cannot be declared virtual\n"));
1778 #else
1779  QSKIP("Only tested on unix/gcc");
1780 #endif
1781 }
1782 
1783 class QTBUG5590_DummyObject: public QObject
1784 {
1785  Q_OBJECT
1786  Q_PROPERTY(bool dummy)
1787 };
1788 
1790 {
1791  Q_OBJECT
1792  Q_PROPERTY(int value READ value WRITE setValue)
1793  Q_PROPERTY(int value2 READ value2 WRITE setValue2)
1794 
1795  public:
1796  QTBUG5590_PropertyObject() : m_value(85), m_value2(40) { }
1797  int value() const { return m_value; }
1798  void setValue(int value) { m_value = value; }
1799  int value2() const { return m_value2; }
1800  void setValue2(int value) { m_value2 = value; }
1801  private:
1802  int m_value, m_value2;
1803 };
1804 
1805 void tst_Moc::QTBUG5590_dummyProperty()
1806 {
1808  QCOMPARE(o.property("value").toInt(), 85);
1809  QCOMPARE(o.property("value2").toInt(), 40);
1810  o.setProperty("value", 32);
1811  QCOMPARE(o.value(), 32);
1812  o.setProperty("value2", 82);
1813  QCOMPARE(o.value2(), 82);
1814 }
1815 
1817 QT_WARNING_DISABLE_CLANG("-Wignored-qualifiers")
1818 QT_WARNING_DISABLE_GCC("-Wignored-qualifiers")
1819 class QTBUG7421_ReturnConstTemplate: public QObject
1820 { Q_OBJECT
1821 public slots:
1824  const int returnConstInt() { return 0; }
1825  const QString returnConstString(const QString s) { return s; }
1826  QString const returnConstString2( QString const s) { return s; }
1827 };
1829 
1831 struct science_const {};
1832 struct constconst {};
1833 struct const_ {};
1834 
1835 class QTBUG9354_constInName: public QObject
1836 { Q_OBJECT
1837 public slots:
1839  void foo(science_const const &) {};
1840  void foo(constconst const &) {};
1841  void foo(constconst *) {};
1842  void foo(const_ *) {};
1843 };
1844 
1845 
1846 template<typename T1, typename T2>
1848 {
1849 };
1850 
1852 { Q_OBJECT
1853 public slots:
1857  TestTemplate2< TestTemplate2 < void, int > , unsigned char *> > ) {}
1858 
1859 signals:
1861 };
1862 
1864 { Q_OBJECT
1865 public slots:
1868  = QSharedPointer<QVarLengthArray<QString, (16 >> 2)> >() ) {}
1869 
1870  void doAnotherThing(bool = (1 < 3), bool = (1 > 4)) {}
1871 
1873  QHash<int, QList<QString>> = QHash<int, QList<QString>>()) {}
1874 };
1875 
1876 
1877 void tst_Moc::QTBUG12260_defaultTemplate()
1878 {
1879  QVERIFY(QTBUG12260_defaultTemplate_Object::staticMetaObject.indexOfSlot("doSomething(QHash<QString,QVariant>)") != -1);
1880  QVERIFY(QTBUG12260_defaultTemplate_Object::staticMetaObject.indexOfSlot("doAnotherThing(bool,bool)") != -1);
1881  QVERIFY(QTBUG12260_defaultTemplate_Object::staticMetaObject.indexOfSlot("doSomethingElse(QSharedPointer<QVarLengthArray<QString,(16>>2)>>)") != -1);
1882  QVERIFY(QTBUG12260_defaultTemplate_Object::staticMetaObject.indexOfSlot("performSomething(QList<QList<QString>>,QHash<int,QList<QString>>)") != -1);
1883 }
1884 
1885 void tst_Moc::notifyError()
1886 {
1887 #ifdef MOC_CROSS_COMPILED
1888  QSKIP("Not tested when cross-compiled");
1889 #endif
1890 #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && QT_CONFIG(process)
1891  QProcess proc;
1892  const QString header = m_sourceDirectory + QStringLiteral("/error-on-wrong-notify.h");
1893  proc.start(m_moc, QStringList(header));
1894  QVERIFY(proc.waitForFinished());
1895  QCOMPARE(proc.exitCode(), 0);
1896  QCOMPARE(proc.exitStatus(), QProcess::NormalExit);
1897  QByteArray mocOut = proc.readAllStandardOutput();
1898  QVERIFY(!mocOut.isEmpty());
1899  QCOMPARE(proc.readAllStandardError(), QByteArray());
1900 
1901  QStringList args;
1902  args << "-c" << "-x" << "c++" << "-I" << "."
1903  << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
1904  proc.start("gcc", args);
1905  QVERIFY(proc.waitForStarted());
1906  proc.write(mocOut);
1907  proc.closeWriteChannel();
1908 
1909  QVERIFY(proc.waitForFinished());
1910  QCOMPARE(proc.exitCode(), 1);
1911  const QString gccOutput = QString::fromLocal8Bit(proc.readAllStandardError());
1912  QVERIFY(gccOutput.contains(QLatin1String("error")));
1913  QVERIFY(gccOutput.contains(QLatin1String("fooChanged")));
1914 #else
1915  QSKIP("Only tested on linux/gcc");
1916 #endif
1917 }
1918 
1919 class QTBUG_17635_InvokableAndProperty : public QObject
1920 {
1921  Q_OBJECT
1922 public:
1927  int numberOfEggs() { return 2; }
1928  int numberOfChickens() { return 4; }
1929 };
1930 
1931 void tst_Moc::QTBUG17635_invokableAndProperty()
1932 {
1933  //Moc used to fail parsing Q_INVOKABLE if they were dirrectly following a Q_PROPERTY;
1935  QString val;
1936  QMetaObject::invokeMethod(&mc, "getEgg", Q_RETURN_ARG(QString, val), Q_ARG(int, 10));
1937  QCOMPARE(val, QString::fromLatin1("Egg"));
1938  QMetaObject::invokeMethod(&mc, "getChicken", Q_RETURN_ARG(QString, val), Q_ARG(int, 10));
1939  QCOMPARE(val, QString::fromLatin1("Chicken"));
1940  QVERIFY(mc.metaObject()->indexOfProperty("numberOfEggs") != -1);
1941  QVERIFY(mc.metaObject()->indexOfProperty("numberOfChickens") != -1);
1942 }
1943 
1944 // If changed, update VersionTestNotify below
1945 class VersionTest : public QObject
1946 {
1947  Q_OBJECT
1948  Q_PROPERTY(int prop1 READ foo)
1949  Q_PROPERTY(int prop2 READ foo REVISION 2)
1950  Q_PROPERTY(int prop514 READ foo REVISION(5, 14))
1951 
1952 public:
1953  int foo() const { return 0; }
1954 
1957  Q_INVOKABLE Q_REVISION(6, 0) void method60() {}
1958 
1959  enum TestEnum { One, Two };
1961 
1962 
1963 public slots:
1964  void slot1() {}
1966  Q_REVISION(6, 1) void slot61() {}
1967 
1968 signals:
1969  void signal1();
1970  Q_REVISION(5) void signal2();
1971  Q_REVISION(6, 2) void signal62();
1972 
1973 public slots Q_REVISION(6):
1974  void slot3() {}
1975  void slot4() {}
1976 
1977 public slots Q_REVISION(5, 12):
1978  void slot512() {}
1979 
1980 signals Q_REVISION(7):
1981  void signal3();
1982  void signal4();
1983 
1985  void signal515();
1986 };
1987 
1988 // If changed, update VersionTest above
1989 class VersionTestNotify : public QObject
1990 {
1991  Q_OBJECT
1992  Q_PROPERTY(int prop1 READ foo NOTIFY fooChanged)
1993  Q_PROPERTY(int prop2 READ foo REVISION 2)
1994  Q_PROPERTY(int prop514 READ foo REVISION(5, 14))
1995 
1996 public:
1997  int foo() const { return 0; }
1998 
2001  Q_INVOKABLE Q_REVISION(6, 0) void method60() {}
2002 
2003  enum TestEnum { One, Two };
2005 
2006 public slots:
2007  void slot1() {}
2009  Q_REVISION(6, 1) void slot61() {}
2010 
2011 signals:
2012  void fooChanged();
2013  void signal1();
2014  Q_REVISION(5) void signal2();
2015  Q_REVISION(6, 2) void signal62();
2016 
2017 public slots Q_REVISION(6):
2018  void slot3() {}
2019  void slot4() {}
2020 
2021 public slots Q_REVISION(5, 12):
2022  void slot512() {}
2023 
2024 signals Q_REVISION(7):
2025  void signal3();
2026  void signal4();
2027 
2029  void signal515();
2030 };
2031 
2032 template <class T>
2033 void tst_Moc::revisions_T()
2034 {
2035  int idx = T::staticMetaObject.indexOfProperty("prop1");
2036  QCOMPARE(T::staticMetaObject.property(idx).revision(), 0);
2037  idx = T::staticMetaObject.indexOfProperty("prop2");
2038  QCOMPARE(T::staticMetaObject.property(idx).revision(),
2039  QTypeRevision::fromMinorVersion(2).toEncodedVersion<int>());
2040  idx = T::staticMetaObject.indexOfProperty("prop514");
2041  QCOMPARE(T::staticMetaObject.property(idx).revision(),
2042  QTypeRevision::fromVersion(5, 14).toEncodedVersion<int>());
2043 
2044  idx = T::staticMetaObject.indexOfMethod("method1()");
2045  QCOMPARE(T::staticMetaObject.method(idx).revision(), 0);
2046  idx = T::staticMetaObject.indexOfMethod("method2()");
2047  QCOMPARE(T::staticMetaObject.method(idx).revision(),
2048  QTypeRevision::fromMinorVersion(4).toEncodedVersion<int>());
2049  idx = T::staticMetaObject.indexOfMethod("method60()");
2050  QCOMPARE(T::staticMetaObject.method(idx).revision(),
2051  QTypeRevision::fromVersion(6, 0).toEncodedVersion<int>());
2052 
2053  idx = T::staticMetaObject.indexOfSlot("slot1()");
2054  QCOMPARE(T::staticMetaObject.method(idx).revision(), 0);
2055  idx = T::staticMetaObject.indexOfSlot("slot2()");
2056  QCOMPARE(T::staticMetaObject.method(idx).revision(),
2057  QTypeRevision::fromMinorVersion(3).toEncodedVersion<int>());
2058  idx = T::staticMetaObject.indexOfSlot("slot61()");
2059  QCOMPARE(T::staticMetaObject.method(idx).revision(),
2060  QTypeRevision::fromVersion(6, 1).toEncodedVersion<int>());
2061 
2062  idx = T::staticMetaObject.indexOfSlot("slot3()");
2063  QCOMPARE(T::staticMetaObject.method(idx).revision(),
2064  QTypeRevision::fromMinorVersion(6).toEncodedVersion<int>());
2065  idx = T::staticMetaObject.indexOfSlot("slot4()");
2066  QCOMPARE(T::staticMetaObject.method(idx).revision(),
2067  QTypeRevision::fromMinorVersion(6).toEncodedVersion<int>());
2068  idx = T::staticMetaObject.indexOfSlot("slot512()");
2069  QCOMPARE(T::staticMetaObject.method(idx).revision(),
2070  QTypeRevision::fromVersion(5, 12).toEncodedVersion<int>());
2071 
2072  idx = T::staticMetaObject.indexOfSignal("signal1()");
2073  QCOMPARE(T::staticMetaObject.method(idx).revision(), 0);
2074  idx = T::staticMetaObject.indexOfSignal("signal2()");
2075  QCOMPARE(T::staticMetaObject.method(idx).revision(),
2076  QTypeRevision::fromMinorVersion(5).toEncodedVersion<int>());
2077  idx = T::staticMetaObject.indexOfSignal("signal62()");
2078  QCOMPARE(T::staticMetaObject.method(idx).revision(),
2079  QTypeRevision::fromVersion(6, 2).toEncodedVersion<int>());
2080 
2081  idx = T::staticMetaObject.indexOfSignal("signal3()");
2082  QCOMPARE(T::staticMetaObject.method(idx).revision(),
2083  QTypeRevision::fromMinorVersion(7).toEncodedVersion<int>());
2084  idx = T::staticMetaObject.indexOfSignal("signal4()");
2085  QCOMPARE(T::staticMetaObject.method(idx).revision(),
2086  QTypeRevision::fromMinorVersion(7).toEncodedVersion<int>());
2087  idx = T::staticMetaObject.indexOfSignal("signal515()");
2088  QCOMPARE(T::staticMetaObject.method(idx).revision(),
2089  QTypeRevision::fromVersion(5, 15).toEncodedVersion<int>());
2090 
2091  idx = T::staticMetaObject.indexOfEnumerator("TestEnum");
2092  QCOMPARE(T::staticMetaObject.enumerator(idx).keyCount(), 2);
2093  QCOMPARE(T::staticMetaObject.enumerator(idx).key(0), "One");
2094 }
2095 
2096 // test using both class that has properties with and without NOTIFY signals
2097 void tst_Moc::revisions()
2098 {
2099  revisions_T<VersionTest>();
2100  revisions_T<VersionTestNotify>();
2101 }
2102 
2103 void tst_Moc::warnings_data()
2104 {
2105  QTest::addColumn<QByteArray>("input");
2106  QTest::addColumn<QStringList>("args");
2107  QTest::addColumn<int>("exitCode");
2108  QTest::addColumn<QString>("expectedStdOut");
2109  QTest::addColumn<QString>("expectedStdErr");
2110 
2111  // empty input should result in "no relevant classes" note
2112  QTest::newRow("No relevant classes")
2113  << QByteArray(" ")
2114  << QStringList()
2115  << 0
2116  << QString()
2117  << QString("standard input:0:1: note: No relevant classes found. No output generated.");
2118 
2119  // passing "-nn" should suppress "no relevant classes" note
2120  QTest::newRow("-nn")
2121  << QByteArray(" ")
2122  << (QStringList() << "-nn")
2123  << 0
2124  << QString()
2125  << QString();
2126 
2127  // passing "-nw" should also suppress "no relevant classes" note
2128  QTest::newRow("-nw")
2129  << QByteArray(" ")
2130  << (QStringList() << "-nw")
2131  << 0
2132  << QString()
2133  << QString();
2134 
2135  // This should output a warning
2136  QTest::newRow("Invalid property warning")
2137  << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };")
2138  << QStringList()
2139  << 0
2140  << QString("IGNORE_ALL_STDOUT")
2141  << QString("standard input:1:1: warning: Property declaration x has neither an associated QProperty<> member, nor a READ accessor function nor an associated MEMBER variable. The property will be invalid.");
2142 
2143  // This should output a warning
2144  QTest::newRow("Duplicate property warning")
2145  << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x READ x) Q_PROPERTY(int x READ y) };")
2146  << QStringList()
2147  << 0
2148  << QString("IGNORE_ALL_STDOUT")
2149  << QString("standard input:1:1: warning: The property 'x' is defined multiple times in class X.");
2150 
2151  // Passing "-nn" should NOT suppress the warning
2152  QTest::newRow("Invalid property warning with -nn")
2153  << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };")
2154  << (QStringList() << "-nn")
2155  << 0
2156  << QString("IGNORE_ALL_STDOUT")
2157  << QString("standard input:1:1: warning: Property declaration x has neither an associated QProperty<> member, nor a READ accessor function nor an associated MEMBER variable. The property will be invalid.");
2158 
2159  // Passing "-nw" should suppress the warning
2160  QTest::newRow("Invalid property warning with -nw")
2161  << QByteArray("class X : public QObject { Q_OBJECT Q_PROPERTY(int x) };")
2162  << (QStringList() << "-nw")
2163  << 0
2164  << QString("IGNORE_ALL_STDOUT")
2165  << QString();
2166 
2167  // This should output an error
2168  QTest::newRow("Does not inherit QObject")
2169  << QByteArray("class X { Q_OBJECT };")
2170  << QStringList()
2171  << 1
2172  << QString()
2173  << QString("standard input:1:1: error: Class contains Q_OBJECT macro but does not inherit from QObject");
2174 
2175  // "-nn" should not suppress the error
2176  QTest::newRow("Does not inherit QObject with -nn")
2177  << QByteArray("class X { Q_OBJECT };")
2178  << (QStringList() << "-nn")
2179  << 1
2180  << QString()
2181  << QString("standard input:1:1: error: Class contains Q_OBJECT macro but does not inherit from QObject");
2182 
2183  // "-nw" should not suppress the error
2184  QTest::newRow("Does not inherit QObject with -nw")
2185  << QByteArray("class X { Q_OBJECT };")
2186  << (QStringList() << "-nw")
2187  << 1
2188  << QString()
2189  << QString("standard input:1:1: error: Class contains Q_OBJECT macro but does not inherit from QObject");
2190 
2191  QTest::newRow("Warning on invalid macro")
2192  << QByteArray("#define Foo(a, b)\n class X : public QObject { Q_OBJECT }; \n Foo(a) \n Foo(a,b,c) \n")
2193  << QStringList()
2194  << 0
2195  << QString("IGNORE_ALL_STDOUT")
2196  << QString();
2197 
2198  QTest::newRow("Class declaration lacks Q_OBJECT macro.")
2199  << QByteArray("class X : public QObject \n { \n public slots: \n void foo() {} \n };")
2200  << QStringList()
2201  << 1
2202  << QString()
2203  << QString("standard input:5:1: error: Class declaration lacks Q_OBJECT macro.");
2204 
2205  QTest::newRow("Namespace declaration lacks Q_NAMESPACE macro.")
2206  << QByteArray("namespace X {\nQ_CLASSINFO(\"key\",\"value\")\nenum class MyEnum {Key1 = 1}\nQ_ENUMS(MyEnum)\n}\n")
2207  << QStringList()
2208  << 1
2209  << QString()
2210  << QString("standard input:1:1: error: Namespace declaration lacks Q_NAMESPACE macro.");
2211 
2212  QTest::newRow("Wrong Q_ENUM context.")
2213  << QByteArray("namespace X {\nQ_NAMESPACE\n\nenum class MyEnum {Key1 = 1}\nQ_ENUM(MyEnum)\n}\n")
2214  << QStringList()
2215  << 1
2216  << QString()
2217  << QString("standard input:5:1: error: Q_ENUM can't be used in a Q_NAMESPACE, use Q_ENUM_NS instead");
2218 
2219  QTest::newRow("Wrong Q_FLAG context.")
2220  << QByteArray("namespace X {\nQ_NAMESPACE\n\nenum class MyEnum {Key1 = 1}\nQ_FLAG(MyEnum)\n}\n")
2221  << QStringList()
2222  << 1
2223  << QString()
2224  << QString("standard input:5:1: error: Q_FLAG can't be used in a Q_NAMESPACE, use Q_FLAG_NS instead");
2225 
2226  QTest::newRow("Wrong Q_ENUM_NS context.")
2227  << QByteArray("class X {\nQ_GADGET\n\nenum class MyEnum {Key1 = 1}\nQ_ENUM_NS(MyEnum)\n};\n")
2228  << QStringList()
2229  << 1
2230  << QString()
2231  << QString("standard input:5:1: error: Q_ENUM_NS can't be used in a Q_OBJECT/Q_GADGET, use Q_ENUM instead");
2232 
2233  QTest::newRow("Wrong Q_FLAG_NS context.")
2234  << QByteArray("class X {\nQ_GADGET\n\nenum class MyEnum {Key1 = 1}\nQ_FLAG_NS(MyEnum)\n};\n")
2235  << QStringList()
2236  << 1
2237  << QString()
2238  << QString("standard input:5:1: error: Q_FLAG_NS can't be used in a Q_OBJECT/Q_GADGET, use Q_FLAG instead");
2239 
2240  QTest::newRow("Invalid macro definition")
2241  << QByteArray("#define Foo(a, b, c) a b c #a #b #c a##b##c #d\n Foo(45, 42, 39);")
2242  << QStringList()
2243  << 1
2244  << QString("IGNORE_ALL_STDOUT")
2245  << QString(":2:1: error: '#' is not followed by a macro parameter");
2246 
2247  QTest::newRow("QTBUG-46210: crash on invalid macro invocation")
2248  << QByteArray("#define Foo(a, b, c) a b c #a #b #c a##b##c\n Foo(45);")
2249  << QStringList()
2250  << 1
2251  << QString("IGNORE_ALL_STDOUT")
2252  << QString(":2:1: error: Macro invoked with too few parameters for a use of '#'");
2253 
2254  QTest::newRow("QTBUG-54609: crash on invalid input")
2255  << QByteArray::fromBase64("EAkJCQkJbGFzcyBjbGFzcyBiYWkcV2kgTUEKcGYjZGVmaW5lIE1BKFEs/4D/FoQ=")
2256  << QStringList()
2257  << 1
2258  << QString("IGNORE_ALL_STDOUT")
2259  << QString(":-1:1: error: Unexpected character in macro argument list.");
2260 
2261  QTest::newRow("Missing header warning")
2262  << QByteArray("class X : public QObject { Q_OBJECT };")
2263  << (QStringList() << QStringLiteral("--include") << QStringLiteral("doesnotexist.h"))
2264  << 0
2265  << QString("IGNORE_ALL_STDOUT")
2266  << QStringLiteral("Warning: Failed to resolve include \"doesnotexist.h\" for moc file <standard input>");
2267 
2268  QTest::newRow("QTBUG-54815: Crash on invalid input")
2269  << QByteArray("class M{(})F<{}d000000000000000#0")
2270  << QStringList()
2271  << 0
2272  << QString()
2273  << QString("standard input:1:1: note: No relevant classes found. No output generated.");
2274 
2275  QTest::newRow("Q_PLUGIN_METADATA: invalid file")
2276  << QByteArray("class X { \n Q_PLUGIN_METADATA(FILE \"does.not.exists\") \n };")
2277  << QStringList()
2278  << 1
2279  << QString()
2280  << QString("standard input:2:1: error: Plugin Metadata file \"does.not.exists\" does not exist. Declaration will be ignored");
2281 
2282  QTest::newRow("Auto-declared, missing trailing return")
2283  << QByteArray("class X { \n public slots: \n auto fun() { return 1; } };")
2284  << QStringList()
2285  << 1
2286  << QString()
2287  << QString("standard input:3:1: error: Function declared with auto as return type but missing trailing return type. Return type deduction is not supported.");
2288 
2289  QTest::newRow("Auto-declared, volatile auto as trailing return type")
2290  << QByteArray("class X { \n public slots: \n auto fun() -> volatile auto { return 1; } };")
2291  << QStringList()
2292  << 1
2293  << QString()
2294  << QString("standard input:3:1: error: Function declared with auto as return type but missing trailing return type. Return type deduction is not supported.");
2295 
2296  // We don't currently support the decltype keyword, so it's not the same error as above.
2297  // The test is just here to make sure this keeps generating an error until return type deduction
2298  // is supported.
2299  QTest::newRow("Auto-declared, decltype in trailing return type")
2300  << QByteArray("class X { \n public slots: \n auto fun() -> decltype(0+1) { return 1; } };")
2301  << QStringList()
2302  << 1
2303  << QString()
2304  << QString("standard input:3:1: error: Parse error at \"decltype\"");
2305 
2306 #ifdef Q_OS_UNIX // Limit to Unix because the error message is platform-dependent
2307  QTest::newRow("Q_PLUGIN_METADATA: unreadable file")
2308  << QByteArray("class X { \n Q_PLUGIN_METADATA(FILE \".\") \n };")
2309  << QStringList()
2310  << 1
2311  << QString()
2312  << QString("standard input:2:1: error: Plugin Metadata file \".\" could not be opened: file to open is a directory");
2313 #endif
2314 }
2315 
2316 void tst_Moc::warnings()
2317 {
2318 #ifdef MOC_CROSS_COMPILED
2319  QSKIP("Not tested when cross-compiled");
2320 #endif
2323  QFETCH(int, exitCode);
2324  QFETCH(QString, expectedStdOut);
2325  QFETCH(QString, expectedStdErr);
2326 
2327 #ifdef Q_CC_MSVC
2328  // moc compiled with MSVC uses a different output format to match MSVC compiler style
2329  QRegularExpression lineNumberRe(":(-?\\d+):(\\d+)", QRegularExpression::InvertedGreedinessOption);
2330  expectedStdErr.replace(lineNumberRe, "(\\1:\\2)");
2331 #endif
2332 
2333 #if QT_CONFIG(process)
2334  QProcess proc;
2335 
2337  env.insert("QT_MESSAGE_PATTERN", "no qDebug or qWarning please");
2338  proc.setProcessEnvironment(env);
2339 
2340  proc.start(m_moc, args);
2341  QVERIFY(proc.waitForStarted());
2342 
2343  QCOMPARE(proc.write(input), qint64(input.size()));
2344 
2345  proc.closeWriteChannel();
2346 
2347  QVERIFY(proc.waitForFinished());
2348 
2349  QCOMPARE(proc.exitCode(), exitCode);
2350  QCOMPARE(proc.exitStatus(), QProcess::NormalExit);
2351 
2352  // magic value "IGNORE_ALL_STDOUT" ignores stdout
2353  if (expectedStdOut != "IGNORE_ALL_STDOUT")
2354  QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardOutput()).trimmed(), expectedStdOut);
2355  QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()).trimmed().remove('\r'), expectedStdErr);
2356 #else
2357  QSKIP("Only tested if QProcess is available");
2358 #endif
2359 }
2360 
2361 class tst_Moc::PrivateClass : public QObject {
2362  Q_PROPERTY(int someProperty READ someSlot WRITE someSlot2)
2363 Q_OBJECT
2364 Q_SIGNALS:
2365  void someSignal();
2366 public Q_SLOTS:
2367  int someSlot() { return 1; }
2368  void someSlot2(int) {}
2369 public:
2371 };
2372 
2373 void tst_Moc::privateClass()
2374 {
2375  QCOMPARE(PrivateClass::staticMetaObject.indexOfConstructor("PrivateClass()"), 0);
2376  QVERIFY(PrivateClass::staticMetaObject.indexOfSignal("someSignal()") > 0);
2377 }
2378 
2379 void tst_Moc::cxx11Enums_data()
2380 {
2381  QTest::addColumn<const QMetaObject *>("meta");
2382  QTest::addColumn<QByteArray>("typeName");
2383  QTest::addColumn<QByteArray>("enumName");
2384  QTest::addColumn<char>("prefix");
2385  QTest::addColumn<bool>("isScoped");
2386 
2387  const QMetaObject *meta1 = &CXX11Enums::staticMetaObject;
2388  const QMetaObject *meta2 = &CXX11Enums2::staticMetaObject;
2389 
2390  QTest::newRow("EnumClass") << meta1 << QByteArray("EnumClass") << QByteArray("EnumClass") << 'A' << true;
2391  QTest::newRow("EnumClass 2") << meta2 << QByteArray("EnumClass") << QByteArray("EnumClass") << 'A' << true;
2392  QTest::newRow("TypedEnum") << meta1 << QByteArray("TypedEnum") << QByteArray("TypedEnum") << 'B' << false;
2393  QTest::newRow("TypedEnum 2") << meta2 << QByteArray("TypedEnum") << QByteArray("TypedEnum") << 'B' << false;
2394  QTest::newRow("TypedEnumClass") << meta1 << QByteArray("TypedEnumClass") << QByteArray("TypedEnumClass") << 'C' << true;
2395  QTest::newRow("TypedEnumClass 2") << meta2 << QByteArray("TypedEnumClass") << QByteArray("TypedEnumClass") << 'C' << true;
2396  QTest::newRow("NormalEnum") << meta1 << QByteArray("NormalEnum") << QByteArray("NormalEnum") << 'D' << false;
2397  QTest::newRow("NormalEnum 2") << meta2 << QByteArray("NormalEnum") << QByteArray("NormalEnum") << 'D' << false;
2398  QTest::newRow("ClassFlags") << meta1 << QByteArray("ClassFlags") << QByteArray("ClassFlag") << 'F' << true;
2399  QTest::newRow("ClassFlags 2") << meta2 << QByteArray("ClassFlags") << QByteArray("ClassFlag") << 'F' << true;
2400  QTest::newRow("EnumStruct") << meta1 << QByteArray("EnumStruct") << QByteArray("EnumStruct") << 'G' << true;
2401  QTest::newRow("TypedEnumStruct") << meta1 << QByteArray("TypedEnumStruct") << QByteArray("TypedEnumStruct") << 'H' << true;
2402  QTest::newRow("StructFlags") << meta1 << QByteArray("StructFlags") << QByteArray("StructFlag") << 'I' << true;
2403 }
2404 
2405 void tst_Moc::cxx11Enums()
2406 {
2407  QFETCH(const QMetaObject *,meta);
2408  QCOMPARE(meta->enumeratorOffset(), 0);
2409 
2411  QFETCH(QByteArray, enumName);
2412  QFETCH(char, prefix);
2413  QFETCH(bool, isScoped);
2414 
2415  int idx = meta->indexOfEnumerator(typeName);
2416  QVERIFY(idx != -1);
2417  QCOMPARE(meta->indexOfEnumerator(enumName), idx);
2418 
2419  QCOMPARE(meta->enumerator(idx).enclosingMetaObject(), meta);
2420  QCOMPARE(meta->enumerator(idx).isValid(), true);
2421  QCOMPARE(meta->enumerator(idx).keyCount(), 4);
2422  QCOMPARE(meta->enumerator(idx).name(), typeName.constData());
2423  QCOMPARE(meta->enumerator(idx).enumName(), enumName.constData());
2424  bool isFlag = meta->enumerator(idx).isFlag();
2425  for (int i = 0; i < 4; i++) {
2426  QByteArray v = prefix + QByteArray::number(i);
2427  const int value = isFlag ? (1 << i) : i;
2428  QCOMPARE(meta->enumerator(idx).keyToValue(v), value);
2429  QCOMPARE(meta->enumerator(idx).valueToKey(value), v.constData());
2430  }
2431  QCOMPARE(meta->enumerator(idx).isScoped(), isScoped);
2432 }
2433 
2434 void tst_Moc::cxx11TrailingReturn()
2435 {
2436  CXX11TrailingReturn retClass;
2437  const QMetaObject *mobj = retClass.metaObject();
2438  QVERIFY(mobj->indexOfSlot("fun()") != -1);
2439  QVERIFY(mobj->indexOfSlot("arguments(int,char)") != -1);
2440  QVERIFY(mobj->indexOfSlot("inlineFunc(int)") != -1);
2441  QVERIFY(mobj->indexOfSlot("constRefReturn()") != -1);
2442  QVERIFY(mobj->indexOfSlot("constConstRefReturn()") != -1);
2443  QVERIFY(mobj->indexOfSignal("trailingSignalReturn(int)") != -1);
2444 }
2445 
2446 void tst_Moc::returnRefs()
2447 {
2448  TestClass tst;
2449  const QMetaObject *mobj = tst.metaObject();
2450  QVERIFY(mobj->indexOfMethod("myInvokableReturningRef()") != -1);
2451  QVERIFY(mobj->indexOfMethod("myInvokableReturningConstRef()") != -1);
2452  // Those two functions are copied from the qscriptextqobject test in qtscript
2453  // they used to cause miscompilation of the moc generated file.
2454 }
2455 
2456 void tst_Moc::memberProperties_data()
2457 {
2458  QTest::addColumn<int>("object");
2459  QTest::addColumn<QString>("property");
2460  QTest::addColumn<QString>("signal");
2461  QTest::addColumn<QString>("writeValue");
2462  QTest::addColumn<bool>("expectedWriteResult");
2463  QTest::addColumn<QString>("expectedReadResult");
2464 
2465  pPPTest = new PrivatePropertyTest( this );
2466 
2467  QTest::newRow("MEMBER property")
2468  << 0 << "member1" << "" << "abc" << true << "abc";
2469  QTest::newRow("MEMBER property with READ function")
2470  << 0 << "member2" << "" << "def" << true << "def";
2471  QTest::newRow("MEMBER property with WRITE function")
2472  << 0 << "member3" << "" << "ghi" << true << "ghi";
2473  QTest::newRow("MEMBER property with NOTIFY")
2474  << 0 << "member4" << "member4Changed()" << "lmn" << true << "lmn";
2475  QTest::newRow("MEMBER property with NOTIFY(value)")
2476  << 0 << "member5" << "member5Changed(const QString&)" << "opq" << true << "opq";
2477  QTest::newRow("MEMBER property with CONSTANT")
2478  << 0 << "member6" << "" << "test" << false << "const";
2479  QTest::newRow("private MEMBER property")
2480  << 1 << "blub" << "" << "abc" << true << "abc";
2481  QTest::newRow("private MEMBER property with READ function")
2482  << 1 << "blub2" << "" << "def" << true << "def";
2483  QTest::newRow("private MEMBER property with WRITE function")
2484  << 1 << "blub3" << "" << "ghi" << true << "ghi";
2485  QTest::newRow("private MEMBER property with NOTIFY")
2486  << 1 << "blub4" << "blub4Changed()" << "jkl" << true << "jkl";
2487  QTest::newRow("private MEMBER property with NOTIFY(value)")
2488  << 1 << "blub5" << "blub5Changed(const QString&)" << "mno" << true << "mno";
2489  QTest::newRow("private MEMBER property with CONSTANT")
2490  << 1 << "blub6" << "" << "test" << false << "const";
2491  QTest::newRow("sub1")
2492  << 0 << "sub1" << "" << "helloSub1" << true << "helloSub1";
2493  QTest::newRow("sub2")
2494  << 0 << "sub2" << "" << "helloSub2" << true << "helloSub2";
2495 }
2496 
2497 void tst_Moc::memberProperties()
2498 {
2499  QFETCH(int, object);
2501  QFETCH(QString, signal);
2502  QFETCH(QString, writeValue);
2503  QFETCH(bool, expectedWriteResult);
2504  QFETCH(QString, expectedReadResult);
2505 
2506  QObject *pObj = (object == 0) ? this : static_cast<QObject*>(pPPTest);
2507 
2508  QString sSignalDeclaration;
2509  if (!signal.isEmpty())
2510  sSignalDeclaration = QString(SIGNAL(%1)).arg(signal);
2511  else
2512  QTest::ignoreMessage(QtWarningMsg, "QSignalSpy: Not a valid signal, use the SIGNAL macro");
2513  QSignalSpy notifySpy(pObj, sSignalDeclaration.toLatin1().constData());
2514 
2515  int index = pObj->metaObject()->indexOfProperty(property.toLatin1().constData());
2516  QVERIFY(index != -1);
2517  QMetaProperty prop = pObj->metaObject()->property(index);
2518 
2519  QCOMPARE(prop.write(pObj, writeValue), expectedWriteResult);
2520 
2521  QVariant readValue = prop.read(pObj);
2522  QCOMPARE(readValue.toString(), expectedReadResult);
2523 
2524  if (!signal.isEmpty())
2525  {
2526  QCOMPARE(notifySpy.count(), 1);
2527  if (prop.notifySignal().parameterNames().size() > 0) {
2528  QList<QVariant> arguments = notifySpy.takeFirst();
2529  QCOMPARE(arguments.size(), 1);
2530  QCOMPARE(arguments.at(0).toString(), expectedReadResult);
2531  }
2532 
2533  notifySpy.clear();
2534  // a second write with the same value should not cause the signal to be emitted again
2535  QCOMPARE(prop.write(pObj, writeValue), expectedWriteResult);
2536  QCOMPARE(notifySpy.count(), 0);
2537  }
2538 }
2539 
2540 //this used to fail to compile
2541 class ClassWithOneMember : public QObject {
2542  Q_PROPERTY(int member MEMBER member)
2543  Q_OBJECT
2544 public:
2545  int member;
2546 };
2547 
2548 void tst_Moc::memberProperties2()
2549 {
2551  o.member = 442;
2552  QCOMPARE(o.property("member").toInt(), 442);
2553  QVERIFY(o.setProperty("member", 6666));
2554  QCOMPARE(o.member, 6666);
2555 }
2556 
2557 class SignalConnectionTester : public QObject
2558 {
2559  Q_OBJECT
2560 public:
2561  SignalConnectionTester(QObject *parent = nullptr)
2562  : QObject(parent), testPassed(false)
2563  {
2564 
2565  }
2566 
2567 public Q_SLOTS:
2568  void testSlot()
2569  {
2570  testPassed = true;
2571  }
2573  {
2574  testPassed = i == 42;
2575  }
2576  void testSlotWith2Args(int i, const QString &s)
2577  {
2578  testPassed = i == 42 && s == "Hello";
2579  }
2580 
2581 public:
2582  bool testPassed;
2583 };
2584 
2585 class ClassWithPrivateSignals : public QObject
2586 {
2587  Q_OBJECT
2588 public:
2589  ClassWithPrivateSignals(QObject *parent = nullptr)
2590  : QObject(parent)
2591  {
2592 
2593  }
2594 
2596  {
2597  emit privateSignal1(QPrivateSignal());
2598  emit privateSignalWith1Arg(42, QPrivateSignal());
2599  emit privateSignalWith2Args(42, "Hello", QPrivateSignal());
2600 
2601  emit privateOverloadedSignal(QPrivateSignal());
2602  emit privateOverloadedSignal(42, QPrivateSignal());
2603 
2605  emit overloadedMaybePrivate(42, QPrivateSignal());
2606  }
2607 
2608 Q_SIGNALS:
2609  void privateSignal1(QPrivateSignal);
2610  void privateSignalWith1Arg(int arg1, QPrivateSignal);
2611  void privateSignalWith2Args(int arg1, const QString &arg2, QPrivateSignal);
2612 
2613  void privateOverloadedSignal(QPrivateSignal);
2614  void privateOverloadedSignal(int, QPrivateSignal);
2615 
2617  void overloadedMaybePrivate(int, QPrivateSignal);
2618 
2619 };
2620 
2622 {
2623  Q_OBJECT
2624 public:
2627  {
2628 
2629  }
2630 
2632  {
2633  // Compile test: All of this intentionally does not compile:
2634 // emit privateSignal1();
2635 // emit privateSignalWith1Arg(42);
2636 // emit privateSignalWith2Args(42, "Hello");
2637 //
2638 // emit privateSignal1(QPrivateSignal());
2639 // emit privateSignalWith1Arg(42, QPrivateSignal());
2640 // emit privateSignalWith2Args(42, "Hello", QPrivateSignal());
2641 //
2642 // emit privateSignal1(ClassWithPrivateSignals::QPrivateSignal());
2643 // emit privateSignalWith1Arg(42, ClassWithPrivateSignals::QPrivateSignal());
2644 // emit privateSignalWith2Args(42, "Hello", ClassWithPrivateSignals::QPrivateSignal());
2645 
2646 // emit privateOverloadedSignal();
2647 // emit privateOverloadedSignal(42);
2648 
2649 // emit overloadedMaybePrivate();
2650 // emit overloadedMaybePrivate(42);
2651 
2652 
2653  }
2654 };
2655 
2656 void tst_Moc::privateSignalConnection()
2657 {
2658  // Function pointer connects. Matching signals and slots
2659  {
2660  ClassWithPrivateSignals classWithPrivateSignals;
2661  SignalConnectionTester tester;
2663 
2664  QVERIFY(!tester.testPassed);
2665 
2666  classWithPrivateSignals.emitPrivateSignals();
2667 
2668  QVERIFY(tester.testPassed);
2669  tester.testPassed = false;
2670  QMetaObject::invokeMethod(&classWithPrivateSignals, "privateSignal1");
2671  QVERIFY(tester.testPassed);
2672  }
2673  {
2674  SubClassFromPrivateSignals subClassFromPrivateSignals;
2675  SignalConnectionTester tester;
2677 
2678  QVERIFY(!tester.testPassed);
2679 
2680  subClassFromPrivateSignals.emitPrivateSignals();
2681 
2682  QVERIFY(tester.testPassed);
2683  tester.testPassed = false;
2684  QMetaObject::invokeMethod(&subClassFromPrivateSignals, "privateSignal1");
2685  QVERIFY(tester.testPassed);
2686  }
2687  {
2688  ClassWithPrivateSignals classWithPrivateSignals;
2689  SignalConnectionTester tester;
2691 
2692  QVERIFY(!tester.testPassed);
2693 
2694  classWithPrivateSignals.emitPrivateSignals();
2695 
2696  QVERIFY(tester.testPassed);
2697  tester.testPassed = false;
2698  QMetaObject::invokeMethod(&classWithPrivateSignals, "privateSignalWith1Arg", Q_ARG(int, 42));
2699  QVERIFY(tester.testPassed);
2700  }
2701  {
2702  SubClassFromPrivateSignals subClassFromPrivateSignals;
2703  SignalConnectionTester tester;
2705 
2706  QVERIFY(!tester.testPassed);
2707 
2708  subClassFromPrivateSignals.emitPrivateSignals();
2709 
2710  QVERIFY(tester.testPassed);
2711  tester.testPassed = false;
2712  QMetaObject::invokeMethod(&subClassFromPrivateSignals, "privateSignalWith1Arg", Q_ARG(int, 42));
2713  QVERIFY(tester.testPassed);
2714  }
2715  {
2716  ClassWithPrivateSignals classWithPrivateSignals;
2717  SignalConnectionTester tester;
2719 
2720  QVERIFY(!tester.testPassed);
2721 
2722  classWithPrivateSignals.emitPrivateSignals();
2723 
2724  QVERIFY(tester.testPassed);
2725  tester.testPassed = false;
2726  QMetaObject::invokeMethod(&classWithPrivateSignals, "privateSignalWith2Args", Q_ARG(int, 42), Q_ARG(QString, "Hello"));
2727  QVERIFY(tester.testPassed);
2728  }
2729  {
2730  SubClassFromPrivateSignals subClassFromPrivateSignals;
2731  SignalConnectionTester tester;
2733 
2734  QVERIFY(!tester.testPassed);
2735 
2736  subClassFromPrivateSignals.emitPrivateSignals();
2737 
2738  QVERIFY(tester.testPassed);
2739  tester.testPassed = false;
2740  QMetaObject::invokeMethod(&subClassFromPrivateSignals, "privateSignalWith2Args", Q_ARG(int, 42), Q_ARG(QString, "Hello"));
2741  QVERIFY(tester.testPassed);
2742  }
2743 
2744 
2745  // String based connects. Matching signals and slots
2746  {
2747  ClassWithPrivateSignals classWithPrivateSignals;
2748  SignalConnectionTester tester;
2749  QObject::connect(&classWithPrivateSignals, SIGNAL(privateSignal1()), &tester, SLOT(testSlot()));
2750 
2751  QVERIFY(!tester.testPassed);
2752 
2753  classWithPrivateSignals.emitPrivateSignals();
2754 
2755  QVERIFY(tester.testPassed);
2756  }
2757  {
2758  SubClassFromPrivateSignals subClassFromPrivateSignals;
2759  SignalConnectionTester tester;
2760  QObject::connect(&subClassFromPrivateSignals, SIGNAL(privateSignal1()), &tester, SLOT(testSlot()));
2761 
2762  QVERIFY(!tester.testPassed);
2763 
2764  subClassFromPrivateSignals.emitPrivateSignals();
2765 
2766  QVERIFY(tester.testPassed);
2767  }
2768  {
2769  ClassWithPrivateSignals classWithPrivateSignals;
2770  SignalConnectionTester tester;
2771  QObject::connect(&classWithPrivateSignals, SIGNAL(privateSignalWith1Arg(int)), &tester, SLOT(testSlotWith1Arg(int)));
2772 
2773  QVERIFY(!tester.testPassed);
2774 
2775  classWithPrivateSignals.emitPrivateSignals();
2776 
2777  QVERIFY(tester.testPassed);
2778  }
2779  {
2780  SubClassFromPrivateSignals subClassFromPrivateSignals;
2781  SignalConnectionTester tester;
2782  QObject::connect(&subClassFromPrivateSignals, SIGNAL(privateSignalWith1Arg(int)), &tester, SLOT(testSlotWith1Arg(int)));
2783 
2784  QVERIFY(!tester.testPassed);
2785 
2786  subClassFromPrivateSignals.emitPrivateSignals();
2787 
2788  QVERIFY(tester.testPassed);
2789  }
2790  {
2791  ClassWithPrivateSignals classWithPrivateSignals;
2792  SignalConnectionTester tester;
2793  QObject::connect(&classWithPrivateSignals, SIGNAL(privateSignalWith2Args(int,QString)), &tester, SLOT(testSlotWith2Args(int,QString)));
2794  QVERIFY(!tester.testPassed);
2795 
2796  classWithPrivateSignals.emitPrivateSignals();
2797 
2798  QVERIFY(tester.testPassed);
2799  }
2800  {
2801  SubClassFromPrivateSignals subClassFromPrivateSignals;
2802  SignalConnectionTester tester;
2803  QObject::connect(&subClassFromPrivateSignals, SIGNAL(privateSignalWith2Args(int,QString)), &tester, SLOT(testSlotWith2Args(int,QString)));
2804 
2805  QVERIFY(!tester.testPassed);
2806 
2807  subClassFromPrivateSignals.emitPrivateSignals();
2808 
2809  QVERIFY(tester.testPassed);
2810  }
2811 
2812  // Function pointer connects. Decayed slot arguments
2813  {
2814  ClassWithPrivateSignals classWithPrivateSignals;
2815  SignalConnectionTester tester;
2817 
2818  QVERIFY(!tester.testPassed);
2819 
2820  classWithPrivateSignals.emitPrivateSignals();
2821 
2822  QVERIFY(tester.testPassed);
2823  }
2824  {
2825  SubClassFromPrivateSignals subClassFromPrivateSignals;
2826  SignalConnectionTester tester;
2828 
2829  QVERIFY(!tester.testPassed);
2830 
2831  subClassFromPrivateSignals.emitPrivateSignals();
2832 
2833  QVERIFY(tester.testPassed);
2834  }
2835  {
2836  ClassWithPrivateSignals classWithPrivateSignals;
2837  SignalConnectionTester tester;
2839  QVERIFY(!tester.testPassed);
2840 
2841  classWithPrivateSignals.emitPrivateSignals();
2842 
2843  QVERIFY(tester.testPassed);
2844  }
2845  {
2846  SubClassFromPrivateSignals subClassFromPrivateSignals;
2847  SignalConnectionTester tester;
2849 
2850  QVERIFY(!tester.testPassed);
2851 
2852  subClassFromPrivateSignals.emitPrivateSignals();
2853 
2854  QVERIFY(tester.testPassed);
2855  }
2856  {
2857  ClassWithPrivateSignals classWithPrivateSignals;
2858  SignalConnectionTester tester;
2860  QVERIFY(!tester.testPassed);
2861 
2862  classWithPrivateSignals.emitPrivateSignals();
2863 
2864  QVERIFY(tester.testPassed);
2865  }
2866  {
2867  SubClassFromPrivateSignals subClassFromPrivateSignals;
2868  SignalConnectionTester tester;
2870 
2871  QVERIFY(!tester.testPassed);
2872 
2873  subClassFromPrivateSignals.emitPrivateSignals();
2874 
2875  QVERIFY(tester.testPassed);
2876  }
2877 
2878  // String based connects. Decayed slot arguments
2879  {
2880  ClassWithPrivateSignals classWithPrivateSignals;
2881  SignalConnectionTester tester;
2882  QObject::connect(&classWithPrivateSignals, SIGNAL(privateSignalWith1Arg(int)), &tester, SLOT(testSlot()));
2883 
2884  QVERIFY(!tester.testPassed);
2885 
2886  classWithPrivateSignals.emitPrivateSignals();
2887 
2888  QVERIFY(tester.testPassed);
2889  }
2890  {
2891  SubClassFromPrivateSignals subClassFromPrivateSignals;
2892  SignalConnectionTester tester;
2893  QObject::connect(&subClassFromPrivateSignals, SIGNAL(privateSignalWith1Arg(int)), &tester, SLOT(testSlot()));
2894 
2895  QVERIFY(!tester.testPassed);
2896 
2897  subClassFromPrivateSignals.emitPrivateSignals();
2898 
2899  QVERIFY(tester.testPassed);
2900  }
2901  {
2902  ClassWithPrivateSignals classWithPrivateSignals;
2903  SignalConnectionTester tester;
2904  QObject::connect(&classWithPrivateSignals, SIGNAL(privateSignalWith2Args(int,QString)), &tester, SLOT(testSlotWith1Arg(int)));
2905  QVERIFY(!tester.testPassed);
2906 
2907  classWithPrivateSignals.emitPrivateSignals();
2908 
2909  QVERIFY(tester.testPassed);
2910  }
2911  {
2912  SubClassFromPrivateSignals subClassFromPrivateSignals;
2913  SignalConnectionTester tester;
2914  QObject::connect(&subClassFromPrivateSignals, SIGNAL(privateSignalWith2Args(int,QString)), &tester, SLOT(testSlotWith1Arg(int)));
2915 
2916  QVERIFY(!tester.testPassed);
2917 
2918  subClassFromPrivateSignals.emitPrivateSignals();
2919 
2920  QVERIFY(tester.testPassed);
2921  }
2922  {
2923  ClassWithPrivateSignals classWithPrivateSignals;
2924  SignalConnectionTester tester;
2925  QObject::connect(&classWithPrivateSignals, SIGNAL(privateSignalWith2Args(int,QString)), &tester, SLOT(testSlot()));
2926  QVERIFY(!tester.testPassed);
2927 
2928  classWithPrivateSignals.emitPrivateSignals();
2929 
2930  QVERIFY(tester.testPassed);
2931  }
2932  {
2933  SubClassFromPrivateSignals subClassFromPrivateSignals;
2934  SignalConnectionTester tester;
2935  QObject::connect(&subClassFromPrivateSignals, SIGNAL(privateSignalWith2Args(int,QString)), &tester, SLOT(testSlot()));
2936 
2937  QVERIFY(!tester.testPassed);
2938 
2939  subClassFromPrivateSignals.emitPrivateSignals();
2940 
2941  QVERIFY(tester.testPassed);
2942  }
2943 
2944  // Overloaded private signals
2945  {
2946 
2947  ClassWithPrivateSignals classWithPrivateSignals;
2948  SignalConnectionTester tester;
2949  QObject::connect(&classWithPrivateSignals, SIGNAL(privateOverloadedSignal()), &tester, SLOT(testSlot()));
2950  QVERIFY(!tester.testPassed);
2951 
2952  classWithPrivateSignals.emitPrivateSignals();
2953 
2954  QVERIFY(tester.testPassed);
2955  }
2956  {
2957 
2958  ClassWithPrivateSignals classWithPrivateSignals;
2959  SignalConnectionTester tester;
2960  QObject::connect(&classWithPrivateSignals, SIGNAL(privateOverloadedSignal(int)), &tester, SLOT(testSlotWith1Arg(int)));
2961  QVERIFY(!tester.testPassed);
2962 
2963  classWithPrivateSignals.emitPrivateSignals();
2964 
2965  QVERIFY(tester.testPassed);
2966  }
2967  // We can't use function pointer connections to private signals which are overloaded because we would have to cast in this case to:
2968  // static_cast<void (ClassWithPrivateSignals::*)(int, ClassWithPrivateSignals::QPrivateSignal)>(&ClassWithPrivateSignals::privateOverloadedSignal)
2969  // Which doesn't work as ClassWithPrivateSignals::QPrivateSignal is private.
2970 
2971  // Overload with either private or not private signals
2972  {
2973 
2974  ClassWithPrivateSignals classWithPrivateSignals;
2975  SignalConnectionTester tester;
2976  QObject::connect(&classWithPrivateSignals, SIGNAL(overloadedMaybePrivate()), &tester, SLOT(testSlot()));
2977  QVERIFY(!tester.testPassed);
2978 
2979  classWithPrivateSignals.emitPrivateSignals();
2980 
2981  QVERIFY(tester.testPassed);
2982  }
2983  {
2984 
2985  ClassWithPrivateSignals classWithPrivateSignals;
2986  SignalConnectionTester tester;
2987  QObject::connect(&classWithPrivateSignals, SIGNAL(privateOverloadedSignal(int)), &tester, SLOT(testSlotWith1Arg(int)));
2988  QVERIFY(!tester.testPassed);
2989 
2990  classWithPrivateSignals.emitPrivateSignals();
2991 
2992  QVERIFY(tester.testPassed);
2993  }
2994  {
2995 
2996  ClassWithPrivateSignals classWithPrivateSignals;
2997  SignalConnectionTester tester;
2998  QObject::connect(&classWithPrivateSignals,
3001  QVERIFY(!tester.testPassed);
3002 
3003  classWithPrivateSignals.emitPrivateSignals();
3004 
3005  QVERIFY(tester.testPassed);
3006  }
3007  // We can't use function pointer connections to private signals which are overloaded because we would have to cast in this case to:
3008  // static_cast<void (ClassWithPrivateSignals::*)(int, ClassWithPrivateSignals::QPrivateSignal)>(&ClassWithPrivateSignals::overloadedMaybePrivate)
3009  // Which doesn't work as ClassWithPrivateSignals::QPrivateSignal is private.
3010 
3011  // Connecting from one private signal to another
3012  {
3013  ClassWithPrivateSignals classWithPrivateSignals1;
3014  ClassWithPrivateSignals classWithPrivateSignals2;
3015  SignalConnectionTester tester;
3016  QObject::connect(&classWithPrivateSignals1, &ClassWithPrivateSignals::privateSignal1,
3017  &classWithPrivateSignals2, &ClassWithPrivateSignals::privateSignal1);
3018  QObject::connect(&classWithPrivateSignals2, &ClassWithPrivateSignals::privateSignal1,
3020 
3021  QVERIFY(!tester.testPassed);
3022  classWithPrivateSignals1.emitPrivateSignals();
3023  QVERIFY(tester.testPassed);
3024  }
3025 }
3026 
3027 void tst_Moc::finalClasses_data()
3028 {
3029  QTest::addColumn<QString>("className");
3030  QTest::addColumn<QString>("expected");
3031 
3032  QTest::newRow("FinalTestClassQt") << FinalTestClassQt::staticMetaObject.className() << "FinalTestClassQt";
3033  QTest::newRow("ExportedFinalTestClassQt") << ExportedFinalTestClassQt::staticMetaObject.className() << "ExportedFinalTestClassQt";
3034  QTest::newRow("ExportedFinalTestClassQtX") << ExportedFinalTestClassQtX::staticMetaObject.className() << "ExportedFinalTestClassQtX";
3035 
3036  QTest::newRow("FinalTestClassCpp11") << FinalTestClassCpp11::staticMetaObject.className() << "FinalTestClassCpp11";
3037  QTest::newRow("ExportedFinalTestClassCpp11") << ExportedFinalTestClassCpp11::staticMetaObject.className() << "ExportedFinalTestClassCpp11";
3038  QTest::newRow("ExportedFinalTestClassCpp11X") << ExportedFinalTestClassCpp11X::staticMetaObject.className() << "ExportedFinalTestClassCpp11X";
3039 
3040  QTest::newRow("SealedTestClass") << SealedTestClass::staticMetaObject.className() << "SealedTestClass";
3041  QTest::newRow("ExportedSealedTestClass") << ExportedSealedTestClass::staticMetaObject.className() << "ExportedSealedTestClass";
3042  QTest::newRow("ExportedSealedTestClassX") << ExportedSealedTestClassX::staticMetaObject.className() << "ExportedSealedTestClassX";
3043 }
3044 
3045 void tst_Moc::finalClasses()
3046 {
3048  QFETCH(QString, expected);
3049 
3050  QCOMPARE(className, expected);
3051 }
3052 
3053 void tst_Moc::explicitOverrideControl_data()
3054 {
3055  QTest::addColumn<const QMetaObject*>("mo");
3056 
3057 #define ADD(x) QTest::newRow(#x) << &x::staticMetaObject
3066 #undef ADD
3067 }
3068 
3069 void tst_Moc::explicitOverrideControl()
3070 {
3071  QFETCH(const QMetaObject*, mo);
3072 
3073  QVERIFY(mo);
3074  QCOMPARE(mo->indexOfMethod("pureSlot0()"), mo->methodOffset() + 0);
3075  QCOMPARE(mo->indexOfMethod("pureSlot1()"), mo->methodOffset() + 1);
3076  QCOMPARE(mo->indexOfMethod("pureSlot2()"), mo->methodOffset() + 2);
3077  QCOMPARE(mo->indexOfMethod("pureSlot3()"), mo->methodOffset() + 3);
3078 #if 0 // moc doesn't support volatile slots
3079  QCOMPARE(mo->indexOfMethod("pureSlot4()"), mo->methodOffset() + 4);
3080  QCOMPARE(mo->indexOfMethod("pureSlot5()"), mo->methodOffset() + 5);
3081  QCOMPARE(mo->indexOfMethod("pureSlot6()"), mo->methodOffset() + 6);
3082  QCOMPARE(mo->indexOfMethod("pureSlot7()"), mo->methodOffset() + 7);
3083  QCOMPARE(mo->indexOfMethod("pureSlot8()"), mo->methodOffset() + 8);
3084  QCOMPARE(mo->indexOfMethod("pureSlot9()"), mo->methodOffset() + 9);
3085 #endif
3086 }
3087 
3088 class OverloadedAddressOperator : public QObject
3089 {
3090  Q_OBJECT
3091 public:
3092  void* operator&() { return nullptr; }
3093 signals:
3095 public slots:
3097  {
3098  QCOMPARE(std::addressof(o), this);
3099  testResult = (std::addressof(o) == this);
3100  }
3101 public:
3102  bool testResult = false;
3103 };
3104 
3105 void tst_Moc::overloadedAddressOperator()
3106 {
3108  OverloadedAddressOperator *p = std::addressof(o);
3109  QCOMPARE(&o, nullptr);
3110  QVERIFY(p);
3112  emit o.self(o);
3113  QVERIFY(o.testResult);
3114 }
3115 
3116 class CustomQObject : public QObject
3117 {
3118  Q_OBJECT
3119  Q_ENUMS(Number)
3120 public:
3121  enum Number {
3124  Two
3125  };
3126  explicit CustomQObject(QObject *parent = nullptr)
3127  : QObject(parent)
3128  {
3129  }
3130 };
3131 
3133 
3136 
3137 namespace SomeNamespace {
3138 
3139 class NamespacedQObject : public QObject
3140 {
3141  Q_OBJECT
3142 public:
3143  explicit NamespacedQObject(QObject *parent = nullptr)
3144  : QObject(parent)
3145  {
3146 
3147  }
3148 };
3149 
3151 }
3153 
3154 // Need different types for the invokable method tests because otherwise the registration
3155 // done in the property test would interfere.
3156 
3157 class CustomQObject2 : public QObject
3158 {
3159  Q_OBJECT
3160  Q_ENUMS(Number)
3161 public:
3162  enum Number {
3165  Two
3166  };
3167  explicit CustomQObject2(QObject *parent = nullptr)
3168  : QObject(parent)
3169  {
3170  }
3171 };
3172 
3174 
3177 
3178 namespace SomeNamespace2 {
3179 
3180 class NamespacedQObject2 : public QObject
3181 {
3182  Q_OBJECT
3183 public:
3184  explicit NamespacedQObject2(QObject *parent = nullptr)
3185  : QObject(parent)
3186  {
3187 
3188  }
3189 };
3190 
3192 }
3194 
3195 
3196 struct CustomObject3 {};
3197 struct CustomObject4 {};
3198 struct CustomObject5 {};
3199 struct CustomObject6 {};
3200 struct CustomObject7 {};
3201 struct CustomObject8 {};
3202 struct CustomObject9 {};
3203 struct CustomObject10 {};
3204 struct CustomObject11 {};
3205 struct CustomObject12 {};
3206 
3217 
3218 class AutoRegistrationObject : public QObject
3219 {
3220  Q_OBJECT
3221  Q_PROPERTY(QObject* object READ object CONSTANT)
3222  Q_PROPERTY(CustomQObject* customObject READ customObject CONSTANT)
3223  Q_PROPERTY(QSharedPointer<CustomQObject> customObjectP READ customObjectP CONSTANT)
3224  Q_PROPERTY(QWeakPointer<CustomQObject> customObjectWP READ customObjectWP CONSTANT)
3225  Q_PROPERTY(QPointer<CustomQObject> customObjectTP READ customObjectTP CONSTANT)
3226  Q_PROPERTY(QList<int> listInt READ listInt CONSTANT)
3227  Q_PROPERTY(QList<QVariant> listVariant READ listVariant CONSTANT)
3228  Q_PROPERTY(QList<CustomQObject*> listObject READ listObject CONSTANT)
3229  Q_PROPERTY(QList<QList<int>> listListInt READ listListInt CONSTANT)
3230  Q_PROPERTY(QList<QList<CustomQObject *>> listListObject READ listListObject CONSTANT)
3232  Q_PROPERTY(CustomQObjectStar customObjectTypedef READ customObjectTypedef CONSTANT)
3233  Q_PROPERTY(SomeNamespace::NamespacedQObject* customObjectNamespaced READ customObjectNamespaced CONSTANT)
3234  Q_PROPERTY(SomeNamespace::NamespacedNonQObject customNonQObjectNamespaced READ customNonQObjectNamespaced CONSTANT)
3235 public:
3236  AutoRegistrationObject(QObject *parent = nullptr)
3237  : QObject(parent)
3238  {
3239  }
3240 
3241  QObject* object() const
3242  {
3243  return 0;
3244  }
3245 
3247  {
3249  }
3250 
3252  {
3253  return QWeakPointer<CustomQObject>();
3254  }
3255 
3257  {
3258  return QPointer<CustomQObject>();
3259  }
3260 
3262  {
3263  return 0;
3264  }
3265 
3267  {
3268  return QList<int>();
3269  }
3270 
3272 
3274  {
3275  return QList<CustomQObject*>();
3276  }
3277 
3279 
3281 
3283  {
3284  return CustomQObject::Zero;
3285  }
3286 
3288  {
3289  return 0;
3290  }
3291 
3293  {
3294  return 0;
3295  }
3296 
3298  {
3300  }
3301 
3302 public slots:
3303  void objectSlot(QObject*) {}
3317 
3318  void bu1(int, CustomObject3) {}
3319  void bu2(CustomObject4, int) {}
3323  void bu6(int, CustomObject11, int) {}
3324 
3325  // these can't be registered, but they should at least compile
3326  void ref1(int&) {}
3327  void ref2(QList<int>&) {}
3330 
3331 signals:
3333 };
3334 
3335 void tst_Moc::autoPropertyMetaTypeRegistration()
3336 {
3338 
3339  static const int numPropertiesUnderTest = 15;
3340  QList<int> propertyMetaTypeIds;
3341  propertyMetaTypeIds.reserve(numPropertiesUnderTest);
3342 
3343  const QMetaObject *metaObject = aro.metaObject();
3344  QCOMPARE(metaObject->propertyCount(), numPropertiesUnderTest);
3345  for (int i = 0; i < metaObject->propertyCount(); ++i) {
3346  const QMetaProperty prop = metaObject->property(i);
3347  propertyMetaTypeIds.append(prop.userType());
3348  QVariant var = prop.read(&aro);
3349  QVERIFY(var.isValid());
3350  }
3351 
3352  // Verify that QMetaProperty::userType gave us what we expected.
3353  QList<int> expectedMetaTypeIds = QList<int>()
3354  << QMetaType::QString // QObject::userType
3355  << QMetaType::QObjectStar // AutoRegistrationObject::object
3356  << qMetaTypeId<CustomQObject *>() // etc.
3357  << qMetaTypeId<QSharedPointer<CustomQObject>>()
3358  << qMetaTypeId<QWeakPointer<CustomQObject>>() << qMetaTypeId<QPointer<CustomQObject>>()
3359  << qMetaTypeId<QList<int>>() << qMetaTypeId<QList<QVariant>>()
3360  << qMetaTypeId<QList<CustomQObject *>>() << qMetaTypeId<QList<QList<int>>>()
3361  << qMetaTypeId<QList<QList<CustomQObject *>>>() << qMetaTypeId<CustomQObject::Number>()
3362  << qMetaTypeId<CustomQObjectStar>() << qMetaTypeId<SomeNamespace::NamespacedQObject *>()
3363  << qMetaTypeId<SomeNamespace::NamespacedNonQObject>();
3364 
3365  QCOMPARE(propertyMetaTypeIds, expectedMetaTypeIds);
3366 }
3367 
3368 template<typename T>
3370 {
3371  static inline T construct() { return T(); }
3372 };
3373 
3374 template<typename T>
3376 {
3377  static inline T* construct() { return 0; }
3378 };
3379 
3380 void tst_Moc::autoMethodArgumentMetaTypeRegistration()
3381 {
3383 
3384  QList<int> methodArgMetaTypeIds;
3385 
3386  const QMetaObject *metaObject = aro.metaObject();
3387 
3388  int i = metaObject->methodOffset(); // Start after QObject built-in slots;
3389 
3390  while (i < metaObject->methodCount()) {
3391  // Skip over signals so we start at the first slot.
3392  const QMetaMethod method = metaObject->method(i);
3393  if (method.methodType() == QMetaMethod::Signal)
3394  ++i;
3395  else
3396  break;
3397 
3398  }
3399 
3400 #define TYPE_LOOP(TYPE) \
3401  { \
3402  const QMetaMethod method = metaObject->method(i); \
3403  for (int j = 0; j < method.parameterCount(); ++j) \
3404  methodArgMetaTypeIds.append(method.parameterType(j)); \
3405  QVERIFY(method.invoke(&aro, Q_ARG(TYPE, DefaultConstructor<TYPE>::construct()))); \
3406  ++i; \
3407  }
3408 
3409 #define FOR_EACH_SLOT_ARG_TYPE(F) \
3410  F(QObject *) \
3411  F(CustomQObject2 *) \
3412  F(QSharedPointer<CustomQObject2>) \
3413  F(QWeakPointer<CustomQObject2>) \
3414  F(QPointer<CustomQObject2>) \
3415  F(QList<int>) \
3416  F(QList<QVariant>) \
3417  F(QList<CustomQObject2 *>) \
3418  F(QList<QList<int>>) \
3419  F(QList<QList<CustomQObject2 *>>) \
3420  F(CustomQObject2::Number) \
3421  F(CustomQObject2Star) \
3422  F(SomeNamespace2::NamespacedQObject2 *) \
3423  F(SomeNamespace2::NamespacedNonQObject2)
3424 
3425  // Note: mulit-arg slots are tested below.
3426 
3428 
3429 #undef TYPE_LOOP
3430 #undef FOR_EACH_SLOT_ARG_TYPE
3431 
3432  QList<int> expectedMetaTypeIds = QList<int>()
3433  << QMetaType::QObjectStar << qMetaTypeId<CustomQObject2 *>()
3434  << qMetaTypeId<QSharedPointer<CustomQObject2>>()
3436  << qMetaTypeId<QPointer<CustomQObject2>>() << qMetaTypeId<QList<int>>()
3437  << qMetaTypeId<QList<QVariant>>() << qMetaTypeId<QList<CustomQObject2 *>>()
3438  << qMetaTypeId<QList<QList<int>>>() << qMetaTypeId<QList<QList<CustomQObject2 *>>>()
3439  << qMetaTypeId<CustomQObject2::Number>() << qMetaTypeId<CustomQObject2Star>()
3440  << qMetaTypeId<SomeNamespace2::NamespacedQObject2 *>()
3441  << qMetaTypeId<SomeNamespace2::NamespacedNonQObject2>();
3442 
3443  QCOMPARE(methodArgMetaTypeIds, expectedMetaTypeIds);
3444 
3445  QList<int> methodMultiArgMetaTypeIds;
3446 
3447  {
3448  const QMetaMethod method = metaObject->method(i);
3449  QCOMPARE(method.name(), QByteArray("bu1"));
3450  for (int j = 0; j < method.parameterCount(); ++j)
3451  methodMultiArgMetaTypeIds.append(method.parameterType(j));
3452  QVERIFY(method.invoke(&aro, Q_ARG(int, 42), Q_ARG(CustomObject3, CustomObject3())));
3453  ++i;
3454  }
3455  {
3456  const QMetaMethod method = metaObject->method(i);
3457  QCOMPARE(method.name(), QByteArray("bu2"));
3458  for (int j = 0; j < method.parameterCount(); ++j)
3459  methodMultiArgMetaTypeIds.append(method.parameterType(j));
3460  QVERIFY(method.invoke(&aro, Q_ARG(CustomObject4, CustomObject4()), Q_ARG(int, 42)));
3461  ++i;
3462  }
3463  {
3464  const QMetaMethod method = metaObject->method(i);
3465  QCOMPARE(method.name(), QByteArray("bu3"));
3466  for (int j = 0; j < method.parameterCount(); ++j)
3467  methodMultiArgMetaTypeIds.append(method.parameterType(j));
3469  ++i;
3470  }
3471  {
3472  const QMetaMethod method = metaObject->method(i);
3473  QCOMPARE(method.name(), QByteArray("bu4"));
3474  for (int j = 0; j < method.parameterCount(); ++j)
3475  methodMultiArgMetaTypeIds.append(method.parameterType(j));
3477  ++i;
3478  }
3479  {
3480  const QMetaMethod method = metaObject->method(i);
3481  QCOMPARE(method.name(), QByteArray("bu5"));
3482  for (int j = 0; j < method.parameterCount(); ++j)
3483  methodMultiArgMetaTypeIds.append(method.parameterType(j));
3485  ++i;
3486  }
3487  {
3488  const QMetaMethod method = metaObject->method(i);
3489  QCOMPARE(method.name(), QByteArray("bu6"));
3490  for (int j = 0; j < method.parameterCount(); ++j)
3491  methodMultiArgMetaTypeIds.append(method.parameterType(j));
3492  QVERIFY(method.invoke(&aro, Q_ARG(int, 42), Q_ARG(CustomObject11, CustomObject11()), Q_ARG(int, 42)));
3493  ++i;
3494  }
3495 
3496  QList<int> expectedMultiMetaTypeIds = QList<int>()
3497  << QMetaType::Int << qMetaTypeId<CustomObject3>() << qMetaTypeId<CustomObject4>()
3498  << QMetaType::Int << qMetaTypeId<CustomObject5>() << qMetaTypeId<CustomObject6>()
3499  << qMetaTypeId<CustomObject7>() << QMetaType::Int << qMetaTypeId<CustomObject8>()
3500  << QMetaType::Int << qMetaTypeId<CustomObject9>() << qMetaTypeId<CustomObject10>()
3501  << QMetaType::Int << qMetaTypeId<CustomObject11>() << QMetaType::Int;
3502 
3503  QCOMPARE(methodMultiArgMetaTypeIds, expectedMultiMetaTypeIds);
3504 
3505 
3506 }
3507 
3508 void tst_Moc::autoSignalSpyMetaTypeRegistration()
3509 {
3511 
3512  QList<int> methodArgMetaTypeIds;
3513 
3514  const QMetaObject *metaObject = aro.metaObject();
3515 
3516  int i = metaObject->indexOfSignal(QMetaObject::normalizedSignature("someSignal(CustomObject12)"));
3517 
3518  QVERIFY(i > 0);
3519 
3520  QCOMPARE(QMetaType::fromName("CustomObject12").id(), (int)QMetaType::UnknownType);
3521 
3522  QSignalSpy spy(&aro, SIGNAL(someSignal(CustomObject12)));
3523 
3524  QVERIFY(QMetaType::fromName("CustomObject12").id() != QMetaType::UnknownType);
3525  QCOMPARE(QMetaType::fromName("CustomObject12").id(), qMetaTypeId<CustomObject12>());
3526 }
3527 
3528 void tst_Moc::parseDefines()
3529 {
3530  const QMetaObject *mo = &PD_NAMESPACE::PD_CLASSNAME::staticMetaObject;
3532  QVERIFY(mo->indexOfSlot("voidFunction()") != -1);
3533 
3534  int index = mo->indexOfSlot("stringMethod()");
3535  QVERIFY(index != -1);
3536  QCOMPARE(mo->method(index).returnType(), int(QMetaType::QString));
3537 
3538  index = mo->indexOfSlot("combined1()");
3539  QVERIFY(index != -1);
3540 
3541  index = mo->indexOfSlot("combined2()");
3542  QVERIFY(index != -1);
3543 
3544  index = mo->indexOfSlot("combined3()");
3545  QVERIFY(index != -1);
3546 
3547  index = mo->indexOfSlot("combined4(int,int)");
3548  QVERIFY(index != -1);
3549 
3550  index = mo->indexOfSlot("combined5()");
3551  QVERIFY(index != -1);
3552 
3553  index = mo->indexOfSlot("combined6()");
3554  QVERIFY(index != -1);
3555 
3556  index = mo->indexOfSlot("vararg1()");
3557  QVERIFY(index != -1);
3558  index = mo->indexOfSlot("vararg2(int)");
3559  QVERIFY(index != -1);
3560  index = mo->indexOfSlot("vararg3(int,int)");
3561  QVERIFY(index != -1);
3562  index = mo->indexOfSlot("vararg4()");
3563  QVERIFY(index != -1);
3564  index = mo->indexOfSlot("vararg5(int)");
3565  QVERIFY(index != -1);
3566  index = mo->indexOfSlot("vararg6(int,int)");
3567  QVERIFY(index != -1);
3568 
3569  index = mo->indexOfSlot("INNERFUNCTION(int)");
3570  QVERIFY(index != -1);
3571  index = mo->indexOfSlot("inner_expanded(int)");
3572  QVERIFY(index != -1);
3573  index = mo->indexOfSlot("expanded_method(int)");
3574  QVERIFY(index != -1);
3575 
3576  index = mo->indexOfSlot("conditionSlot()");
3577  QVERIFY(index != -1);
3578 
3579  int count = 0;
3580  for (int i = 0; i < mo->classInfoCount(); ++i) {
3581  QMetaClassInfo mci = mo->classInfo(i);
3582  if (!qstrcmp(mci.name(), "TestString")) {
3583  ++count;
3584  QVERIFY(!qstrcmp(mci.value(), "PD_CLASSNAME"));
3585  }
3586  if (!qstrcmp(mci.name(), "TestString2")) {
3587  ++count;
3588  QVERIFY(!qstrcmp(mci.value(), "ParseDefine"));
3589  }
3590  if (!qstrcmp(mci.name(), "TestString3")) {
3591  ++count;
3592  QVERIFY(!qstrcmp(mci.value(), "TestValue"));
3593  }
3594  }
3595  QCOMPARE(count, 3);
3596 
3597  index = mo->indexOfSlot("PD_DEFINE_ITSELF_SUFFIX(int)");
3598  QVERIFY(index != -1);
3599 
3600  index = mo->indexOfSignal("cmdlineSignal(QMap<int,int>)");
3601  QVERIFY(index != -1);
3602 
3603  index = mo->indexOfSignal("signalQTBUG55853()");
3604  QVERIFY(index != -1);
3605 }
3606 
3607 void tst_Moc::preprocessorOnly()
3608 {
3609 #ifdef MOC_CROSS_COMPILED
3610  QSKIP("Not tested when cross-compiled");
3611 #endif
3612 #if defined(Q_OS_UNIX) && defined(Q_CC_GNU) && QT_CONFIG(process)
3613  QProcess proc;
3614  proc.start(m_moc, QStringList() << "-E" << m_sourceDirectory + QStringLiteral("/pp-dollar-signs.h"));
3615  QVERIFY(proc.waitForFinished());
3616  QCOMPARE(proc.exitCode(), 0);
3617  QByteArray mocOut = proc.readAllStandardOutput();
3618  QVERIFY(!mocOut.isEmpty());
3619  QCOMPARE(proc.readAllStandardError(), QByteArray());
3620 
3621  QVERIFY(mocOut.contains("$$ = parser->createFoo()"));
3622 #else
3623  QSKIP("Only tested on unix/gcc");
3624 #endif
3625 }
3626 
3627 
3628 void tst_Moc::unterminatedFunctionMacro()
3629 {
3630 #ifdef MOC_CROSS_COMPILED
3631  QSKIP("Not tested when cross-compiled");
3632 #endif
3633 #if defined(Q_OS_UNIX) && defined(Q_CC_GNU) && QT_CONFIG(process)
3634  QProcess proc;
3635  proc.start(m_moc, QStringList() << "-E" << m_sourceDirectory + QStringLiteral("/unterminated-function-macro.h"));
3636  QVERIFY(proc.waitForFinished());
3637  QCOMPARE(proc.exitCode(), 1);
3638  QCOMPARE(proc.readAllStandardOutput(), QByteArray());
3639  QByteArray errorOutput = proc.readAllStandardError();
3640  QVERIFY(!errorOutput.isEmpty());
3641  QVERIFY(errorOutput.contains("missing ')' in macro usage"));
3642 #else
3643  QSKIP("Only tested on linux/gcc");
3644 #endif
3645 }
3646 
3648  namespace NS {
3649  class Obj : QObject {
3650  Q_OBJECT
3651  Q_PROPERTY(MyEnum p1 MEMBER member)
3655  Q_ENUMS(MyEnum);
3656  public:
3659  };
3660  }
3661 }
3662 
3663 void tst_Moc::QTBUG32933_relatedObjectsDontIncludeItself()
3664 {
3665  const QMetaObject *mo = &QTBUG32933_relatedObjectsDontIncludeItself::NS::Obj::staticMetaObject;
3666  const auto *objects = mo->d.relatedMetaObjects;
3667  // the related objects should be empty because the enums is in the same object.
3668  QVERIFY(!objects);
3669 }
3670 
3671 class UnrelatedClass : public QObject
3672 {
3673  Q_OBJECT
3675 public:
3678  UnrelatedValue = 42
3679  };
3680 };
3681 
3682 // The presence of this macro used to confuse moc and prevent
3683 // UnrelatedClass from being listed in the related meta objects.
3685 
3687 {
3688  Q_OBJECT
3689  Q_PROPERTY(UnrelatedClass::UnrelatedEnum enumProperty READ enumProperty WRITE setEnumProperty)
3690 public:
3692  : m_enumProperty(UnrelatedClass::UnrelatedInvalidValue)
3693  {}
3694 
3696  return m_enumProperty;
3697  }
3698 
3700  m_enumProperty = arg;
3701  }
3702 
3703 private:
3704  UnrelatedClass::UnrelatedEnum m_enumProperty;
3705 };
3706 
3707 void tst_Moc::writeEnumFromUnrelatedClass()
3708 {
3710  QString enumValueAsString("UnrelatedValue");
3711  obj.setProperty("enumProperty", enumValueAsString);
3712  QCOMPARE(int(obj.enumProperty()), int(UnrelatedClass::UnrelatedValue));
3713 }
3714 
3715 
3716 
3717 void tst_Moc::relatedMetaObjectsWithinNamespaces()
3718 {
3719  const QMetaObject *relatedMo = &QTBUG_2151::A::staticMetaObject;
3720 
3721  const QMetaObject *testMo = &QTBUG_2151::B::staticMetaObject;
3722  QVERIFY(testMo->d.relatedMetaObjects);
3723  QCOMPARE(testMo->d.relatedMetaObjects[0], relatedMo);
3724 }
3725 
3726 void tst_Moc::relatedMetaObjectsInGadget()
3727 {
3728  const QMetaObject *relatedMo = &QTBUG_35657::A::staticMetaObject;
3729 
3730  const QMetaObject *testMo = &QTBUG_35657::B::staticMetaObject;
3731  QVERIFY(testMo->d.relatedMetaObjects);
3732  QCOMPARE(testMo->d.relatedMetaObjects[0], relatedMo);
3733 }
3734 
3735 void tst_Moc::relatedMetaObjectsNameConflict_data()
3736 {
3737  typedef QList<const QMetaObject *> QMetaObjects;
3738  QTest::addColumn<const QMetaObject*>("dependingObject");
3739  QTest::addColumn<QMetaObjects>("relatedMetaObjects");
3740 
3741  //NS1
3742  const QMetaObject *n1gadget = &NS1::Gadget::staticMetaObject;
3743  const QMetaObject *n1object = &NS1::Object::staticMetaObject;
3744  const QMetaObject *n1nestedGadget = &NS1::Nested::Gadget::staticMetaObject;
3745  const QMetaObject *n1nestedObject = &NS1::Nested::Object::staticMetaObject;
3746  //N2
3747  const QMetaObject *n2gadget = &NS2::Gadget::staticMetaObject;
3748  const QMetaObject *n2object = &NS2::Object::staticMetaObject;
3749  const QMetaObject *n2nestedGadget = &NS2::Nested::Gadget::staticMetaObject;
3750  const QMetaObject *n2nestedObject = &NS2::Nested::Object::staticMetaObject;
3751 
3752  QTest::newRow("N1::dependingObject") << &NS1::DependingObject::staticMetaObject
3753  << (QMetaObjects() << n1gadget << n1object);
3754  QTest::newRow("N2::dependingObject") << &NS2::DependingObject::staticMetaObject
3755  << (QMetaObjects() << n2gadget << n2object);
3756  QTest::newRow("N1::dependingNestedObject") << &NS1::DependingNestedObject::staticMetaObject
3757  << (QMetaObjects() << n1nestedObject);
3758  QTest::newRow("N2::dependingNestedObject") << &NS2::DependingNestedObject::staticMetaObject
3759  << (QMetaObjects() << n2nestedObject);
3760  QTest::newRow("N1::dependingNestedGadget") << &NS1::DependingNestedGadget::staticMetaObject
3761  << (QMetaObjects() << n1nestedGadget);
3762  QTest::newRow("N2::dependingNestedGadget") << &NS2::DependingNestedGadget::staticMetaObject
3763  << (QMetaObjects() << n2nestedGadget);
3764 }
3765 
3766 void tst_Moc::relatedMetaObjectsNameConflict()
3767 {
3768  typedef QList<const QMetaObject *> QMetaObjects;
3769  QFETCH(const QMetaObject*, dependingObject);
3770  QFETCH(QMetaObjects, relatedMetaObjects);
3771 
3772  // load all specified metaobjects int a set
3773  QSet<const QMetaObject*> dependency;
3774  const auto *i = dependingObject->d.relatedMetaObjects;
3775  while (*i) {
3776  dependency.insert(*i);
3777  ++i;
3778  }
3779 
3780  // check if all required metaobjects are specified
3781  foreach (const QMetaObject *mo, relatedMetaObjects)
3782  QVERIFY(dependency.contains(mo));
3783 
3784  // check if no additional metaobjects ara specified
3785  QCOMPARE(dependency.size(), relatedMetaObjects.size());
3786 }
3787 
3788 class StringLiteralsInMacroExtension: public QObject
3789 {
3790  Q_OBJECT
3791 #define Macro(F) F " " F
3792  Q_CLASSINFO(Macro("String"), Macro("Literal"))
3793 #undef Macro
3794 
3795 #define Macro(F) F
3796  Q_CLASSINFO("String" Macro("!"), "Literal" Macro("!"))
3797  Q_CLASSINFO(Macro("!") "String", Macro("!") "Literal")
3798 #undef Macro
3799 
3800 #define Macro "foo"
3801  Q_CLASSINFO("String" Macro, "Literal" Macro)
3802  Q_CLASSINFO(Macro "String", Macro "Literal")
3803 #undef Macro
3804 };
3805 
3806 void tst_Moc::strignLiteralsInMacroExtension()
3807 {
3808  const QMetaObject *mobj = &StringLiteralsInMacroExtension::staticMetaObject;
3809  QCOMPARE(mobj->classInfoCount(), 5);
3810 
3811  QCOMPARE(mobj->classInfo(0).name(), "String String");
3812  QCOMPARE(mobj->classInfo(0).value(), "Literal Literal");
3813 
3814  QCOMPARE(mobj->classInfo(1).name(), "String!");
3815  QCOMPARE(mobj->classInfo(1).value(), "Literal!");
3816 
3817  QCOMPARE(mobj->classInfo(2).name(), "!String");
3818  QCOMPARE(mobj->classInfo(2).value(), "!Literal");
3819 
3820  QCOMPARE(mobj->classInfo(3).name(), "Stringfoo");
3821  QCOMPARE(mobj->classInfo(3).value(), "Literalfoo");
3822 
3823  QCOMPARE(mobj->classInfo(4).name(), "fooString");
3824  QCOMPARE(mobj->classInfo(4).value(), "fooLiteral");
3825 }
3826 
3827 class VeryLongStringData : public QObject
3828 {
3829  Q_OBJECT
3830 
3831  #define repeat2(V) V V
3832  #define repeat4(V) repeat2(V) repeat2(V)
3833  #define repeat8(V) repeat4(V) repeat4(V)
3834  #define repeat16(V) repeat8(V) repeat8(V)
3835  #define repeat32(V) repeat16(V) repeat16(V)
3836  #define repeat64(V) repeat32(V) repeat32(V)
3837  #define repeat128(V) repeat64(V) repeat64(V)
3838  #define repeat256(V) repeat128(V) repeat128(V)
3839  #define repeat512(V) repeat256(V) repeat256(V)
3840  #define repeat1024(V) repeat512(V) repeat512(V)
3841  #define repeat2048(V) repeat1024(V) repeat1024(V)
3842  #define repeat4096(V) repeat2048(V) repeat2048(V)
3843  #define repeat8192(V) repeat4096(V) repeat4096(V)
3844  #define repeat16384(V) repeat8192(V) repeat8192(V)
3845  #define repeat32768(V) repeat16384(V) repeat16384(V)
3846  #define repeat65534(V) repeat32768(V) repeat16384(V) repeat8192(V) repeat4096(V) repeat2048(V) repeat1024(V) repeat512(V) repeat256(V) repeat128(V) repeat64(V) repeat32(V) repeat16(V) repeat8(V) repeat4(V) repeat2(V)
3847 
3848  Q_CLASSINFO(repeat65534("n"), repeat65534("i"))
3849  Q_CLASSINFO(repeat65534("e"), repeat65534("r"))
3850  Q_CLASSINFO(repeat32768("o"), repeat32768("b"))
3851  Q_CLASSINFO(":", ")")
3852 
3853  #undef repeat2
3854  #undef repeat4
3855  #undef repeat8
3856  #undef repeat16
3857  #undef repeat32
3858  #undef repeat64
3859  #undef repeat128
3860  #undef repeat256
3861  #undef repeat512
3862  #undef repeat1024
3863  #undef repeat2048
3864  #undef repeat4096
3865  #undef repeat8192
3866  #undef repeat16384
3867  #undef repeat32768
3868  #undef repeat65534
3869 };
3870 
3871 void tst_Moc::unnamedNamespaceObjectsAndGadgets()
3872 {
3873  // these just test very basic functionality of gadgets and objects
3874  // defined in unnamed namespaces.
3875  {
3876  GadgetInUnnamedNS gadget(21, 42);
3877  QCOMPARE(gadget.x(), 21);
3878  QCOMPARE(gadget.y(), 42);
3879  gadget.staticMetaObject.property(0).writeOnGadget(&gadget, 12);
3880  gadget.staticMetaObject.property(1).writeOnGadget(&gadget, 24);
3881  QCOMPARE(gadget.x(), 12);
3882  QCOMPARE(gadget.y(), 24);
3883  }
3884 
3885  {
3886  ObjectInUnnamedNS object;
3887  QObject *qObject = &object;
3888  QCOMPARE(static_cast<ObjectInUnnamedNS *>(qObject),
3889  qobject_cast<ObjectInUnnamedNS *>(qObject));
3890  }
3891 }
3892 
3893 void tst_Moc::veryLongStringData()
3894 {
3895  const QMetaObject *mobj = &VeryLongStringData::staticMetaObject;
3896  QCOMPARE(mobj->classInfoCount(), 4);
3897 
3898  QCOMPARE(mobj->classInfo(0).name()[0], 'n');
3899  QCOMPARE(mobj->classInfo(0).value()[0], 'i');
3900  QCOMPARE(mobj->classInfo(1).name()[0], 'e');
3901  QCOMPARE(mobj->classInfo(1).value()[0], 'r');
3902  QCOMPARE(mobj->classInfo(2).name()[0], 'o');
3903  QCOMPARE(mobj->classInfo(2).value()[0], 'b');
3904  QCOMPARE(mobj->classInfo(3).name()[0], ':');
3905  QCOMPARE(mobj->classInfo(3).value()[0], ')');
3906 
3907  QCOMPARE(strlen(mobj->classInfo(0).name()), static_cast<size_t>(65534));
3908  QCOMPARE(strlen(mobj->classInfo(0).value()), static_cast<size_t>(65534));
3909  QCOMPARE(strlen(mobj->classInfo(1).name()), static_cast<size_t>(65534));
3910  QCOMPARE(strlen(mobj->classInfo(1).value()), static_cast<size_t>(65534));
3911  QCOMPARE(strlen(mobj->classInfo(2).name()), static_cast<size_t>(32768));
3912  QCOMPARE(strlen(mobj->classInfo(2).value()), static_cast<size_t>(32768));
3913  QCOMPARE(strlen(mobj->classInfo(3).name()), static_cast<size_t>(1));
3914  QCOMPARE(strlen(mobj->classInfo(3).value()), static_cast<size_t>(1));
3915 }
3916 
3917 void tst_Moc::gadgetHierarchy()
3918 {
3919  QCOMPARE(NonGadgetParent::Derived::staticMetaObject.superClass(), static_cast<const QMetaObject*>(nullptr));
3920  QCOMPARE(GrandParentGadget::DerivedGadget::staticMetaObject.superClass(), &GrandParentGadget::BaseGadget::staticMetaObject);
3921  QCOMPARE(GrandParentGadget::CRTPDerivedGadget::staticMetaObject.superClass(), &GrandParentGadget::BaseGadget::staticMetaObject);
3922 }
3923 
3924 void tst_Moc::optionsFileError_data()
3925 {
3926  QTest::addColumn<QString>("optionsArgument");
3927  QTest::newRow("no filename") << QStringLiteral("@");
3928  QTest::newRow("nonexistent file") << QStringLiteral("@letshuntasnark");
3929 }
3930 
3931 void tst_Moc::optionsFileError()
3932 {
3933 #ifdef MOC_CROSS_COMPILED
3934  QSKIP("Not tested when cross-compiled");
3935 #endif
3936 #if QT_CONFIG(process)
3937  QFETCH(QString, optionsArgument);
3938  QProcess p;
3939  p.start(m_moc, QStringList(optionsArgument));
3940  QVERIFY(p.waitForFinished());
3941  QCOMPARE(p.exitCode(), 1);
3942  QVERIFY(p.readAllStandardOutput().isEmpty());
3943  const QByteArray err = p.readAllStandardError();
3944  QVERIFY(err.contains("moc: "));
3945  QVERIFY(!err.contains("QCommandLineParser"));
3946 #endif
3947 }
3948 
3949 static void checkEnum(const QMetaEnum &enumerator, const QByteArray &name,
3951 {
3952  QCOMPARE(name, QByteArray{enumerator.name()});
3953  QCOMPARE(keys.size(), enumerator.keyCount());
3954  for (int i = 0; i < enumerator.keyCount(); ++i) {
3955  QCOMPARE(keys[i].first, QByteArray{enumerator.key(i)});
3956  QCOMPARE(keys[i].second, enumerator.value(i));
3957  }
3958 }
3959 
3960 class EnumFromNamespaceClass : public QObject
3961 {
3962  Q_OBJECT
3963  Q_PROPERTY(FooNamespace::Enum1 prop READ prop CONSTANT)
3964 public:
3966 };
3967 
3968 void tst_Moc::testQNamespace()
3969 {
3970  QCOMPARE(TestQNamespace::staticMetaObject.enumeratorCount(), 4);
3971  checkEnum(TestQNamespace::staticMetaObject.enumerator(0), "TestEnum1",
3972  {{"Key1", 11}, {"Key2", 12}});
3973  checkEnum(TestQNamespace::staticMetaObject.enumerator(1), "TestEnum2",
3974  {{"Key1", 17}, {"Key2", 18}});
3975  checkEnum(TestQNamespace::staticMetaObject.enumerator(2), "TestFlag1",
3976  {{"None", 0}, {"Flag1", 1}, {"Flag2", 2}, {"Any", 1 | 2}});
3977  checkEnum(TestQNamespace::staticMetaObject.enumerator(3), "TestFlag2",
3978  {{"None", 0}, {"Flag1", 4}, {"Flag2", 8}, {"Any", 4 | 8}});
3979 
3980  QCOMPARE(TestQNamespace::TestGadget::staticMetaObject.enumeratorCount(), 2);
3981  checkEnum(TestQNamespace::TestGadget::staticMetaObject.enumerator(0), "TestGEnum1",
3982  {{"Key1", 13}, {"Key2", 14}});
3983  checkEnum(TestQNamespace::TestGadget::staticMetaObject.enumerator(1), "TestGEnum2",
3984  {{"Key1", 23}, {"Key2", 24}});
3985 
3986  QCOMPARE(TestQNamespace::TestGadgetExport::staticMetaObject.enumeratorCount(), 2);
3987  checkEnum(TestQNamespace::TestGadgetExport::staticMetaObject.enumerator(0), "TestGeEnum1",
3988  {{"Key1", 20}, {"Key2", 21}});
3989  checkEnum(TestQNamespace::TestGadgetExport::staticMetaObject.enumerator(1), "TestGeEnum2",
3990  {{"Key1", 23}, {"Key2", 24}});
3991 
3992  QMetaEnum meta = QMetaEnum::fromType<TestQNamespace::TestEnum1>();
3993  QVERIFY(meta.isValid());
3994  QCOMPARE(meta.name(), "TestEnum1");
3995  QCOMPARE(meta.enclosingMetaObject(), &TestQNamespace::staticMetaObject);
3996  QCOMPARE(meta.keyCount(), 2);
3997 
3998  QCOMPARE(TestExportNamespace::staticMetaObject.enumeratorCount(), 1);
3999  checkEnum(TestExportNamespace::staticMetaObject.enumerator(0), "MyEnum",
4000  {{"Key1", 0}, {"Key2", 1}});
4001 
4002  QCOMPARE(FooNamespace::staticMetaObject.enumeratorCount(), 1);
4003  QCOMPARE(FooNamespace::FooNestedNamespace::staticMetaObject.enumeratorCount(), 2);
4004  QCOMPARE(FooNamespace::FooNestedNamespace::FooMoreNestedNamespace::staticMetaObject.enumeratorCount(), 1);
4005 
4007  const QVariant prop = obj.property("prop");
4008  QCOMPARE(prop.userType(), QMetaType::fromType<FooNamespace::Enum1>().id());
4010 }
4011 
4012 void tst_Moc::cxx17Namespaces()
4013 {
4014  QCOMPARE(CXX17Namespace::A::B::C::D::staticMetaObject.className(),
4015  "CXX17Namespace::A::B::C::D");
4016  QCOMPARE(CXX17Namespace::A::B::C::D::staticMetaObject.enumeratorCount(), 1);
4017  QCOMPARE(CXX17Namespace::A::B::C::D::staticMetaObject.enumerator(0).name(), "NamEn");
4018  QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::NamEn>().name(), "NamEn");
4019  QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::NamEn>().keyCount(), 1);
4020  QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::NamEn>().value(0), 4);
4021 
4022  QCOMPARE(CXX17Namespace::A::B::C::D::ClassInNamespace::staticMetaObject.className(),
4023  "CXX17Namespace::A::B::C::D::ClassInNamespace");
4024  QCOMPARE(CXX17Namespace::A::B::C::D::ClassInNamespace::staticMetaObject.enumeratorCount(), 1);
4025  QCOMPARE(CXX17Namespace::A::B::C::D::ClassInNamespace::staticMetaObject.enumerator(0).name(), "GadEn");
4026  QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::ClassInNamespace::GadEn>().name(), "GadEn");
4027  QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::ClassInNamespace::GadEn>().keyCount(), 1);
4028  QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::ClassInNamespace::GadEn>().value(0), 3);
4029 }
4030 
4031 void tst_Moc::cxxAttributes()
4032 {
4033  auto so = CppAttribute::staticMetaObject;
4034  QCOMPARE(so.className(), "CppAttribute");
4035  QCOMPARE(so.enumeratorCount(), 0);
4036  QVERIFY(so.indexOfSignal("deprecatedSignal") != 1);
4037  for (auto a: {"deprecatedSlot", "deprecatedSlot2", "deprecatedReason", "deprecatedReasonWithLBRACK",
4038  "deprecatedReasonWith2LBRACK", "deprecatedReasonWithRBRACK", "deprecatedReasonWith2RBRACK",
4039  "slotWithArguments"
4040 #if !defined(_MSC_VER) || _MSC_VER >= 1912
4041  , "noreturnSlot", "noreturnSlot2", "returnInt", "noreturnDeprecatedSlot",
4042  "noreturnSlot3"
4043 #endif
4044  }) {
4045  QVERIFY(so.indexOfSlot(a) != 1);
4046  }
4047 
4048  QCOMPARE(TestQNamespaceDeprecated::staticMetaObject.enumeratorCount(), 2);
4049  checkEnum(TestQNamespaceDeprecated::staticMetaObject.enumerator(0), "TestEnum1",
4050  {{"Key1", 11}, {"Key2", 12}, {"Key3", 13}, {"Key4", 14}, {"Key5", 15}, {"Key6", 16},
4051  {"Key7", 17}});
4052  checkEnum(TestQNamespaceDeprecated::staticMetaObject.enumerator(1), "TestFlag1",
4053  {{"None", 0}, {"Flag1", 1}, {"Flag2", 2}, {"Flag3", 3}, {"Any", 1 | 2 | 3}});
4054 
4055  QCOMPARE(TestQNamespaceDeprecated::TestGadget::staticMetaObject.enumeratorCount(), 1);
4056  checkEnum(TestQNamespaceDeprecated::TestGadget::staticMetaObject.enumerator(0), "TestGEnum1",
4057  {{"Key1", 13}, {"Key2", 14}, {"Key3", 15}});
4058 
4059  QMetaEnum meta = QMetaEnum::fromType<TestQNamespaceDeprecated::TestEnum1>();
4060  QVERIFY(meta.isValid());
4061  QCOMPARE(meta.name(), "TestEnum1");
4062  QCOMPARE(meta.enclosingMetaObject(), &TestQNamespaceDeprecated::staticMetaObject);
4063  QCOMPARE(meta.keyCount(), 7);
4064 }
4065 
4066 void tst_Moc::mocJsonOutput()
4067 {
4068  const auto readFile = [](const QString &fileName) {
4069  QFile f(fileName);
4070  f.open(QIODevice::ReadOnly);
4071  return QJsonDocument::fromJson(f.readAll());
4072  };
4073 
4074  QString actualFile = QStringLiteral(":/allmocs.json");
4075  QString expectedFile = QStringLiteral(":/allmocs_baseline.json");
4076  if (!QFile::exists(actualFile)) {
4077  // TODO: necessary with cmake as we cannot generate the qrc file soon enough
4078  auto const appDir = QCoreApplication::applicationDirPath();
4079  actualFile = appDir + QDir::separator() + QLatin1String("./allmocs.json");
4080  expectedFile = appDir + QDir::separator() + QLatin1String("./allmocs_baseline.json");
4081  }
4082 
4083  QVERIFY2(QFile::exists(actualFile), qPrintable(actualFile));
4084  QVERIFY2(QFile::exists(expectedFile), qPrintable(expectedFile));
4085 
4086  QJsonDocument actualOutput = readFile(actualFile);
4087  QJsonDocument expectedOutput = readFile(expectedFile);
4088 
4089  const auto showPotentialDiff = [](const QJsonDocument &actual, const QJsonDocument &expected) -> QByteArray {
4090 #if defined(Q_OS_UNIX)
4091  QByteArray actualStr = actual.toJson();
4092  QByteArray expectedStr = expected.toJson();
4093 
4094  QTemporaryFile actualFile;
4095  if (!actualFile.open())
4096  return "Error opening actual temp file";
4097  actualFile.write(actualStr);
4098  actualFile.flush();
4099 
4100  QTemporaryFile expectedFile;
4101  if (!expectedFile.open())
4102  return "Error opening expected temp file";
4103  expectedFile.write(expectedStr);
4104  expectedFile.flush();
4105 
4106  QProcess diffProc;
4107  diffProc.setProgram("diff");
4108  diffProc.setArguments(QStringList() << "-ub" << expectedFile.fileName() << actualFile.fileName());
4109  diffProc.start();
4110  if (!diffProc.waitForStarted())
4111  return "Error waiting for diff process to start.";
4112  if (!diffProc.waitForFinished())
4113  return "Error waiting for diff process to finish.";
4114  return diffProc.readAllStandardOutput();
4115 #else
4116  return "Cannot launch diff. Please check allmocs.json and allmocs_baseline.json on disk.";
4117 #endif
4118  };
4119 
4120  QVERIFY2(actualOutput == expectedOutput, showPotentialDiff(actualOutput, expectedOutput).constData());
4121 }
4122 
4124 {
4125  prop1.reset(new FwdClass1(v));
4126 }
4128 {
4129  prop2.reset(new FwdClass2(v));
4130 }
4132 {
4133  prop3.reset(new FwdClass3(v));
4134 }
4136 
4138 
4139 void tst_Moc::mocInclude()
4140 {
4142  obj.setProperty("prop1", QVariant::fromValue(FwdClass1 { 45 }));
4143  QCOMPARE(obj.prop1->x, 45);
4144 }
4145 
4146 class RequiredTest :public QObject
4147 {
4148  Q_OBJECT
4149 
4150  Q_PROPERTY(int required MEMBER m_required REQUIRED)
4151  Q_PROPERTY(int notRequired MEMBER m_notRequired)
4152 
4153 private:
4154  int m_required;
4155  int m_notRequired;
4156 };
4157 
4158 void tst_Moc::requiredProperties()
4159 {
4160  QMetaObject mo = RequiredTest::staticMetaObject;
4161  QMetaProperty required = mo.property(mo.indexOfProperty("required"));
4162  QVERIFY(required.isValid());
4163  QVERIFY(required.isRequired());
4164  QMetaProperty notRequired = mo.property(mo.indexOfProperty("notRequired"));
4165  QVERIFY(notRequired.isValid());
4166  QVERIFY(!notRequired.isRequired());
4167 }
4168 
4169 class ClassWithQPropertyMembers : public QObject
4170 {
4171  Q_OBJECT
4173  NOTIFY publicPropertyChanged)
4175 public:
4176 
4177 signals:
4179 
4180 public:
4184 
4185 
4186 protected:
4188 
4189 private:
4190  QProperty<int> privateProperty;
4192 };
4193 
4194 void tst_Moc::qpropertyMembers()
4195 {
4196  const auto metaObject = &ClassWithQPropertyMembers::staticMetaObject;
4197 
4198  QCOMPARE(metaObject->propertyCount() - metaObject->superClass()->propertyCount(), 2);
4199 
4200  QCOMPARE(metaObject->indexOfProperty("notExposed"), -1);
4201 
4202  QMetaProperty prop = metaObject->property(metaObject->indexOfProperty("publicProperty"));
4203  QVERIFY(prop.isValid());
4204 
4205  QVERIFY(metaObject->property(metaObject->indexOfProperty("privateExposedProperty")).isValid());
4206 
4207  ClassWithQPropertyMembers instance;
4208 
4209  prop.write(&instance, 42);
4210  QCOMPARE(instance.publicProperty.value(), 42);
4211 
4212  QSignalSpy publicPropertySpy(&instance, SIGNAL(publicPropertyChanged()));
4213 
4214  instance.publicProperty.setValue(100);
4215  QCOMPARE(prop.read(&instance).toInt(), 100);
4216  QCOMPARE(publicPropertySpy.count(), 1);
4217 
4219 
4220  QVERIFY(prop.notifySignal().isValid());
4221 }
4222 
4223 
4224 
4225 void tst_Moc::observerMetaCall()
4226 {
4227  const auto metaObject = &ClassWithQPropertyMembers::staticMetaObject;
4228  QMetaProperty prop = metaObject->property(metaObject->indexOfProperty("publicProperty"));
4229  QVERIFY(prop.isValid());
4230 
4231  ClassWithQPropertyMembers instance;
4232 
4233  int observerCallCount = 0;
4234 
4235 
4236  auto observer = [&observerCallCount]() {
4237  ++observerCallCount;
4238  };
4239 
4240  auto bindable = prop.bindable(&instance);
4241  QVERIFY(bindable.isBindable());
4242 
4243  auto handler = bindable.onValueChanged(observer);
4244 
4245  QCOMPARE(observerCallCount, 0);
4246  instance.publicProperty.setValue(100);
4247  QCOMPARE(observerCallCount, 1);
4248  instance.publicProperty.setValue(101);
4249  QCOMPARE(observerCallCount, 2);
4250 }
4251 
4252 
4253 
4254 void tst_Moc::setQPRopertyBinding()
4255 {
4256  const auto metaObject = &ClassWithQPropertyMembers::staticMetaObject;
4257  QMetaProperty prop = metaObject->property(metaObject->indexOfProperty("publicProperty"));
4258  QVERIFY(prop.isValid());
4259 
4260  ClassWithQPropertyMembers instance;
4261 
4262  bool bindingCalled = false;
4263  auto binding = Qt::makePropertyBinding([&bindingCalled]() {
4264  bindingCalled = true;
4265  return 42;
4266  });
4267 
4268  auto bindable = prop.bindable(&instance);
4269  QVERIFY(bindable.isBindable());
4270  bindable.setBinding(binding);
4271 
4272  QCOMPARE(instance.publicProperty.value(), 42);
4273  QVERIFY(bindingCalled); // but now it should've been called :)
4274 }
4275 
4276 class ClassWithPrivateQPropertyShim :public QObject
4277 {
4278  Q_OBJECT
4279 public:
4281  BINDABLE bindableTestProperty NOTIFY testPropertyChanged)
4283  BINDABLE bindableTestProperty2)
4284  //Q_PROPERTY(d_func(), int, lazyTestProperty, setLazyTestProperty, NOTIFY lazyTestPropertyChanged)
4285 
4286 signals:
4289 public:
4290 
4291  int testProperty() const { return priv.testProperty; }
4292  void setTestProperty(int val) { priv.testProperty = val; }
4293  int testProperty2() const { return priv.testProperty2; }
4295 
4298 
4299  struct Private {
4301  : q(pub)
4302  {}
4303 
4305 
4307 
4308  void onTestPropertyChanged() { q->testPropertyChanged(); }
4311  };
4312  Private priv{this};
4313 
4314  Private *d_func() { return &priv; }
4315  const Private *d_func() const { return &priv; }
4316 };
4317 
4319 {
4320  return &o->bindingStorage;
4321 }
4323 {
4324  return &o->bindingStorage;
4325 }
4326 
4327 void tst_Moc::privateQPropertyShim()
4328 {
4330 
4331  {
4332  auto metaObject = &ClassWithPrivateQPropertyShim::staticMetaObject;
4333  QMetaProperty prop = metaObject->property(metaObject->indexOfProperty("testProperty"));
4334  QVERIFY(prop.isValid());
4335  QVERIFY(prop.notifySignal().isValid());
4336  }
4337 
4338  testObject.priv.testProperty.setValue(42);
4339  QCOMPARE(testObject.property("testProperty").toInt(), 42);
4340 
4341  // Behave like a QProperty
4342  QVERIFY(!testObject.bindableTestProperty().hasBinding());
4343  testObject.bindableTestProperty().setBinding([]() { return 100; });
4344  QCOMPARE(testObject.testProperty(), 100);
4345  QVERIFY(testObject.bindableTestProperty().hasBinding());
4346 
4347  // Old style setter getters
4348  testObject.setTestProperty(400);
4349  QVERIFY(!testObject.bindableTestProperty().hasBinding());
4350  QCOMPARE(testObject.testProperty(), 400);
4351 
4352  // moc generates correct code for plain QProperty in PIMPL
4353  testObject.setTestProperty2(42);
4354  QCOMPARE(testObject.priv.testProperty2.value(), 42);
4355 }
4356 
4357 QTEST_MAIN(tst_Moc)
4358 
4359 // the generated code must compile with QT_NO_KEYWORDS
4360 #undef signals
4361 #undef slots
4362 #undef emit
4363 
4364 #include "tst_moc.moc"
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
#define value
[5]
CustomQObject::Number enumValue() const
Definition: tst_moc.cpp:3282
QList< QVariant > listVariant() const
Definition: tst_moc.cpp:3271
void bu1(int, CustomObject3)
Definition: tst_moc.cpp:3318
QList< QList< int > > listListInt() const
Definition: tst_moc.cpp:3278
void ref4(QSharedPointer< CustomQObject2 > &)
Definition: tst_moc.cpp:3329
void bu6(int, CustomObject11, int)
Definition: tst_moc.cpp:3323
void weakPointerSlot(QWeakPointer< CustomQObject2 >)
Definition: tst_moc.cpp:3306
void sharedPointerSlot(QSharedPointer< CustomQObject2 >)
Definition: tst_moc.cpp:3305
void trackingPointerSlot(QPointer< CustomQObject2 >)
Definition: tst_moc.cpp:3307
QSharedPointer< CustomQObject > customObjectP() const
Definition: tst_moc.cpp:3246
void namespacedNonQObjectSlot(SomeNamespace2::NamespacedNonQObject2)
Definition: tst_moc.cpp:3316
void listListIntSlot(QList< QList< int >>)
Definition: tst_moc.cpp:3311
QPointer< CustomQObject > customObjectTP() const
Definition: tst_moc.cpp:3256
void namespacedQObjectSlot(SomeNamespace2::NamespacedQObject2 *)
Definition: tst_moc.cpp:3315
void enumSlot(CustomQObject2::Number)
Definition: tst_moc.cpp:3313
QList< int > listInt() const
Definition: tst_moc.cpp:3266
CustomQObject * customObject() const
Definition: tst_moc.cpp:3261
QList< QList< CustomQObject * > > listListObject() const
Definition: tst_moc.cpp:3280
QList< CustomQObject * > listObject() const
Definition: tst_moc.cpp:3273
void someSignal(CustomObject12)
QWeakPointer< CustomQObject > customObjectWP() const
Definition: tst_moc.cpp:3251
void bu5(int, CustomObject9, CustomObject10)
Definition: tst_moc.cpp:3322
SomeNamespace::NamespacedQObject * customObjectNamespaced() const
Definition: tst_moc.cpp:3292
void bu2(CustomObject4, int)
Definition: tst_moc.cpp:3319
void objectSlot(QObject *)
Definition: tst_moc.cpp:3303
void listListCustomObjectSlot(QList< QList< CustomQObject2 * >>)
Definition: tst_moc.cpp:3312
void listVariantSlot(QList< QVariant >)
Definition: tst_moc.cpp:3309
void listIntSlot(QList< int >)
Definition: tst_moc.cpp:3308
void ref3(CustomQObject2 &)
Definition: tst_moc.cpp:3328
void listCustomObjectSlot(QList< CustomQObject2 * >)
Definition: tst_moc.cpp:3310
void customObjectSlot(CustomQObject2 *)
Definition: tst_moc.cpp:3304
void typedefSlot(CustomQObject2Star)
Definition: tst_moc.cpp:3314
SomeNamespace::NamespacedNonQObject customNonQObjectNamespaced() const
Definition: tst_moc.cpp:3297
void bu3(CustomObject5, CustomObject6)
Definition: tst_moc.cpp:3320
void bu4(CustomObject7, int, CustomObject8)
Definition: tst_moc.cpp:3321
AutoRegistrationObject(QObject *parent=nullptr)
Definition: tst_moc.cpp:3236
CustomQObjectStar customObjectTypedef() const
Definition: tst_moc.cpp:3287
QObject * object() const
Definition: tst_moc.cpp:3241
void ref2(QList< int > &)
Definition: tst_moc.cpp:3327
const Private * d_func() const
Definition: tst_moc.cpp:4315
QBindable< int > bindableTestProperty()
Definition: tst_moc.cpp:4296
void setTestProperty2(int val)
Definition: tst_moc.cpp:4294
QBindable< int > bindableTestProperty2()
Definition: tst_moc.cpp:4297
void privateSignal1(QPrivateSignal)
void privateOverloadedSignal(QPrivateSignal)
void privateSignalWith1Arg(int arg1, QPrivateSignal)
void privateOverloadedSignal(int, QPrivateSignal)
void overloadedMaybePrivate(int, QPrivateSignal)
ClassWithPrivateSignals(QObject *parent=nullptr)
Definition: tst_moc.cpp:2589
void privateSignalWith2Args(int arg1, const QString &arg2, QPrivateSignal)
QProperty< int > protectedProperty
Definition: tst_moc.cpp:4187
Q_OBJECT_BINDABLE_PROPERTY(ClassWithQPropertyMembers, int, publicProperty, &ClassWithQPropertyMembers::publicPropertyChanged)
QProperty< int > notExposed
Definition: tst_moc.cpp:4183
QBindable< int > bindablePublicProperty()
Definition: tst_moc.cpp:4181
CustomQObject2(QObject *parent=nullptr)
Definition: tst_moc.cpp:3167
CustomQObject(QObject *parent=nullptr)
Definition: tst_moc.cpp:3126
FooNamespace::Enum1 prop
Definition: tst_moc.cpp:3963
QList< Foo::Bar::Flags > flagsList
Foo::Bar::Flags flags
void assertSelf(OverloadedAddressOperator &o)
Definition: tst_moc.cpp:3096
void self(OverloadedAddressOperator &)
void setFoo(int value)
Definition: tst_moc.cpp:1616
const MyDPointer * d_func() const
Definition: tst_moc.cpp:1618
MyDPointer * d_func()
Definition: tst_moc.cpp:1617
void blub5Changed(const QString &newBlub)
PrivatePropertyTest(QObject *parent=nullptr)
Definition: tst_moc.cpp:1614
QBindable is a wrapper class around binding-enabled properties. It allows type-safe operations while ...
Definition: qproperty.h:753
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
const char * constData() const noexcept
Definition: qbytearray.h:144
static QByteArray fromBase64(const QByteArray &base64, Base64Options options=Base64Encoding)
bool contains(char c) const
Definition: qbytearray.h:565
bool isEmpty() const noexcept
Definition: qbytearray.h:129
static QByteArray number(int, int base=10)
int qstrcmp(const char *str1, const char *str2)
Definition: qbytearray.cpp:215
static QString applicationDirPath()
static QChar separator()
Definition: qdir.h:234
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:94
bool exists() const
Definition: qfile.cpp:376
qint64 write(const char *data, qint64 len)
Definition: qiodevice.cpp:1681
The QJsonArray class encapsulates a JSON array.
Definition: qjsonarray.h:54
qsizetype size() const
Definition: qjsonarray.cpp:288
The QJsonDocument class provides a way to read and write JSON documents.
Definition: qjsondocument.h:83
QByteArray toJson(JsonFormat format=Indented) const
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error=nullptr)
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
Definition: qlist.h:108
qsizetype size() const noexcept
Definition: qlist.h:414
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
value_type takeFirst()
Definition: qlist.h:564
qsizetype count() const noexcept
Definition: qlist.h:415
void reserve(qsizetype size)
Definition: qlist.h:757
void append(parameter_type t)
Definition: qlist.h:469
The QMetaClassInfo class provides additional information about a class.
Definition: qmetaobject.h:362
const char * name() const
const char * value() const
The QMetaEnum class provides meta-data about an enumerator.
Definition: qmetaobject.h:220
int value(int index) const
const char * name() const
const char * key(int index) const
int keyCount() const
The QMetaMethod class provides meta-data about a member function.
Definition: qmetaobject.h:54
Access access() const
const char * typeName() const
bool isValid() const
Definition: qmetaobject.h:172
QList< QByteArray > parameterTypes() const
QByteArray methodSignature() const
MethodType methodType() const
QList< QByteArray > parameterNames() const
The QMetaProperty class provides meta-data about a property.
Definition: qmetaobject.h:277
bool isBindable() const
int userType() const
Definition: qmetaobject.h:291
bool write(QObject *obj, const QVariant &value) const
QMetaType metaType() const
QVariant read(const QObject *obj) const
QMetaMethod notifySignal() const
bool isValid() const
Definition: qmetaobject.h:331
QUntypedBindable bindable(QObject *object) const
bool isRequired() const
The QMetaType class manages named types in the meta-object system.
Definition: qmetatype.h:328
static QMetaType fromName(QByteArrayView name)
Definition: qmetatype.cpp:2789
int qMetaTypeId()
Definition: qmetatype.h:1302
@ UnknownType
Definition: qmetatype.h:346
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Definition: qobject.cpp:2772
QVariant property(const char *name) const
Definition: qobject.cpp:4118
bool setProperty(const char *name, const QVariant &value)
Definition: qobject.cpp:4063
static QList< QStaticPlugin > staticPlugins()
The QPointer class is a template class that provides guarded pointers to QObject.
Definition: qpointer.h:54
The QProcessEnvironment class holds the environment variables that can be passed to a program.
Definition: qprocess.h:66
static QProcessEnvironment systemEnvironment()
void remove(const QString &name)
Definition: qprocess.cpp:332
void insert(const QString &name, const QString &value)
Definition: qprocess.cpp:317
The QRegularExpression class provides pattern matching using regular expressions.
T * data() const noexcept
Definition: qset.h:54
qsizetype size() const
Definition: qset.h:86
bool contains(const T &value) const
Definition: qset.h:107
iterator insert(const T &value)
Definition: qset.h:191
The QSharedPointer class holds a strong reference to a shared pointer.
The QString class provides a Unicode character string.
Definition: qstring.h:388
QByteArray toLatin1() const &
Definition: qstring.h:745
static QString fromLatin1(QByteArrayView ba)
Definition: qstring.cpp:5488
static QString fromLocal8Bit(QByteArrayView ba)
Definition: qstring.cpp:5563
bool isEmpty() const
Definition: qstring.h:1216
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.h:1353
QString trimmed() const &
Definition: qstring.h:623
QString & remove(qsizetype i, qsizetype len)
Definition: qstring.cpp:3252
The QStringList class provides a list of strings.
void testSlot3(TestTemplate2< TestTemplate2< const int, const short * > const *, TestTemplate2< TestTemplate2< void, int >, unsigned char * > >)
Definition: tst_moc.cpp:1856
void testSlot2(TestTemplate2< int, short const *const >)
Definition: tst_moc.cpp:1855
void testSlot(TestTemplate2< const int, const short * >)
Definition: tst_moc.cpp:1854
void testSignal(TestTemplate2< const int, const short * >)
void doAnotherThing(bool=(1< 3), bool=(1 > 4))
Definition: tst_moc.cpp:1870
void doSomething(QHash< QString, QVariant >=QHash< QString, QVariant >())
Definition: tst_moc.cpp:1866
void performSomething(QList< QList< QString >>=QList< QList< QString >>(8< 1), QHash< int, QList< QString >>=QHash< int, QList< QString >>())
Definition: tst_moc.cpp:1872
void doSomethingElse(QSharedPointer< QVarLengthArray< QString,(16 >> 2)> >=QSharedPointer< QVarLengthArray< QString,(16 >> 2)> >())
Definition: tst_moc.cpp:1867
void setValue2(int value)
Definition: tst_moc.cpp:1800
void setValue(int value)
Definition: tst_moc.cpp:1798
const QString returnConstString(const QString s)
Definition: tst_moc.cpp:1825
QList< int > const returnConstTemplate2()
Definition: tst_moc.cpp:1823
QString const returnConstString2(QString const s)
Definition: tst_moc.cpp:1826
const QList< int > returnConstTemplate1()
Definition: tst_moc.cpp:1822
void foo(constconst const &)
Definition: tst_moc.cpp:1840
void foo(constconst *)
Definition: tst_moc.cpp:1841
void foo(const_ *)
Definition: tst_moc.cpp:1842
void slotChooseScientificConst0(science_constant const &)
Definition: tst_moc.cpp:1838
void foo(science_const const &)
Definition: tst_moc.cpp:1839
Q_INVOKABLE QString getEgg(int index)
Definition: tst_moc.cpp:1925
Q_INVOKABLE QString getChicken(int index)
Definition: tst_moc.cpp:1926
The QTemporaryFile class is an I/O device that operates on temporary files.
QString fileName() const override
static constexpr QTypeRevision fromVersion(Major majorVersion, Minor minorVersion)
static constexpr QTypeRevision fromMinorVersion(Minor minorVersion)
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:95
static auto fromValue(const T &value) -> std::enable_if_t< std::is_copy_constructible_v< T >, QVariant >
Definition: qvariant.h:391
bool isValid() const
Definition: qvariant.h:582
int toInt(bool *ok=nullptr) const
Definition: qvariant.cpp:1833
int userType() const
Definition: qvariant.h:240
QString toString() const
Definition: qvariant.cpp:1416
The QWeakPointer class holds a weak reference to a shared pointer.
void testSlotWith2Args(int i, const QString &s)
Definition: tst_moc.cpp:2576
SignalConnectionTester(QObject *parent=nullptr)
Definition: tst_moc.cpp:2561
void testSlotWith1Arg(int i)
Definition: tst_moc.cpp:2572
NamespacedQObject(QObject *parent=nullptr)
Definition: tst_moc.cpp:3143
SubClassFromPrivateSignals(QObject *parent=nullptr)
Definition: tst_moc.cpp:2625
UnrelatedClass::UnrelatedEnum enumProperty() const
Definition: tst_moc.cpp:3695
void setEnumProperty(UnrelatedClass::UnrelatedEnum arg)
Definition: tst_moc.cpp:3699
void setProp3(const FwdClass3 &val)
Definition: tst_moc.cpp:4131
FwdClass2 prop2
Definition: moc_include.h:49
FwdClass3 prop3
Definition: moc_include.h:50
FwdClass1 prop1
Definition: moc_include.h:48
void setProp2(const FwdClass2 &val)
Definition: tst_moc.cpp:4127
void setProp1(const FwdClass1 &val)
Definition: tst_moc.cpp:4123
signals Q_REVISION(7) void signal4()
Q_REVISION(3) void slot2()
Definition: tst_moc.cpp:1965
void signal1()
int foo() const
Definition: tst_moc.cpp:1953
void slot4()
Definition: tst_moc.cpp:1975
public slots Q_REVISION(5, 12)
Definition: tst_moc.cpp:1977
Q_INVOKABLE void method1()
Definition: tst_moc.cpp:1955
Q_INVOKABLE Q_REVISION(6, 0) void method60()
Definition: tst_moc.cpp:1957
Q_INVOKABLE Q_REVISION(4) void method2()
Definition: tst_moc.cpp:1956
Q_ENUM(TestEnum)
void slot1()
Definition: tst_moc.cpp:1964
Q_REVISION(5) void signal2()
Q_REVISION(6, 1) void slot61()
Definition: tst_moc.cpp:1966
Q_REVISION(5) void signal2()
signals Q_REVISION(7) void signal4()
Q_INVOKABLE Q_REVISION(6, 0) void method60()
Definition: tst_moc.cpp:2001
int foo() const
Definition: tst_moc.cpp:1997
Q_INVOKABLE void method1()
Definition: tst_moc.cpp:1999
Q_REVISION(3) void slot2()
Definition: tst_moc.cpp:2008
public slots Q_REVISION(5, 12)
Definition: tst_moc.cpp:2021
Q_INVOKABLE Q_REVISION(4) void method2()
Definition: tst_moc.cpp:2000
Q_REVISION(6, 1) void slot61()
Definition: tst_moc.cpp:2009
Q_INVOKABLE PrivateClass()
Definition: tst_moc.cpp:2370
#define T(x)
Definition: main.cpp:42
QString str
[2]
double e
auto signal
auto mo
[7]
QSignalSpy spy(myCustomObject, SIGNAL(mySignal(int, QString, double)))
[0]
QList< QVariant > arguments
QCOMPARE(spy.count(), 1)
int Int
Definition: ftraster.c:307
backing_store_ptr info
[4]
Definition: jmemsys.h:161
void method2()
Definition: listnames.cpp:73
void slot3(const QString &a, const QString &b, const QString &c)
void slot2(const QString &a, const QString &b)
void toString(QString &appendTo, IPv4Address address)
Definition: qipaddress.cpp:131
Q_TESTLIB_EXPORT QTestData & newRow(const char *dataTag)
Definition: qtestcase.cpp:2658
Q_TESTLIB_EXPORT void ignoreMessage(QtMsgType type, const char *message)
Definition: qtestcase.cpp:2292
auto makePropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor >> *=nullptr)
Definition: qproperty.h:222
typing.Tuple[int, int] test(str binary_directory, *debug=False)
required
Definition: devices.py:75
QString enumValue(const QString &value)
Definition: language.cpp:492
#define QString()
Definition: parse-defines.h:51
#define PD_NAMESPACE
Definition: parse-defines.h:36
#define PD_CLASSNAME
Definition: parse-defines.h:40
#define PD_SCOPED_STRING(a, b)
Definition: parse-defines.h:44
PCRE2_SIZE PRIV() strlen(PCRE2_SPTR str)
void
Definition: png.h:1080
#define None
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_GCC(text)
#define QT_WARNING_PUSH
#define QT_WARNING_DISABLE_CLANG(text)
std::pair< T1, T2 > QPair
Definition: qcontainerfwd.h:56
QList< QString > QStringList
Definition: qcontainerfwd.h:64
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
long long qint64
Definition: qglobal.h:298
#define qDebug
[1]
Definition: qlogging.h:177
@ QtWarningMsg
Definition: qlogging.h:62
#define qWarning
Definition: qlogging.h:179
#define NS(x)
Definition: qmetatype.cpp:98
const char * typeName
Definition: qmetatype.cpp:869
#define SLOT(a)
Definition: qobjectdefs.h:87
#define Q_ARG(type, data)
Definition: qobjectdefs.h:98
#define SIGNAL(a)
Definition: qobjectdefs.h:88
#define Q_RETURN_ARG(type, data)
Definition: qobjectdefs.h:99
GLint GLfloat GLfloat GLfloat v2
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLuint64 key
GLboolean r
[2]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint index
[2]
GLenum GLenum GLsizei count
GLuint object
[3]
GLfloat GLfloat f
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint name
GLint first
GLhandleARB obj
[2]
Definition: qopenglext.h:4164
GLuint GLfloat * val
Definition: qopenglext.h:1513
GLuint GLuint GLuint GLuint arg1
Definition: qopenglext.h:6221
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: qopenglext.h:6222
GLdouble GLdouble GLdouble GLdouble q
Definition: qopenglext.h:259
GLdouble s
[6]
Definition: qopenglext.h:235
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
GLenum GLenum GLenum input
Definition: qopenglext.h:10816
void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin)
SSL_CTX int(*) void arg)
#define QStringLiteral(str)
#define QTEST_MAIN(TestObject)
Definition: qtest.h:664
#define QSKIP(statement,...)
Definition: qtestcase.h:222
#define QFETCH(Type, name)
Definition: qtestcase.h:230
#define QFAIL(message)
Definition: qtestcase.h:70
#define QVERIFY2(statement, description)
Definition: qtestcase.h:76
#define Q_ENUM(x)
Definition: qtmetamacros.h:104
#define Q_PROPERTY(...)
Definition: qtmetamacros.h:92
#define Q_GADGET_EXPORT(...)
Definition: qtmetamacros.h:179
#define Q_OBJECT
Definition: qtmetamacros.h:158
#define Q_CLASSINFO(name, value)
Definition: qtmetamacros.h:88
#define Q_INVOKABLE
Definition: qtmetamacros.h:112
#define Q_FLAG_NS(x)
Definition: qtmetamacros.h:110
#define Q_SLOTS
Definition: qtmetamacros.h:80
#define Q_GADGET
Definition: qtmetamacros.h:193
#define Q_ENUM_NS(x)
Definition: qtmetamacros.h:109
#define slots
Definition: qtmetamacros.h:76
#define Q_ENUMS(x)
Definition: qtmetamacros.h:99
#define signals
Definition: qtmetamacros.h:77
#define Q_SIGNALS
Definition: qtmetamacros.h:81
#define emit
Definition: qtmetamacros.h:85
#define Q_PRIVATE_PROPERTY(d, text)
Definition: qtmetamacros.h:93
#define Q_NAMESPACE
Definition: qtmetamacros.h:202
#define Q_NAMESPACE_EXPORT(...)
Definition: qtmetamacros.h:196
T qvariant_cast(const QVariant &)
Definition: qvariant.h:620
const char property[13]
Definition: qwizard.cpp:136
const char className[16]
[1]
Definition: qwizard.cpp:135
Q_UNUSED(salary)
[21]
QByteArray ba
[0]
QStringList keys
obj metaObject() -> className()
QHttpRequestHeader header("GET", QUrl::toPercentEncoding("/index.html"))
[1]
void testObject()
[11]
Private(ClassWithPrivateQPropertyShim *pub)
Definition: tst_moc.cpp:4300
Q_OBJECT_BINDABLE_PROPERTY(Private, int, testProperty, &Private::onTestPropertyChanged)
static T construct()
Definition: tst_moc.cpp:3371
void setFlags(Flags f)
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:53
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
static QByteArray normalizedSignature(const char *method)
QStaticPlugin is a struct containing a reference to a static plugin instance together with its meta d...
Definition: qplugin.h:142
Definition: main.cpp:38
QThreadStorage< int * > dummy[8]
const QBindingStorage * qGetBindingStorage(const ClassWithPrivateQPropertyShim::Private *o)
Definition: tst_moc.cpp:4318
#define TESTEXPORTMACRO
Definition: tst_moc.cpp:92
QObject * qt_plugin_instance()
Definition: main.cpp:45
QPluginMetaData qt_plugin_query_metadata_v2()
Q_DECLARE_METATYPE(const QMetaObject *)
#define ADD(x)
idx
Definition: tst_moc.cpp:908
#define repeat32768(V)
Definition: tst_moc.cpp:3845
#define FOR_EACH_SLOT_ARG_TYPE(F)
#define TYPE_LOOP(TYPE)
QVERIFY(idx !=-1)
@ Flag2
Definition: tst_qdebug.cpp:728
@ Flag1
Definition: tst_qdebug.cpp:727
MyEnum
Definition: tst_qflags.cpp:497
@ Two
Definition: tst_qflags.cpp:497
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent