/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>
#include <QtCore/qlocale.h>
#include <private/qmetaobjectbuilder_p.h>

class tst_QMetaObjectBuilder : public QObject
{
    Q_OBJECT
private slots:
    void create();
    void className();
    void superClass();
    void flags();
    void method();
    void slot();
    void signal();
    void constructor();
    void property();
    void variantProperty();
    void notifySignal();
    void enumerator();
    void classInfo();
    void relatedMetaObject();
    void staticMetacall();
    void copyMetaObject();
    void serialize();
    void relocatableData();
    void removeNotifySignal();

    void usage_signal();
    void usage_property();
    void usage_slot();
    void usage_method();
    void usage_constructor();
    void usage_connect();
    void usage_templateConnect();

    void classNameFirstInStringData();

private:
    static bool checkForSideEffects
        (const QMetaObjectBuilder& builder,
         QMetaObjectBuilder::AddMembers members);
    static bool sameMetaObject
        (const QMetaObject *meta1, const QMetaObject *meta2);
};

// Dummy class that has something of every type of thing moc can generate.
class SomethingOfEverything : public QObject
{
    Q_OBJECT
    Q_CLASSINFO("ci_foo", "ABC")
    Q_CLASSINFO("ci_bar", "DEF")
    Q_PROPERTY(QString prop READ prop WRITE setProp NOTIFY propChanged)
    Q_PROPERTY(QString prop2 READ prop WRITE setProp)
    Q_PROPERTY(QString revisionProp READ prop WRITE setProp REVISION 42)
    Q_PROPERTY(SomethingEnum eprop READ eprop)
    Q_PROPERTY(SomethingFlagEnum fprop READ fprop)
    Q_PROPERTY(QLocale::Language language READ language)
    Q_ENUMS(SomethingEnum)
    Q_FLAGS(SomethingFlagEnum)
public:
    Q_INVOKABLE SomethingOfEverything() {}
    ~SomethingOfEverything() {}

    enum SomethingEnum
    {
        GHI,
        JKL = 10
    };

    enum SomethingFlagEnum
    {
        XYZ = 1,
        UVW = 8
    };

    Q_INVOKABLE Q_SCRIPTABLE void method1() {}

    QString prop() const { return QString(); }
    void setProp(const QString& v) { Q_UNUSED(v); }

    SomethingOfEverything::SomethingEnum eprop() const { return GHI; }
    SomethingOfEverything::SomethingFlagEnum fprop() const { return XYZ; }
    QLocale::Language language() const { return QLocale::English; }

public slots:
    void slot1(const QString&) {}
    void slot2(int, const QString&) {}
    Q_REVISION(24) void revisionSlot() {}

private slots:
    void slot3() {}

protected slots:
    Q_SCRIPTABLE void slot4(int) {}
    void slot5(int a, const QString& b) { Q_UNUSED(a); Q_UNUSED(b); }

signals:
    void sig1();
    void sig2(int x, const QString& y);
    void propChanged(const QString&);
};

void tst_QMetaObjectBuilder::create()
{
    QMetaObjectBuilder builder;
    QVERIFY(builder.className().isEmpty());
    QCOMPARE(builder.superClass(), &QObject::staticMetaObject);
    QCOMPARE(builder.methodCount(), 0);
    QCOMPARE(builder.constructorCount(), 0);
    QCOMPARE(builder.propertyCount(), 0);
    QCOMPARE(builder.enumeratorCount(), 0);
    QCOMPARE(builder.classInfoCount(), 0);
    QCOMPARE(builder.relatedMetaObjectCount(), 0);
    QVERIFY(!builder.staticMetacallFunction());
}

void tst_QMetaObjectBuilder::className()
{
    QMetaObjectBuilder builder;

    // Change the class name.
    builder.setClassName("Foo");
    QCOMPARE(builder.className(), QByteArray("Foo"));

    // Change it again.
    builder.setClassName("Bar");
    QCOMPARE(builder.className(), QByteArray("Bar"));

    // Clone the class name off a static QMetaObject.
    builder.addMetaObject(&QObject::staticMetaObject, QMetaObjectBuilder::ClassName);
    QCOMPARE(builder.className(), QByteArray("QObject"));

    // Check that nothing else changed.
    QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::ClassName));
}

void tst_QMetaObjectBuilder::superClass()
{
    QMetaObjectBuilder builder;

    // Change the super class.
    builder.setSuperClass(&QObject::staticMetaObject);
    QCOMPARE(builder.superClass(), &QObject::staticMetaObject);

    // Change it again.
    builder.setSuperClass(&staticMetaObject);
    QCOMPARE(builder.superClass(), &staticMetaObject);

    // Clone the super class off a static QMetaObject.
    builder.addMetaObject(&QObject::staticMetaObject, QMetaObjectBuilder::SuperClass);
    QVERIFY(!builder.superClass());
    builder.addMetaObject(&staticMetaObject, QMetaObjectBuilder::SuperClass);
    QCOMPARE(builder.superClass(), staticMetaObject.superClass());

    // Check that nothing else changed.
    QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::SuperClass));
}

void tst_QMetaObjectBuilder::flags()
{
    QMetaObjectBuilder builder;

    // Check default
    QCOMPARE(builder.flags(), 0);

    // Set flags
    builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
    QCOMPARE(builder.flags(), QMetaObjectBuilder::DynamicMetaObject);
}

void tst_QMetaObjectBuilder::method()
{
    QMetaObjectBuilder builder;

    // Check null method
    QMetaMethodBuilder nullMethod;
    QCOMPARE(nullMethod.signature(), QByteArray());
    QCOMPARE(nullMethod.methodType(), QMetaMethod::Method);
    QVERIFY(nullMethod.returnType().isEmpty());
    QVERIFY(nullMethod.parameterTypes().isEmpty());
    QVERIFY(nullMethod.parameterNames().isEmpty());
    QVERIFY(nullMethod.tag().isEmpty());
    QCOMPARE(nullMethod.access(), QMetaMethod::Public);
    QCOMPARE(nullMethod.attributes(), 0);
    QCOMPARE(nullMethod.revision(), 0);
    QCOMPARE(nullMethod.index(), 0);

    // Add a method and check its attributes.
    QMetaMethodBuilder method1 = builder.addMethod("foo(const QString&, int)");
    QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
    QCOMPARE(method1.methodType(), QMetaMethod::Method);
    QCOMPARE(method1.returnType(), QByteArray("void"));
    QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
    QVERIFY(method1.parameterNames().isEmpty());
    QVERIFY(method1.tag().isEmpty());
    QCOMPARE(method1.access(), QMetaMethod::Public);
    QCOMPARE(method1.attributes(), 0);
    QCOMPARE(method1.revision(), 0);
    QCOMPARE(method1.index(), 0);
    QCOMPARE(builder.methodCount(), 1);

    // Add another method and check again.
    QMetaMethodBuilder method2 = builder.addMethod("bar(QString)", "int");
    QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
    QCOMPARE(method2.methodType(), QMetaMethod::Method);
    QCOMPARE(method2.returnType(), QByteArray("int"));
    QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
    QVERIFY(method2.parameterNames().isEmpty());
    QVERIFY(method2.tag().isEmpty());
    QCOMPARE(method2.access(), QMetaMethod::Public);
    QCOMPARE(method2.attributes(), 0);
    QCOMPARE(method2.revision(), 0);
    QCOMPARE(method2.index(), 1);
    QCOMPARE(builder.methodCount(), 2);

    // Perform index-based lookup.
    QCOMPARE(builder.indexOfMethod("foo(const QString&, int)"), 0);
    QCOMPARE(builder.indexOfMethod("bar(QString)"), 1);
    QCOMPARE(builder.indexOfMethod("baz()"), -1);

    // Modify the attributes on method1.
    method1.setReturnType("int");
    method1.setParameterNames(QList<QByteArray>() << "a" << "b");
    method1.setTag("tag");
    method1.setAccess(QMetaMethod::Private);
    method1.setAttributes(42);
    method1.setRevision(123);

    // Check that method1 is changed, but method2 is not.
    QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
    QCOMPARE(method1.methodType(), QMetaMethod::Method);
    QCOMPARE(method1.returnType(), QByteArray("int"));
    QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
    QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
    QCOMPARE(method1.tag(), QByteArray("tag"));
    QCOMPARE(method1.access(), QMetaMethod::Private);
    QCOMPARE(method1.attributes(), 42);
    QCOMPARE(method1.revision(), 123);
    QCOMPARE(method1.index(), 0);
    QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
    QCOMPARE(method2.methodType(), QMetaMethod::Method);
    QCOMPARE(method2.returnType(), QByteArray("int"));
    QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
    QVERIFY(method2.parameterNames().isEmpty());
    QVERIFY(method2.tag().isEmpty());
    QCOMPARE(method2.access(), QMetaMethod::Public);
    QCOMPARE(method2.attributes(), 0);
    QCOMPARE(method2.revision(), 0);
    QCOMPARE(method2.index(), 1);
    QCOMPARE(builder.methodCount(), 2);

    // Modify the attributes on method2.
    method2.setReturnType("QString");
    method2.setParameterNames(QList<QByteArray>() << "c");
    method2.setTag("Q_FOO");
    method2.setAccess(QMetaMethod::Protected);
    method2.setAttributes(24);
    method2.setRevision(321);

    // This time check that only method2 changed.
    QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
    QCOMPARE(method1.methodType(), QMetaMethod::Method);
    QCOMPARE(method1.returnType(), QByteArray("int"));
    QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
    QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
    QCOMPARE(method1.tag(), QByteArray("tag"));
    QCOMPARE(method1.access(), QMetaMethod::Private);
    QCOMPARE(method1.attributes(), 42);
    QCOMPARE(method1.revision(), 123);
    QCOMPARE(method1.index(), 0);
    QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
    QCOMPARE(method2.methodType(), QMetaMethod::Method);
    QCOMPARE(method2.returnType(), QByteArray("QString"));
    QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
    QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
    QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
    QCOMPARE(method2.access(), QMetaMethod::Protected);
    QCOMPARE(method2.attributes(), 24);
    QCOMPARE(method2.revision(), 321);
    QCOMPARE(method2.index(), 1);
    QCOMPARE(builder.methodCount(), 2);

    // Remove method1 and check that method2 becomes index 0.
    builder.removeMethod(0);
    QCOMPARE(builder.methodCount(), 1);
    method2 = builder.method(0);
    QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
    QCOMPARE(method2.methodType(), QMetaMethod::Method);
    QCOMPARE(method2.returnType(), QByteArray("QString"));
    QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
    QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
    QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
    QCOMPARE(method2.access(), QMetaMethod::Protected);
    QCOMPARE(method2.attributes(), 24);
    QCOMPARE(method2.revision(), 321);
    QCOMPARE(method2.index(), 0);

    // Perform index-based lookup again.
    QCOMPARE(builder.indexOfMethod("foo(const QString&, int)"), -1);
    QCOMPARE(builder.indexOfMethod("bar(QString)"), 0);
    QCOMPARE(builder.indexOfMethod("baz()"), -1);
    QCOMPARE(builder.method(0).signature(), QByteArray("bar(QString)"));
    QCOMPARE(builder.method(9).signature(), QByteArray());

    // Check that nothing else changed.
    QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Methods));
}

