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 void mocVersionCheck();
63 void relatedMetaObject();
64 void staticMetacall();
65 void copyMetaObject();
67 void removeNotifySignal();
70 static bool checkForSideEffects
71 (const QMetaObjectBuilder& builder,
72 QMetaObjectBuilder::AddMembers members);
73 static bool sameMetaObject
74 (const QMetaObject *meta1, const QMetaObject *meta2);
77 // Dummy class that has something of every type of thing moc can generate.
78 class SomethingOfEverything : public QObject
81 Q_CLASSINFO("ci_foo", "ABC")
82 Q_CLASSINFO("ci_bar", "DEF")
83 Q_PROPERTY(QString prop READ prop WRITE setProp NOTIFY propChanged)
84 Q_PROPERTY(QString prop2 READ prop WRITE setProp)
85 Q_PROPERTY(SomethingEnum eprop READ eprop)
86 Q_PROPERTY(SomethingFlagEnum fprop READ fprop)
87 Q_PROPERTY(QLocale::Language language READ language)
88 Q_ENUMS(SomethingEnum)
89 Q_FLAGS(SomethingFlagEnum)
91 Q_INVOKABLE SomethingOfEverything() {}
92 ~SomethingOfEverything() {}
100 enum SomethingFlagEnum
106 Q_INVOKABLE Q_SCRIPTABLE void method1() {}
108 QString prop() const { return QString(); }
109 void setProp(const QString& v) { Q_UNUSED(v); }
111 SomethingOfEverything::SomethingEnum eprop() const { return GHI; }
112 SomethingOfEverything::SomethingFlagEnum fprop() const { return XYZ; }
113 QLocale::Language language() const { return QLocale::English; }
116 void slot1(const QString&) {}
117 void slot2(int, const QString&) {}
123 Q_SCRIPTABLE void slot4(int) {}
124 void slot5(int a, const QString& b) { Q_UNUSED(a); Q_UNUSED(b); }
128 void sig2(int x, const QString& y);
129 void propChanged(const QString&);
132 void tst_QMetaObjectBuilder::mocVersionCheck()
134 // This test will fail when the moc version number is changed.
135 // It is intended as a reminder to also update QMetaObjectBuilder
136 // whenenver moc changes. Once QMetaObjectBuilder has been
137 // updated, this test can be changed to check for the next version.
138 int version = int(QObject::staticMetaObject.d.data[0]);
139 QVERIFY(version == 4 || version == 5 || version == 6);
140 version = int(staticMetaObject.d.data[0]);
141 QVERIFY(version == 4 || version == 5 || version == 6);
144 void tst_QMetaObjectBuilder::create()
146 QMetaObjectBuilder builder;
147 QVERIFY(builder.className().isEmpty());
148 QVERIFY(builder.superClass() == &QObject::staticMetaObject);
149 QCOMPARE(builder.methodCount(), 0);
150 QCOMPARE(builder.constructorCount(), 0);
151 QCOMPARE(builder.propertyCount(), 0);
152 QCOMPARE(builder.enumeratorCount(), 0);
153 QCOMPARE(builder.classInfoCount(), 0);
154 QCOMPARE(builder.relatedMetaObjectCount(), 0);
155 QVERIFY(builder.staticMetacallFunction() == 0);
158 void tst_QMetaObjectBuilder::className()
160 QMetaObjectBuilder builder;
162 // Change the class name.
163 builder.setClassName("Foo");
164 QCOMPARE(builder.className(), QByteArray("Foo"));
167 builder.setClassName("Bar");
168 QCOMPARE(builder.className(), QByteArray("Bar"));
170 // Clone the class name off a static QMetaObject.
171 builder.addMetaObject(&QObject::staticMetaObject, QMetaObjectBuilder::ClassName);
172 QCOMPARE(builder.className(), QByteArray("QObject"));
174 // Check that nothing else changed.
175 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::ClassName));
178 void tst_QMetaObjectBuilder::superClass()
180 QMetaObjectBuilder builder;
182 // Change the super class.
183 builder.setSuperClass(&QObject::staticMetaObject);
184 QVERIFY(builder.superClass() == &QObject::staticMetaObject);
187 builder.setSuperClass(&staticMetaObject);
188 QVERIFY(builder.superClass() == &staticMetaObject);
190 // Clone the super class off a static QMetaObject.
191 builder.addMetaObject(&QObject::staticMetaObject, QMetaObjectBuilder::SuperClass);
192 QVERIFY(builder.superClass() == 0);
193 builder.addMetaObject(&staticMetaObject, QMetaObjectBuilder::SuperClass);
194 QVERIFY(builder.superClass() == staticMetaObject.superClass());
196 // Check that nothing else changed.
197 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::SuperClass));
200 void tst_QMetaObjectBuilder::flags()
202 QMetaObjectBuilder builder;
205 QVERIFY(builder.flags() == 0);
208 builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
209 QVERIFY(builder.flags() == QMetaObjectBuilder::DynamicMetaObject);
212 void tst_QMetaObjectBuilder::method()
214 QMetaObjectBuilder builder;
217 QMetaMethodBuilder nullMethod;
218 QCOMPARE(nullMethod.signature(), QByteArray());
219 QVERIFY(nullMethod.methodType() == QMetaMethod::Method);
220 QVERIFY(nullMethod.returnType().isEmpty());
221 QVERIFY(nullMethod.parameterNames().isEmpty());
222 QVERIFY(nullMethod.tag().isEmpty());
223 QVERIFY(nullMethod.access() == QMetaMethod::Public);
224 QCOMPARE(nullMethod.attributes(), 0);
225 QCOMPARE(nullMethod.index(), 0);
227 // Add a method and check its attributes.
228 QMetaMethodBuilder method1 = builder.addMethod("foo(const QString&, int)");
229 QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
230 QVERIFY(method1.methodType() == QMetaMethod::Method);
231 QVERIFY(method1.returnType().isEmpty());
232 QVERIFY(method1.parameterNames().isEmpty());
233 QVERIFY(method1.tag().isEmpty());
234 QVERIFY(method1.access() == QMetaMethod::Public);
235 QCOMPARE(method1.attributes(), 0);
236 QCOMPARE(method1.index(), 0);
237 QCOMPARE(builder.methodCount(), 1);
239 // Add another method and check again.
240 QMetaMethodBuilder method2 = builder.addMethod("bar(QString)", "int");
241 QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
242 QVERIFY(method2.methodType() == QMetaMethod::Method);
243 QCOMPARE(method2.returnType(), QByteArray("int"));
244 QVERIFY(method2.parameterNames().isEmpty());
245 QVERIFY(method2.tag().isEmpty());
246 QVERIFY(method2.access() == QMetaMethod::Public);
247 QCOMPARE(method2.attributes(), 0);
248 QCOMPARE(method2.index(), 1);
249 QCOMPARE(builder.methodCount(), 2);
251 // Perform index-based lookup.
252 QCOMPARE(builder.indexOfMethod("foo(const QString&, int)"), 0);
253 QCOMPARE(builder.indexOfMethod("bar(QString)"), 1);
254 QCOMPARE(builder.indexOfMethod("baz()"), -1);
256 // Modify the attributes on method1.
257 method1.setReturnType("int");
258 method1.setParameterNames(QList<QByteArray>() << "a" << "b");
259 method1.setTag("tag");
260 method1.setAccess(QMetaMethod::Private);
261 method1.setAttributes(42);
263 // Check that method1 is changed, but method2 is not.
264 QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
265 QVERIFY(method1.methodType() == QMetaMethod::Method);
266 QCOMPARE(method1.returnType(), QByteArray("int"));
267 QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
268 QCOMPARE(method1.tag(), QByteArray("tag"));
269 QVERIFY(method1.access() == QMetaMethod::Private);
270 QCOMPARE(method1.attributes(), 42);
271 QCOMPARE(method1.index(), 0);
272 QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
273 QVERIFY(method2.methodType() == QMetaMethod::Method);
274 QCOMPARE(method2.returnType(), QByteArray("int"));
275 QVERIFY(method2.parameterNames().isEmpty());
276 QVERIFY(method2.tag().isEmpty());
277 QVERIFY(method2.access() == QMetaMethod::Public);
278 QCOMPARE(method2.attributes(), 0);
279 QCOMPARE(method2.index(), 1);
280 QCOMPARE(builder.methodCount(), 2);
282 // Modify the attributes on method2.
283 method2.setReturnType("QString");
284 method2.setParameterNames(QList<QByteArray>() << "c");
285 method2.setTag("Q_FOO");
286 method2.setAccess(QMetaMethod::Protected);
287 method2.setAttributes(24);
289 // This time check that only method2 changed.
290 QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
291 QVERIFY(method1.methodType() == QMetaMethod::Method);
292 QCOMPARE(method1.returnType(), QByteArray("int"));
293 QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
294 QCOMPARE(method1.tag(), QByteArray("tag"));
295 QVERIFY(method1.access() == QMetaMethod::Private);
296 QCOMPARE(method1.attributes(), 42);
297 QCOMPARE(method1.index(), 0);
298 QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
299 QVERIFY(method2.methodType() == QMetaMethod::Method);
300 QCOMPARE(method2.returnType(), QByteArray("QString"));
301 QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
302 QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
303 QVERIFY(method2.access() == QMetaMethod::Protected);
304 QCOMPARE(method2.attributes(), 24);
305 QCOMPARE(method2.index(), 1);
306 QCOMPARE(builder.methodCount(), 2);
308 // Remove method1 and check that method2 becomes index 0.
309 builder.removeMethod(0);
310 QCOMPARE(builder.methodCount(), 1);
311 method2 = builder.method(0);
312 QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
313 QVERIFY(method2.methodType() == QMetaMethod::Method);
314 QCOMPARE(method2.returnType(), QByteArray("QString"));
315 QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
316 QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
317 QVERIFY(method2.access() == QMetaMethod::Protected);
318 QCOMPARE(method2.attributes(), 24);
319 QCOMPARE(method2.index(), 0);
321 // Perform index-based lookup again.
322 QCOMPARE(builder.indexOfMethod("foo(const QString&, int)"), -1);
323 QCOMPARE(builder.indexOfMethod("bar(QString)"), 0);
324 QCOMPARE(builder.indexOfMethod("baz()"), -1);
325 QCOMPARE(builder.method(0).signature(), QByteArray("bar(QString)"));
326 QCOMPARE(builder.method(9).signature(), QByteArray());
328 // Check that nothing else changed.
329 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Methods));
332 void tst_QMetaObjectBuilder::slot()
334 QMetaObjectBuilder builder;
336 // Add a slot and check its attributes.
337 QMetaMethodBuilder method1 = builder.addSlot("foo(const QString&, int)");
338 QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
339 QVERIFY(method1.methodType() == QMetaMethod::Slot);
340 QVERIFY(method1.returnType().isEmpty());
341 QVERIFY(method1.parameterNames().isEmpty());
342 QVERIFY(method1.tag().isEmpty());
343 QVERIFY(method1.access() == QMetaMethod::Public);
344 QCOMPARE(method1.attributes(), 0);
345 QCOMPARE(method1.index(), 0);
346 QCOMPARE(builder.methodCount(), 1);
348 // Add another slot and check again.
349 QMetaMethodBuilder method2 = builder.addSlot("bar(QString)");
350 QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
351 QVERIFY(method2.methodType() == QMetaMethod::Slot);
352 QVERIFY(method2.returnType().isEmpty());
353 QVERIFY(method2.parameterNames().isEmpty());
354 QVERIFY(method2.tag().isEmpty());
355 QVERIFY(method2.access() == QMetaMethod::Public);
356 QCOMPARE(method2.attributes(), 0);
357 QCOMPARE(method2.index(), 1);
358 QCOMPARE(builder.methodCount(), 2);
360 // Perform index-based lookup
361 QCOMPARE(builder.indexOfSlot("foo(const QString &, int)"), 0);
362 QCOMPARE(builder.indexOfSlot("bar(QString)"), 1);
363 QCOMPARE(builder.indexOfSlot("baz()"), -1);
365 // Check that nothing else changed.
366 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Methods));
369 void tst_QMetaObjectBuilder::signal()
371 QMetaObjectBuilder builder;
373 // Add a signal and check its attributes.
374 QMetaMethodBuilder method1 = builder.addSignal("foo(const QString&, int)");
375 QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
376 QVERIFY(method1.methodType() == QMetaMethod::Signal);
377 QVERIFY(method1.returnType().isEmpty());
378 QVERIFY(method1.parameterNames().isEmpty());
379 QVERIFY(method1.tag().isEmpty());
380 QVERIFY(method1.access() == QMetaMethod::Protected);
381 QCOMPARE(method1.attributes(), 0);
382 QCOMPARE(method1.index(), 0);
383 QCOMPARE(builder.methodCount(), 1);
385 // Add another signal and check again.
386 QMetaMethodBuilder method2 = builder.addSignal("bar(QString)");
387 QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
388 QVERIFY(method2.methodType() == QMetaMethod::Signal);
389 QVERIFY(method2.returnType().isEmpty());
390 QVERIFY(method2.parameterNames().isEmpty());
391 QVERIFY(method2.tag().isEmpty());
392 QVERIFY(method2.access() == QMetaMethod::Protected);
393 QCOMPARE(method2.attributes(), 0);
394 QCOMPARE(method2.index(), 1);
395 QCOMPARE(builder.methodCount(), 2);
397 // Perform index-based lookup
398 QCOMPARE(builder.indexOfSignal("foo(const QString &, int)"), 0);
399 QCOMPARE(builder.indexOfSignal("bar(QString)"), 1);
400 QCOMPARE(builder.indexOfSignal("baz()"), -1);
402 // Check that nothing else changed.
403 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Methods));
406 void tst_QMetaObjectBuilder::constructor()
408 QMetaObjectBuilder builder;
410 // Add a constructor and check its attributes.
411 QMetaMethodBuilder ctor1 = builder.addConstructor("foo(const QString&, int)");
412 QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
413 QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
414 QVERIFY(ctor1.returnType().isEmpty());
415 QVERIFY(ctor1.parameterNames().isEmpty());
416 QVERIFY(ctor1.tag().isEmpty());
417 QVERIFY(ctor1.access() == QMetaMethod::Public);
418 QCOMPARE(ctor1.attributes(), 0);
419 QCOMPARE(ctor1.index(), 0);
420 QCOMPARE(builder.constructorCount(), 1);
422 // Add another constructor and check again.
423 QMetaMethodBuilder ctor2 = builder.addConstructor("bar(QString)");
424 QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
425 QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
426 QVERIFY(ctor2.returnType().isEmpty());
427 QVERIFY(ctor2.parameterNames().isEmpty());
428 QVERIFY(ctor2.tag().isEmpty());
429 QVERIFY(ctor2.access() == QMetaMethod::Public);
430 QCOMPARE(ctor2.attributes(), 0);
431 QCOMPARE(ctor2.index(), 1);
432 QCOMPARE(builder.constructorCount(), 2);
434 // Perform index-based lookup.
435 QCOMPARE(builder.indexOfConstructor("foo(const QString&, int)"), 0);
436 QCOMPARE(builder.indexOfConstructor("bar(QString)"), 1);
437 QCOMPARE(builder.indexOfConstructor("baz()"), -1);
438 QCOMPARE(builder.constructor(1).signature(), QByteArray("bar(QString)"));
439 QCOMPARE(builder.constructor(9).signature(), QByteArray());
441 // Modify the attributes on ctor1.
442 ctor1.setReturnType("int");
443 ctor1.setParameterNames(QList<QByteArray>() << "a" << "b");
445 ctor1.setAccess(QMetaMethod::Private);
446 ctor1.setAttributes(42);
448 // Check that ctor1 is changed, but ctor2 is not.
449 QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
450 QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
451 QCOMPARE(ctor1.returnType(), QByteArray("int"));
452 QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
453 QCOMPARE(ctor1.tag(), QByteArray("tag"));
454 QVERIFY(ctor1.access() == QMetaMethod::Private);
455 QCOMPARE(ctor1.attributes(), 42);
456 QCOMPARE(ctor1.index(), 0);
457 QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
458 QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
459 QVERIFY(ctor2.returnType().isEmpty());
460 QVERIFY(ctor2.parameterNames().isEmpty());
461 QVERIFY(ctor2.tag().isEmpty());
462 QVERIFY(ctor2.access() == QMetaMethod::Public);
463 QCOMPARE(ctor2.attributes(), 0);
464 QCOMPARE(ctor2.index(), 1);
465 QCOMPARE(builder.constructorCount(), 2);
467 // Modify the attributes on ctor2.
468 ctor2.setReturnType("QString");
469 ctor2.setParameterNames(QList<QByteArray>() << "c");
470 ctor2.setTag("Q_FOO");
471 ctor2.setAccess(QMetaMethod::Protected);
472 ctor2.setAttributes(24);
474 // This time check that only ctor2 changed.
475 QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
476 QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
477 QCOMPARE(ctor1.returnType(), QByteArray("int"));
478 QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
479 QCOMPARE(ctor1.tag(), QByteArray("tag"));
480 QVERIFY(ctor1.access() == QMetaMethod::Private);
481 QCOMPARE(ctor1.attributes(), 42);
482 QCOMPARE(ctor1.index(), 0);
483 QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
484 QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
485 QCOMPARE(ctor2.returnType(), QByteArray("QString"));
486 QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
487 QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
488 QVERIFY(ctor2.access() == QMetaMethod::Protected);
489 QCOMPARE(ctor2.attributes(), 24);
490 QCOMPARE(ctor2.index(), 1);
491 QCOMPARE(builder.constructorCount(), 2);
493 // Remove ctor1 and check that ctor2 becomes index 0.
494 builder.removeConstructor(0);
495 QCOMPARE(builder.constructorCount(), 1);
496 ctor2 = builder.constructor(0);
497 QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
498 QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
499 QCOMPARE(ctor2.returnType(), QByteArray("QString"));
500 QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
501 QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
502 QVERIFY(ctor2.access() == QMetaMethod::Protected);
503 QCOMPARE(ctor2.attributes(), 24);
504 QCOMPARE(ctor2.index(), 0);
506 // Perform index-based lookup again.
507 QCOMPARE(builder.indexOfConstructor("foo(const QString&, int)"), -1);
508 QCOMPARE(builder.indexOfConstructor("bar(QString)"), 0);
509 QCOMPARE(builder.indexOfConstructor("baz()"), -1);
511 // Add constructor from prototype
512 QMetaMethod prototype = SomethingOfEverything::staticMetaObject.constructor(0);
513 QMetaMethodBuilder prototypeConstructor = builder.addMethod(prototype);
514 QCOMPARE(builder.constructorCount(), 2);
516 QCOMPARE(prototypeConstructor.signature(), QByteArray("SomethingOfEverything()"));
517 QVERIFY(prototypeConstructor.methodType() == QMetaMethod::Constructor);
518 QCOMPARE(prototypeConstructor.returnType(), QByteArray());
519 QVERIFY(prototypeConstructor.access() == QMetaMethod::Public);
520 QCOMPARE(prototypeConstructor.index(), 1);
522 // Check that nothing else changed.
523 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Constructors));
526 void tst_QMetaObjectBuilder::property()
528 QMetaObjectBuilder builder;
530 // Null property builder
531 QMetaPropertyBuilder nullProp;
532 QCOMPARE(nullProp.name(), QByteArray());
533 QCOMPARE(nullProp.type(), QByteArray());
534 QVERIFY(!nullProp.hasNotifySignal());
535 QVERIFY(!nullProp.isReadable());
536 QVERIFY(!nullProp.isWritable());
537 QVERIFY(!nullProp.isResettable());
538 QVERIFY(!nullProp.isDesignable());
539 QVERIFY(!nullProp.isScriptable());
540 QVERIFY(!nullProp.isStored());
541 QVERIFY(!nullProp.isEditable());
542 QVERIFY(!nullProp.isUser());
543 QVERIFY(!nullProp.hasStdCppSet());
544 QVERIFY(!nullProp.isEnumOrFlag());
545 QVERIFY(!nullProp.isConstant());
546 QVERIFY(!nullProp.isFinal());
547 QCOMPARE(nullProp.index(), 0);
549 // Add a property and check its attributes.
550 QMetaPropertyBuilder prop1 = builder.addProperty("foo", "const QString &");
551 QCOMPARE(prop1.name(), QByteArray("foo"));
552 QCOMPARE(prop1.type(), QByteArray("QString"));
553 QVERIFY(!prop1.hasNotifySignal());
554 QVERIFY(prop1.isReadable());
555 QVERIFY(prop1.isWritable());
556 QVERIFY(!prop1.isResettable());
557 QVERIFY(!prop1.isDesignable());
558 QVERIFY(prop1.isScriptable());
559 QVERIFY(!prop1.isStored());
560 QVERIFY(!prop1.isEditable());
561 QVERIFY(!prop1.isUser());
562 QVERIFY(!prop1.hasStdCppSet());
563 QVERIFY(!prop1.isEnumOrFlag());
564 QVERIFY(!prop1.isConstant());
565 QVERIFY(!prop1.isFinal());
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 QVERIFY(!prop2.isConstant());
585 QVERIFY(!prop2.isFinal());
586 QCOMPARE(prop2.index(), 1);
587 QCOMPARE(builder.propertyCount(), 2);
589 // Perform index-based lookup.
590 QCOMPARE(builder.indexOfProperty("foo"), 0);
591 QCOMPARE(builder.indexOfProperty("bar"), 1);
592 QCOMPARE(builder.indexOfProperty("baz"), -1);
593 QCOMPARE(builder.property(1).name(), QByteArray("bar"));
594 QCOMPARE(builder.property(9).name(), QByteArray());
596 // Modify the attributes on prop1.
597 prop1.setReadable(false);
598 prop1.setWritable(false);
599 prop1.setResettable(true);
600 prop1.setDesignable(true);
601 prop1.setScriptable(false);
602 prop1.setStored(true);
603 prop1.setEditable(true);
605 prop1.setStdCppSet(true);
606 prop1.setEnumOrFlag(true);
607 prop1.setConstant(true);
608 prop1.setFinal(true);
610 // Check that prop1 is changed, but prop2 is not.
611 QCOMPARE(prop1.name(), QByteArray("foo"));
612 QCOMPARE(prop1.type(), QByteArray("QString"));
613 QVERIFY(!prop1.isReadable());
614 QVERIFY(!prop1.isWritable());
615 QVERIFY(prop1.isResettable());
616 QVERIFY(prop1.isDesignable());
617 QVERIFY(!prop1.isScriptable());
618 QVERIFY(prop1.isStored());
619 QVERIFY(prop1.isEditable());
620 QVERIFY(prop1.isUser());
621 QVERIFY(prop1.hasStdCppSet());
622 QVERIFY(prop1.isEnumOrFlag());
623 QVERIFY(prop1.isConstant());
624 QVERIFY(prop1.isFinal());
625 QVERIFY(prop2.isReadable());
626 QVERIFY(prop2.isWritable());
627 QCOMPARE(prop2.name(), QByteArray("bar"));
628 QCOMPARE(prop2.type(), QByteArray("int"));
629 QVERIFY(!prop2.isResettable());
630 QVERIFY(!prop2.isDesignable());
631 QVERIFY(prop2.isScriptable());
632 QVERIFY(!prop2.isStored());
633 QVERIFY(!prop2.isEditable());
634 QVERIFY(!prop2.isUser());
635 QVERIFY(!prop2.hasStdCppSet());
636 QVERIFY(!prop2.isEnumOrFlag());
637 QVERIFY(!prop2.isConstant());
638 QVERIFY(!prop2.isFinal());
640 // Remove prop1 and check that prop2 becomes index 0.
641 builder.removeProperty(0);
642 QCOMPARE(builder.propertyCount(), 1);
643 prop2 = builder.property(0);
644 QCOMPARE(prop2.name(), QByteArray("bar"));
645 QCOMPARE(prop2.type(), QByteArray("int"));
646 QVERIFY(!prop2.isResettable());
647 QVERIFY(!prop2.isDesignable());
648 QVERIFY(prop2.isScriptable());
649 QVERIFY(!prop2.isStored());
650 QVERIFY(!prop2.isEditable());
651 QVERIFY(!prop2.isUser());
652 QVERIFY(!prop2.hasStdCppSet());
653 QVERIFY(!prop2.isEnumOrFlag());
654 QVERIFY(!prop2.isConstant());
655 QVERIFY(!prop2.isFinal());
656 QCOMPARE(prop2.index(), 0);
658 // Perform index-based lookup again.
659 QCOMPARE(builder.indexOfProperty("foo"), -1);
660 QCOMPARE(builder.indexOfProperty("bar"), 0);
661 QCOMPARE(builder.indexOfProperty("baz"), -1);
663 // Check for side-effects between the flags on prop2.
664 // Setting a flag to true shouldn't set any of the others to true.
665 // This checks for cut-and-paste bugs in the implementation where
666 // the flag code was pasted but the flag name was not changed.
667 #define CLEAR_FLAGS() \
669 prop2.setReadable(false); \
670 prop2.setWritable(false); \
671 prop2.setResettable(false); \
672 prop2.setDesignable(false); \
673 prop2.setScriptable(false); \
674 prop2.setStored(false); \
675 prop2.setEditable(false); \
676 prop2.setUser(false); \
677 prop2.setStdCppSet(false); \
678 prop2.setEnumOrFlag(false); \
679 prop2.setConstant(false); \
680 prop2.setFinal(false); \
682 #define COUNT_FLAGS() \
683 ((prop2.isReadable() ? 1 : 0) + \
684 (prop2.isWritable() ? 1 : 0) + \
685 (prop2.isResettable() ? 1 : 0) + \
686 (prop2.isDesignable() ? 1 : 0) + \
687 (prop2.isScriptable() ? 1 : 0) + \
688 (prop2.isStored() ? 1 : 0) + \
689 (prop2.isEditable() ? 1 : 0) + \
690 (prop2.isUser() ? 1 : 0) + \
691 (prop2.hasStdCppSet() ? 1 : 0) + \
692 (prop2.isEnumOrFlag() ? 1 : 0) + \
693 (prop2.isConstant() ? 1 : 0) + \
694 (prop2.isFinal() ? 1 : 0))
695 #define CHECK_FLAG(setFunc,isFunc) \
698 QCOMPARE(COUNT_FLAGS(), 0); \
699 prop2.setFunc(true); \
700 QVERIFY(prop2.isFunc()); \
701 QCOMPARE(COUNT_FLAGS(), 1); \
703 CHECK_FLAG(setReadable, isReadable);
704 CHECK_FLAG(setWritable, isWritable);
705 CHECK_FLAG(setResettable, isResettable);
706 CHECK_FLAG(setDesignable, isDesignable);
707 CHECK_FLAG(setScriptable, isScriptable);
708 CHECK_FLAG(setStored, isStored);
709 CHECK_FLAG(setEditable, isEditable);
710 CHECK_FLAG(setUser, isUser);
711 CHECK_FLAG(setStdCppSet, hasStdCppSet);
712 CHECK_FLAG(setEnumOrFlag, isEnumOrFlag);
713 CHECK_FLAG(setConstant, isConstant);
714 CHECK_FLAG(setFinal, isFinal);
716 // Check that nothing else changed.
717 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Properties));
719 // Add property from prototype
720 QMetaProperty prototype = SomethingOfEverything::staticMetaObject.property(1);
721 QVERIFY(prototype.name() == QByteArray("prop"));
722 QMetaPropertyBuilder prototypeProp = builder.addProperty(prototype);
723 QCOMPARE(prototypeProp.name(), QByteArray("prop"));
724 QVERIFY(prototypeProp.hasNotifySignal());
725 QCOMPARE(prototypeProp.notifySignal().signature(), QByteArray("propChanged(QString)"));
726 QCOMPARE(builder.methodCount(), 1);
727 QCOMPARE(builder.method(0).signature(), QByteArray("propChanged(QString)"));
730 void tst_QMetaObjectBuilder::notifySignal()
732 QMetaObjectBuilder builder;
734 QMetaPropertyBuilder prop = builder.addProperty("foo", "const QString &");
735 builder.addSlot("setFoo(QString)");
736 QMetaMethodBuilder notify = builder.addSignal("fooChanged(QString)");
738 QVERIFY(!prop.hasNotifySignal());
739 QCOMPARE(prop.notifySignal().index(), 0);
741 prop.setNotifySignal(notify);
742 QVERIFY(prop.hasNotifySignal());
743 QCOMPARE(prop.notifySignal().index(), 1);
745 prop.setNotifySignal(QMetaMethodBuilder());
746 QVERIFY(!prop.hasNotifySignal());
747 QCOMPARE(prop.notifySignal().index(), 0);
749 prop.setNotifySignal(notify);
750 prop.removeNotifySignal();
751 QVERIFY(!prop.hasNotifySignal());
752 QCOMPARE(prop.notifySignal().index(), 0);
754 QCOMPARE(builder.methodCount(), 2);
755 QCOMPARE(builder.propertyCount(), 1);
757 // Check that nothing else changed except methods and properties.
758 QVERIFY(checkForSideEffects
759 (builder, QMetaObjectBuilder::Methods | QMetaObjectBuilder::Properties));
762 void tst_QMetaObjectBuilder::enumerator()
764 QMetaObjectBuilder builder;
766 // Add an enumerator and check its attributes.
767 QMetaEnumBuilder enum1 = builder.addEnumerator("foo");
768 QCOMPARE(enum1.name(), QByteArray("foo"));
769 QVERIFY(!enum1.isFlag());
770 QCOMPARE(enum1.keyCount(), 0);
771 QCOMPARE(enum1.index(), 0);
772 QCOMPARE(builder.enumeratorCount(), 1);
774 // Add another enumerator and check again.
775 QMetaEnumBuilder enum2 = builder.addEnumerator("bar");
776 QCOMPARE(enum2.name(), QByteArray("bar"));
777 QVERIFY(!enum2.isFlag());
778 QCOMPARE(enum2.keyCount(), 0);
779 QCOMPARE(enum2.index(), 1);
780 QCOMPARE(builder.enumeratorCount(), 2);
782 // Perform index-based lookup.
783 QCOMPARE(builder.indexOfEnumerator("foo"), 0);
784 QCOMPARE(builder.indexOfEnumerator("bar"), 1);
785 QCOMPARE(builder.indexOfEnumerator("baz"), -1);
786 QCOMPARE(builder.enumerator(1).name(), QByteArray("bar"));
787 QCOMPARE(builder.enumerator(9).name(), QByteArray());
789 // Modify the attributes on enum1.
790 enum1.setIsFlag(true);
791 QCOMPARE(enum1.addKey("ABC", 0), 0);
792 QCOMPARE(enum1.addKey("DEF", 1), 1);
793 QCOMPARE(enum1.addKey("GHI", -1), 2);
795 // Check that enum1 is changed, but enum2 is not.
796 QCOMPARE(enum1.name(), QByteArray("foo"));
797 QVERIFY(enum1.isFlag());
798 QCOMPARE(enum1.keyCount(), 3);
799 QCOMPARE(enum1.index(), 0);
800 QCOMPARE(enum1.key(0), QByteArray("ABC"));
801 QCOMPARE(enum1.key(1), QByteArray("DEF"));
802 QCOMPARE(enum1.key(2), QByteArray("GHI"));
803 QCOMPARE(enum1.key(3), QByteArray());
804 QCOMPARE(enum1.value(0), 0);
805 QCOMPARE(enum1.value(1), 1);
806 QCOMPARE(enum1.value(2), -1);
807 QCOMPARE(enum2.name(), QByteArray("bar"));
808 QVERIFY(!enum2.isFlag());
809 QCOMPARE(enum2.keyCount(), 0);
810 QCOMPARE(enum2.index(), 1);
812 // Modify the attributes on enum2.
813 enum2.setIsFlag(true);
814 QCOMPARE(enum2.addKey("XYZ", 10), 0);
815 QCOMPARE(enum2.addKey("UVW", 19), 1);
817 // This time check that only method2 changed.
818 QCOMPARE(enum1.name(), QByteArray("foo"));
819 QVERIFY(enum1.isFlag());
820 QCOMPARE(enum1.keyCount(), 3);
821 QCOMPARE(enum1.index(), 0);
822 QCOMPARE(enum1.key(0), QByteArray("ABC"));
823 QCOMPARE(enum1.key(1), QByteArray("DEF"));
824 QCOMPARE(enum1.key(2), QByteArray("GHI"));
825 QCOMPARE(enum1.key(3), QByteArray());
826 QCOMPARE(enum1.value(0), 0);
827 QCOMPARE(enum1.value(1), 1);
828 QCOMPARE(enum1.value(2), -1);
829 QCOMPARE(enum2.name(), QByteArray("bar"));
830 QVERIFY(enum2.isFlag());
831 QCOMPARE(enum2.keyCount(), 2);
832 QCOMPARE(enum2.index(), 1);
833 QCOMPARE(enum2.key(0), QByteArray("XYZ"));
834 QCOMPARE(enum2.key(1), QByteArray("UVW"));
835 QCOMPARE(enum2.key(2), QByteArray());
836 QCOMPARE(enum2.value(0), 10);
837 QCOMPARE(enum2.value(1), 19);
841 QCOMPARE(enum1.name(), QByteArray("foo"));
842 QVERIFY(enum1.isFlag());
843 QCOMPARE(enum1.keyCount(), 2);
844 QCOMPARE(enum1.index(), 0);
845 QCOMPARE(enum1.key(0), QByteArray("ABC"));
846 QCOMPARE(enum1.key(1), QByteArray("DEF"));
847 QCOMPARE(enum1.key(2), QByteArray());
848 QCOMPARE(enum1.value(0), 0);
849 QCOMPARE(enum1.value(1), 1);
850 QCOMPARE(enum1.value(2), -1);
851 QCOMPARE(enum2.name(), QByteArray("bar"));
852 QVERIFY(enum2.isFlag());
853 QCOMPARE(enum2.keyCount(), 2);
854 QCOMPARE(enum2.index(), 1);
855 QCOMPARE(enum2.key(0), QByteArray("XYZ"));
856 QCOMPARE(enum2.key(1), QByteArray("UVW"));
857 QCOMPARE(enum2.key(2), QByteArray());
858 QCOMPARE(enum2.value(0), 10);
859 QCOMPARE(enum2.value(1), 19);
861 // Remove enum1 and check that enum2 becomes index 0.
862 builder.removeEnumerator(0);
863 QCOMPARE(builder.enumeratorCount(), 1);
864 enum2 = builder.enumerator(0);
865 QCOMPARE(enum2.name(), QByteArray("bar"));
866 QVERIFY(enum2.isFlag());
867 QCOMPARE(enum2.keyCount(), 2);
868 QCOMPARE(enum2.index(), 0);
869 QCOMPARE(enum2.key(0), QByteArray("XYZ"));
870 QCOMPARE(enum2.key(1), QByteArray("UVW"));
871 QCOMPARE(enum2.key(2), QByteArray());
872 QCOMPARE(enum2.value(0), 10);
873 QCOMPARE(enum2.value(1), 19);
875 // Perform index-based lookup again.
876 QCOMPARE(builder.indexOfEnumerator("foo"), -1);
877 QCOMPARE(builder.indexOfEnumerator("bar"), 0);
878 QCOMPARE(builder.indexOfEnumerator("baz"), -1);
880 // Check that nothing else changed.
881 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Enumerators));
884 void tst_QMetaObjectBuilder::classInfo()
886 QMetaObjectBuilder builder;
888 // Add two items of class information and check their attributes.
889 QCOMPARE(builder.addClassInfo("foo", "value1"), 0);
890 QCOMPARE(builder.addClassInfo("bar", "value2"), 1);
891 QCOMPARE(builder.classInfoName(0), QByteArray("foo"));
892 QCOMPARE(builder.classInfoValue(0), QByteArray("value1"));
893 QCOMPARE(builder.classInfoName(1), QByteArray("bar"));
894 QCOMPARE(builder.classInfoValue(1), QByteArray("value2"));
895 QCOMPARE(builder.classInfoName(9), QByteArray());
896 QCOMPARE(builder.classInfoValue(9), QByteArray());
897 QCOMPARE(builder.classInfoCount(), 2);
899 // Perform index-based lookup.
900 QCOMPARE(builder.indexOfClassInfo("foo"), 0);
901 QCOMPARE(builder.indexOfClassInfo("bar"), 1);
902 QCOMPARE(builder.indexOfClassInfo("baz"), -1);
904 // Remove the first one and check again.
905 builder.removeClassInfo(0);
906 QCOMPARE(builder.classInfoName(0), QByteArray("bar"));
907 QCOMPARE(builder.classInfoValue(0), QByteArray("value2"));
908 QCOMPARE(builder.classInfoCount(), 1);
910 // Perform index-based lookup again.
911 QCOMPARE(builder.indexOfClassInfo("foo"), -1);
912 QCOMPARE(builder.indexOfClassInfo("bar"), 0);
913 QCOMPARE(builder.indexOfClassInfo("baz"), -1);
915 // Check that nothing else changed.
916 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::ClassInfos));
919 void tst_QMetaObjectBuilder::relatedMetaObject()
921 QMetaObjectBuilder builder;
923 // Add two related meta objects and check their attributes.
924 QCOMPARE(builder.addRelatedMetaObject(&QObject::staticMetaObject), 0);
925 QCOMPARE(builder.addRelatedMetaObject(&staticMetaObject), 1);
926 QVERIFY(builder.relatedMetaObject(0) == &QObject::staticMetaObject);
927 QVERIFY(builder.relatedMetaObject(1) == &staticMetaObject);
928 QCOMPARE(builder.relatedMetaObjectCount(), 2);
930 // Remove the first one and check again.
931 builder.removeRelatedMetaObject(0);
932 QVERIFY(builder.relatedMetaObject(0) == &staticMetaObject);
933 QCOMPARE(builder.relatedMetaObjectCount(), 1);
935 // Check that nothing else changed.
936 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::RelatedMetaObjects));
939 static void smetacall(QObject *, QMetaObject::Call, int, void **)
944 void tst_QMetaObjectBuilder::staticMetacall()
946 QMetaObjectBuilder builder;
947 QVERIFY(!builder.staticMetacallFunction());
948 builder.setStaticMetacallFunction(smetacall);
949 QVERIFY(builder.staticMetacallFunction() == smetacall);
950 QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::StaticMetacall));
953 // Copy the entire contents of a static QMetaObject and then check
954 // that QMetaObjectBuilder will produce an exact copy as output.
955 void tst_QMetaObjectBuilder::copyMetaObject()
957 QMetaObjectBuilder builder(&QObject::staticMetaObject);
958 QMetaObject *meta = builder.toMetaObject();
959 QVERIFY(sameMetaObject(meta, &QObject::staticMetaObject));
962 QMetaObjectBuilder builder2(&staticMetaObject);
963 meta = builder2.toMetaObject();
964 QVERIFY(sameMetaObject(meta, &staticMetaObject));
967 QMetaObjectBuilder builder3(&SomethingOfEverything::staticMetaObject);
968 meta = builder3.toMetaObject();
969 QVERIFY(sameMetaObject(meta, &SomethingOfEverything::staticMetaObject));
973 // Serialize and deserialize a meta object and check that
974 // it round-trips to the exact same value.
975 void tst_QMetaObjectBuilder::serialize()
977 // Full QMetaObjectBuilder
979 QMetaObjectBuilder builder(&SomethingOfEverything::staticMetaObject);
980 QMetaObject *meta = builder.toMetaObject();
983 QDataStream stream(&data, QIODevice::WriteOnly | QIODevice::Append);
984 builder.serialize(stream);
986 QMetaObjectBuilder builder2;
987 QDataStream stream2(data);
988 QMap<QByteArray, const QMetaObject *> references;
989 references.insert(QByteArray("QLocale"), &QLocale::staticMetaObject);
990 builder2.deserialize(stream2, references);
991 builder2.setStaticMetacallFunction(builder.staticMetacallFunction());
992 QMetaObject *meta2 = builder2.toMetaObject();
994 QVERIFY(sameMetaObject(meta, meta2));
999 // Partial QMetaObjectBuilder
1001 QMetaObjectBuilder builder;
1002 builder.setClassName("Test");
1003 builder.addProperty("foo", "int");
1006 QDataStream stream(&data, QIODevice::WriteOnly | QIODevice::Append);
1007 builder.serialize(stream);
1009 QMetaObjectBuilder builder2;
1010 QDataStream stream2(data);
1011 builder2.deserialize(stream2, QMap<QByteArray, const QMetaObject *>());
1013 QCOMPARE(builder.superClass(), builder2.superClass());
1014 QCOMPARE(builder.className(), builder2.className());
1015 QCOMPARE(builder.propertyCount(), builder2.propertyCount());
1016 QCOMPARE(builder.property(0).name(), builder2.property(0).name());
1017 QCOMPARE(builder.property(0).type(), builder2.property(0).type());
1021 // Check that removing a method updates notify signals appropriately
1022 void tst_QMetaObjectBuilder::removeNotifySignal()
1024 QMetaObjectBuilder builder;
1026 QMetaMethodBuilder method1 = builder.addSignal("foo(const QString&, int)");
1027 QMetaMethodBuilder method2 = builder.addSignal("bar(QString)");
1030 QMetaPropertyBuilder prop = builder.addProperty("prop", "const QString &");
1031 prop.setNotifySignal(method2);
1032 QVERIFY(prop.hasNotifySignal());
1033 QCOMPARE(prop.notifySignal().index(), 1);
1035 // Remove non-notify signal
1036 builder.removeMethod(0);
1037 QVERIFY(prop.hasNotifySignal());
1038 QCOMPARE(prop.notifySignal().index(), 0);
1040 // Remove notify signal
1041 builder.removeMethod(0);
1042 QVERIFY(!prop.hasNotifySignal());
1045 // Check that the only changes to a "builder" relative to the default
1046 // state is specified by "members".
1047 bool tst_QMetaObjectBuilder::checkForSideEffects
1048 (const QMetaObjectBuilder& builder,
1049 QMetaObjectBuilder::AddMembers members)
1051 if ((members & QMetaObjectBuilder::ClassName) == 0) {
1052 if (!builder.className().isEmpty())
1056 if ((members & QMetaObjectBuilder::SuperClass) == 0) {
1057 if (builder.superClass() != &QObject::staticMetaObject)
1061 if ((members & QMetaObjectBuilder::Methods) == 0) {
1062 if (builder.methodCount() != 0)
1066 if ((members & QMetaObjectBuilder::Constructors) == 0) {
1067 if (builder.constructorCount() != 0)
1071 if ((members & QMetaObjectBuilder::Properties) == 0) {
1072 if (builder.propertyCount() != 0)
1076 if ((members & QMetaObjectBuilder::Enumerators) == 0) {
1077 if (builder.enumeratorCount() != 0)
1081 if ((members & QMetaObjectBuilder::ClassInfos) == 0) {
1082 if (builder.classInfoCount() != 0)
1086 if ((members & QMetaObjectBuilder::RelatedMetaObjects) == 0) {
1087 if (builder.relatedMetaObjectCount() != 0)
1091 if ((members & QMetaObjectBuilder::StaticMetacall) == 0) {
1092 if (builder.staticMetacallFunction() != 0)
1099 static bool sameMethod(const QMetaMethod& method1, const QMetaMethod& method2)
1101 if (QByteArray(method1.signature()) != QByteArray(method2.signature()))
1104 if (QByteArray(method1.typeName()) != QByteArray(method2.typeName()))
1107 if (method1.parameterNames() != method2.parameterNames())
1110 if (QByteArray(method1.tag()) != QByteArray(method2.tag()))
1113 if (method1.access() != method2.access())
1116 if (method1.methodType() != method2.methodType())
1119 if (method1.attributes() != method2.attributes())
1125 static bool sameProperty(const QMetaProperty& prop1, const QMetaProperty& prop2)
1127 if (QByteArray(prop1.name()) != QByteArray(prop2.name()))
1130 if (QByteArray(prop1.typeName()) != QByteArray(prop2.typeName()))
1133 if (prop1.isReadable() != prop2.isReadable() ||
1134 prop1.isWritable() != prop2.isWritable() ||
1135 prop1.isResettable() != prop2.isResettable() ||
1136 prop1.isDesignable() != prop2.isDesignable() ||
1137 prop1.isScriptable() != prop2.isScriptable() ||
1138 prop1.isStored() != prop2.isStored() ||
1139 prop1.isEditable() != prop2.isEditable() ||
1140 prop1.isUser() != prop2.isUser() ||
1141 prop1.isFlagType() != prop2.isFlagType() ||
1142 prop1.isEnumType() != prop2.isEnumType() ||
1143 prop1.hasNotifySignal() != prop2.hasNotifySignal() ||
1144 prop1.hasStdCppSet() != prop2.hasStdCppSet())
1147 if (prop1.hasNotifySignal()) {
1148 if (prop1.notifySignalIndex() != prop2.notifySignalIndex())
1155 static bool sameEnumerator(const QMetaEnum& enum1, const QMetaEnum& enum2)
1157 if (QByteArray(enum1.name()) != QByteArray(enum2.name()))
1160 if (enum1.isFlag() != enum2.isFlag())
1163 if (enum1.keyCount() != enum2.keyCount())
1166 for (int index = 0; index < enum1.keyCount(); ++index) {
1167 if (QByteArray(enum1.key(index)) != QByteArray(enum2.key(index)))
1169 if (enum1.value(index) != enum2.value(index))
1173 if (QByteArray(enum1.scope()) != QByteArray(enum2.scope()))
1179 // Determine if two meta objects are identical.
1180 bool tst_QMetaObjectBuilder::sameMetaObject
1181 (const QMetaObject *meta1, const QMetaObject *meta2)
1185 if (strcmp(meta1->className(), meta2->className()) != 0)
1188 if (meta1->superClass() != meta2->superClass())
1191 if (meta1->constructorCount() != meta2->constructorCount() ||
1192 meta1->methodCount() != meta2->methodCount() ||
1193 meta1->enumeratorCount() != meta2->enumeratorCount() ||
1194 meta1->propertyCount() != meta2->propertyCount() ||
1195 meta1->classInfoCount() != meta2->classInfoCount())
1198 for (index = 0; index < meta1->constructorCount(); ++index) {
1199 if (!sameMethod(meta1->constructor(index), meta2->constructor(index)))
1203 for (index = 0; index < meta1->methodCount(); ++index) {
1204 if (!sameMethod(meta1->method(index), meta2->method(index)))
1208 for (index = 0; index < meta1->propertyCount(); ++index) {
1209 if (!sameProperty(meta1->property(index), meta2->property(index)))
1213 for (index = 0; index < meta1->enumeratorCount(); ++index) {
1214 if (!sameEnumerator(meta1->enumerator(index), meta2->enumerator(index)))
1218 for (index = 0; index < meta1->classInfoCount(); ++index) {
1219 if (QByteArray(meta1->classInfo(index).name()) !=
1220 QByteArray(meta2->classInfo(index).name()))
1222 if (QByteArray(meta1->classInfo(index).value()) !=
1223 QByteArray(meta2->classInfo(index).value()))
1227 const QMetaObject **objects1 = 0;
1228 const QMetaObject **objects2 = 0;
1229 if (meta1->d.data[0] == meta2->d.data[0] && meta1->d.data[0] >= 2) {
1230 QMetaObjectExtraData *extra1 = (QMetaObjectExtraData *)(meta1->d.extradata);
1231 QMetaObjectExtraData *extra2 = (QMetaObjectExtraData *)(meta2->d.extradata);
1232 if (extra1 && !extra2)
1234 if (extra2 && !extra1)
1236 if (extra1 && extra2) {
1237 if (extra1->static_metacall != extra2->static_metacall)
1239 objects1 = extra1->objects;
1240 objects2 = extra1->objects;
1242 } else if (meta1->d.data[0] == meta2->d.data[0] && meta1->d.data[0] == 1) {
1243 objects1 = (const QMetaObject **)(meta1->d.extradata);
1244 objects2 = (const QMetaObject **)(meta2->d.extradata);
1246 if (objects1 && !objects2)
1248 if (objects2 && !objects1)
1250 if (objects1 && objects2) {
1251 while (*objects1 != 0 && *objects2 != 0) {
1252 if (*objects1 != *objects2)
1262 QTEST_MAIN(tst_QMetaObjectBuilder)
1264 #include "tst_qmetaobjectbuilder.moc"