1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtTest/QtTest>
43 #include <QtCore/qlocale.h>
44 #include <private/qmetaobjectbuilder_p.h>
46 class tst_QMetaObjectBuilder : public QObject
50 tst_QMetaObjectBuilder() {}
51 ~tst_QMetaObjectBuilder() {}
54 void mocVersionCheck();
67 void relatedMetaObject();
68 void staticMetacall();
69 void copyMetaObject();
71 void removeNotifySignal();
74 static bool checkForSideEffects
75 (const QMetaObjectBuilder& builder,
76 QMetaObjectBuilder::AddMembers members);
77 static bool sameMetaObject
78 (const QMetaObject *meta1, const QMetaObject *meta2);
81 // Dummy class that has something of every type of thing moc can generate.
82 class SomethingOfEverything : public QObject
85 Q_CLASSINFO("ci_foo", "ABC")
86 Q_CLASSINFO("ci_bar", "DEF")
87 Q_PROPERTY(QString prop READ prop WRITE setProp NOTIFY propChanged)
88 Q_PROPERTY(QString prop2 READ prop WRITE setProp)
89 Q_PROPERTY(SomethingEnum eprop READ eprop)
90 Q_PROPERTY(SomethingFlagEnum fprop READ fprop)
91 Q_PROPERTY(QLocale::Language language READ language)
92 Q_ENUMS(SomethingEnum)
93 Q_FLAGS(SomethingFlagEnum)
95 Q_INVOKABLE SomethingOfEverything() {}
96 ~SomethingOfEverything() {}
104 enum SomethingFlagEnum
110 Q_INVOKABLE Q_SCRIPTABLE void method1() {}
112 QString prop() const { return QString(); }
113 void setProp(const QString& v) { Q_UNUSED(v); }
115 SomethingOfEverything::SomethingEnum eprop() const { return GHI; }
116 SomethingOfEverything::SomethingFlagEnum fprop() const { return XYZ; }
117 QLocale::Language language() const { return QLocale::English; }
120 void slot1(const QString&) {}
121 void slot2(int, const QString&) {}
127 Q_SCRIPTABLE void slot4(int) {}
128 void slot5(int a, const QString& b) { Q_UNUSED(a); Q_UNUSED(b); }
132 void sig2(int x, const QString& y);
133 void propChanged(const QString&);
136 void tst_QMetaObjectBuilder::mocVersionCheck()
138 // This test will fail when the moc version number is changed.
139 // It is intended as a reminder to also update QMetaObjectBuilder
140 // whenenver moc changes. Once QMetaObjectBuilder has been
141 // updated, this test can be changed to check for the next version.
142 int version = int(QObject::staticMetaObject.d.data[0]);
143 QVERIFY(version == 4 || version == 5 || version == 6);
144 version = int(staticMetaObject.d.data[0]);
145 QVERIFY(version == 4 || version == 5 || version == 6);
148 void tst_QMetaObjectBuilder::create()
150 QMetaObjectBuilder builder;
151 QVERIFY(builder.className().isEmpty());
152 QVERIFY(builder.superClass() == &QObject::staticMetaObject);
153 QCOMPARE(builder.methodCount(), 0);
154 QCOMPARE(builder.constructorCount(), 0);
155 QCOMPARE(builder.propertyCount(), 0);
156 QCOMPARE(builder.enumeratorCount(), 0);
157 QCOMPARE(builder.classInfoCount(), 0);
158 QCOMPARE(builder.relatedMetaObjectCount(), 0);
159 QVERIFY(builder.staticMetacallFunction() == 0);
162 void tst_QMetaObjectBuilder::className()
164 QMetaObjectBuilder builder;
166 // Change the class name.
167 builder.setClassName("Foo");
168 QCOMPARE(builder.className(), QByteArray("Foo"));
171 builder.setClassName("Bar");
172 QCOMPARE(builder.className(), QByteArray("Bar"));
174 // Clone the class name off a static QMetaObject.
175 builder.addMetaObject(&QObject::staticMetaObject, QMetaObjectBuilder::ClassName);
176 QCOMPARE(builder.className(), QByteArray("QObject"));
178 // Check that nothing else changed.
179 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::ClassName));
182 void tst_QMetaObjectBuilder::superClass()
184 QMetaObjectBuilder builder;
186 // Change the super class.
187 builder.setSuperClass(&QObject::staticMetaObject);
188 QVERIFY(builder.superClass() == &QObject::staticMetaObject);
191 builder.setSuperClass(&staticMetaObject);
192 QVERIFY(builder.superClass() == &staticMetaObject);
194 // Clone the super class off a static QMetaObject.
195 builder.addMetaObject(&QObject::staticMetaObject, QMetaObjectBuilder::SuperClass);
196 QVERIFY(builder.superClass() == 0);
197 builder.addMetaObject(&staticMetaObject, QMetaObjectBuilder::SuperClass);
198 QVERIFY(builder.superClass() == staticMetaObject.superClass());
200 // Check that nothing else changed.
201 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::SuperClass));
204 void tst_QMetaObjectBuilder::flags()
206 QMetaObjectBuilder builder;
209 QVERIFY(builder.flags() == 0);
212 builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
213 QVERIFY(builder.flags() == QMetaObjectBuilder::DynamicMetaObject);
216 void tst_QMetaObjectBuilder::method()
218 QMetaObjectBuilder builder;
221 QMetaMethodBuilder nullMethod;
222 QCOMPARE(nullMethod.signature(), QByteArray());
223 QVERIFY(nullMethod.methodType() == QMetaMethod::Method);
224 QVERIFY(nullMethod.returnType().isEmpty());
225 QVERIFY(nullMethod.parameterNames().isEmpty());
226 QVERIFY(nullMethod.tag().isEmpty());
227 QVERIFY(nullMethod.access() == QMetaMethod::Public);
228 QCOMPARE(nullMethod.attributes(), 0);
229 QCOMPARE(nullMethod.index(), 0);
231 // Add a method and check its attributes.
232 QMetaMethodBuilder method1 = builder.addMethod("foo(const QString&, int)");
233 QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
234 QVERIFY(method1.methodType() == QMetaMethod::Method);
235 QVERIFY(method1.returnType().isEmpty());
236 QVERIFY(method1.parameterNames().isEmpty());
237 QVERIFY(method1.tag().isEmpty());
238 QVERIFY(method1.access() == QMetaMethod::Public);
239 QCOMPARE(method1.attributes(), 0);
240 QCOMPARE(method1.index(), 0);
241 QCOMPARE(builder.methodCount(), 1);
243 // Add another method and check again.
244 QMetaMethodBuilder method2 = builder.addMethod("bar(QString)", "int");
245 QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
246 QVERIFY(method2.methodType() == QMetaMethod::Method);
247 QCOMPARE(method2.returnType(), QByteArray("int"));
248 QVERIFY(method2.parameterNames().isEmpty());
249 QVERIFY(method2.tag().isEmpty());
250 QVERIFY(method2.access() == QMetaMethod::Public);
251 QCOMPARE(method2.attributes(), 0);
252 QCOMPARE(method2.index(), 1);
253 QCOMPARE(builder.methodCount(), 2);
255 // Perform index-based lookup.
256 QCOMPARE(builder.indexOfMethod("foo(const QString&, int)"), 0);
257 QCOMPARE(builder.indexOfMethod("bar(QString)"), 1);
258 QCOMPARE(builder.indexOfMethod("baz()"), -1);
260 // Modify the attributes on method1.
261 method1.setReturnType("int");
262 method1.setParameterNames(QList<QByteArray>() << "a" << "b");
263 method1.setTag("tag");
264 method1.setAccess(QMetaMethod::Private);
265 method1.setAttributes(42);
267 // Check that method1 is changed, but method2 is not.
268 QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
269 QVERIFY(method1.methodType() == QMetaMethod::Method);
270 QCOMPARE(method1.returnType(), QByteArray("int"));
271 QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
272 QCOMPARE(method1.tag(), QByteArray("tag"));
273 QVERIFY(method1.access() == QMetaMethod::Private);
274 QCOMPARE(method1.attributes(), 42);
275 QCOMPARE(method1.index(), 0);
276 QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
277 QVERIFY(method2.methodType() == QMetaMethod::Method);
278 QCOMPARE(method2.returnType(), QByteArray("int"));
279 QVERIFY(method2.parameterNames().isEmpty());
280 QVERIFY(method2.tag().isEmpty());
281 QVERIFY(method2.access() == QMetaMethod::Public);
282 QCOMPARE(method2.attributes(), 0);
283 QCOMPARE(method2.index(), 1);
284 QCOMPARE(builder.methodCount(), 2);
286 // Modify the attributes on method2.
287 method2.setReturnType("QString");
288 method2.setParameterNames(QList<QByteArray>() << "c");
289 method2.setTag("Q_FOO");
290 method2.setAccess(QMetaMethod::Protected);
291 method2.setAttributes(24);
293 // This time check that only method2 changed.
294 QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
295 QVERIFY(method1.methodType() == QMetaMethod::Method);
296 QCOMPARE(method1.returnType(), QByteArray("int"));
297 QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
298 QCOMPARE(method1.tag(), QByteArray("tag"));
299 QVERIFY(method1.access() == QMetaMethod::Private);
300 QCOMPARE(method1.attributes(), 42);
301 QCOMPARE(method1.index(), 0);
302 QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
303 QVERIFY(method2.methodType() == QMetaMethod::Method);
304 QCOMPARE(method2.returnType(), QByteArray("QString"));
305 QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
306 QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
307 QVERIFY(method2.access() == QMetaMethod::Protected);
308 QCOMPARE(method2.attributes(), 24);
309 QCOMPARE(method2.index(), 1);
310 QCOMPARE(builder.methodCount(), 2);
312 // Remove method1 and check that method2 becomes index 0.
313 builder.removeMethod(0);
314 QCOMPARE(builder.methodCount(), 1);
315 method2 = builder.method(0);
316 QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
317 QVERIFY(method2.methodType() == QMetaMethod::Method);
318 QCOMPARE(method2.returnType(), QByteArray("QString"));
319 QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
320 QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
321 QVERIFY(method2.access() == QMetaMethod::Protected);
322 QCOMPARE(method2.attributes(), 24);
323 QCOMPARE(method2.index(), 0);
325 // Perform index-based lookup again.
326 QCOMPARE(builder.indexOfMethod("foo(const QString&, int)"), -1);
327 QCOMPARE(builder.indexOfMethod("bar(QString)"), 0);
328 QCOMPARE(builder.indexOfMethod("baz()"), -1);
329 QCOMPARE(builder.method(0).signature(), QByteArray("bar(QString)"));
330 QCOMPARE(builder.method(9).signature(), QByteArray());
332 // Check that nothing else changed.
333 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Methods));
336 void tst_QMetaObjectBuilder::slot()
338 QMetaObjectBuilder builder;
340 // Add a slot and check its attributes.
341 QMetaMethodBuilder method1 = builder.addSlot("foo(const QString&, int)");
342 QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
343 QVERIFY(method1.methodType() == QMetaMethod::Slot);
344 QVERIFY(method1.returnType().isEmpty());
345 QVERIFY(method1.parameterNames().isEmpty());
346 QVERIFY(method1.tag().isEmpty());
347 QVERIFY(method1.access() == QMetaMethod::Public);
348 QCOMPARE(method1.attributes(), 0);
349 QCOMPARE(method1.index(), 0);
350 QCOMPARE(builder.methodCount(), 1);
352 // Add another slot and check again.
353 QMetaMethodBuilder method2 = builder.addSlot("bar(QString)");
354 QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
355 QVERIFY(method2.methodType() == QMetaMethod::Slot);
356 QVERIFY(method2.returnType().isEmpty());
357 QVERIFY(method2.parameterNames().isEmpty());
358 QVERIFY(method2.tag().isEmpty());
359 QVERIFY(method2.access() == QMetaMethod::Public);
360 QCOMPARE(method2.attributes(), 0);
361 QCOMPARE(method2.index(), 1);
362 QCOMPARE(builder.methodCount(), 2);
364 // Perform index-based lookup
365 QCOMPARE(builder.indexOfSlot("foo(const QString &, int)"), 0);
366 QCOMPARE(builder.indexOfSlot("bar(QString)"), 1);
367 QCOMPARE(builder.indexOfSlot("baz()"), -1);
369 // Check that nothing else changed.
370 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Methods));
373 void tst_QMetaObjectBuilder::signal()
375 QMetaObjectBuilder builder;
377 // Add a signal and check its attributes.
378 QMetaMethodBuilder method1 = builder.addSignal("foo(const QString&, int)");
379 QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
380 QVERIFY(method1.methodType() == QMetaMethod::Signal);
381 QVERIFY(method1.returnType().isEmpty());
382 QVERIFY(method1.parameterNames().isEmpty());
383 QVERIFY(method1.tag().isEmpty());
384 QVERIFY(method1.access() == QMetaMethod::Protected);
385 QCOMPARE(method1.attributes(), 0);
386 QCOMPARE(method1.index(), 0);
387 QCOMPARE(builder.methodCount(), 1);
389 // Add another signal and check again.
390 QMetaMethodBuilder method2 = builder.addSignal("bar(QString)");
391 QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
392 QVERIFY(method2.methodType() == QMetaMethod::Signal);
393 QVERIFY(method2.returnType().isEmpty());
394 QVERIFY(method2.parameterNames().isEmpty());
395 QVERIFY(method2.tag().isEmpty());
396 QVERIFY(method2.access() == QMetaMethod::Protected);
397 QCOMPARE(method2.attributes(), 0);
398 QCOMPARE(method2.index(), 1);
399 QCOMPARE(builder.methodCount(), 2);
401 // Perform index-based lookup
402 QCOMPARE(builder.indexOfSignal("foo(const QString &, int)"), 0);
403 QCOMPARE(builder.indexOfSignal("bar(QString)"), 1);
404 QCOMPARE(builder.indexOfSignal("baz()"), -1);
406 // Check that nothing else changed.
407 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Methods));
410 void tst_QMetaObjectBuilder::constructor()
412 QMetaObjectBuilder builder;
414 // Add a constructor and check its attributes.
415 QMetaMethodBuilder ctor1 = builder.addConstructor("foo(const QString&, int)");
416 QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
417 QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
418 QVERIFY(ctor1.returnType().isEmpty());
419 QVERIFY(ctor1.parameterNames().isEmpty());
420 QVERIFY(ctor1.tag().isEmpty());
421 QVERIFY(ctor1.access() == QMetaMethod::Public);
422 QCOMPARE(ctor1.attributes(), 0);
423 QCOMPARE(ctor1.index(), 0);
424 QCOMPARE(builder.constructorCount(), 1);
426 // Add another constructor and check again.
427 QMetaMethodBuilder ctor2 = builder.addConstructor("bar(QString)");
428 QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
429 QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
430 QVERIFY(ctor2.returnType().isEmpty());
431 QVERIFY(ctor2.parameterNames().isEmpty());
432 QVERIFY(ctor2.tag().isEmpty());
433 QVERIFY(ctor2.access() == QMetaMethod::Public);
434 QCOMPARE(ctor2.attributes(), 0);
435 QCOMPARE(ctor2.index(), 1);
436 QCOMPARE(builder.constructorCount(), 2);
438 // Perform index-based lookup.
439 QCOMPARE(builder.indexOfConstructor("foo(const QString&, int)"), 0);
440 QCOMPARE(builder.indexOfConstructor("bar(QString)"), 1);
441 QCOMPARE(builder.indexOfConstructor("baz()"), -1);
442 QCOMPARE(builder.constructor(1).signature(), QByteArray("bar(QString)"));
443 QCOMPARE(builder.constructor(9).signature(), QByteArray());
445 // Modify the attributes on ctor1.
446 ctor1.setReturnType("int");
447 ctor1.setParameterNames(QList<QByteArray>() << "a" << "b");
449 ctor1.setAccess(QMetaMethod::Private);
450 ctor1.setAttributes(42);
452 // Check that ctor1 is changed, but ctor2 is not.
453 QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
454 QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
455 QCOMPARE(ctor1.returnType(), QByteArray("int"));
456 QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
457 QCOMPARE(ctor1.tag(), QByteArray("tag"));
458 QVERIFY(ctor1.access() == QMetaMethod::Private);
459 QCOMPARE(ctor1.attributes(), 42);
460 QCOMPARE(ctor1.index(), 0);
461 QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
462 QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
463 QVERIFY(ctor2.returnType().isEmpty());
464 QVERIFY(ctor2.parameterNames().isEmpty());
465 QVERIFY(ctor2.tag().isEmpty());
466 QVERIFY(ctor2.access() == QMetaMethod::Public);
467 QCOMPARE(ctor2.attributes(), 0);
468 QCOMPARE(ctor2.index(), 1);
469 QCOMPARE(builder.constructorCount(), 2);
471 // Modify the attributes on ctor2.
472 ctor2.setReturnType("QString");
473 ctor2.setParameterNames(QList<QByteArray>() << "c");
474 ctor2.setTag("Q_FOO");
475 ctor2.setAccess(QMetaMethod::Protected);
476 ctor2.setAttributes(24);
478 // This time check that only ctor2 changed.
479 QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
480 QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
481 QCOMPARE(ctor1.returnType(), QByteArray("int"));
482 QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
483 QCOMPARE(ctor1.tag(), QByteArray("tag"));
484 QVERIFY(ctor1.access() == QMetaMethod::Private);
485 QCOMPARE(ctor1.attributes(), 42);
486 QCOMPARE(ctor1.index(), 0);
487 QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
488 QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
489 QCOMPARE(ctor2.returnType(), QByteArray("QString"));
490 QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
491 QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
492 QVERIFY(ctor2.access() == QMetaMethod::Protected);
493 QCOMPARE(ctor2.attributes(), 24);
494 QCOMPARE(ctor2.index(), 1);
495 QCOMPARE(builder.constructorCount(), 2);
497 // Remove ctor1 and check that ctor2 becomes index 0.
498 builder.removeConstructor(0);
499 QCOMPARE(builder.constructorCount(), 1);
500 ctor2 = builder.constructor(0);
501 QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
502 QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
503 QCOMPARE(ctor2.returnType(), QByteArray("QString"));
504 QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
505 QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
506 QVERIFY(ctor2.access() == QMetaMethod::Protected);
507 QCOMPARE(ctor2.attributes(), 24);
508 QCOMPARE(ctor2.index(), 0);
510 // Perform index-based lookup again.
511 QCOMPARE(builder.indexOfConstructor("foo(const QString&, int)"), -1);
512 QCOMPARE(builder.indexOfConstructor("bar(QString)"), 0);
513 QCOMPARE(builder.indexOfConstructor("baz()"), -1);
515 // Add constructor from prototype
516 QMetaMethod prototype = SomethingOfEverything::staticMetaObject.constructor(0);
517 QMetaMethodBuilder prototypeConstructor = builder.addMethod(prototype);
518 QCOMPARE(builder.constructorCount(), 2);
520 QCOMPARE(prototypeConstructor.signature(), QByteArray("SomethingOfEverything()"));
521 QVERIFY(prototypeConstructor.methodType() == QMetaMethod::Constructor);
522 QCOMPARE(prototypeConstructor.returnType(), QByteArray());
523 QVERIFY(prototypeConstructor.access() == QMetaMethod::Public);
524 QCOMPARE(prototypeConstructor.index(), 1);
526 // Check that nothing else changed.
527 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Constructors));
530 void tst_QMetaObjectBuilder::property()
532 QMetaObjectBuilder builder;
534 // Null property builder
535 QMetaPropertyBuilder nullProp;
536 QCOMPARE(nullProp.name(), QByteArray());
537 QCOMPARE(nullProp.type(), QByteArray());
538 QVERIFY(!nullProp.hasNotifySignal());
539 QVERIFY(!nullProp.isReadable());
540 QVERIFY(!nullProp.isWritable());
541 QVERIFY(!nullProp.isResettable());
542 QVERIFY(!nullProp.isDesignable());
543 QVERIFY(!nullProp.isScriptable());
544 QVERIFY(!nullProp.isStored());
545 QVERIFY(!nullProp.isEditable());
546 QVERIFY(!nullProp.isUser());
547 QVERIFY(!nullProp.hasStdCppSet());
548 QVERIFY(!nullProp.isEnumOrFlag());
549 QCOMPARE(nullProp.index(), 0);
551 // Add a property and check its attributes.
552 QMetaPropertyBuilder prop1 = builder.addProperty("foo", "const QString &");
553 QCOMPARE(prop1.name(), QByteArray("foo"));
554 QCOMPARE(prop1.type(), QByteArray("QString"));
555 QVERIFY(!prop1.hasNotifySignal());
556 QVERIFY(prop1.isReadable());
557 QVERIFY(prop1.isWritable());
558 QVERIFY(!prop1.isResettable());
559 QVERIFY(!prop1.isDesignable());
560 QVERIFY(prop1.isScriptable());
561 QVERIFY(!prop1.isStored());
562 QVERIFY(!prop1.isEditable());
563 QVERIFY(!prop1.isUser());
564 QVERIFY(!prop1.hasStdCppSet());
565 QVERIFY(!prop1.isEnumOrFlag());
566 QCOMPARE(prop1.index(), 0);
567 QCOMPARE(builder.propertyCount(), 1);
569 // Add another property and check again.
570 QMetaPropertyBuilder prop2 = builder.addProperty("bar", "int");
571 QCOMPARE(prop2.name(), QByteArray("bar"));
572 QCOMPARE(prop2.type(), QByteArray("int"));
573 QVERIFY(!prop2.hasNotifySignal());
574 QVERIFY(prop2.isReadable());
575 QVERIFY(prop2.isWritable());
576 QVERIFY(!prop2.isResettable());
577 QVERIFY(!prop2.isDesignable());
578 QVERIFY(prop2.isScriptable());
579 QVERIFY(!prop2.isStored());
580 QVERIFY(!prop2.isEditable());
581 QVERIFY(!prop2.isUser());
582 QVERIFY(!prop2.hasStdCppSet());
583 QVERIFY(!prop2.isEnumOrFlag());
584 QCOMPARE(prop2.index(), 1);
585 QCOMPARE(builder.propertyCount(), 2);
587 // Perform index-based lookup.
588 QCOMPARE(builder.indexOfProperty("foo"), 0);
589 QCOMPARE(builder.indexOfProperty("bar"), 1);
590 QCOMPARE(builder.indexOfProperty("baz"), -1);
591 QCOMPARE(builder.property(1).name(), QByteArray("bar"));
592 QCOMPARE(builder.property(9).name(), QByteArray());
594 // Modify the attributes on prop1.
595 prop1.setReadable(false);
596 prop1.setWritable(false);
597 prop1.setResettable(true);
598 prop1.setDesignable(true);
599 prop1.setScriptable(false);
600 prop1.setStored(true);
601 prop1.setEditable(true);
603 prop1.setStdCppSet(true);
604 prop1.setEnumOrFlag(true);
606 // Check that prop1 is changed, but prop2 is not.
607 QCOMPARE(prop1.name(), QByteArray("foo"));
608 QCOMPARE(prop1.type(), QByteArray("QString"));
609 QVERIFY(!prop1.isReadable());
610 QVERIFY(!prop1.isWritable());
611 QVERIFY(prop1.isResettable());
612 QVERIFY(prop1.isDesignable());
613 QVERIFY(!prop1.isScriptable());
614 QVERIFY(prop1.isStored());
615 QVERIFY(prop1.isEditable());
616 QVERIFY(prop1.isUser());
617 QVERIFY(prop1.hasStdCppSet());
618 QVERIFY(prop1.isEnumOrFlag());
619 QVERIFY(prop2.isReadable());
620 QVERIFY(prop2.isWritable());
621 QCOMPARE(prop2.name(), QByteArray("bar"));
622 QCOMPARE(prop2.type(), QByteArray("int"));
623 QVERIFY(!prop2.isResettable());
624 QVERIFY(!prop2.isDesignable());
625 QVERIFY(prop2.isScriptable());
626 QVERIFY(!prop2.isStored());
627 QVERIFY(!prop2.isEditable());
628 QVERIFY(!prop2.isUser());
629 QVERIFY(!prop2.hasStdCppSet());
630 QVERIFY(!prop2.isEnumOrFlag());
632 // Remove prop1 and check that prop2 becomes index 0.
633 builder.removeProperty(0);
634 QCOMPARE(builder.propertyCount(), 1);
635 prop2 = builder.property(0);
636 QCOMPARE(prop2.name(), QByteArray("bar"));
637 QCOMPARE(prop2.type(), QByteArray("int"));
638 QVERIFY(!prop2.isResettable());
639 QVERIFY(!prop2.isDesignable());
640 QVERIFY(prop2.isScriptable());
641 QVERIFY(!prop2.isStored());
642 QVERIFY(!prop2.isEditable());
643 QVERIFY(!prop2.isUser());
644 QVERIFY(!prop2.hasStdCppSet());
645 QVERIFY(!prop2.isEnumOrFlag());
646 QCOMPARE(prop2.index(), 0);
648 // Perform index-based lookup again.
649 QCOMPARE(builder.indexOfProperty("foo"), -1);
650 QCOMPARE(builder.indexOfProperty("bar"), 0);
651 QCOMPARE(builder.indexOfProperty("baz"), -1);
653 // Check for side-effects between the flags on prop2.
654 // Setting a flag to true shouldn't set any of the others to true.
655 // This checks for cut-and-paste bugs in the implementation where
656 // the flag code was pasted but the flag name was not changed.
657 #define CLEAR_FLAGS() \
659 prop2.setReadable(false); \
660 prop2.setWritable(false); \
661 prop2.setResettable(false); \
662 prop2.setDesignable(false); \
663 prop2.setScriptable(false); \
664 prop2.setStored(false); \
665 prop2.setEditable(false); \
666 prop2.setUser(false); \
667 prop2.setStdCppSet(false); \
668 prop2.setEnumOrFlag(false); \
670 #define COUNT_FLAGS() \
671 ((prop2.isReadable() ? 1 : 0) + \
672 (prop2.isWritable() ? 1 : 0) + \
673 (prop2.isResettable() ? 1 : 0) + \
674 (prop2.isDesignable() ? 1 : 0) + \
675 (prop2.isScriptable() ? 1 : 0) + \
676 (prop2.isStored() ? 1 : 0) + \
677 (prop2.isEditable() ? 1 : 0) + \
678 (prop2.isUser() ? 1 : 0) + \
679 (prop2.hasStdCppSet() ? 1 : 0) + \
680 (prop2.isEnumOrFlag() ? 1 : 0))
681 #define CHECK_FLAG(setFunc,isFunc) \
684 QCOMPARE(COUNT_FLAGS(), 0); \
685 prop2.setFunc(true); \
686 QVERIFY(prop2.isFunc()); \
687 QCOMPARE(COUNT_FLAGS(), 1); \
689 CHECK_FLAG(setReadable, isReadable);
690 CHECK_FLAG(setWritable, isWritable);
691 CHECK_FLAG(setResettable, isResettable);
692 CHECK_FLAG(setDesignable, isDesignable);
693 CHECK_FLAG(setScriptable, isScriptable);
694 CHECK_FLAG(setStored, isStored);
695 CHECK_FLAG(setEditable, isEditable);
696 CHECK_FLAG(setUser, isUser);
697 CHECK_FLAG(setStdCppSet, hasStdCppSet);
698 CHECK_FLAG(setEnumOrFlag, isEnumOrFlag);
700 // Check that nothing else changed.
701 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Properties));
703 // Add property from prototype
704 QMetaProperty prototype = SomethingOfEverything::staticMetaObject.property(1);
705 QVERIFY(prototype.name() == QByteArray("prop"));
706 QMetaPropertyBuilder prototypeProp = builder.addProperty(prototype);
707 QCOMPARE(prototypeProp.name(), QByteArray("prop"));
708 QVERIFY(prototypeProp.hasNotifySignal());
709 QCOMPARE(prototypeProp.notifySignal().signature(), QByteArray("propChanged(QString)"));
710 QCOMPARE(builder.methodCount(), 1);
711 QCOMPARE(builder.method(0).signature(), QByteArray("propChanged(QString)"));
714 void tst_QMetaObjectBuilder::notifySignal()
716 QMetaObjectBuilder builder;
718 QMetaPropertyBuilder prop = builder.addProperty("foo", "const QString &");
719 builder.addSlot("setFoo(QString)");
720 QMetaMethodBuilder notify = builder.addSignal("fooChanged(QString)");
722 QVERIFY(!prop.hasNotifySignal());
723 QCOMPARE(prop.notifySignal().index(), 0);
725 prop.setNotifySignal(notify);
726 QVERIFY(prop.hasNotifySignal());
727 QCOMPARE(prop.notifySignal().index(), 1);
729 prop.setNotifySignal(QMetaMethodBuilder());
730 QVERIFY(!prop.hasNotifySignal());
731 QCOMPARE(prop.notifySignal().index(), 0);
733 prop.setNotifySignal(notify);
734 prop.removeNotifySignal();
735 QVERIFY(!prop.hasNotifySignal());
736 QCOMPARE(prop.notifySignal().index(), 0);
738 QCOMPARE(builder.methodCount(), 2);
739 QCOMPARE(builder.propertyCount(), 1);
741 // Check that nothing else changed except methods and properties.
742 QVERIFY(checkForSideEffects
743 (builder, QMetaObjectBuilder::Methods | QMetaObjectBuilder::Properties));
746 void tst_QMetaObjectBuilder::enumerator()
748 QMetaObjectBuilder builder;
750 // Add an enumerator and check its attributes.
751 QMetaEnumBuilder enum1 = builder.addEnumerator("foo");
752 QCOMPARE(enum1.name(), QByteArray("foo"));
753 QVERIFY(!enum1.isFlag());
754 QCOMPARE(enum1.keyCount(), 0);
755 QCOMPARE(enum1.index(), 0);
756 QCOMPARE(builder.enumeratorCount(), 1);
758 // Add another enumerator and check again.
759 QMetaEnumBuilder enum2 = builder.addEnumerator("bar");
760 QCOMPARE(enum2.name(), QByteArray("bar"));
761 QVERIFY(!enum2.isFlag());
762 QCOMPARE(enum2.keyCount(), 0);
763 QCOMPARE(enum2.index(), 1);
764 QCOMPARE(builder.enumeratorCount(), 2);
766 // Perform index-based lookup.
767 QCOMPARE(builder.indexOfEnumerator("foo"), 0);
768 QCOMPARE(builder.indexOfEnumerator("bar"), 1);
769 QCOMPARE(builder.indexOfEnumerator("baz"), -1);
770 QCOMPARE(builder.enumerator(1).name(), QByteArray("bar"));
771 QCOMPARE(builder.enumerator(9).name(), QByteArray());
773 // Modify the attributes on enum1.
774 enum1.setIsFlag(true);
775 QCOMPARE(enum1.addKey("ABC", 0), 0);
776 QCOMPARE(enum1.addKey("DEF", 1), 1);
777 QCOMPARE(enum1.addKey("GHI", -1), 2);
779 // Check that enum1 is changed, but enum2 is not.
780 QCOMPARE(enum1.name(), QByteArray("foo"));
781 QVERIFY(enum1.isFlag());
782 QCOMPARE(enum1.keyCount(), 3);
783 QCOMPARE(enum1.index(), 0);
784 QCOMPARE(enum1.key(0), QByteArray("ABC"));
785 QCOMPARE(enum1.key(1), QByteArray("DEF"));
786 QCOMPARE(enum1.key(2), QByteArray("GHI"));
787 QCOMPARE(enum1.key(3), QByteArray());
788 QCOMPARE(enum1.value(0), 0);
789 QCOMPARE(enum1.value(1), 1);
790 QCOMPARE(enum1.value(2), -1);
791 QCOMPARE(enum2.name(), QByteArray("bar"));
792 QVERIFY(!enum2.isFlag());
793 QCOMPARE(enum2.keyCount(), 0);
794 QCOMPARE(enum2.index(), 1);
796 // Modify the attributes on enum2.
797 enum2.setIsFlag(true);
798 QCOMPARE(enum2.addKey("XYZ", 10), 0);
799 QCOMPARE(enum2.addKey("UVW", 19), 1);
801 // This time check that only method2 changed.
802 QCOMPARE(enum1.name(), QByteArray("foo"));
803 QVERIFY(enum1.isFlag());
804 QCOMPARE(enum1.keyCount(), 3);
805 QCOMPARE(enum1.index(), 0);
806 QCOMPARE(enum1.key(0), QByteArray("ABC"));
807 QCOMPARE(enum1.key(1), QByteArray("DEF"));
808 QCOMPARE(enum1.key(2), QByteArray("GHI"));
809 QCOMPARE(enum1.key(3), QByteArray());
810 QCOMPARE(enum1.value(0), 0);
811 QCOMPARE(enum1.value(1), 1);
812 QCOMPARE(enum1.value(2), -1);
813 QCOMPARE(enum2.name(), QByteArray("bar"));
814 QVERIFY(enum2.isFlag());
815 QCOMPARE(enum2.keyCount(), 2);
816 QCOMPARE(enum2.index(), 1);
817 QCOMPARE(enum2.key(0), QByteArray("XYZ"));
818 QCOMPARE(enum2.key(1), QByteArray("UVW"));
819 QCOMPARE(enum2.key(2), QByteArray());
820 QCOMPARE(enum2.value(0), 10);
821 QCOMPARE(enum2.value(1), 19);
825 QCOMPARE(enum1.name(), QByteArray("foo"));
826 QVERIFY(enum1.isFlag());
827 QCOMPARE(enum1.keyCount(), 2);
828 QCOMPARE(enum1.index(), 0);
829 QCOMPARE(enum1.key(0), QByteArray("ABC"));
830 QCOMPARE(enum1.key(1), QByteArray("DEF"));
831 QCOMPARE(enum1.key(2), QByteArray());
832 QCOMPARE(enum1.value(0), 0);
833 QCOMPARE(enum1.value(1), 1);
834 QCOMPARE(enum1.value(2), -1);
835 QCOMPARE(enum2.name(), QByteArray("bar"));
836 QVERIFY(enum2.isFlag());
837 QCOMPARE(enum2.keyCount(), 2);
838 QCOMPARE(enum2.index(), 1);
839 QCOMPARE(enum2.key(0), QByteArray("XYZ"));
840 QCOMPARE(enum2.key(1), QByteArray("UVW"));
841 QCOMPARE(enum2.key(2), QByteArray());
842 QCOMPARE(enum2.value(0), 10);
843 QCOMPARE(enum2.value(1), 19);
845 // Remove enum1 and check that enum2 becomes index 0.
846 builder.removeEnumerator(0);
847 QCOMPARE(builder.enumeratorCount(), 1);
848 enum2 = builder.enumerator(0);
849 QCOMPARE(enum2.name(), QByteArray("bar"));
850 QVERIFY(enum2.isFlag());
851 QCOMPARE(enum2.keyCount(), 2);
852 QCOMPARE(enum2.index(), 0);
853 QCOMPARE(enum2.key(0), QByteArray("XYZ"));
854 QCOMPARE(enum2.key(1), QByteArray("UVW"));
855 QCOMPARE(enum2.key(2), QByteArray());
856 QCOMPARE(enum2.value(0), 10);
857 QCOMPARE(enum2.value(1), 19);
859 // Perform index-based lookup again.
860 QCOMPARE(builder.indexOfEnumerator("foo"), -1);
861 QCOMPARE(builder.indexOfEnumerator("bar"), 0);
862 QCOMPARE(builder.indexOfEnumerator("baz"), -1);
864 // Check that nothing else changed.
865 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Enumerators));
868 void tst_QMetaObjectBuilder::classInfo()
870 QMetaObjectBuilder builder;
872 // Add two items of class information and check their attributes.
873 QCOMPARE(builder.addClassInfo("foo", "value1"), 0);
874 QCOMPARE(builder.addClassInfo("bar", "value2"), 1);
875 QCOMPARE(builder.classInfoName(0), QByteArray("foo"));
876 QCOMPARE(builder.classInfoValue(0), QByteArray("value1"));
877 QCOMPARE(builder.classInfoName(1), QByteArray("bar"));
878 QCOMPARE(builder.classInfoValue(1), QByteArray("value2"));
879 QCOMPARE(builder.classInfoName(9), QByteArray());
880 QCOMPARE(builder.classInfoValue(9), QByteArray());
881 QCOMPARE(builder.classInfoCount(), 2);
883 // Perform index-based lookup.
884 QCOMPARE(builder.indexOfClassInfo("foo"), 0);
885 QCOMPARE(builder.indexOfClassInfo("bar"), 1);
886 QCOMPARE(builder.indexOfClassInfo("baz"), -1);
888 // Remove the first one and check again.
889 builder.removeClassInfo(0);
890 QCOMPARE(builder.classInfoName(0), QByteArray("bar"));
891 QCOMPARE(builder.classInfoValue(0), QByteArray("value2"));
892 QCOMPARE(builder.classInfoCount(), 1);
894 // Perform index-based lookup again.
895 QCOMPARE(builder.indexOfClassInfo("foo"), -1);
896 QCOMPARE(builder.indexOfClassInfo("bar"), 0);
897 QCOMPARE(builder.indexOfClassInfo("baz"), -1);
899 // Check that nothing else changed.
900 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::ClassInfos));
903 void tst_QMetaObjectBuilder::relatedMetaObject()
905 QMetaObjectBuilder builder;
907 // Add two related meta objects and check their attributes.
908 QCOMPARE(builder.addRelatedMetaObject(&QObject::staticMetaObject), 0);
909 QCOMPARE(builder.addRelatedMetaObject(&staticMetaObject), 1);
910 QVERIFY(builder.relatedMetaObject(0) == &QObject::staticMetaObject);
911 QVERIFY(builder.relatedMetaObject(1) == &staticMetaObject);
912 QCOMPARE(builder.relatedMetaObjectCount(), 2);
914 // Remove the first one and check again.
915 builder.removeRelatedMetaObject(0);
916 QVERIFY(builder.relatedMetaObject(0) == &staticMetaObject);
917 QCOMPARE(builder.relatedMetaObjectCount(), 1);
919 // Check that nothing else changed.
920 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::RelatedMetaObjects));
923 static void smetacall(QObject *, QMetaObject::Call, int, void **)
928 void tst_QMetaObjectBuilder::staticMetacall()
930 QMetaObjectBuilder builder;
931 QVERIFY(!builder.staticMetacallFunction());
932 builder.setStaticMetacallFunction(smetacall);
933 QVERIFY(builder.staticMetacallFunction() == smetacall);
934 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::StaticMetacall));
937 // Copy the entire contents of a static QMetaObject and then check
938 // that QMetaObjectBuilder will produce an exact copy as output.
939 void tst_QMetaObjectBuilder::copyMetaObject()
941 QMetaObjectBuilder builder(&QObject::staticMetaObject);
942 QMetaObject *meta = builder.toMetaObject();
943 QVERIFY(sameMetaObject(meta, &QObject::staticMetaObject));
946 QMetaObjectBuilder builder2(&staticMetaObject);
947 meta = builder2.toMetaObject();
948 QVERIFY(sameMetaObject(meta, &staticMetaObject));
951 QMetaObjectBuilder builder3(&SomethingOfEverything::staticMetaObject);
952 meta = builder3.toMetaObject();
953 QVERIFY(sameMetaObject(meta, &SomethingOfEverything::staticMetaObject));
957 // Serialize and deserialize a meta object and check that
958 // it round-trips to the exact same value.
959 void tst_QMetaObjectBuilder::serialize()
961 // Full QMetaObjectBuilder
963 QMetaObjectBuilder builder(&SomethingOfEverything::staticMetaObject);
964 QMetaObject *meta = builder.toMetaObject();
967 QDataStream stream(&data, QIODevice::WriteOnly | QIODevice::Append);
968 builder.serialize(stream);
970 QMetaObjectBuilder builder2;
971 QDataStream stream2(data);
972 QMap<QByteArray, const QMetaObject *> references;
973 references.insert(QByteArray("QLocale"), &QLocale::staticMetaObject);
974 builder2.deserialize(stream2, references);
975 builder2.setStaticMetacallFunction(builder.staticMetacallFunction());
976 QMetaObject *meta2 = builder2.toMetaObject();
978 QVERIFY(sameMetaObject(meta, meta2));
983 // Partial QMetaObjectBuilder
985 QMetaObjectBuilder builder;
986 builder.setClassName("Test");
987 builder.addProperty("foo", "int");
990 QDataStream stream(&data, QIODevice::WriteOnly | QIODevice::Append);
991 builder.serialize(stream);
993 QMetaObjectBuilder builder2;
994 QDataStream stream2(data);
995 builder2.deserialize(stream2, QMap<QByteArray, const QMetaObject *>());
997 QCOMPARE(builder.superClass(), builder2.superClass());
998 QCOMPARE(builder.className(), builder2.className());
999 QCOMPARE(builder.propertyCount(), builder2.propertyCount());
1000 QCOMPARE(builder.property(0).name(), builder2.property(0).name());
1001 QCOMPARE(builder.property(0).type(), builder2.property(0).type());
1005 // Check that removing a method updates notify signals appropriately
1006 void tst_QMetaObjectBuilder::removeNotifySignal()
1008 QMetaObjectBuilder builder;
1010 QMetaMethodBuilder method1 = builder.addSignal("foo(const QString&, int)");
1011 QMetaMethodBuilder method2 = builder.addSignal("bar(QString)");
1014 QMetaPropertyBuilder prop = builder.addProperty("prop", "const QString &");
1015 prop.setNotifySignal(method2);
1016 QVERIFY(prop.hasNotifySignal());
1017 QCOMPARE(prop.notifySignal().index(), 1);
1019 // Remove non-notify signal
1020 builder.removeMethod(0);
1021 QVERIFY(prop.hasNotifySignal());
1022 QCOMPARE(prop.notifySignal().index(), 0);
1024 // Remove notify signal
1025 builder.removeMethod(0);
1026 QVERIFY(!prop.hasNotifySignal());
1029 // Check that the only changes to a "builder" relative to the default
1030 // state is specified by "members".
1031 bool tst_QMetaObjectBuilder::checkForSideEffects
1032 (const QMetaObjectBuilder& builder,
1033 QMetaObjectBuilder::AddMembers members)
1035 if ((members & QMetaObjectBuilder::ClassName) == 0) {
1036 if (!builder.className().isEmpty())
1040 if ((members & QMetaObjectBuilder::SuperClass) == 0) {
1041 if (builder.superClass() != &QObject::staticMetaObject)
1045 if ((members & QMetaObjectBuilder::Methods) == 0) {
1046 if (builder.methodCount() != 0)
1050 if ((members & QMetaObjectBuilder::Constructors) == 0) {
1051 if (builder.constructorCount() != 0)
1055 if ((members & QMetaObjectBuilder::Properties) == 0) {
1056 if (builder.propertyCount() != 0)
1060 if ((members & QMetaObjectBuilder::Enumerators) == 0) {
1061 if (builder.enumeratorCount() != 0)
1065 if ((members & QMetaObjectBuilder::ClassInfos) == 0) {
1066 if (builder.classInfoCount() != 0)
1070 if ((members & QMetaObjectBuilder::RelatedMetaObjects) == 0) {
1071 if (builder.relatedMetaObjectCount() != 0)
1075 if ((members & QMetaObjectBuilder::StaticMetacall) == 0) {
1076 if (builder.staticMetacallFunction() != 0)
1083 static bool sameMethod(const QMetaMethod& method1, const QMetaMethod& method2)
1085 if (QByteArray(method1.signature()) != QByteArray(method2.signature()))
1088 if (QByteArray(method1.typeName()) != QByteArray(method2.typeName()))
1091 if (method1.parameterNames() != method2.parameterNames())
1094 if (QByteArray(method1.tag()) != QByteArray(method2.tag()))
1097 if (method1.access() != method2.access())
1100 if (method1.methodType() != method2.methodType())
1103 if (method1.attributes() != method2.attributes())
1109 static bool sameProperty(const QMetaProperty& prop1, const QMetaProperty& prop2)
1111 if (QByteArray(prop1.name()) != QByteArray(prop2.name()))
1114 if (QByteArray(prop1.typeName()) != QByteArray(prop2.typeName()))
1117 if (prop1.isReadable() != prop2.isReadable() ||
1118 prop1.isWritable() != prop2.isWritable() ||
1119 prop1.isResettable() != prop2.isResettable() ||
1120 prop1.isDesignable() != prop2.isDesignable() ||
1121 prop1.isScriptable() != prop2.isScriptable() ||
1122 prop1.isStored() != prop2.isStored() ||
1123 prop1.isEditable() != prop2.isEditable() ||
1124 prop1.isUser() != prop2.isUser() ||
1125 prop1.isFlagType() != prop2.isFlagType() ||
1126 prop1.isEnumType() != prop2.isEnumType() ||
1127 prop1.hasNotifySignal() != prop2.hasNotifySignal() ||
1128 prop1.hasStdCppSet() != prop2.hasStdCppSet())
1131 if (prop1.hasNotifySignal()) {
1132 if (prop1.notifySignalIndex() != prop2.notifySignalIndex())
1139 static bool sameEnumerator(const QMetaEnum& enum1, const QMetaEnum& enum2)
1141 if (QByteArray(enum1.name()) != QByteArray(enum2.name()))
1144 if (enum1.isFlag() != enum2.isFlag())
1147 if (enum1.keyCount() != enum2.keyCount())
1150 for (int index = 0; index < enum1.keyCount(); ++index) {
1151 if (QByteArray(enum1.key(index)) != QByteArray(enum2.key(index)))
1153 if (enum1.value(index) != enum2.value(index))
1157 if (QByteArray(enum1.scope()) != QByteArray(enum2.scope()))
1163 // Determine if two meta objects are identical.
1164 bool tst_QMetaObjectBuilder::sameMetaObject
1165 (const QMetaObject *meta1, const QMetaObject *meta2)
1169 if (strcmp(meta1->className(), meta2->className()) != 0)
1172 if (meta1->superClass() != meta2->superClass())
1175 if (meta1->constructorCount() != meta2->constructorCount() ||
1176 meta1->methodCount() != meta2->methodCount() ||
1177 meta1->enumeratorCount() != meta2->enumeratorCount() ||
1178 meta1->propertyCount() != meta2->propertyCount() ||
1179 meta1->classInfoCount() != meta2->classInfoCount())
1182 for (index = 0; index < meta1->constructorCount(); ++index) {
1183 if (!sameMethod(meta1->constructor(index), meta2->constructor(index)))
1187 for (index = 0; index < meta1->methodCount(); ++index) {
1188 if (!sameMethod(meta1->method(index), meta2->method(index)))
1192 for (index = 0; index < meta1->propertyCount(); ++index) {
1193 if (!sameProperty(meta1->property(index), meta2->property(index)))
1197 for (index = 0; index < meta1->enumeratorCount(); ++index) {
1198 if (!sameEnumerator(meta1->enumerator(index), meta2->enumerator(index)))
1202 for (index = 0; index < meta1->classInfoCount(); ++index) {
1203 if (QByteArray(meta1->classInfo(index).name()) !=
1204 QByteArray(meta2->classInfo(index).name()))
1206 if (QByteArray(meta1->classInfo(index).value()) !=
1207 QByteArray(meta2->classInfo(index).value()))
1211 const QMetaObject **objects1 = 0;
1212 const QMetaObject **objects2 = 0;
1213 if (meta1->d.data[0] == meta2->d.data[0] && meta1->d.data[0] >= 2) {
1214 QMetaObjectExtraData *extra1 = (QMetaObjectExtraData *)(meta1->d.extradata);
1215 QMetaObjectExtraData *extra2 = (QMetaObjectExtraData *)(meta2->d.extradata);
1216 if (extra1 && !extra2)
1218 if (extra2 && !extra1)
1220 if (extra1 && extra2) {
1221 if (extra1->static_metacall != extra2->static_metacall)
1223 objects1 = extra1->objects;
1224 objects2 = extra1->objects;
1226 } else if (meta1->d.data[0] == meta2->d.data[0] && meta1->d.data[0] == 1) {
1227 objects1 = (const QMetaObject **)(meta1->d.extradata);
1228 objects2 = (const QMetaObject **)(meta2->d.extradata);
1230 if (objects1 && !objects2)
1232 if (objects2 && !objects1)
1234 if (objects1 && objects2) {
1235 while (*objects1 != 0 && *objects2 != 0) {
1236 if (*objects1 != *objects2)
1246 QTEST_MAIN(tst_QMetaObjectBuilder)
1248 #include "tst_qmetaobjectbuilder.moc"