void tst_QMetaObjectBuilder::slot()
{
    QMetaObjectBuilder builder;

    // Add a slot and check its attributes.
    QMetaMethodBuilder method1 = builder.addSlot("foo(const QString&, int)");
    QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
    QCOMPARE(method1.methodType(), QMetaMethod::Slot);
    QCOMPARE(method1.returnType(), QByteArray("void"));
    QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
    QVERIFY(method1.parameterNames().isEmpty());
    QVERIFY(method1.tag().isEmpty());
    QCOMPARE(method1.access(), QMetaMethod::Public);
    QCOMPARE(method1.attributes(), 0);
    QCOMPARE(method1.index(), 0);
    QCOMPARE(builder.methodCount(), 1);

    // Add another slot and check again.
    QMetaMethodBuilder method2 = builder.addSlot("bar(QString)");
    QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
    QCOMPARE(method2.methodType(), QMetaMethod::Slot);
    QCOMPARE(method2.returnType(), QByteArray("void"));
    QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
    QVERIFY(method2.parameterNames().isEmpty());
    QVERIFY(method2.tag().isEmpty());
    QCOMPARE(method2.access(), QMetaMethod::Public);
    QCOMPARE(method2.attributes(), 0);
    QCOMPARE(method2.index(), 1);
    QCOMPARE(builder.methodCount(), 2);

    // Perform index-based lookup
    QCOMPARE(builder.indexOfSlot("foo(const QString &, int)"), 0);
    QCOMPARE(builder.indexOfSlot("bar(QString)"), 1);
    QCOMPARE(builder.indexOfSlot("baz()"), -1);

    // Check that nothing else changed.
    QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Methods));
}

void tst_QMetaObjectBuilder::signal()
{
    QMetaObjectBuilder builder;

    // Add a signal and check its attributes.
    QMetaMethodBuilder method1 = builder.addSignal("foo(const QString&, int)");
    QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
    QCOMPARE(method1.methodType(), QMetaMethod::Signal);
    QCOMPARE(method1.returnType(), QByteArray("void"));
    QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
    QVERIFY(method1.parameterNames().isEmpty());
    QVERIFY(method1.tag().isEmpty());
    QCOMPARE(method1.access(), QMetaMethod::Public);
    QCOMPARE(method1.attributes(), 0);
    QCOMPARE(method1.index(), 0);
    QCOMPARE(builder.methodCount(), 1);

    // Add another signal and check again.
    QMetaMethodBuilder method2 = builder.addSignal("bar(QString)");
    QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
    QCOMPARE(method2.methodType(), QMetaMethod::Signal);
    QCOMPARE(method2.returnType(), QByteArray("void"));
    QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
    QVERIFY(method2.parameterNames().isEmpty());
    QVERIFY(method2.tag().isEmpty());
    QCOMPARE(method2.access(), QMetaMethod::Public);
    QCOMPARE(method2.attributes(), 0);
    QCOMPARE(method2.index(), 1);
    QCOMPARE(builder.methodCount(), 2);

    // Perform index-based lookup
    QCOMPARE(builder.indexOfSignal("foo(const QString &, int)"), 0);
    QCOMPARE(builder.indexOfSignal("bar(QString)"), 1);
    QCOMPARE(builder.indexOfSignal("baz()"), -1);

    // Check that nothing else changed.
    QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Methods));
}

void tst_QMetaObjectBuilder::constructor()
{
    QMetaObjectBuilder builder;

    // Add a constructor and check its attributes.
    QMetaMethodBuilder ctor1 = builder.addConstructor("foo(const QString&, int)");
    QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
    QCOMPARE(ctor1.methodType(), QMetaMethod::Constructor);
    QVERIFY(ctor1.returnType().isEmpty());
    QCOMPARE(ctor1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
    QVERIFY(ctor1.parameterNames().isEmpty());
    QVERIFY(ctor1.tag().isEmpty());
    QCOMPARE(ctor1.access(), QMetaMethod::Public);
    QCOMPARE(ctor1.attributes(), 0);
    QCOMPARE(ctor1.index(), 0);
    QCOMPARE(builder.constructorCount(), 1);

    // Add another constructor and check again.
    QMetaMethodBuilder ctor2 = builder.addConstructor("bar(QString)");
    QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
    QCOMPARE(ctor2.methodType(), QMetaMethod::Constructor);
    QVERIFY(ctor2.returnType().isEmpty());
    QCOMPARE(ctor2.parameterTypes(), QList<QByteArray>() << "QString");
    QVERIFY(ctor2.parameterNames().isEmpty());
    QVERIFY(ctor2.tag().isEmpty());
    QCOMPARE(ctor2.access(), QMetaMethod::Public);
    QCOMPARE(ctor2.attributes(), 0);
    QCOMPARE(ctor2.index(), 1);
    QCOMPARE(builder.constructorCount(), 2);

    // Perform index-based lookup.
    QCOMPARE(builder.indexOfConstructor("foo(const QString&, int)"), 0);
    QCOMPARE(builder.indexOfConstructor("bar(QString)"), 1);
    QCOMPARE(builder.indexOfConstructor("baz()"), -1);
    QCOMPARE(builder.constructor(1).signature(), QByteArray("bar(QString)"));
    QCOMPARE(builder.constructor(9).signature(), QByteArray());

    // Modify the attributes on ctor1.
    ctor1.setReturnType("int");
    ctor1.setParameterNames(QList<QByteArray>() << "a" << "b");
    ctor1.setTag("tag");
    ctor1.setAccess(QMetaMethod::Private);
    ctor1.setAttributes(42);

    // Check that ctor1 is changed, but ctor2 is not.
    QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
    QCOMPARE(ctor1.methodType(), QMetaMethod::Constructor);
    QCOMPARE(ctor1.returnType(), QByteArray("int"));
    QCOMPARE(ctor1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
    QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
    QCOMPARE(ctor1.tag(), QByteArray("tag"));
    QCOMPARE(ctor1.access(), QMetaMethod::Private);
    QCOMPARE(ctor1.attributes(), 42);
    QCOMPARE(ctor1.index(), 0);
    QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
    QCOMPARE(ctor2.methodType(), QMetaMethod::Constructor);
    QVERIFY(ctor2.returnType().isEmpty());
    QCOMPARE(ctor2.parameterTypes(), QList<QByteArray>() << "QString");
    QVERIFY(ctor2.parameterNames().isEmpty());
    QVERIFY(ctor2.tag().isEmpty());
    QCOMPARE(ctor2.access(), QMetaMethod::Public);
    QCOMPARE(ctor2.attributes(), 0);
    QCOMPARE(ctor2.index(), 1);
    QCOMPARE(builder.constructorCount(), 2);

    // Modify the attributes on ctor2.
    ctor2.setReturnType("QString");
    ctor2.setParameterNames(QList<QByteArray>() << "c");
    ctor2.setTag("Q_FOO");
    ctor2.setAccess(QMetaMethod::Protected);
    ctor2.setAttributes(24);

    // This time check that only ctor2 changed.
    QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
    QCOMPARE(ctor1.methodType(), QMetaMethod::Constructor);
    QCOMPARE(ctor1.returnType(), QByteArray("int"));
    QCOMPARE(ctor1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
    QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
    QCOMPARE(ctor1.tag(), QByteArray("tag"));
    QCOMPARE(ctor1.access(), QMetaMethod::Private);
    QCOMPARE(ctor1.attributes(), 42);
    QCOMPARE(ctor1.index(), 0);
    QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
    QCOMPARE(ctor2.methodType(), QMetaMethod::Constructor);
    QCOMPARE(ctor2.returnType(), QByteArray("QString"));
    QCOMPARE(ctor2.parameterTypes(), QList<QByteArray>() << "QString");
    QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
    QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
    QCOMPARE(ctor2.access(), QMetaMethod::Protected);
    QCOMPARE(ctor2.attributes(), 24);
    QCOMPARE(ctor2.index(), 1);
    QCOMPARE(builder.constructorCount(), 2);

    // Remove ctor1 and check that ctor2 becomes index 0.
    builder.removeConstructor(0);
    QCOMPARE(builder.constructorCount(), 1);
    ctor2 = builder.constructor(0);
    QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
    QCOMPARE(ctor2.methodType(), QMetaMethod::Constructor);
    QCOMPARE(ctor2.returnType(), QByteArray("QString"));
    QCOMPARE(ctor2.parameterTypes(), QList<QByteArray>() << "QString");
    QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
    QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
    QCOMPARE(ctor2.access(), QMetaMethod::Protected);
    QCOMPARE(ctor2.attributes(), 24);
    QCOMPARE(ctor2.index(), 0);

    // Perform index-based lookup again.
    QCOMPARE(builder.indexOfConstructor("foo(const QString&, int)"), -1);
    QCOMPARE(builder.indexOfConstructor("bar(QString)"), 0);
    QCOMPARE(builder.indexOfConstructor("baz()"), -1);

    // Add constructor from prototype
    QMetaMethod prototype = SomethingOfEverything::staticMetaObject.constructor(0);
    QMetaMethodBuilder prototypeConstructor = builder.addMethod(prototype);
    QCOMPARE(builder.constructorCount(), 2);

    QCOMPARE(prototypeConstructor.signature(), QByteArray("SomethingOfEverything()"));
    QCOMPARE(prototypeConstructor.methodType(), QMetaMethod::Constructor);
    QCOMPARE(prototypeConstructor.returnType(), QByteArray());
    QVERIFY(prototypeConstructor.parameterTypes().isEmpty());
    QCOMPARE(prototypeConstructor.access(), QMetaMethod::Public);
    QCOMPARE(prototypeConstructor.index(), 1);

    // Check that nothing else changed.
    QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Constructors));
}

void tst_QMetaObjectBuilder::property()
{
    QMetaObjectBuilder builder;

    // Null property builder
    QMetaPropertyBuilder nullProp;
    QCOMPARE(nullProp.name(), QByteArray());
    QCOMPARE(nullProp.type(), QByteArray());
    QVERIFY(!nullProp.hasNotifySignal());
    QVERIFY(!nullProp.isReadable());
    QVERIFY(!nullProp.isWritable());
    QVERIFY(!nullProp.isResettable());
    QVERIFY(!nullProp.isDesignable());
    QVERIFY(!nullProp.isScriptable());
    QVERIFY(!nullProp.isStored());
    QVERIFY(!nullProp.isEditable());
    QVERIFY(!nullProp.isUser());
    QVERIFY(!nullProp.hasStdCppSet());
    QVERIFY(!nullProp.isEnumOrFlag());
    QVERIFY(!nullProp.isConstant());
    QVERIFY(!nullProp.isFinal());
    QCOMPARE(nullProp.index(), 0);
    QCOMPARE(nullProp.revision(), 0);

    // Add a property and check its attributes.
    QMetaPropertyBuilder prop1 = builder.addProperty("foo", "const QString &");
    QCOMPARE(prop1.name(), QByteArray("foo"));
    QCOMPARE(prop1.type(), QByteArray("QString"));
    QVERIFY(!prop1.hasNotifySignal());
    QVERIFY(prop1.isReadable());
    QVERIFY(prop1.isWritable());
    QVERIFY(!prop1.isResettable());
    QVERIFY(!prop1.isDesignable());
    QVERIFY(prop1.isScriptable());
    QVERIFY(!prop1.isStored());
    QVERIFY(!prop1.isEditable());
    QVERIFY(!prop1.isUser());
    QVERIFY(!prop1.hasStdCppSet());
    QVERIFY(!prop1.isEnumOrFlag());
    QVERIFY(!prop1.isConstant());
    QVERIFY(!prop1.isFinal());
    QCOMPARE(prop1.revision(), 0);
    QCOMPARE(prop1.index(), 0);
    QCOMPARE(builder.propertyCount(), 1);

    // Add another property and check again.
    QMetaPropertyBuilder prop2 = builder.addProperty("bar", "int");
    QCOMPARE(prop2.name(), QByteArray("bar"));
    QCOMPARE(prop2.type(), QByteArray("int"));
    QVERIFY(!prop2.hasNotifySignal());
    QVERIFY(prop2.isReadable());
    QVERIFY(prop2.isWritable());
    QVERIFY(!prop2.isResettable());
    QVERIFY(!prop2.isDesignable());
    QVERIFY(prop2.isScriptable());
    QVERIFY(!prop2.isStored());
    QVERIFY(!prop2.isEditable());
    QVERIFY(!prop2.isUser());
    QVERIFY(!prop2.hasStdCppSet());
    QVERIFY(!prop2.isEnumOrFlag());
    QVERIFY(!prop2.isConstant());
    QVERIFY(!prop2.isFinal());
    QCOMPARE(prop2.revision(), 0);
    QCOMPARE(prop2.index(), 1);
    QCOMPARE(builder.propertyCount(), 2);

    // Perform index-based lookup.
    QCOMPARE(builder.indexOfProperty("foo"), 0);
    QCOMPARE(builder.indexOfProperty("bar"), 1);
    QCOMPARE(builder.indexOfProperty("baz"), -1);
    QCOMPARE(builder.property(1).name(), QByteArray("bar"));
    QCOMPARE(builder.property(9).name(), QByteArray());

    // Modify the attributes on prop1.
    prop1.setReadable(false);
    prop1.setWritable(false);
    prop1.setResettable(true);
    prop1.setDesignable(true);
    prop1.setScriptable(false);
    prop1.setStored(true);
    prop1.setEditable(true);
    prop1.setUser(true);
    prop1.setStdCppSet(true);
    prop1.setEnumOrFlag(true);
    prop1.setConstant(true);
    prop1.setFinal(true);
    prop1.setRevision(123);

    // Check that prop1 is changed, but prop2 is not.
    QCOMPARE(prop1.name(), QByteArray("foo"));
    QCOMPARE(prop1.type(), QByteArray("QString"));
    QVERIFY(!prop1.isReadable());
    QVERIFY(!prop1.isWritable());
    QVERIFY(prop1.isResettable());
    QVERIFY(prop1.isDesignable());
    QVERIFY(!prop1.isScriptable());
    QVERIFY(prop1.isStored());
    QVERIFY(prop1.isEditable());
    QVERIFY(prop1.isUser());
    QVERIFY(prop1.hasStdCppSet());
    QVERIFY(prop1.isEnumOrFlag());
    QVERIFY(prop1.isConstant());
    QVERIFY(prop1.isFinal());
    QCOMPARE(prop1.revision(), 123);
    QVERIFY(prop2.isReadable());
    QVERIFY(prop2.isWritable());
    QCOMPARE(prop2.name(), QByteArray("bar"));
    QCOMPARE(prop2.type(), QByteArray("int"));
    QVERIFY(!prop2.isResettable());
    QVERIFY(!prop2.isDesignable());
    QVERIFY(prop2.isScriptable());
    QVERIFY(!prop2.isStored());
    QVERIFY(!prop2.isEditable());
    QVERIFY(!prop2.isUser());
    QVERIFY(!prop2.hasStdCppSet());
    QVERIFY(!prop2.isEnumOrFlag());
    QVERIFY(!prop2.isConstant());
    QVERIFY(!prop2.isFinal());
    QCOMPARE(prop2.revision(), 0);

    // Remove prop1 and check that prop2 becomes index 0.
    builder.removeProperty(0);
    QCOMPARE(builder.propertyCount(), 1);
    prop2 = builder.property(0);
    QCOMPARE(prop2.name(), QByteArray("bar"));
    QCOMPARE(prop2.type(), QByteArray("int"));
    QVERIFY(!prop2.isResettable());
    QVERIFY(!prop2.isDesignable());
    QVERIFY(prop2.isScriptable());
    QVERIFY(!prop2.isStored());
    QVERIFY(!prop2.isEditable());
    QVERIFY(!prop2.isUser());
    QVERIFY(!prop2.hasStdCppSet());
    QVERIFY(!prop2.isEnumOrFlag());
    QVERIFY(!prop2.isConstant());
    QVERIFY(!prop2.isFinal());
    QCOMPARE(prop2.revision(), 0);
    QCOMPARE(prop2.index(), 0);

    // Perform index-based lookup again.
    QCOMPARE(builder.indexOfProperty("foo"), -1);
    QCOMPARE(builder.indexOfProperty("bar"), 0);
    QCOMPARE(builder.indexOfProperty("baz"), -1);

    // Check for side-effects between the flags on prop2.
    // Setting a flag to true shouldn't set any of the others to true.
    // This checks for cut-and-paste bugs in the implementation where
    // the flag code was pasted but the flag name was not changed.
#define CLEAR_FLAGS() \
        do { \
            prop2.setReadable(false); \
            prop2.setWritable(false); \
            prop2.setResettable(false); \
            prop2.setDesignable(false); \
            prop2.setScriptable(false); \
            prop2.setStored(false); \
            prop2.setEditable(false); \
            prop2.setUser(false); \
            prop2.setStdCppSet(false); \
            prop2.setEnumOrFlag(false); \
            prop2.setConstant(false); \
            prop2.setFinal(false); \
        } while (0)
#define COUNT_FLAGS() \
        ((prop2.isReadable() ? 1 : 0) + \
         (prop2.isWritable() ? 1 : 0) + \
         (prop2.isResettable() ? 1 : 0) + \
         (prop2.isDesignable() ? 1 : 0) + \
         (prop2.isScriptable() ? 1 : 0) + \
         (prop2.isStored() ? 1 : 0) + \
         (prop2.isEditable() ? 1 : 0) + \
         (prop2.isUser() ? 1 : 0) + \
         (prop2.hasStdCppSet() ? 1 : 0) + \
         (prop2.isEnumOrFlag() ? 1 : 0) + \
         (prop2.isConstant() ? 1 : 0) + \
         (prop2.isFinal() ? 1 : 0))
#define CHECK_FLAG(setFunc,isFunc) \
        do { \
            CLEAR_FLAGS(); \
            QCOMPARE(COUNT_FLAGS(), 0); \
            prop2.setFunc(true); \
            QVERIFY(prop2.isFunc()); \
            QCOMPARE(COUNT_FLAGS(), 1); \
        } while (0)
    CHECK_FLAG(setReadable, isReadable);
    CHECK_FLAG(setWritable, isWritable);
    CHECK_FLAG(setResettable, isResettable);
    CHECK_FLAG(setDesignable, isDesignable);
    CHECK_FLAG(setScriptable, isScriptable);
    CHECK_FLAG(setStored, isStored);
    CHECK_FLAG(setEditable, isEditable);
    CHECK_FLAG(setUser, isUser);
    CHECK_FLAG(setStdCppSet, hasStdCppSet);
    CHECK_FLAG(setEnumOrFlag, isEnumOrFlag);
    CHECK_FLAG(setConstant, isConstant);
    CHECK_FLAG(setFinal, isFinal);

    // Check that nothing else changed.
    QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Properties));

    // Add property from prototype
    QMetaProperty prototype = SomethingOfEverything::staticMetaObject.property(1);
    QVERIFY(prototype.name() == QByteArray("prop"));
    QMetaPropertyBuilder prototypeProp = builder.addProperty(prototype);
    QCOMPARE(prototypeProp.name(), QByteArray("prop"));
    QVERIFY(prototypeProp.hasNotifySignal());
    QCOMPARE(prototypeProp.notifySignal().signature(), QByteArray("propChanged(QString)"));
    QCOMPARE(builder.methodCount(), 1);
    QCOMPARE(builder.method(0).signature(), QByteArray("propChanged(QString)"));
}

void tst_QMetaObjectBuilder::variantProperty()
{
    QMetaObjectBuilder builder;
    builder.addProperty("variant", "const QVariant &");
    QMetaObject *meta = builder.toMetaObject();

    QMetaProperty prop = meta->property(meta->propertyOffset());
    QCOMPARE(QMetaType::Type(prop.type()), QMetaType::QVariant);
    QCOMPARE(QMetaType::Type(prop.userType()), QMetaType::QVariant);
    QCOMPARE(QByteArray(prop.typeName()), QByteArray("QVariant"));

    free(meta);
}

void tst_QMetaObjectBuilder::notifySignal()
{
    QMetaObjectBuilder builder;

    QMetaPropertyBuilder prop = builder.addProperty("foo", "const QString &");
    builder.addSlot("setFoo(QString)");
    QMetaMethodBuilder notify = builder.addSignal("fooChanged(QString)");

    QVERIFY(!prop.hasNotifySignal());
    QCOMPARE(prop.notifySignal().index(), 0);

    prop.setNotifySignal(notify);
    QVERIFY(prop.hasNotifySignal());
    QCOMPARE(prop.notifySignal().index(), 1);

    prop.setNotifySignal(QMetaMethodBuilder());
    QVERIFY(!prop.hasNotifySignal());
    QCOMPARE(prop.notifySignal().index(), 0);

    prop.setNotifySignal(notify);
    prop.removeNotifySignal();
    QVERIFY(!prop.hasNotifySignal());
    QCOMPARE(prop.notifySignal().index(), 0);

    QCOMPARE(builder.methodCount(), 2);
    QCOMPARE(builder.propertyCount(), 1);

    // Check that nothing else changed except methods and properties.
    QVERIFY(checkForSideEffects
        (builder, QMetaObjectBuilder::Methods | QMetaObjectBuilder::Properties));
}

void tst_QMetaObjectBuilder::enumerator()
{
    QMetaObjectBuilder builder;

    // Add an enumerator and check its attributes.
    QMetaEnumBuilder enum1 = builder.addEnumerator("foo");
    QCOMPARE(enum1.name(), QByteArray("foo"));
    QVERIFY(!enum1.isFlag());
    QVERIFY(!enum1.isScoped());
    QCOMPARE(enum1.keyCount(), 0);
    QCOMPARE(enum1.index(), 0);
    QCOMPARE(builder.enumeratorCount(), 1);

    // Add another enumerator and check again.
    QMetaEnumBuilder enum2 = builder.addEnumerator("bar");
    QCOMPARE(enum2.name(), QByteArray("bar"));
    QVERIFY(!enum2.isFlag());
    QVERIFY(!enum2.isScoped());
    QCOMPARE(enum2.keyCount(), 0);
    QCOMPARE(enum2.index(), 1);
    QCOMPARE(builder.enumeratorCount(), 2);

    // Perform index-based lookup.
    QCOMPARE(builder.indexOfEnumerator("foo"), 0);
    QCOMPARE(builder.indexOfEnumerator("bar"), 1);
    QCOMPARE(builder.indexOfEnumerator("baz"), -1);
    QCOMPARE(builder.enumerator(1).name(), QByteArray("bar"));
    QCOMPARE(builder.enumerator(9).name(), QByteArray());

    // Modify the attributes on enum1.
    enum1.setIsFlag(true);
    enum1.setIsScoped(true);
    enum1.setEnumName(QByteArrayLiteral("fooFlag"));
    QCOMPARE(enum1.addKey("ABC", 0), 0);
    QCOMPARE(enum1.addKey("DEF", 1), 1);
    QCOMPARE(enum1.addKey("GHI", -1), 2);

    // Check that enum1 is changed, but enum2 is not.
    QCOMPARE(enum1.name(), QByteArray("foo"));
    QVERIFY(enum1.isFlag());
    QVERIFY(enum1.isScoped());
    QCOMPARE(enum1.enumName(), QByteArray("fooFlag"));
    QCOMPARE(enum1.keyCount(), 3);
    QCOMPARE(enum1.index(), 0);
    QCOMPARE(enum1.key(0), QByteArray("ABC"));
    QCOMPARE(enum1.key(1), QByteArray("DEF"));
    QCOMPARE(enum1.key(2), QByteArray("GHI"));
    QCOMPARE(enum1.key(3), QByteArray());
    QCOMPARE(enum1.value(0), 0);
    QCOMPARE(enum1.value(1), 1);
    QCOMPARE(enum1.value(2), -1);
    QCOMPARE(enum2.name(), QByteArray("bar"));
    QVERIFY(!enum2.isFlag());
    QVERIFY(!enum2.isScoped());
    QCOMPARE(enum2.keyCount(), 0);
    QCOMPARE(enum2.index(), 1);

    // Modify the attributes on enum2.
    enum2.setIsFlag(true);
    QCOMPARE(enum2.addKey("XYZ", 10), 0);
    QCOMPARE(enum2.addKey("UVW", 19), 1);

    // This time check that only method2 changed.
    QCOMPARE(enum1.name(), QByteArray("foo"));
    QVERIFY(enum1.isFlag());
    QVERIFY(enum1.isScoped());
    QCOMPARE(enum1.keyCount(), 3);
    QCOMPARE(enum1.index(), 0);
    QCOMPARE(enum1.key(0), QByteArray("ABC"));
    QCOMPARE(enum1.key(1), QByteArray("DEF"));
    QCOMPARE(enum1.key(2), QByteArray("GHI"));
    QCOMPARE(enum1.key(3), QByteArray());
    QCOMPARE(enum1.value(0), 0);
    QCOMPARE(enum1.value(1), 1);
    QCOMPARE(enum1.value(2), -1);
    QCOMPARE(enum2.name(), QByteArray("bar"));
    QVERIFY(enum2.isFlag());
    QVERIFY(!enum2.isScoped());
    QCOMPARE(enum2.keyCount(), 2);
    QCOMPARE(enum2.index(), 1);
    QCOMPARE(enum2.key(0), QByteArray("XYZ"));
    QCOMPARE(enum2.key(1), QByteArray("UVW"));
    QCOMPARE(enum2.key(2), QByteArray());
    QCOMPARE(enum2.value(0), 10);
    QCOMPARE(enum2.value(1), 19);

    // Remove enum1 key
    enum1.removeKey(2);
    QCOMPARE(enum1.name(), QByteArray("foo"));
    QVERIFY(enum1.isFlag());
    QVERIFY(enum1.isScoped());
    QCOMPARE(enum1.keyCount(), 2);
    QCOMPARE(enum1.index(), 0);
    QCOMPARE(enum1.key(0), QByteArray("ABC"));
    QCOMPARE(enum1.key(1), QByteArray("DEF"));
    QCOMPARE(enum1.key(2), QByteArray());
    QCOMPARE(enum1.value(0), 0);
    QCOMPARE(enum1.value(1), 1);
    QCOMPARE(enum1.value(2), -1);
    QCOMPARE(enum2.name(), QByteArray("bar"));
    QVERIFY(enum2.isFlag());
    QVERIFY(!enum2.isScoped());
    QCOMPARE(enum2.keyCount(), 2);
    QCOMPARE(enum2.index(), 1);
    QCOMPARE(enum2.key(0), QByteArray("XYZ"));
    QCOMPARE(enum2.key(1), QByteArray("UVW"));
    QCOMPARE(enum2.key(2), QByteArray());
    QCOMPARE(enum2.value(0), 10);
    QCOMPARE(enum2.value(1), 19);

    // Remove enum1 and check that enum2 becomes index 0.
    builder.removeEnumerator(0);
    QCOMPARE(builder.enumeratorCount(), 1);
    enum2 = builder.enumerator(0);
    QCOMPARE(enum2.name(), QByteArray("bar"));
    QVERIFY(enum2.isFlag());
    QVERIFY(!enum2.isScoped());
    QCOMPARE(enum2.keyCount(), 2);
    QCOMPARE(enum2.index(), 0);
    QCOMPARE(enum2.key(0), QByteArray("XYZ"));
    QCOMPARE(enum2.key(1), QByteArray("UVW"));
    QCOMPARE(enum2.key(2), QByteArray());
    QCOMPARE(enum2.value(0), 10);
    QCOMPARE(enum2.value(1), 19);

    // Perform index-based lookup again.
    QCOMPARE(builder.indexOfEnumerator("foo"), -1);
    QCOMPARE(builder.indexOfEnumerator("bar"), 0);
    QCOMPARE(builder.indexOfEnumerator("baz"), -1);

    // Check that nothing else changed.
    QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Enumerators));
}

void tst_QMetaObjectBuilder::classInfo()
{
    QMetaObjectBuilder builder;

    // Add two items of class information and check their attributes.
    QCOMPARE(builder.addClassInfo("foo", "value1"), 0);
    QCOMPARE(builder.addClassInfo("bar", "value2"), 1);
    QCOMPARE(builder.classInfoName(0), QByteArray("foo"));
    QCOMPARE(builder.classInfoValue(0), QByteArray("value1"));
    QCOMPARE(builder.classInfoName(1), QByteArray("bar"));
    QCOMPARE(builder.classInfoValue(1), QByteArray("value2"));
    QCOMPARE(builder.classInfoName(9), QByteArray());
    QCOMPARE(builder.classInfoValue(9), QByteArray());
    QCOMPARE(builder.classInfoCount(), 2);

    // Perform index-based lookup.
    QCOMPARE(builder.indexOfClassInfo("foo"), 0);
    QCOMPARE(builder.indexOfClassInfo("bar"), 1);
    QCOMPARE(builder.indexOfClassInfo("baz"), -1);

    // Remove the first one and check again.
    builder.removeClassInfo(0);
    QCOMPARE(builder.classInfoName(0), QByteArray("bar"));
    QCOMPARE(builder.classInfoValue(0), QByteArray("value2"));
    QCOMPARE(builder.classInfoCount(), 1);

    // Perform index-based lookup again.
    QCOMPARE(builder.indexOfClassInfo("foo"), -1);
    QCOMPARE(builder.indexOfClassInfo("bar"), 0);
    QCOMPARE(builder.indexOfClassInfo("baz"), -1);

    // Check that nothing else changed.
    QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::ClassInfos));
}

void tst_QMetaObjectBuilder::relatedMetaObject()
{
    QMetaObjectBuilder builder;

    // Add two related meta objects and check their attributes.
    QCOMPARE(builder.addRelatedMetaObject(&QObject::staticMetaObject), 0);
    QCOMPARE(builder.addRelatedMetaObject(&staticMetaObject), 1);
    QCOMPARE(builder.relatedMetaObject(0), &QObject::staticMetaObject);
    QCOMPARE(builder.relatedMetaObject(1), &staticMetaObject);
    QCOMPARE(builder.relatedMetaObjectCount(), 2);

    // Remove the first one and check again.
    builder.removeRelatedMetaObject(0);
    QCOMPARE(builder.relatedMetaObject(0), &staticMetaObject);
    QCOMPARE(builder.relatedMetaObjectCount(), 1);

    // Check that nothing else changed.
    QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::RelatedMetaObjects));
}

static void smetacall(QObject *, QMetaObject::Call, int, void **)
{
    return;
}

void tst_QMetaObjectBuilder::staticMetacall()
{
    QMetaObjectBuilder builder;
    QVERIFY(!builder.staticMetacallFunction());
    builder.setStaticMetacallFunction(smetacall);
    QVERIFY(builder.staticMetacallFunction() == smetacall);
    QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::StaticMetacall));
}

// Copy the entire contents of a static QMetaObject and then check
// that QMetaObjectBuilder will produce an exact copy as output.
void tst_QMetaObjectBuilder::copyMetaObject()
{
    QMetaObjectBuilder builder(&QObject::staticMetaObject);
    QMetaObject *meta = builder.toMetaObject();
    QVERIFY(sameMetaObject(meta, &QObject::staticMetaObject));
    free(meta);

    QMetaObjectBuilder builder2(&staticMetaObject);
    meta = builder2.toMetaObject();
    QVERIFY(sameMetaObject(meta, &staticMetaObject));
    free(meta);

    QMetaObjectBuilder builder3(&SomethingOfEverything::staticMetaObject);
    meta = builder3.toMetaObject();
    QVERIFY(sameMetaObject(meta, &SomethingOfEverything::staticMetaObject));
    free(meta);
}

// Serialize and deserialize a meta object and check that
// it round-trips to the exact same value.
void tst_QMetaObjectBuilder::serialize()
{
    // Full QMetaObjectBuilder
    {
    QMetaObjectBuilder builder(&SomethingOfEverything::staticMetaObject);
    QMetaObject *meta = builder.toMetaObject();

    QByteArray data;
    QDataStream stream(&data, QIODevice::WriteOnly | QIODevice::Append);
    builder.serialize(stream);

    QMetaObjectBuilder builder2;
    QDataStream stream2(data);
    QMap<QByteArray, const QMetaObject *> references;
    references.insert(QByteArray("QLocale"), &QLocale::staticMetaObject);
    builder2.deserialize(stream2, references);
    builder2.setStaticMetacallFunction(builder.staticMetacallFunction());
    QMetaObject *meta2 = builder2.toMetaObject();

    QVERIFY(sameMetaObject(meta, meta2));
    free(meta);
    free(meta2);
    }

    // Partial QMetaObjectBuilder
    {
    QMetaObjectBuilder builder;
    builder.setClassName("Test");
    builder.addProperty("foo", "int");

    QByteArray data;
    QDataStream stream(&data, QIODevice::WriteOnly | QIODevice::Append);
    builder.serialize(stream);

    QMetaObjectBuilder builder2;
    QDataStream stream2(data);
    builder2.deserialize(stream2, QMap<QByteArray, const QMetaObject *>());

    QCOMPARE(builder.superClass(), builder2.superClass());
    QCOMPARE(builder.className(), builder2.className());
    QCOMPARE(builder.propertyCount(), builder2.propertyCount());
    QCOMPARE(builder.property(0).name(), builder2.property(0).name());
    QCOMPARE(builder.property(0).type(), builder2.property(0).type());
    }
}

void tst_QMetaObjectBuilder::relocatableData()
{
    QMetaObjectBuilder builder;
    builder.setClassName("TestObject");

    QMetaMethodBuilder intPropChanged = builder.addSignal("intPropChanged(int)");
    intPropChanged.setParameterNames(QList<QByteArray>() << "newIntPropValue");

    QMetaPropertyBuilder prop = builder.addProperty("intProp", "int");
    prop.setNotifySignal(intPropChanged);

    QMetaMethodBuilder voidSlotInt = builder.addSlot("voidSlotInt(int)");
    voidSlotInt.setParameterNames(QList<QByteArray>() << "slotIntArg");

    QMetaMethodBuilder listInvokableQRealQString = builder.addMethod("listInvokableQRealQString(qreal,QString)");
    listInvokableQRealQString.setReturnType("QVariantList");
    listInvokableQRealQString.setParameterNames(QList<QByteArray>() << "qrealArg" << "qstringArg");

    bool ok = false;
    QByteArray data = builder.toRelocatableData(&ok);
    QVERIFY(ok);

    QMetaObjectBuilder builder2;
    QMetaObject meta2;
    builder2.fromRelocatableData(&meta2, &QObject::staticMetaObject, data);

    QMetaObject *meta = builder.toMetaObject();

    QVERIFY(sameMetaObject(meta, &meta2));

    QVERIFY(!meta2.d.extradata);
    QVERIFY(!meta2.d.relatedMetaObjects);
    QVERIFY(!meta2.d.static_metacall);

    free(meta);
}


// Check that removing a method updates notify signals appropriately
void tst_QMetaObjectBuilder::removeNotifySignal()
{
    QMetaObjectBuilder builder;

    builder.addSignal("foo(const QString&, int)");
    QMetaMethodBuilder method = builder.addSignal("bar(QString)");

    // Setup property
    QMetaPropertyBuilder prop = builder.addProperty("prop", "const QString &");
    prop.setNotifySignal(method);
    QVERIFY(prop.hasNotifySignal());
    QCOMPARE(prop.notifySignal().index(), 1);

    // Remove non-notify signal
    builder.removeMethod(0);
    QVERIFY(prop.hasNotifySignal());
    QCOMPARE(prop.notifySignal().index(), 0);

    // Remove notify signal
    builder.removeMethod(0);
    QVERIFY(!prop.hasNotifySignal());
}

// Check that the only changes to a "builder" relative to the default
// state is specified by "members".
bool tst_QMetaObjectBuilder::checkForSideEffects
        (const QMetaObjectBuilder& builder,
         QMetaObjectBuilder::AddMembers members)
{
    if ((members & QMetaObjectBuilder::ClassName) == 0) {
        if (!builder.className().isEmpty())
            return false;
    }

    if ((members & QMetaObjectBuilder::SuperClass) == 0) {
        if (builder.superClass() != &QObject::staticMetaObject)
            return false;
    }

    if ((members & QMetaObjectBuilder::Methods) == 0) {
        if (builder.methodCount() != 0)
            return false;
    }

    if ((members & QMetaObjectBuilder::Constructors) == 0) {
        if (builder.constructorCount() != 0)
            return false;
    }

    if ((members & QMetaObjectBuilder::Properties) == 0) {
        if (builder.propertyCount() != 0)
            return false;
    }

    if ((members & QMetaObjectBuilder::Enumerators) == 0) {
        if (builder.enumeratorCount() != 0)
            return false;
    }

    if ((members & QMetaObjectBuilder::ClassInfos) == 0) {
        if (builder.classInfoCount() != 0)
            return false;
    }

    if ((members & QMetaObjectBuilder::RelatedMetaObjects) == 0) {
        if (builder.relatedMetaObjectCount() != 0)
            return false;
    }

    if ((members & QMetaObjectBuilder::StaticMetacall) == 0) {
        if (builder.staticMetacallFunction() != 0)
            return false;
    }

    return true;
}

static bool sameMethod(const QMetaMethod& method1, const QMetaMethod& method2)
{
    if (method1.methodSignature() != method2.methodSignature())
        return false;

    if (QByteArray(method1.typeName()) != QByteArray(method2.typeName()))
        return false;

    if (method1.parameterTypes() != method2.parameterTypes())
        return false;

    if (method1.parameterNames() != method2.parameterNames())
        return false;

    if (QByteArray(method1.tag()) != QByteArray(method2.tag()))
        return false;

    if (method1.access() != method2.access())
        return false;

    if (method1.methodType() != method2.methodType())
        return false;

    if (method1.attributes() != method2.attributes())
        return false;

    if (method1.revision() != method2.revision())
        return false;

    return true;
}

static bool sameProperty(const QMetaProperty& prop1, const QMetaProperty& prop2)
{
    if (QByteArray(prop1.name()) != QByteArray(prop2.name()))
        return false;

    if (QByteArray(prop1.typeName()) != QByteArray(prop2.typeName()))
        return false;

    if (prop1.isReadable() != prop2.isReadable() ||
        prop1.isWritable() != prop2.isWritable() ||
        prop1.isResettable() != prop2.isResettable() ||
        prop1.isDesignable() != prop2.isDesignable() ||
        prop1.isScriptable() != prop2.isScriptable() ||
        prop1.isStored() != prop2.isStored() ||
        prop1.isEditable() != prop2.isEditable() ||
        prop1.isUser() != prop2.isUser() ||
        prop1.isFlagType() != prop2.isFlagType() ||
        prop1.isEnumType() != prop2.isEnumType() ||
        prop1.hasNotifySignal() != prop2.hasNotifySignal() ||
        prop1.hasStdCppSet() != prop2.hasStdCppSet())
        return false;

    if (prop1.hasNotifySignal()) {
        if (prop1.notifySignalIndex() != prop2.notifySignalIndex())
            return false;
    }

    if (prop1.revision() != prop2.revision())
        return false;

    return true;
}

static bool sameEnumerator(const QMetaEnum& enum1, const QMetaEnum& enum2)
{
    if (QByteArray(enum1.name()) != QByteArray(enum2.name()))
        return false;

    if (enum1.isFlag() != enum2.isFlag())
        return false;

    if (enum1.keyCount() != enum2.keyCount())
        return false;

    for (int index = 0; index < enum1.keyCount(); ++index) {
        if (QByteArray(enum1.key(index)) != QByteArray(enum2.key(index)))
            return false;
        if (enum1.value(index) != enum2.value(index))
            return false;
    }

    if (QByteArray(enum1.scope()) != QByteArray(enum2.scope()))
        return false;

    return true;
}

// Determine if two meta objects are identical.
bool tst_QMetaObjectBuilder::sameMetaObject
        (const QMetaObject *meta1, const QMetaObject *meta2)
{
    int index;

    if (strcmp(meta1->className(), meta2->className()) != 0)
        return false;

    if (meta1->superClass() != meta2->superClass())
        return false;

    if (meta1->constructorCount() != meta2->constructorCount() ||
        meta1->methodCount() != meta2->methodCount() ||
        meta1->enumeratorCount() != meta2->enumeratorCount() ||
        meta1->propertyCount() != meta2->propertyCount() ||
        meta1->classInfoCount() != meta2->classInfoCount())
        return false;

    for (index = 0; index < meta1->constructorCount(); ++index) {
        if (!sameMethod(meta1->constructor(index), meta2->constructor(index)))
            return false;
    }

    for (index = 0; index < meta1->methodCount(); ++index) {
        if (!sameMethod(meta1->method(index), meta2->method(index)))
            return false;
    }

    for (index = 0; index < meta1->propertyCount(); ++index) {
        if (!sameProperty(meta1->property(index), meta2->property(index)))
            return false;
    }

    for (index = 0; index < meta1->enumeratorCount(); ++index) {
        if (!sameEnumerator(meta1->enumerator(index), meta2->enumerator(index)))
            return false;
    }

    for (index = 0; index < meta1->classInfoCount(); ++index) {
        if (QByteArray(meta1->classInfo(index).name()) !=
            QByteArray(meta2->classInfo(index).name()))
            return false;
        if (QByteArray(meta1->classInfo(index).value()) !=
            QByteArray(meta2->classInfo(index).value()))
            return false;
    }

    const auto *objects1 = meta1->d.relatedMetaObjects;
    const auto *objects2 = meta2->d.relatedMetaObjects;
    if (objects1 && !objects2)
        return false;
    if (objects2 && !objects1)
        return false;
    if (objects1 && objects2) {
        while (*objects1 != 0 && *objects2 != 0) {
            if (*objects1 != *objects2)
                return false;
            ++objects1;
            ++objects2;
        }
    }

    return true;
}


// This class is used to test that the meta-object generated by QMOB can be
// used by a real object.
// The class manually implements the functions normally generated by moc, and
// creates the corresponding meta-object using QMOB. The autotests check that
// this object can be used by QObject/QMetaObject functionality (property
// access, signals & slots, constructing instances, ...).

class TestObject : public QObject
{
    // Manually expanded from Q_OBJECT macro
public:
    Q_OBJECT_CHECK
    static QMetaObject staticMetaObject;
    virtual const QMetaObject *metaObject() const;
    virtual void *qt_metacast(const char *);
    virtual int qt_metacall(QMetaObject::Call, int, void **);
private:
    Q_DECL_HIDDEN static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);

    //Q_PROPERTY(int intProp READ intProp WRITE setIntProp NOTIFY intPropChanged)
public:
    TestObject(QObject *parent = 0); // Q_INVOKABLE
    ~TestObject();

    // Property accessors
    int intProp() const;
    void setIntProp(int v);

    void emitIntPropChanged();

    int voidSlotIntArgument() const;

// Q_INVOKABLE
    QVariantList listInvokableQRealQString(qreal, const QString &);

//public Q_SLOTS:
    void voidSlotInt(int);

//Q_SIGNALS:
    void intPropChanged(int);

private:
    static QMetaObject *buildMetaObject();

    QMetaObject *m_metaObject;
    int m_intProp;
    int m_voidSlotIntArg;
};

QMetaObject TestObject::staticMetaObject = {
    { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }
};

TestObject::TestObject(QObject *parent)
    : QObject(parent), m_metaObject(buildMetaObject()),
      m_intProp(-1), m_voidSlotIntArg(-1)
{
    staticMetaObject = *m_metaObject;
}

TestObject::~TestObject()
{
    free(m_metaObject);
}

QMetaObject *TestObject::buildMetaObject()
{
    QMetaObjectBuilder builder;
    // NOTE: If you change the meta-object, remember to adapt qt_metacall and
    // friends below accordingly.

    builder.setClassName("TestObject");

    builder.setStaticMetacallFunction(qt_static_metacall);

    QMetaMethodBuilder intPropChanged = builder.addSignal("intPropChanged(int)");
    intPropChanged.setParameterNames(QList<QByteArray>() << "newIntPropValue");

    QMetaPropertyBuilder prop = builder.addProperty("intProp", "int");
    prop.setNotifySignal(intPropChanged);

    QMetaMethodBuilder voidSlotInt = builder.addSlot("voidSlotInt(int)");
    voidSlotInt.setParameterNames(QList<QByteArray>() << "slotIntArg");

    QMetaMethodBuilder listInvokableQRealQString = builder.addMethod("listInvokableQRealQString(qreal,QString)");
    listInvokableQRealQString.setReturnType("QVariantList");
    listInvokableQRealQString.setParameterNames(QList<QByteArray>() << "qrealArg" << "qstringArg");

    builder.addConstructor("TestObject(QObject*)");
    builder.addConstructor("TestObject()");

    return builder.toMetaObject();
}

int TestObject::intProp() const
{
    return m_intProp;
}

void TestObject::setIntProp(int value)
{
    if (m_intProp != value) {
        m_intProp = value;
        emit intPropChanged(value);
    }
}

void TestObject::emitIntPropChanged()
{
    emit intPropChanged(m_intProp);
}

QVariantList TestObject::listInvokableQRealQString(qreal r, const QString &s)
{
    return QVariantList() << r << s;
}

void TestObject::voidSlotInt(int value)
{
    m_voidSlotIntArg = value;
}

int TestObject::voidSlotIntArgument() const
{
    return m_voidSlotIntArg;
}

void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
    if (_c == QMetaObject::CreateInstance) {
        switch (_id) {
        case 0: { TestObject *_r = new TestObject((*reinterpret_cast< QObject*(*)>(_a[1])));
            if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;
        case 1: { TestObject *_r = new TestObject();
            if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;
        default: {
            QMetaMethod ctor = _o->metaObject()->constructor(_id);
            qFatal("You forgot to add a case for CreateInstance %s", ctor.methodSignature().constData());
          }
        }
    } else if (_c == QMetaObject::InvokeMetaMethod) {
        Q_ASSERT(_o->metaObject()->cast(_o));
        TestObject *_t = static_cast<TestObject *>(_o);
        switch (_id) {
        case 0: _t->intPropChanged((*reinterpret_cast< int(*)>(_a[1]))); break;
        case 1: _t->voidSlotInt((*reinterpret_cast< int(*)>(_a[1]))); break;
        case 2: *reinterpret_cast<QVariantList(*)>(_a[0]) = _t->listInvokableQRealQString(*reinterpret_cast<qreal(*)>(_a[1]), *reinterpret_cast<QString(*)>(_a[2])); break;
        default: {
            QMetaMethod method = _o->metaObject()->method(_o->metaObject()->methodOffset() + _id);
            qFatal("You forgot to add a case for InvokeMetaMethod %s", method.methodSignature().constData());
          }
        }
    } else if (_c == QMetaObject::IndexOfMethod) {
        int *result = reinterpret_cast<int *>(_a[0]);
        void **func = reinterpret_cast<void **>(_a[1]);
        {
            typedef void (TestObject::*_t)(int );
            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&TestObject::intPropChanged)) {
                *result = 0;
            }
        }
        {
            typedef void (TestObject::*_t)(int );
            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&TestObject::voidSlotInt)) {
                *result = 1;
            }
        }
        {
            typedef QVariantList (TestObject::*_t)(qreal, const QString &);
            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&TestObject::listInvokableQRealQString)) {
                *result = 2;
            }
        }
    }
}

const QMetaObject *TestObject::metaObject() const
{
    return m_metaObject;
}

void *TestObject::qt_metacast(const char *_clname)
{
    if (!_clname) return 0;
    if (!strcmp(_clname, "TestObject"))
        return static_cast<void*>(const_cast< TestObject*>(this));
    return QObject::qt_metacast(_clname);
}

int TestObject::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QObject::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    int ownMethodCount = m_metaObject->methodCount() - m_metaObject->methodOffset();
    int ownPropertyCount = m_metaObject->propertyCount() - m_metaObject->propertyOffset();
    if (_c == QMetaObject::InvokeMetaMethod) {
        if (_id < ownMethodCount)
            qt_static_metacall(this, _c, _id, _a);
        _id -= ownMethodCount;
    }
#ifndef QT_NO_PROPERTIES
      else if (_c == QMetaObject::ReadProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: *reinterpret_cast< int*>(_v) = intProp(); break;
        default: if (_id < ownPropertyCount) {
            QMetaProperty prop = m_metaObject->property(m_metaObject->propertyOffset() + _id);
            qFatal("You forgot to add a case for ReadProperty %s", prop.name());
          }
        }
        _id -= ownPropertyCount;
    } else if (_c == QMetaObject::WriteProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: setIntProp(*reinterpret_cast< int*>(_v)); break;
        default: if (_id < ownPropertyCount) {
            QMetaProperty prop = m_metaObject->property(m_metaObject->propertyOffset() + _id);
            qFatal("You forgot to add a case for WriteProperty %s", prop.name());
          }
        }
        _id -= ownPropertyCount;
    } else if (_c == QMetaObject::ResetProperty) {
        _id -= ownPropertyCount;
    } else if (_c == QMetaObject::QueryPropertyDesignable) {
        _id -= ownPropertyCount;
    } else if (_c == QMetaObject::QueryPropertyScriptable) {
        _id -= ownPropertyCount;
    } else if (_c == QMetaObject::QueryPropertyStored) {
        _id -= ownPropertyCount;
    } else if (_c == QMetaObject::QueryPropertyEditable) {
        _id -= ownPropertyCount;
    } else if (_c == QMetaObject::QueryPropertyUser) {
        _id -= ownPropertyCount;
    }
#endif // QT_NO_PROPERTIES
    return _id;
}

// SIGNAL 0
void TestObject::intPropChanged(int _t1)
{
    void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
    QMetaObject::activate(this, m_metaObject, 0, _a);
}


void tst_QMetaObjectBuilder::usage_signal()
{
    QScopedPointer<TestObject> testObject(new TestObject);

    QSignalSpy propChangedSpy(testObject.data(), &TestObject::intPropChanged);
    testObject->emitIntPropChanged();
    QCOMPARE(propChangedSpy.count(), 1);
    QCOMPARE(propChangedSpy.at(0).count(), 1);
    QCOMPARE(propChangedSpy.at(0).at(0).toInt(), testObject->intProp());
}

void tst_QMetaObjectBuilder::usage_property()
{
    QScopedPointer<TestObject> testObject(new TestObject);

    QVariant prop = testObject->property("intProp");
    QCOMPARE(prop.type(), QVariant::Int);
    QCOMPARE(prop.toInt(), testObject->intProp());

    QSignalSpy propChangedSpy(testObject.data(), &TestObject::intPropChanged);
    QVERIFY(testObject->intProp() != 123);
    testObject->setProperty("intProp", 123);
    QCOMPARE(propChangedSpy.count(), 1);
    prop = testObject->property("intProp");
    QCOMPARE(prop.type(), QVariant::Int);
    QCOMPARE(prop.toInt(), 123);
}

void tst_QMetaObjectBuilder::usage_slot()
{
    QScopedPointer<TestObject> testObject(new TestObject);

    int index = testObject->metaObject()->indexOfMethod("voidSlotInt(int)");
    QVERIFY(index != -1);
    QMetaMethod voidSlotInt = testObject->metaObject()->method(index);

    QCOMPARE(testObject->voidSlotIntArgument(), -1);
    QVERIFY(voidSlotInt.invoke(testObject.data(), Q_ARG(int, 123)));
    QCOMPARE(testObject->voidSlotIntArgument(), 123);
}

void tst_QMetaObjectBuilder::usage_method()
{
    QScopedPointer<TestObject> testObject(new TestObject);

    int index = testObject->metaObject()->indexOfMethod("listInvokableQRealQString(qreal,QString)");
    QVERIFY(index != -1);
    QMetaMethod listInvokableQRealQString = testObject->metaObject()->method(index);
    QVariantList list;
    QVERIFY(listInvokableQRealQString.invoke(testObject.data(), Q_RETURN_ARG(QVariantList, list),
                                             Q_ARG(qreal, 123.0), Q_ARG(QString, "ciao")));
    QCOMPARE(list.size(), 2);
    QCOMPARE(list.at(0).type(), QVariant::Type(QMetaType::QReal));
    QCOMPARE(list.at(0).toDouble(), double(123));
    QCOMPARE(list.at(1).type(), QVariant::String);
    QCOMPARE(list.at(1).toString(), QString::fromLatin1("ciao"));
}

void tst_QMetaObjectBuilder::usage_constructor()
{
    QScopedPointer<TestObject> testObject(new TestObject);

    QCOMPARE(testObject->metaObject()->constructorCount(), 2);
    QScopedPointer<QObject> testInstance(testObject->metaObject()->newInstance());
    QVERIFY(testInstance != 0);
    QScopedPointer<QObject> testInstance2(testObject->metaObject()->newInstance(Q_ARG(QObject*, testInstance.data())));
    QVERIFY(testInstance2 != 0);
    QCOMPARE(testInstance2->parent(), testInstance.data());
}

void tst_QMetaObjectBuilder::usage_connect()
{
    QScopedPointer<TestObject> testObject(new TestObject);

    QVERIFY(QObject::connect(testObject.data(), SIGNAL(intPropChanged(int)),
                             testObject.data(), SLOT(voidSlotInt(int))));

    QCOMPARE(testObject->voidSlotIntArgument(), -1);
    testObject->setProperty("intProp", 123);
    QCOMPARE(testObject->voidSlotIntArgument(), 123);

    QVERIFY(QObject::disconnect(testObject.data(), SIGNAL(intPropChanged(int)),
                                testObject.data(), SLOT(voidSlotInt(int))));
}

void tst_QMetaObjectBuilder::usage_templateConnect()
{
    QScopedPointer<TestObject> testObject(new TestObject);

    QMetaObject::Connection con = QObject::connect(testObject.data(), &TestObject::intPropChanged,
                                                   testObject.data(), &TestObject::voidSlotInt);
    QVERIFY(con);

    QCOMPARE(testObject->voidSlotIntArgument(), -1);
    testObject->setProperty("intProp", 123);
    QCOMPARE(testObject->voidSlotIntArgument(), 123);

    QVERIFY(QObject::disconnect(testObject.data(), &TestObject::intPropChanged,
                                testObject.data(), &TestObject::voidSlotInt));

    // Something that isn't a signal
    QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in TestObject");
    con = QObject::connect(testObject.data(), &TestObject::setIntProp,
                           testObject.data(), &TestObject::intPropChanged);
    QVERIFY(!con);
}

void tst_QMetaObjectBuilder::classNameFirstInStringData()
{
    QMetaObjectBuilder builder;
    builder.addMetaObject(&SomethingOfEverything::staticMetaObject);
    builder.setClassName(QByteArrayLiteral("TestClass"));
    QMetaObject *mo = builder.toMetaObject();

    QByteArrayDataPtr header;
    header.ptr = const_cast<QByteArrayData*>(mo->d.stringdata);
    QCOMPARE(QByteArray(header), QByteArrayLiteral("TestClass"));

    free(mo);
}

QTEST_MAIN(tst_QMetaObjectBuilder)

#include "tst_qmetaobjectbuilder.moc"
