aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/ApiExtractor/tests
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/ApiExtractor/tests')
-rw-r--r--sources/shiboken2/ApiExtractor/tests/CMakeLists.txt73
-rw-r--r--sources/shiboken2/ApiExtractor/tests/a.xml13
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp527
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h55
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp216
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h47
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp453
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testaddfunction.h54
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp129
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testarrayargument.h42
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp106
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcodeinjection.h45
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcontainer.cpp105
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcontainer.h41
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp188
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testconversionoperator.h44
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testconversionruletag.cpp250
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testconversionruletag.h43
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testctorinformation.cpp76
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testctorinformation.h44
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp145
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testdroptypeentries.h44
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp86
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testdtorinformation.h46
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testenum.cpp416
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testenum.h47
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp85
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testextrainclude.h42
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testfunctiontag.cpp97
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testfunctiontag.h42
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp163
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testimplicitconversions.h46
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testinserttemplate.cpp130
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testinserttemplate.h44
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp80
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.h41
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp249
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h45
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.cpp74
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.h43
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testnamespace.cpp96
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testnamespace.h44
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp128
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testnestedtypes.h41
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp119
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.h42
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.cpp60
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.h41
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp100
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testrefcounttag.h42
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp59
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testreferencetopointer.h41
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testremovefield.cpp62
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testremovefield.h41
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp69
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testremoveimplconv.h41
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.cpp116
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.h41
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp64
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testresolvetype.h41
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testreverseoperators.cpp138
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testreverseoperators.h41
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtemplates.cpp438
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtemplates.h51
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtoposort.cpp69
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtoposort.h42
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp71
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtyperevision.h42
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testutil.h66
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.cpp64
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.h41
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testvoidarg.cpp87
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testvoidarg.h42
-rw-r--r--sources/shiboken2/ApiExtractor/tests/utf8code.txt1
74 files changed, 6997 insertions, 0 deletions
diff --git a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
new file mode 100644
index 000000000..5429c1cb8
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
@@ -0,0 +1,73 @@
+find_package(Qt5Core)
+find_package(Qt5Gui)
+find_package(Qt5Test)
+find_package(Qt5Xml)
+find_package(Qt5XmlPatterns)
+
+macro(declare_test testname)
+ # gone: qt4_automoc("${testname}.cpp")
+ if (EXISTS "${testname}.h")
+ add_executable(${testname} "${testname}.h ${testname}.cpp")
+ else ()
+ add_executable(${testname} "${testname}.cpp")
+ endif ()
+ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${apiextractor_SOURCE_DIR}
+ ${Qt5Test_INCLUDE_DIRS}
+ )
+ target_link_libraries(${testname}
+ ${Qt5XmlPatterns_LIBRARIES}
+ ${Qt5Test_LIBRARIES}
+ ${Qt5Core_LIBRARIES}
+ ${Qt5Gui_LIBRARIES}
+ apiextractor)
+ add_test(${testname} ${testname})
+ if (INSTALL_TESTS)
+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${testname}
+ DESTINATION share/apiextractor${apiextractor_SUFFIX}/tests)
+ endif()
+endmacro(declare_test testname)
+
+declare_test(testabstractmetaclass)
+declare_test(testabstractmetatype)
+declare_test(testaddfunction)
+declare_test(testarrayargument)
+declare_test(testcodeinjection)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/utf8code.txt"
+ "${CMAKE_CURRENT_BINARY_DIR}/utf8code.txt" COPYONLY)
+declare_test(testcontainer)
+declare_test(testconversionoperator)
+declare_test(testconversionruletag)
+declare_test(testctorinformation)
+declare_test(testdroptypeentries)
+declare_test(testdtorinformation)
+declare_test(testenum)
+declare_test(testextrainclude)
+declare_test(testfunctiontag)
+declare_test(testimplicitconversions)
+declare_test(testinserttemplate)
+declare_test(testmodifyfunction)
+declare_test(testmultipleinheritance)
+declare_test(testnamespace)
+declare_test(testnestedtypes)
+declare_test(testnumericaltypedef)
+declare_test(testprimitivetypetag)
+declare_test(testrefcounttag)
+declare_test(testreferencetopointer)
+declare_test(testremovefield)
+declare_test(testremoveimplconv)
+declare_test(testremoveoperatormethod)
+declare_test(testresolvetype)
+declare_test(testreverseoperators)
+declare_test(testtemplates)
+declare_test(testtoposort)
+declare_test(testvaluetypedefaultctortag)
+declare_test(testvoidarg)
+declare_test(testtyperevision)
+if (NOT DISABLE_DOCSTRINGS)
+ declare_test(testmodifydocumentation)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/a.xml"
+ "${CMAKE_CURRENT_BINARY_DIR}/a.xml" COPYONLY)
+endif()
+
diff --git a/sources/shiboken2/ApiExtractor/tests/a.xml b/sources/shiboken2/ApiExtractor/tests/a.xml
new file mode 100644
index 000000000..1c6d62a17
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/a.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+
+<WebXML>
+ <document>
+ <class name="A">
+ <description>oi
+ <para>Paragraph number 1</para>
+ <para>Paragraph number 2</para>
+ <para>Paragraph number 3</para>
+ </description>
+ </class>
+ </document>
+</WebXML>
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
new file mode 100644
index 000000000..028522159
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
@@ -0,0 +1,527 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testabstractmetaclass.h"
+#include "abstractmetabuilder.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestAbstractMetaClass::testClassName()
+{
+ const char* cppCode ="class ClassName {};";
+ const char* xmlCode = "<typesystem package=\"Foo\"><value-type name=\"ClassName\"/></typesystem>";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 1);
+ QCOMPARE(classes[0]->name(), QLatin1String("ClassName"));
+}
+
+void TestAbstractMetaClass::testClassNameUnderNamespace()
+{
+ const char* cppCode ="namespace Namespace { class ClassName {}; }\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <namespace-type name=\"Namespace\"/>\n\
+ <value-type name=\"Namespace::ClassName\"/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2); // 1 namespace + 1 class
+ if (classes.first()->name() != QLatin1String("ClassName"))
+ classes.swap(0, 1);
+
+ QCOMPARE(classes[0]->name(), QLatin1String("ClassName"));
+ QCOMPARE(classes[0]->qualifiedCppName(), QLatin1String("Namespace::ClassName"));
+ QCOMPARE(classes[1]->name(), QLatin1String("Namespace"));
+ QVERIFY(classes[1]->isNamespace());
+
+ // Check ctors info
+ QVERIFY(classes[0]->hasConstructors());
+ QCOMPARE(classes[0]->functions().size(), 2); // default ctor + copy ctor
+
+ AbstractMetaFunctionList ctors = classes[0]->queryFunctions(AbstractMetaClass::Constructors);
+ QCOMPARE(ctors.size(), 2);
+ if (ctors.first()->minimalSignature() != QLatin1String("ClassName()"))
+ ctors.swap(0, 1);
+
+ QCOMPARE(ctors[0]->arguments().size(), 0);
+ QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("ClassName()"));
+ QCOMPARE(ctors[1]->arguments().size(), 1);
+ QCOMPARE(ctors[1]->minimalSignature(), QLatin1String("ClassName(Namespace::ClassName)"));
+
+ QVERIFY(!classes[0]->hasPrivateDestructor());
+ QVERIFY(classes[0]->hasCloneOperator()); // implicit default copy ctor
+ QVERIFY(!classes[0]->hasHashFunction());
+
+ // This method is buggy and nobody wants to fix it or needs it fixed :-/
+ // QVERIFY(classes[0]->hasNonPrivateConstructor());
+}
+
+void TestAbstractMetaClass::testVirtualMethods()
+{
+ const char* cppCode ="\
+ class A {\n\
+ public:\n\
+ virtual int pureVirtual() const = 0;\n\
+ };\n\
+ class B : public A {};\n\
+ class C : public B {\n\
+ public:\n\
+ int pureVirtual() const { return 0; }\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <primitive-type name='int'/>\n\
+ <object-type name='A'/>\n\
+ <object-type name='B'/>\n\
+ <object-type name='C'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 3);
+ AbstractMetaClass* a = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ AbstractMetaClass* b = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ AbstractMetaClass* c = AbstractMetaClass::findClass(classes, QLatin1String("C"));
+
+ AbstractMetaClass* no_class = 0;
+
+ QCOMPARE(a->baseClass(), no_class);
+ QCOMPARE(b->baseClass(), a);
+ QCOMPARE(c->baseClass(), b);
+
+ QCOMPARE(a->functions().size(), 2); // default ctor + the pure virtual method
+ QCOMPARE(b->functions().size(), 2);
+ QCOMPARE(c->functions().size(), 2);
+
+ // implementing class, ownclass, declaringclass
+ AbstractMetaFunction* ctorA = a->queryFunctions(AbstractMetaClass::Constructors).first();
+ AbstractMetaFunction* ctorB = b->queryFunctions(AbstractMetaClass::Constructors).first();
+ AbstractMetaFunction* ctorC = c->queryFunctions(AbstractMetaClass::Constructors).first();
+ QVERIFY(ctorA->isConstructor());
+ QVERIFY(!ctorA->isVirtual());
+ QVERIFY(ctorB->isConstructor());
+ QVERIFY(!ctorB->isVirtual());
+ QVERIFY(ctorC->isConstructor());
+ QVERIFY(!ctorC->isVirtual());
+ QCOMPARE(ctorA->implementingClass(), a);
+ QCOMPARE(ctorA->ownerClass(), a);
+ QCOMPARE(ctorA->declaringClass(), a);
+
+ QCOMPARE(a->virtualFunctions().size(), 1); // Add a pureVirtualMethods method !?
+ QCOMPARE(b->virtualFunctions().size(), 1);
+ QCOMPARE(c->virtualFunctions().size(), 1);
+
+ AbstractMetaFunction* funcA = a->virtualFunctions().first();
+ AbstractMetaFunction* funcB = b->virtualFunctions().first();
+ AbstractMetaFunction* funcC = c->virtualFunctions().first();
+
+ QCOMPARE(funcA->ownerClass(), a);
+ QCOMPARE(funcB->ownerClass(), b);
+ QCOMPARE(funcC->ownerClass(), c);
+
+ QCOMPARE(funcA->declaringClass(), a);
+ QCOMPARE(funcB->declaringClass(), a);
+ QCOMPARE(funcC->declaringClass(), a);
+
+ // The next two tests could return null, because it makes more sense.
+ // But we have too many code written relying on this behaviour where
+ // implementingClass is equals to declaringClass on pure virtual functions
+ QCOMPARE(funcA->implementingClass(), a);
+ QCOMPARE(funcB->implementingClass(), a);
+ QCOMPARE(funcC->implementingClass(), c);
+}
+
+void TestAbstractMetaClass::testDefaultValues()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ class B {};\n\
+ void method(B b = B());\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A'/>\n\
+ <value-type name='A::B'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classA->queryFunctionsByName(QLatin1String("method")).count(), 1);
+ AbstractMetaFunction* method = classA->queryFunctionsByName(QLatin1String("method")).first();
+ AbstractMetaArgument* arg = method->arguments().first();
+ QCOMPARE(arg->defaultValueExpression(), arg->originalDefaultValueExpression());
+}
+
+void TestAbstractMetaClass::testModifiedDefaultValues()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ class B {};\n\
+ void method(B b = B());\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A'>\n\
+ <modify-function signature='method(A::B)'>\n\
+ <modify-argument index='1'>\n\
+ <replace-default-expression with='Hello'/>\n\
+ </modify-argument>\n\
+ </modify-function>\n\
+ </value-type>\n\
+ <value-type name='A::B'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classA->queryFunctionsByName(QLatin1String("method")).count(), 1);
+ AbstractMetaFunction* method = classA->queryFunctionsByName(QLatin1String("method")).first();
+ AbstractMetaArgument* arg = method->arguments().first();
+ QCOMPARE(arg->defaultValueExpression(), QLatin1String("Hello"));
+ QCOMPARE(arg->originalDefaultValueExpression(), QLatin1String("A::B()"));
+}
+
+void TestAbstractMetaClass::testInnerClassOfAPolymorphicOne()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ class B {};\n\
+ virtual void method();\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <object-type name='A'/>\n\
+ <value-type name='A::B'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QVERIFY(classA->isPolymorphic());
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("A::B"));
+ QVERIFY(classB);
+ QVERIFY(!classB->isPolymorphic());
+}
+
+void TestAbstractMetaClass::testForwardDeclaredInnerClass()
+{
+ const char cppCode[] ="\
+ class A {\n\
+ class B;\n\
+ };\n\
+ class A::B {\n\
+ public:\n\
+ void foo();\n\
+ };\n";
+ const char xmlCode[] = "\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A'/>\n\
+ <value-type name='A::B'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("A::B"));
+ QVERIFY(classB);
+ const AbstractMetaFunction *fooF = classB->findFunction(QLatin1String("foo"));
+ QVERIFY(fooF);
+}
+
+void TestAbstractMetaClass::testSpecialFunctions()
+{
+ const char cppCode[] ="\
+ struct A {\n\
+ A();\n\
+ A(const A&);\n\
+ A &operator=(const A&);\n\
+ };\n\
+ struct B {\n\
+ B();\n\
+ B(const B &);\n\
+ B &operator=(B);\n\
+ };\n";
+ const char xmlCode[] = "\
+ <typesystem package=\"Foo\">\n\
+ <object-type name='A'/>\n\
+ <object-type name='B'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors);
+ QCOMPARE(ctors.size(), 2);
+ QCOMPARE(ctors.first()->functionType(), AbstractMetaFunction::ConstructorFunction);
+ QCOMPARE(ctors.at(1)->functionType(), AbstractMetaFunction::CopyConstructorFunction);
+ AbstractMetaFunctionList assigmentOps = classA->queryFunctionsByName(QLatin1String("operator="));
+ QCOMPARE(assigmentOps.size(), 1);
+ QCOMPARE(assigmentOps.first()->functionType(), AbstractMetaFunction::AssignmentOperatorFunction);
+
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classB);
+ ctors = classB->queryFunctions(AbstractMetaClass::Constructors);
+ QCOMPARE(ctors.size(), 2);
+ QCOMPARE(ctors.first()->functionType(), AbstractMetaFunction::ConstructorFunction);
+ QCOMPARE(ctors.at(1)->functionType(), AbstractMetaFunction::CopyConstructorFunction);
+ assigmentOps = classA->queryFunctionsByName(QLatin1String("operator="));
+ QCOMPARE(assigmentOps.size(), 1);
+ QCOMPARE(assigmentOps.first()->functionType(), AbstractMetaFunction::AssignmentOperatorFunction);
+}
+
+void TestAbstractMetaClass::testClassDefaultConstructors()
+{
+ const char* cppCode ="\
+ struct A {};\n\
+ \n\
+ struct B {\n\
+ B();\n\
+ private: \n\
+ B(const B&);\n\
+ };\n\
+ \n\
+ struct C {\n\
+ C(const C&);\n\
+ };\n\
+ \n\
+ struct D {\n\
+ private: \n\
+ D(const D&);\n\
+ };\n\
+ \n\
+ struct E {\n\
+ private: \n\
+ ~E();\n\
+ };\n\
+ \n\
+ struct F {\n\
+ F(int, int);\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <value-type name='A'/>\n\
+ <object-type name='B'/>\n\
+ <value-type name='C'/>\n\
+ <object-type name='D'/>\n\
+ <object-type name='E'/>\n\
+ <value-type name='F'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 6);
+
+ AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QCOMPARE(classA->functions().size(), 2);
+
+ AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors);
+ QCOMPARE(ctors.size(), 2);
+ if (ctors.first()->minimalSignature() != QLatin1String("A()"))
+ ctors.swap(0, 1);
+
+ QCOMPARE(ctors[0]->arguments().size(), 0);
+ QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("A()"));
+ QCOMPARE(ctors[1]->arguments().size(), 1);
+ QCOMPARE(ctors[1]->minimalSignature(), QLatin1String("A(A)"));
+
+ AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classB);
+ QCOMPARE(classB->functions().size(), 2);
+ QCOMPARE(classB->functions().first()->minimalSignature(), QLatin1String("B()"));
+
+ AbstractMetaClass* classC = AbstractMetaClass::findClass(classes, QLatin1String("C"));
+ QVERIFY(classC);
+ QCOMPARE(classC->functions().size(), 1);
+ QCOMPARE(classC->functions().first()->minimalSignature(), QLatin1String("C(C)"));
+
+ AbstractMetaClass* classD = AbstractMetaClass::findClass(classes, QLatin1String("D"));
+ QVERIFY(classD);
+ QCOMPARE(classD->functions().size(), 1);
+ QCOMPARE(classD->functions().first()->minimalSignature(), QLatin1String("D(D)"));
+ QVERIFY(classD->functions().first()->isPrivate());
+
+ AbstractMetaClass* classE = AbstractMetaClass::findClass(classes, QLatin1String("E"));
+ QVERIFY(classE);
+ QVERIFY(classE->hasPrivateDestructor());
+ QCOMPARE(classE->functions().size(), 0);
+
+ AbstractMetaClass* classF = AbstractMetaClass::findClass(classes, QLatin1String("F"));
+ QVERIFY(classF);
+
+ ctors = classF->queryFunctions(AbstractMetaClass::Constructors);
+ QCOMPARE(ctors.size(), 2);
+ if (ctors.first()->minimalSignature() != QLatin1String("F(int,int)"))
+ ctors.swap(0, 1);
+
+ QCOMPARE(ctors[0]->arguments().size(), 2);
+ QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("F(int,int)"));
+ QCOMPARE(ctors[1]->arguments().size(), 1);
+ QCOMPARE(ctors[1]->minimalSignature(), QLatin1String("F(F)"));
+}
+
+void TestAbstractMetaClass::testClassInheritedDefaultConstructors()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ A();\n\
+ private: \n\
+ A(const A&);\n\
+ };\n\
+ struct B : public A {};\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <object-type name='A'/>\n\
+ <object-type name='B'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+
+ AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors);
+ QCOMPARE(ctors.size(), 2);
+ if (ctors.first()->minimalSignature() != QLatin1String("A()"))
+ ctors.swap(0, 1);
+
+ QCOMPARE(ctors[0]->arguments().size(), 0);
+ QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("A()"));
+ QCOMPARE(ctors[1]->arguments().size(), 1);
+ QCOMPARE(ctors[1]->minimalSignature(), QLatin1String("A(A)"));
+ QVERIFY(ctors[1]->isPrivate());
+
+ AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classB);
+
+ ctors = classB->queryFunctions(AbstractMetaClass::Constructors);
+ QCOMPARE(ctors.size(), 1);
+ QCOMPARE(ctors.first()->arguments().size(), 0);
+ QCOMPARE(ctors.first()->minimalSignature(), QLatin1String("B()"));
+}
+
+void TestAbstractMetaClass::testAbstractClassDefaultConstructors()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ virtual void method() = 0;\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <object-type name='A'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 1);
+ AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+
+ AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors);
+ QCOMPARE(ctors.size(), 1);
+ QCOMPARE(ctors.first()->arguments().size(), 0);
+ QCOMPARE(ctors.first()->minimalSignature(), QLatin1String("A()"));
+}
+
+void TestAbstractMetaClass::testObjectTypesMustNotHaveCopyConstructors()
+{
+ const char* cppCode ="struct A {};\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <object-type name='A'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 1);
+ AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+
+ AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors);
+ QCOMPARE(ctors.size(), 1);
+ QCOMPARE(ctors.first()->arguments().size(), 0);
+ QCOMPARE(ctors.first()->minimalSignature(), QLatin1String("A()"));
+}
+
+void TestAbstractMetaClass::testIsPolymorphic()
+{
+ const char* cppCode = "\
+ class A\n\
+ {\n\
+ public:\n\
+ A();\n\
+ inline bool abc() const {}\n\
+ };\n\
+ \n\
+ class B : public A\n\
+ {\n\
+ public:\n\
+ B();\n\
+ inline bool abc() const {}\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='bool'/>\n\
+ <value-type name='A'/>\n\
+ <value-type name='B'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ AbstractMetaClass* b = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+
+ QVERIFY(!b->isPolymorphic());
+ AbstractMetaClass* a = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(!a->isPolymorphic());
+}
+
+QTEST_APPLESS_MAIN(TestAbstractMetaClass)
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h
new file mode 100644
index 000000000..811bf5a10
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTABSTRACTMETACLASS_H
+#define TESTABSTRACTMETACLASS_H
+
+#include <QObject>
+
+class AbstractMetaBuilder;
+
+class TestAbstractMetaClass : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testClassName();
+ void testClassNameUnderNamespace();
+ void testVirtualMethods();
+ void testDefaultValues();
+ void testModifiedDefaultValues();
+ void testInnerClassOfAPolymorphicOne();
+ void testForwardDeclaredInnerClass();
+ void testSpecialFunctions();
+ void testClassDefaultConstructors();
+ void testClassInheritedDefaultConstructors();
+ void testAbstractClassDefaultConstructors();
+ void testObjectTypesMustNotHaveCopyConstructors();
+ void testIsPolymorphic();
+};
+
+#endif // TESTABSTRACTMETACLASS_H
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
new file mode 100644
index 000000000..1d52c1e41
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testabstractmetatype.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestAbstractMetaType::testConstCharPtrType()
+{
+ const char* cppCode ="const char* justAtest();\n";
+ const char* xmlCode = "<typesystem package=\"Foo\">\n\
+ <primitive-type name='char'/>\n\
+ <function signature='justAtest()' />\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ QCOMPARE(builder->globalFunctions().size(), 1);
+ AbstractMetaFunction* func = builder->globalFunctions().first();
+ AbstractMetaType* rtype = func->type();
+ // Test properties of const char*
+ QVERIFY(rtype);
+ QCOMPARE(rtype->package(), QLatin1String("Foo"));
+ QCOMPARE(rtype->name(), QLatin1String("char"));
+ QVERIFY(rtype->isConstant());
+ QVERIFY(!rtype->isArray());
+ QVERIFY(!rtype->isContainer());
+ QVERIFY(!rtype->isObject());
+ QVERIFY(!rtype->isPrimitive()); // const char* differs from char, so it's not considered a primitive type by apiextractor
+ QVERIFY(rtype->isNativePointer());
+ QVERIFY(!rtype->isQObject());
+ QCOMPARE(rtype->referenceType(), NoReference);
+ QVERIFY(!rtype->isValue());
+ QVERIFY(!rtype->isValuePointer());
+}
+
+void TestAbstractMetaType::testApiVersionSupported()
+{
+ const char* cppCode ="class foo {}; class foo2 {};\n\
+ void justAtest(); void justAtest3();\n";
+ const char* xmlCode = "<typesystem package='Foo'>\n\
+ <value-type name='foo' since='0.1'/>\n\
+ <value-type name='foo2' since='1.0'/>\n\
+ <value-type name='foo3' since='1.1'/>\n\
+ <function signature='justAtest()' since='0.1'/>\n\
+ <function signature='justAtest2()' since='1.1'/>\n\
+ <function signature='justAtest3()'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, "1.0"));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.size(), 2);
+
+
+ AbstractMetaFunctionList functions = builder->globalFunctions();
+ QCOMPARE(functions.size(), 2);
+}
+
+
+void TestAbstractMetaType::testApiVersionNotSupported()
+{
+ const char* cppCode ="class object {};\n";
+ const char* xmlCode = "<typesystem package='Foo'>\n\
+ <value-type name='object' since='0.1'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "0.1"));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.size(), 1);
+}
+
+void TestAbstractMetaType::testCharType()
+{
+ const char* cppCode ="char justAtest(); class A {};\n";
+ const char* xmlCode = "<typesystem package=\"Foo\">\n\
+ <primitive-type name='char'/>\n\
+ <value-type name='A'/>\n\
+ <function signature='justAtest()'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.size(), 1);
+ QCOMPARE(classes.first()->package(), QLatin1String("Foo"));
+
+ AbstractMetaFunctionList functions = builder->globalFunctions();
+ QCOMPARE(functions.size(), 1);
+ AbstractMetaFunction* func = functions.first();
+ AbstractMetaType* rtype = func->type();
+ // Test properties of const char*
+ QVERIFY(rtype);
+ QCOMPARE(rtype->package(), QLatin1String("Foo"));
+ QCOMPARE(rtype->name(), QLatin1String("char"));
+ QVERIFY(!rtype->isConstant());
+ QVERIFY(!rtype->isArray());
+ QVERIFY(!rtype->isContainer());
+ QVERIFY(!rtype->isObject());
+ QVERIFY(rtype->isPrimitive());
+ QVERIFY(!rtype->isNativePointer());
+ QVERIFY(!rtype->isQObject());
+ QCOMPARE(rtype->referenceType(), NoReference);
+ QVERIFY(!rtype->isValue());
+ QVERIFY(!rtype->isValuePointer());
+}
+
+void TestAbstractMetaType::testTypedef()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ void someMethod();\n\
+ };\n\
+ typedef A B;\n\
+ typedef B C;\n";
+ const char* xmlCode = "<typesystem package=\"Foo\">\n\
+ <value-type name='C' />\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.size(), 1);
+ const AbstractMetaClass *c = AbstractMetaClass::findClass(classes, QLatin1String("C"));
+ QVERIFY(c);
+ QVERIFY(c->isTypeDef());
+}
+
+void TestAbstractMetaType::testTypedefWithTemplates()
+{
+ const char* cppCode ="\
+ template<typename T>\n\
+ class A {};\n\
+ \n\
+ class B {};\n\
+ typedef A<B> C;\n\
+ \n\
+ void func(C c);\n";
+ const char* xmlCode = "<typesystem package=\"Foo\">\n\
+ <container-type name='A' type='list'/>\n\
+ <value-type name='B' />\n\
+ <function signature='func(A&lt;B&gt;)'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.size(), 1);
+ AbstractMetaFunctionList functions = builder->globalFunctions();
+ QCOMPARE(functions.count(), 1);
+ AbstractMetaFunction* function = functions.first();
+ AbstractMetaArgumentList args = function->arguments();
+ QCOMPARE(args.count(), 1);
+ AbstractMetaArgument* arg = args.first();
+ AbstractMetaType* metaType = arg->type();
+ QCOMPARE(metaType->cppSignature(), QLatin1String("A<B >"));
+}
+
+
+void TestAbstractMetaType::testObjectTypeUsedAsValue()
+{
+ const char* cppCode ="\
+ class A {\n\
+ void method(A);\n\
+ };\n";
+ const char* xmlCode = "<typesystem package='Foo'>\n\
+ <object-type name='A'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.size(), 1);
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ AbstractMetaFunctionList overloads = classA->queryFunctionsByName(QLatin1String("method"));
+ QCOMPARE(overloads.count(), 1);
+ AbstractMetaFunction* method = overloads.first();
+ QVERIFY(method);
+ AbstractMetaArgumentList args = method->arguments();
+ QCOMPARE(args.count(), 1);
+ AbstractMetaArgument* arg = args.first();
+ AbstractMetaType* metaType = arg->type();
+ QCOMPARE(metaType->cppSignature(), QLatin1String("A"));
+ QVERIFY(metaType->isValue());
+ QVERIFY(metaType->typeEntry()->isObject());
+}
+
+QTEST_APPLESS_MAIN(TestAbstractMetaType)
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h
new file mode 100644
index 000000000..a806d36e3
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTABSTRACTMETATYPE_H
+#define TESTABSTRACTMETATYPE_H
+
+#include <QObject>
+
+class TestAbstractMetaType : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testConstCharPtrType();
+ void testCharType();
+ void testTypedef();
+ void testTypedefWithTemplates();
+ void testApiVersionSupported();
+ void testApiVersionNotSupported();
+ void testObjectTypeUsedAsValue();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
new file mode 100644
index 000000000..6e1da17ae
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
@@ -0,0 +1,453 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testaddfunction.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestAddFunction::testParsingFuncNameAndConstness()
+{
+ // generic test...
+ const char sig1[] = "func(type1, const type2, const type3* const)";
+ AddedFunction f1(QLatin1String(sig1), QLatin1String("void"), 0);
+ QCOMPARE(f1.name(), QLatin1String("func"));
+ QCOMPARE(f1.arguments().count(), 3);
+ AddedFunction::TypeInfo retval = f1.returnType();
+ QCOMPARE(retval.name, QLatin1String("void"));
+ QCOMPARE(retval.indirections, 0);
+ QCOMPARE(retval.isConstant, false);
+ QCOMPARE(retval.isReference, false);
+
+ // test with a ugly template as argument and other ugly stuff
+ const char sig2[] = " _fu__nc_ ( type1, const type2, const Abc<int& , C<char*> * > * *, const type3* const ) const ";
+ AddedFunction f2(QLatin1String(sig2), QLatin1String("const Abc<int& , C<char*> * > * *"), 0);
+ QCOMPARE(f2.name(), QLatin1String("_fu__nc_"));
+ QList< AddedFunction::TypeInfo > args = f2.arguments();
+ QCOMPARE(args.count(), 4);
+ retval = f2.returnType();
+ QCOMPARE(retval.name, QLatin1String("Abc<int& , C<char*> * >"));
+ QCOMPARE(retval.indirections, 2);
+ QCOMPARE(retval.isConstant, true);
+ QCOMPARE(retval.isReference, false);
+ retval = args[2];
+ QCOMPARE(retval.name, QLatin1String("Abc<int& , C<char*> * >"));
+ QCOMPARE(retval.indirections, 2);
+ QCOMPARE(retval.isConstant, true);
+ QCOMPARE(retval.isReference, false);
+
+ // function with no args.
+ const char sig3[] = "func()";
+ AddedFunction f3(QLatin1String(sig3), QLatin1String("void"), 0);
+ QCOMPARE(f3.name(), QLatin1String("func"));
+ QCOMPARE(f3.arguments().count(), 0);
+}
+
+void TestAddFunction::testAddFunction()
+{
+ const char cppCode[] = "struct B {}; struct A { void a(int); };\n";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <primitive-type name='float'/>\n\
+ <value-type name='B'/>\n\
+ <value-type name='A'>\n\
+ <add-function signature='b(int, float = 4.6, const B&amp;)' return-type='int' access='protected'>\n\
+ </add-function>\n\
+ </value-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ TypeDatabase* typeDb = TypeDatabase::instance();
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QCOMPARE(classA->functions().count(), 4); // default ctor, default copy ctor, func a() and the added function
+
+ AbstractMetaFunction* addedFunc = classA->functions().last();
+ QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Protected);
+ QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction);
+ QVERIFY(addedFunc->isUserAdded());
+ QCOMPARE(addedFunc->ownerClass(), classA);
+ QCOMPARE(addedFunc->implementingClass(), classA);
+ QCOMPARE(addedFunc->declaringClass(), classA);
+ QVERIFY(!addedFunc->isVirtual());
+ QVERIFY(!addedFunc->isSignal());
+ QVERIFY(!addedFunc->isSlot());
+ QVERIFY(!addedFunc->isStatic());
+
+ AbstractMetaType* returnType = addedFunc->type();
+ QCOMPARE(returnType->typeEntry(), typeDb->findPrimitiveType(QLatin1String("int")));
+ AbstractMetaArgumentList args = addedFunc->arguments();
+ QCOMPARE(args.count(), 3);
+ QCOMPARE(args[0]->type()->typeEntry(), returnType->typeEntry());
+ QCOMPARE(args[1]->defaultValueExpression(), QLatin1String("4.6"));
+ QCOMPARE(args[2]->type()->typeEntry(), typeDb->findType(QLatin1String("B")));
+}
+
+void TestAddFunction::testAddFunctionConstructor()
+{
+ const char cppCode[] = "struct A { A() {} };\n";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <value-type name='A'>\n\
+ <add-function signature='A(int)'/>\n\
+ </value-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QCOMPARE(classA->functions().count(), 3); // default and added ctors
+ AbstractMetaFunction* addedFunc = classA->functions().last();
+ QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Public);
+ QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::ConstructorFunction);
+ QCOMPARE(addedFunc->arguments().size(), 1);
+ QVERIFY(addedFunc->isUserAdded());
+ QVERIFY(!addedFunc->type());
+}
+
+void TestAddFunction::testAddFunctionTagDefaultValues()
+{
+ const char cppCode[] = "struct A {};\n";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <value-type name='A'>\n\
+ <add-function signature='func()'/>\n\
+ </value-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QCOMPARE(classA->functions().count(), 3); // default ctor, default copy ctor and the added function
+ AbstractMetaFunction* addedFunc = classA->functions().last();
+ QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Public);
+ QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction);
+ QVERIFY(addedFunc->isUserAdded());
+ QVERIFY(!addedFunc->type());
+}
+
+void TestAddFunction::testAddFunctionCodeSnippets()
+{
+ const char cppCode[] = "struct A {};\n";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <value-type name='A'>\n\
+ <add-function signature='func()'>\n\
+ <inject-code class='target' position='end'>Hi!, I am the code.</inject-code>\n\
+ </add-function>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ AbstractMetaFunction* addedFunc = classA->functions().last();
+ QVERIFY(addedFunc->hasInjectedCode());
+}
+
+void TestAddFunction::testAddFunctionWithoutParenteses()
+{
+ const char sig1[] = "func";
+ AddedFunction f1(QLatin1String(sig1), QLatin1String("void"), 0);
+
+ QCOMPARE(f1.name(), QLatin1String("func"));
+ QCOMPARE(f1.arguments().count(), 0);
+ QCOMPARE(f1.isConstant(), false);
+
+ const char cppCode[] = "struct A {};\n";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <value-type name='A'>\n\
+ <add-function signature='func'>\n\
+ <inject-code class='target' position='end'>Hi!, I am the code.</inject-code>\n\
+ </add-function>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("func"));
+ QVERIFY(addedFunc);
+ QVERIFY(addedFunc->hasInjectedCode());
+ QCOMPARE(addedFunc->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode).count(), 1);
+}
+
+void TestAddFunction::testAddFunctionWithDefaultArgs()
+{
+ const char sig1[] = "func";
+ AddedFunction f1(QLatin1String(sig1), QLatin1String("void"), 0);
+
+ QCOMPARE(f1.name(), QLatin1String("func"));
+ QCOMPARE(f1.arguments().count(), 0);
+ QCOMPARE(f1.isConstant(), false);
+
+ const char cppCode[] = "struct A { };\n";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <value-type name='A'>\n\
+ <add-function signature='func(int, int)'>\n\
+ <modify-argument index='2'>\n\
+ <replace-default-expression with='2'/>\n\
+ </modify-argument>\n\
+ </add-function>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("func"));
+ QVERIFY(addedFunc);
+ AbstractMetaArgument *arg = addedFunc->arguments()[1];
+ QCOMPARE(arg->defaultValueExpression(), QLatin1String("2"));
+}
+
+void TestAddFunction::testAddFunctionAtModuleLevel()
+{
+ const char cppCode[] = "struct A { };\n";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <value-type name='A'/>\n\
+ <add-function signature='func(int, int)'>\n\
+ <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\
+ </add-function>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+
+ TypeDatabase* typeDb = TypeDatabase::instance();
+
+ AddedFunctionList addedFuncs = typeDb->findGlobalUserFunctions(QLatin1String("func"));
+
+ QCOMPARE(addedFuncs.size(), 1);
+
+ FunctionModificationList mods = typeDb->functionModifications(QLatin1String("func(int,int)"));
+
+ QCOMPARE(mods.size(), 1);
+ QVERIFY(mods.first().isCodeInjection());
+ CodeSnip snip = mods.first().snips.first();
+ QCOMPARE(snip.code(), QLatin1String("custom_code();"));
+}
+
+void TestAddFunction::testAddFunctionWithVarargs()
+{
+ const char sig1[] = "func(int,char,...)";
+ AddedFunction f1( QLatin1String(sig1), QLatin1String("void"), 0);
+
+ QCOMPARE(f1.name(), QLatin1String("func"));
+ QCOMPARE(f1.arguments().count(), 3);
+ QVERIFY(!f1.isConstant());
+
+ const char cppCode[] = "struct A {};\n";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <primitive-type name='char'/>\n\
+ <value-type name='A'>\n\
+ <add-function signature='func(int,char,...)'/>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("func"));
+ QVERIFY(addedFunc);
+ const AbstractMetaArgument* arg = addedFunc->arguments().last();
+ QVERIFY(arg->type()->isVarargs());
+ QVERIFY(arg->type()->typeEntry()->isVarargs());
+}
+
+void TestAddFunction::testAddStaticFunction()
+{
+ const char cppCode[] = "struct A { };\n";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <value-type name='A'>\n\
+ <add-function signature='func(int, int)' static='yes'>\n\
+ <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\
+ </add-function>\n\
+ </value-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("func"));
+ QVERIFY(addedFunc);
+ QVERIFY(addedFunc->isStatic());
+}
+
+void TestAddFunction::testAddGlobalFunction()
+{
+ const char cppCode[] = "struct A { };struct B {};\n";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <value-type name='A'/>\n\
+ <add-function signature='globalFunc(int, int)' static='yes'>\n\
+ <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\
+ </add-function>\n\
+ <add-function signature='globalFunc2(int, int)' static='yes'>\n\
+ <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\
+ </add-function>\n\
+ <value-type name='B'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaFunctionList globalFuncs = builder->globalFunctions();
+ QCOMPARE(globalFuncs.count(), 2);
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(builder->classes(), QLatin1String("B"));
+ QVERIFY(classB);
+ QVERIFY(!classB->findFunction(QLatin1String("globalFunc")));
+ QVERIFY(!classB->findFunction(QLatin1String("globalFunc2")));
+ QVERIFY(!globalFuncs[0]->injectedCodeSnips().isEmpty());
+ QVERIFY(!globalFuncs[1]->injectedCodeSnips().isEmpty());
+}
+
+void TestAddFunction::testAddFunctionWithApiVersion()
+{
+ const char cppCode[] = "";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <add-function signature='globalFunc(int, int)' static='yes' since='1.3'>\n\
+ <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\
+ </add-function>\n\
+ <add-function signature='globalFunc2(int, int)' static='yes' since='0.1'>\n\
+ <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\
+ </add-function>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "0.1"));
+ QVERIFY(!builder.isNull());
+ AbstractMetaFunctionList globalFuncs = builder->globalFunctions();
+ QCOMPARE(globalFuncs.count(), 1);
+}
+
+void TestAddFunction::testModifyAddedFunction()
+{
+ const char cppCode[] = "class Foo { };\n";
+ const char xmlCode[] = "\
+ <typesystem package='Package'>\n\
+ <primitive-type name='float'/>\n\
+ <primitive-type name='int'/>\n\
+ <value-type name='Foo'>\n\
+ <add-function signature='method(float, int)'>\n\
+ <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\
+ <modify-argument index='2'>\n\
+ <replace-default-expression with='0'/>\n\
+ <rename to='varName'/>\n\
+ </modify-argument>\n\
+ </add-function>\n\
+ </value-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ AbstractMetaClass* foo = AbstractMetaClass::findClass(classes, QLatin1String("Foo"));
+ const AbstractMetaFunction* method = foo->findFunction(QLatin1String("method"));
+ QCOMPARE(method->arguments().size(), 2);
+ AbstractMetaArgument* arg = method->arguments().at(1);
+ QCOMPARE(arg->defaultValueExpression(), QLatin1String("0"));
+ QCOMPARE(arg->name(), QLatin1String("varName"));
+ QCOMPARE(method->argumentName(2), QLatin1String("varName"));
+}
+
+void TestAddFunction::testAddFunctionOnTypedef()
+{
+ const char cppCode[] = "template<class T> class Foo { }; typedef Foo<int> FooInt;\n";
+ const char xmlCode[] = "\
+ <typesystem package='Package'>\n\
+ <custom-type name='PySequence'/>\n\
+ <primitive-type name='int'/>\n\
+ <value-type name='FooInt'>\n\
+ <add-function signature='FooInt(PySequence)'>\n\
+ <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\
+ </add-function>\n\
+ <add-function signature='method()'>\n\
+ <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\
+ </add-function>\n\
+ </value-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ AbstractMetaClass* foo = AbstractMetaClass::findClass(classes, QLatin1String("FooInt"));
+ QVERIFY(foo);
+ QVERIFY(foo->hasNonPrivateConstructor());
+ AbstractMetaFunctionList lst = foo->queryFunctions(AbstractMetaClass::Constructors);
+ foreach(AbstractMetaFunction* f, lst)
+ QVERIFY(f->signature().startsWith(f->name()));
+ QCOMPARE(lst.size(), 2);
+ const AbstractMetaFunction* method = foo->findFunction(QLatin1String("method"));
+ QVERIFY(method);
+}
+
+void TestAddFunction::testAddFunctionWithTemplateArg()
+{
+ const char cppCode[] = "template<class T> class Foo { };\n";
+ const char xmlCode[] = "\
+ <typesystem package='Package'>\n\
+ <primitive-type name='int'/>\n\
+ <container-type name='Foo' type='list'/>\n\
+ <add-function signature='func(Foo&lt;int>)'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ QCOMPARE(builder->globalFunctions().size(), 1);
+ AbstractMetaFunction* func = builder->globalFunctions().first();
+ AbstractMetaArgument* arg = func->arguments().first();
+ QCOMPARE(arg->type()->instantiations().count(), 1);
+}
+
+QTEST_APPLESS_MAIN(TestAddFunction)
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.h b/sources/shiboken2/ApiExtractor/tests/testaddfunction.h
new file mode 100644
index 000000000..16a4ede09
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testaddfunction.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTADDFUNCTION_H
+#define TESTADDFUNCTION_H
+#include <QObject>
+
+class TestAddFunction : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testParsingFuncNameAndConstness();
+ void testAddFunction();
+ void testAddFunctionConstructor();
+ void testAddFunctionTagDefaultValues();
+ void testAddFunctionCodeSnippets();
+ void testAddFunctionWithoutParenteses();
+ void testAddFunctionWithDefaultArgs();
+ void testAddFunctionAtModuleLevel();
+ void testAddFunctionWithVarargs();
+ void testAddStaticFunction();
+ void testAddGlobalFunction();
+ void testAddFunctionWithApiVersion();
+ void testModifyAddedFunction();
+ void testAddFunctionOnTypedef();
+ void testAddFunctionWithTemplateArg();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp b/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp
new file mode 100644
index 000000000..5385c9140
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testarrayargument.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestArrayArgument::testArrayArgumentWithSizeDefinedByInteger()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ enum SomeEnum { Value0, Value1, NValues };\n\
+ void method(double[3]);\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='double'/>\n\
+ <object-type name='A'>\n\
+ <enum-type name='SomeEnum'/>\n\
+ </object-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ QVERIFY(classA);
+
+ const AbstractMetaArgument* arg = classA->functions().last()->arguments().first();
+ QVERIFY(arg->type()->isArray());
+ QCOMPARE(arg->type()->arrayElementCount(), 3);
+ QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double"));
+}
+
+void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValue()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ enum SomeEnum { Value0, Value1, NValues };\n\
+ void method(double[NValues]);\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='double'/>\n\
+ <object-type name='A'>\n\
+ <enum-type name='SomeEnum'/>\n\
+ </object-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ QVERIFY(classA);
+
+ AbstractMetaEnum* someEnum = classA->findEnum(QLatin1String("SomeEnum"));
+ QVERIFY(someEnum);
+ AbstractMetaEnumValue* nvalues = classA->findEnumValue(QLatin1String("NValues"), someEnum);
+ QVERIFY(nvalues);
+
+ const AbstractMetaArgument* arg = classA->functions().last()->arguments().first();
+ QVERIFY(arg->type()->isArray());
+ QCOMPARE(arg->type()->arrayElementCount(), nvalues->value());
+ QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double"));
+};
+
+void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnum()
+{
+ const char* cppCode ="\
+ enum SomeEnum { Value0, Value1, NValues };\n\
+ struct A {\n\
+ void method(double[NValues]);\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='double'/>\n\
+ <enum-type name='SomeEnum'/>\n\
+ <object-type name='A'>\n\
+ </object-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ QVERIFY(classA);
+
+ AbstractMetaEnum* someEnum = builder->globalEnums().first();
+ QVERIFY(someEnum);
+ AbstractMetaEnumValue* nvalues = 0;
+ foreach (AbstractMetaEnumValue* enumValue, someEnum->values()) {
+ if (enumValue->name() == QLatin1String("NValues")) {
+ nvalues = enumValue;
+ break;
+ }
+ }
+ QVERIFY(nvalues);
+
+ const AbstractMetaArgument* arg = classA->functions().last()->arguments().first();
+ QVERIFY(arg->type()->isArray());
+ QCOMPARE(arg->type()->arrayElementCount(), nvalues->value());
+ QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double"));
+};
+
+QTEST_APPLESS_MAIN(TestArrayArgument)
diff --git a/sources/shiboken2/ApiExtractor/tests/testarrayargument.h b/sources/shiboken2/ApiExtractor/tests/testarrayargument.h
new file mode 100644
index 000000000..b50232ef4
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testarrayargument.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTARRAYARGUMENT_H
+#define TESTARRAYARGUMENT_H
+#include <QObject>
+
+class TestArrayArgument : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testArrayArgumentWithSizeDefinedByInteger();
+ void testArrayArgumentWithSizeDefinedByEnumValue();
+ void testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnum();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
new file mode 100644
index 000000000..ad245633e
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testcodeinjection.h"
+#include <QFileInfo>
+#include <QDir>
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestCodeInjections::testReadFileUtf8()
+{
+ const char* cppCode ="struct A {};\n";
+ int argc = 0;
+ char *argv[] = {NULL};
+ QCoreApplication app(argc, argv);
+ QString filePath = QDir::currentPath();
+ QString xmlCode = QLatin1String("\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A'>\n\
+ <conversion-rule file='") + filePath + QLatin1String("/utf8code.txt'/>\n\
+ <inject-code class='target' file='") + filePath
+ + QLatin1String("/utf8code.txt'/>\n\
+ </value-type>\n\
+ <value-type name='A::B'/>\n\
+ </typesystem>\n");
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode.toLocal8Bit().constData()));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classA->typeEntry()->codeSnips().count(), 1);
+ QString code = classA->typeEntry()->codeSnips().first().code();
+ QString utf8Data = QString::fromUtf8("\xC3\xA1\xC3\xA9\xC3\xAD\xC3\xB3\xC3\xBA");
+ QVERIFY(code.indexOf(utf8Data) != -1);
+ code = classA->typeEntry()->conversionRule();
+ QVERIFY(code.indexOf(utf8Data) != -1);
+}
+
+void TestCodeInjections::testInjectWithValidApiVersion()
+{
+ const char* cppCode ="struct A {};\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <value-type name='A'>\n\
+ <inject-code class='target' since='1.0'>\n\
+ test Inject code\n\
+ </inject-code>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "1.0"));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classA->typeEntry()->codeSnips().count(), 1);
+}
+
+void TestCodeInjections::testInjectWithInvalidApiVersion()
+{
+ const char* cppCode ="struct A {};\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A'>\n\
+ <inject-code class='target' since='1.0'>\n\
+ test Inject code\n\
+ </inject-code>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "0.1"));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classA->typeEntry()->codeSnips().count(), 0);
+}
+
+
+
+QTEST_APPLESS_MAIN(TestCodeInjections)
diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h
new file mode 100644
index 000000000..56c1c7cba
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTCODEINJECTIONS_H
+#define TESTCODEINJECTIONS_H
+
+#include <QObject>
+
+class AbstractMetaBuilder;
+
+class TestCodeInjections : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testReadFileUtf8();
+ void testInjectWithValidApiVersion();
+ void testInjectWithInvalidApiVersion();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp b/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp
new file mode 100644
index 000000000..1c79a5a7a
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testcontainer.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestContainer::testContainerType()
+{
+ const char* cppCode ="\
+ namespace std {\n\
+ template<class T>\n\
+ class list {\n\
+ T get(int x) { return 0; }\n\
+ };\n\
+ }\n\
+ class A : public std::list<int> {\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <namespace-type name='std' generate='no' />\n\
+ <container-type name='std::list' type='list' />\n\
+ <object-type name='A'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ //search for class A
+ AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QVERIFY(classA->typeEntry()->baseContainerType());
+ QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(classA->typeEntry()->baseContainerType())->type(), ContainerTypeEntry::ListContainer);
+}
+
+void TestContainer::testListOfValueType()
+{
+ const char* cppCode ="\
+ namespace std {\n\
+ template<class T>\n\
+ class list {\n\
+ T get(int x) { return 0; }\n\
+ };\n\
+ }\n\
+ class ValueType {};\n\
+ class A : public std::list<ValueType> {\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <namespace-type name='std' generate='no'/>\n\
+ <container-type name='std::list' type='list'/>\n\
+ <value-type name='ValueType'/>\n\
+ <value-type name='A'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 3);
+
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QCOMPARE(classA->templateBaseClassInstantiations().count(), 1);
+ const AbstractMetaType* templateInstanceType = classA->templateBaseClassInstantiations().first();
+ QVERIFY(templateInstanceType);
+
+ QCOMPARE(templateInstanceType->indirections(), 0);
+ QVERIFY(!templateInstanceType->typeEntry()->isObject());
+ QVERIFY(templateInstanceType->typeEntry()->isValue());
+ QCOMPARE(templateInstanceType->referenceType(), NoReference);
+ QVERIFY(!templateInstanceType->isObject());
+ QVERIFY(!templateInstanceType->isValuePointer());
+ QVERIFY(templateInstanceType->isValue());
+}
+
+QTEST_APPLESS_MAIN(TestContainer)
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testcontainer.h b/sources/shiboken2/ApiExtractor/tests/testcontainer.h
new file mode 100644
index 000000000..f154ea212
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testcontainer.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTCONTAINER_H
+#define TESTCONTAINER_H
+#include <QObject>
+
+class TestContainer : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testContainerType();
+ void testListOfValueType();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp b/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp
new file mode 100644
index 000000000..cae4a3a62
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testconversionoperator.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestConversionOperator::testConversionOperator()
+{
+ const char cppCode[] = "\
+ struct A {\n\
+ };\n\
+ struct B {\n\
+ operator A() const;\n\
+ };\n\
+ struct C {\n\
+ operator A() const;\n\
+ };\n";
+ const char xmlCode[] = "\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A'/>\n\
+ <value-type name='B'/>\n\
+ <value-type name='C'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, QLatin1String("C"));
+ QVERIFY(classA);
+ QVERIFY(classB);
+ QVERIFY(classC);
+ QCOMPARE(classA->functions().count(), 2);
+ QCOMPARE(classB->functions().count(), 3);
+ QCOMPARE(classC->functions().count(), 3);
+ QCOMPARE(classA->externalConversionOperators().count(), 2);
+
+ AbstractMetaFunction* convOp = 0;
+ foreach(AbstractMetaFunction* func, classB->functions()) {
+ if (func->isConversionOperator()) {
+ convOp = func;
+ break;
+ }
+ }
+ QVERIFY(convOp);
+ QVERIFY(classA->externalConversionOperators().contains(convOp));
+}
+
+void TestConversionOperator::testConversionOperatorOfDiscardedClass()
+{
+ const char cppCode[] = "\
+ struct A {\n\
+ };\n\
+ struct B {\n\
+ operator A() const;\n\
+ };\n";
+ const char xmlCode[] = "\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A' />\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QCOMPARE(classA->externalConversionOperators().count(), 0);
+}
+
+void TestConversionOperator::testRemovedConversionOperator()
+{
+ const char cppCode[] = "\
+ struct A {\n\
+ };\n\
+ struct B {\n\
+ operator A() const;\n\
+ };\n";
+ const char xmlCode[] = "\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A' />\n\
+ <value-type name='B'>\n\
+ <modify-function signature='operator A() const' remove='all'/>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classA);
+ QVERIFY(classB);
+ QCOMPARE(classA->functions().count(), 2);
+ QCOMPARE(classB->functions().count(), 3);
+ QCOMPARE(classA->externalConversionOperators().count(), 0);
+ QCOMPARE(classA->implicitConversions().count(), 0);
+}
+
+void TestConversionOperator::testConversionOperatorReturningReference()
+{
+ const char cppCode[] = "\
+ struct A {};\n\
+ struct B {\n\
+ operator A&() const;\n\
+ };\n";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <value-type name='A'/>\n\
+ <value-type name='B'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classA);
+ QVERIFY(classB);
+ QCOMPARE(classA->functions().count(), 2);
+ QCOMPARE(classB->functions().count(), 3);
+ QCOMPARE(classA->externalConversionOperators().count(), 1);
+ QCOMPARE(classA->externalConversionOperators().first()->type()->cppSignature(), QLatin1String("A"));
+ QCOMPARE(classA->externalConversionOperators().first()->ownerClass()->name(), QLatin1String("B"));
+ QCOMPARE(classA->implicitConversions().count(), 1);
+ QCOMPARE(classA->implicitConversions().first()->type()->cppSignature(), QLatin1String("A"));
+ QCOMPARE(classA->implicitConversions().first()->ownerClass()->name(), QLatin1String("B"));
+}
+
+void TestConversionOperator::testConversionOperatorReturningConstReference()
+{
+ const char cppCode[] = "\
+ struct A {};\n\
+ struct B {\n\
+ operator const A&() const;\n\
+ };\n";
+ const char xmlCode[] = "\
+ <typesystem package='Foo'>\n\
+ <value-type name='A'/>\n\
+ <value-type name='B'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classA);
+ QVERIFY(classB);
+ QCOMPARE(classA->functions().count(), 2);
+ QCOMPARE(classB->functions().count(), 3);
+ QCOMPARE(classA->externalConversionOperators().count(), 1);
+ QCOMPARE(classA->externalConversionOperators().first()->type()->cppSignature(), QLatin1String("A"));
+ QCOMPARE(classA->externalConversionOperators().first()->ownerClass()->name(), QLatin1String("B"));
+ QCOMPARE(classA->implicitConversions().count(), 1);
+ QCOMPARE(classA->implicitConversions().first()->type()->cppSignature(), QLatin1String("A"));
+ QCOMPARE(classA->implicitConversions().first()->ownerClass()->name(), QLatin1String("B"));
+}
+
+QTEST_APPLESS_MAIN(TestConversionOperator)
diff --git a/sources/shiboken2/ApiExtractor/tests/testconversionoperator.h b/sources/shiboken2/ApiExtractor/tests/testconversionoperator.h
new file mode 100644
index 000000000..f28747ab5
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testconversionoperator.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTCONVERSIONOPERATOR_H
+#define TESTCONVERSIONOPERATOR_H
+#include <QObject>
+
+class TestConversionOperator : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testConversionOperator();
+ void testConversionOperatorOfDiscardedClass();
+ void testRemovedConversionOperator();
+ void testConversionOperatorReturningReference();
+ void testConversionOperatorReturningConstReference();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testconversionruletag.cpp b/sources/shiboken2/ApiExtractor/tests/testconversionruletag.cpp
new file mode 100644
index 000000000..fb9290795
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testconversionruletag.cpp
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testconversionruletag.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+#include <QFile>
+#include <QTemporaryFile>
+
+void TestConversionRuleTag::testConversionRuleTagWithFile()
+{
+ // temp file used later
+ const char conversionData[] = "Hi! I'm a conversion rule.";
+ QTemporaryFile file;
+ file.open();
+ QCOMPARE(file.write(conversionData), qint64(sizeof(conversionData)-1));
+ file.close();
+
+ const char cppCode[] = "struct A {};\n";
+ QString xmlCode = QLatin1String("\
+ <typesystem package='Foo'>\n\
+ <value-type name='A'>\n\
+ <conversion-rule file='") + file.fileName() + QLatin1String("'/>\n\
+ </value-type>\n\
+ </typesystem>\n");
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode.toLocal8Bit().data()));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ const ComplexTypeEntry* typeEntry = classA->typeEntry();
+ QVERIFY(typeEntry->hasConversionRule());
+ QCOMPARE(typeEntry->conversionRule(), QLatin1String(conversionData));
+}
+
+void TestConversionRuleTag::testConversionRuleTagReplace()
+{
+ const char cppCode[] = "\
+ struct A {\n\
+ A();\n\
+ A(const char*, int);\n\
+ };\n\
+ struct B {\n\
+ A createA();\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <primitive-type name='char'/>\n\
+ <primitive-type name='A'>\n\
+ <conversion-rule>\n\
+ <native-to-target>\n\
+ DoThis();\n\
+ return ConvertFromCppToPython(%IN);\n\
+ </native-to-target>\n\
+ <target-to-native>\n\
+ <add-conversion type='TargetNone' check='%IN == Target_None'>\n\
+ DoThat();\n\
+ DoSomething();\n\
+ %OUT = A();\n\
+ </add-conversion>\n\
+ <add-conversion type='B' check='CheckIfInputObjectIsB(%IN)'>\n\
+ %OUT = %IN.createA();\n\
+ </add-conversion>\n\
+ <add-conversion type='String' check='String_Check(%IN)'>\n\
+ %OUT = new A(String_AsString(%IN), String_GetSize(%IN));\n\
+ </add-conversion>\n\
+ </target-to-native>\n\
+ </conversion-rule>\n\
+ </primitive-type>\n\
+ <value-type name='B'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ TypeDatabase* typeDb = TypeDatabase::instance();
+ PrimitiveTypeEntry* typeA = typeDb->findPrimitiveType(QLatin1String("A"));
+ QVERIFY(typeA);
+
+ CustomConversion* conversion = typeA->customConversion();
+ QVERIFY(conversion);
+
+ QCOMPARE(typeA, conversion->ownerType());
+ QCOMPARE(conversion->nativeToTargetConversion().simplified(),
+ QLatin1String("DoThis(); return ConvertFromCppToPython(%IN);"));
+
+ QVERIFY(conversion->replaceOriginalTargetToNativeConversions());
+ QVERIFY(conversion->hasTargetToNativeConversions());
+ QCOMPARE(conversion->targetToNativeConversions().size(), 3);
+
+ CustomConversion::TargetToNativeConversion* toNative = conversion->targetToNativeConversions().at(0);
+ QVERIFY(toNative);
+ QCOMPARE(toNative->sourceTypeName(), QLatin1String("TargetNone"));
+ QVERIFY(toNative->isCustomType());
+ QCOMPARE(toNative->sourceType(), (const TypeEntry*)0);
+ QCOMPARE(toNative->sourceTypeCheck(), QLatin1String("%IN == Target_None"));
+ QCOMPARE(toNative->conversion().simplified(),
+ QLatin1String("DoThat(); DoSomething(); %OUT = A();"));
+
+ toNative = conversion->targetToNativeConversions().at(1);
+ QVERIFY(toNative);
+ QCOMPARE(toNative->sourceTypeName(), QLatin1String("B"));
+ QVERIFY(!toNative->isCustomType());
+ TypeEntry* typeB = typeDb->findType(QLatin1String("B"));
+ QVERIFY(typeB);
+ QCOMPARE(toNative->sourceType(), typeB);
+ QCOMPARE(toNative->sourceTypeCheck(), QLatin1String("CheckIfInputObjectIsB(%IN)"));
+ QCOMPARE(toNative->conversion().trimmed(), QLatin1String("%OUT = %IN.createA();"));
+
+ toNative = conversion->targetToNativeConversions().at(2);
+ QVERIFY(toNative);
+ QCOMPARE(toNative->sourceTypeName(), QLatin1String("String"));
+ QVERIFY(toNative->isCustomType());
+ QCOMPARE(toNative->sourceType(), (const TypeEntry*)0);
+ QCOMPARE(toNative->sourceTypeCheck(), QLatin1String("String_Check(%IN)"));
+ QCOMPARE(toNative->conversion().trimmed(), QLatin1String("%OUT = new A(String_AsString(%IN), String_GetSize(%IN));"));
+}
+
+void TestConversionRuleTag::testConversionRuleTagAdd()
+{
+ const char cppCode[] = "\
+ struct Date {\n\
+ Date();\n\
+ Date(int, int, int);\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <value-type name='Date'>\n\
+ <conversion-rule>\n\
+ <target-to-native replace='no'>\n\
+ <add-conversion type='TargetDate' check='TargetDate_Check(%IN)'>\n\
+if (!TargetDateTimeAPI) TargetDateTime_IMPORT;\n\
+%OUT = new Date(TargetDate_Day(%IN), TargetDate_Month(%IN), TargetDate_Year(%IN));\n\
+ </add-conversion>\n\
+ </target-to-native>\n\
+ </conversion-rule>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("Date"));
+ QVERIFY(classA);
+
+ CustomConversion* conversion = classA->typeEntry()->customConversion();
+ QVERIFY(conversion);
+
+ QCOMPARE(conversion->nativeToTargetConversion(), QString());
+
+ QVERIFY(!conversion->replaceOriginalTargetToNativeConversions());
+ QVERIFY(conversion->hasTargetToNativeConversions());
+ QCOMPARE(conversion->targetToNativeConversions().size(), 1);
+
+ CustomConversion::TargetToNativeConversion* toNative = conversion->targetToNativeConversions().first();
+ QVERIFY(toNative);
+ QCOMPARE(toNative->sourceTypeName(), QLatin1String("TargetDate"));
+ QVERIFY(toNative->isCustomType());
+ QCOMPARE(toNative->sourceType(), (const TypeEntry*)0);
+ QCOMPARE(toNative->sourceTypeCheck(), QLatin1String("TargetDate_Check(%IN)"));
+ QCOMPARE(toNative->conversion().trimmed(),
+ QLatin1String("if (!TargetDateTimeAPI) TargetDateTime_IMPORT;\n%OUT = new Date(TargetDate_Day(%IN), TargetDate_Month(%IN), TargetDate_Year(%IN));"));
+}
+
+void TestConversionRuleTag::testConversionRuleTagWithInsertTemplate()
+{
+ const char cppCode[] = "struct A {};";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <!-- single line -->\n\
+ <template name='native_to_target'>return ConvertFromCppToPython(%IN);</template>\n\
+ <!-- multi-line -->\n\
+ <template name='target_to_native'>\n\
+%OUT = %IN.createA();\n\
+ </template>\n\
+ <primitive-type name='A'>\n\
+ <conversion-rule>\n\
+ <native-to-target>\n\
+ <insert-template name='native_to_target'/>\n\
+ </native-to-target>\n\
+ <target-to-native>\n\
+ <add-conversion type='TargetType'>\n\
+ <insert-template name='target_to_native'/>\n\
+ </add-conversion>\n\
+ </target-to-native>\n\
+ </conversion-rule>\n\
+ </primitive-type>\n\
+ </typesystem>\n";
+
+ const char nativeToTargetExpected[] =
+ "// TEMPLATE - native_to_target - START\n"
+ "return ConvertFromCppToPython(%IN);\n"
+ "// TEMPLATE - native_to_target - END";
+
+ const char targetToNativeExpected[] =
+ "// TEMPLATE - target_to_native - START\n"
+ "%OUT = %IN.createA();\n"
+ "// TEMPLATE - target_to_native - END";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ TypeDatabase* typeDb = TypeDatabase::instance();
+ PrimitiveTypeEntry* typeA = typeDb->findPrimitiveType(QLatin1String("A"));
+ QVERIFY(typeA);
+
+ CustomConversion* conversion = typeA->customConversion();
+ QVERIFY(conversion);
+
+ QCOMPARE(typeA, conversion->ownerType());
+ QCOMPARE(conversion->nativeToTargetConversion().trimmed(),
+ QLatin1String(nativeToTargetExpected));
+
+ QVERIFY(conversion->hasTargetToNativeConversions());
+ QCOMPARE(conversion->targetToNativeConversions().size(), 1);
+
+ CustomConversion::TargetToNativeConversion* toNative = conversion->targetToNativeConversions().first();
+ QVERIFY(toNative);
+ QCOMPARE(toNative->conversion().trimmed(),
+ QLatin1String(targetToNativeExpected));
+}
+
+QTEST_APPLESS_MAIN(TestConversionRuleTag)
diff --git a/sources/shiboken2/ApiExtractor/tests/testconversionruletag.h b/sources/shiboken2/ApiExtractor/tests/testconversionruletag.h
new file mode 100644
index 000000000..c02a9708b
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testconversionruletag.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTCONVERSIONRULE_H
+#define TESTCONVERSIONRULE_H
+#include <QObject>
+
+class TestConversionRuleTag : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testConversionRuleTagWithFile();
+ void testConversionRuleTagReplace();
+ void testConversionRuleTagAdd();
+ void testConversionRuleTagWithInsertTemplate();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testctorinformation.cpp b/sources/shiboken2/ApiExtractor/tests/testctorinformation.cpp
new file mode 100644
index 000000000..a4b4c2388
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testctorinformation.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testctorinformation.h"
+#include "abstractmetabuilder.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestCtorInformation::testCtorIsPrivate()
+{
+ const char* cppCode = "class Control { public: Control() {} };\n\
+ class Subject { private: Subject() {} };\n\
+ class CtorLess { };\n";
+ const char* xmlCode = "<typesystem package='Foo'>\n\
+ <value-type name='Control'/>\n\
+ <object-type name='Subject'/>\n\
+ <value-type name='CtorLess'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 3);
+ QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->hasNonPrivateConstructor(), true);
+ QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasNonPrivateConstructor(), false);
+ QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("CtorLess"))->hasNonPrivateConstructor(), true);
+}
+
+void TestCtorInformation::testHasNonPrivateCtor()
+{
+ const char* cppCode = "template<typename T>\n\
+ struct Base { Base(double) {} };\n\
+ typedef Base<int> Derived;\n";
+ const char* xmlCode = "<typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <primitive-type name='double'/>\n\
+ <object-type name='Base' generate='no'/>\n\
+ <object-type name='Derived'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ const AbstractMetaClass *base = AbstractMetaClass::findClass(classes, QLatin1String("Base"));
+ QCOMPARE(base->hasNonPrivateConstructor(), true);
+ const AbstractMetaClass *derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived"));
+ QCOMPARE(derived->hasNonPrivateConstructor(), true);
+}
+
+QTEST_APPLESS_MAIN(TestCtorInformation)
diff --git a/sources/shiboken2/ApiExtractor/tests/testctorinformation.h b/sources/shiboken2/ApiExtractor/tests/testctorinformation.h
new file mode 100644
index 000000000..f5ffe5501
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testctorinformation.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTCTORINFORMATION_H
+#define TESTCTORINFORMATION_H
+
+#include <QObject>
+
+class AbstractMetaBuilder;
+
+class TestCtorInformation: public QObject
+{
+ Q_OBJECT
+private slots:
+ void testCtorIsPrivate();
+ void testHasNonPrivateCtor();
+};
+
+#endif // TESTCTORINFORMATION_H
diff --git a/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp b/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp
new file mode 100644
index 000000000..6b6c5d011
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testdroptypeentries.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+static const char* cppCode ="\
+ struct ValueA {};\n\
+ struct ValueB {};\n\
+ struct ObjectA {};\n\
+ struct ObjectB {};\n\
+ namespace NamespaceA {\n\
+ struct InnerClassA {};\n\
+ namespace InnerNamespaceA {}\n\
+ }\n\
+ namespace NamespaceB {}\n\
+ enum EnumA { Value0 };\n\
+ enum EnumB { Value1 };\n\
+ void funcA();\n\
+ void funcB();\n";
+
+static const char* xmlCode = "\
+<typesystem package='Foo'>\n\
+ <value-type name='ValueA'/>\n\
+ <value-type name='ValueB'/>\n\
+ <object-type name='ObjectA'/>\n\
+ <object-type name='ObjectB'/>\n\
+ <namespace-type name='NamespaceA'>\n\
+ <value-type name='InnerClassA'/>\n\
+ <namespace-type name='InnerNamespaceA'/>\n\
+ </namespace-type>\n\
+ <namespace-type name='NamespaceB'/>\n\
+ <enum-type name='EnumA'/>\n\
+ <enum-type name='EnumB'/>\n\
+ <function signature='funcA()'/>\n\
+ <function signature='funcB()'/>\n\
+</typesystem>\n";
+
+void TestDropTypeEntries::testDropEntries()
+{
+ QStringList droppedEntries(QLatin1String("Foo.ValueB"));
+ droppedEntries << QLatin1String("Foo.ObjectB") << QLatin1String("Foo.NamespaceA.InnerClassA");
+ droppedEntries << QLatin1String("Foo.NamespaceB") << QLatin1String("Foo.EnumB") << QLatin1String("Foo.funcB()");
+ droppedEntries << QLatin1String("Foo.NamespaceA.InnerNamespaceA");
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, Q_NULLPTR, droppedEntries));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+ QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("ValueA")));
+ QVERIFY(!AbstractMetaClass::findClass(classes, QLatin1String("ValueB")));
+ QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("ObjectA")));
+ QVERIFY(!AbstractMetaClass::findClass(classes, QLatin1String("ObjectB")));
+ QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("NamespaceA")));
+ QVERIFY(!AbstractMetaClass::findClass(classes, QLatin1String("NamespaceA::InnerClassA")));
+ QVERIFY(!AbstractMetaClass::findClass(classes, QLatin1String("NamespaceB")));
+
+ AbstractMetaEnumList globalEnums = builder->globalEnums();
+ QCOMPARE(globalEnums.count(), 1);
+ QCOMPARE(globalEnums.first()->name(), QLatin1String("EnumA"));
+
+ TypeDatabase* td = TypeDatabase::instance();
+ QVERIFY(td->findType(QLatin1String("funcA")));
+ QVERIFY(!td->findType(QLatin1String("funcB")));
+}
+
+void TestDropTypeEntries::testDontDropEntries()
+{
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+ QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("ValueA")));
+ QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("ValueB")));
+ QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("ObjectA")));
+ QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("ObjectB")));
+ QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("NamespaceA")));
+ QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("NamespaceA::InnerClassA")));
+ QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("NamespaceB")));
+
+ QCOMPARE(builder->globalEnums().size(), 2);
+
+ TypeDatabase* td = TypeDatabase::instance();
+ QVERIFY(td->findType(QLatin1String("funcA")));
+ QVERIFY(td->findType(QLatin1String("funcB")));
+}
+
+static const char* cppCode2 ="\
+ struct ValueA {\n\
+ void func();\n\
+ };\n";
+
+static const char* xmlCode2 = "\
+<typesystem package='Foo'>\n\
+ <value-type name='ValueA'>\n\
+ <modify-function signature='func()'>\n\
+ <remove class='all'/>\n\
+ </modify-function>\n\
+ </value-type>\n\
+</typesystem>\n";
+
+void TestDropTypeEntries::testDropEntryWithChildTags()
+{
+ QStringList droppedEntries(QLatin1String("Foo.ValueA"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false, Q_NULLPTR, droppedEntries));
+ QVERIFY(!builder.isNull());
+ QVERIFY(!AbstractMetaClass::findClass(builder->classes(), QLatin1String("ValueA")));
+}
+
+
+void TestDropTypeEntries::testDontDropEntryWithChildTags()
+{
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false));
+ QVERIFY(!builder.isNull());
+ QVERIFY(AbstractMetaClass::findClass(builder->classes(), QLatin1String("ValueA")));
+}
+
+QTEST_APPLESS_MAIN(TestDropTypeEntries)
diff --git a/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.h b/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.h
new file mode 100644
index 000000000..d04c6dc92
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTDROPTYPEENTRIES_H
+#define TESTDROPTYPEENTRIES_H
+
+#include <QObject>
+
+class TestDropTypeEntries : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testDropEntries();
+ void testDontDropEntries();
+ void testDropEntryWithChildTags();
+ void testDontDropEntryWithChildTags();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp
new file mode 100644
index 000000000..63b745c12
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testdtorinformation.h"
+#include "abstractmetabuilder.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestDtorInformation::testDtorIsPrivate()
+{
+ const char* cppCode ="class Control { public: ~Control() {} }; class Subject { private: ~Subject() {} };";
+ const char* xmlCode = "<typesystem package=\"Foo\"><value-type name=\"Control\"/><value-type name=\"Subject\"/></typesystem>";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->hasPrivateDestructor(), false);
+ QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasPrivateDestructor(), true);
+}
+
+void TestDtorInformation::testDtorIsProtected()
+{
+ const char* cppCode ="class Control { public: ~Control() {} }; class Subject { protected: ~Subject() {} };";
+ const char* xmlCode = "<typesystem package=\"Foo\"><value-type name=\"Control\"/><value-type name=\"Subject\"/></typesystem>";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->hasProtectedDestructor(), false);
+ QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasProtectedDestructor(), true);
+}
+
+void TestDtorInformation::testDtorIsVirtual()
+{
+ const char* cppCode ="class Control { public: ~Control() {} }; class Subject { protected: virtual ~Subject() {} };";
+ const char* xmlCode = "<typesystem package=\"Foo\"><value-type name=\"Control\"/><value-type name=\"Subject\"/></typesystem>";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->hasVirtualDestructor(), false);
+ QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasVirtualDestructor(), true);
+}
+
+void TestDtorInformation::testClassWithVirtualDtorIsPolymorphic()
+{
+ const char* cppCode ="class Control { public: virtual ~Control() {} }; class Subject { protected: virtual ~Subject() {} };";
+ const char* xmlCode = "<typesystem package=\"Foo\"><value-type name=\"Control\"/><value-type name=\"Subject\"/></typesystem>";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->isPolymorphic(), true);
+ QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->isPolymorphic(), true);
+}
+
+QTEST_APPLESS_MAIN(TestDtorInformation)
+
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h
new file mode 100644
index 000000000..21a3b1822
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTDTORINFORMATION_H
+#define TESTDTORINFORMATION_H
+
+#include <QObject>
+
+class AbstractMetaBuilder;
+
+class TestDtorInformation: public QObject
+{
+ Q_OBJECT
+private slots:
+ void testDtorIsPrivate();
+ void testDtorIsProtected();
+ void testDtorIsVirtual();
+ void testClassWithVirtualDtorIsPolymorphic();
+};
+
+#endif // TESTDTORINFORMATION_H
diff --git a/sources/shiboken2/ApiExtractor/tests/testenum.cpp b/sources/shiboken2/ApiExtractor/tests/testenum.cpp
new file mode 100644
index 000000000..6700239d6
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testenum.cpp
@@ -0,0 +1,416 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testenum.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestEnum::testEnumCppSignature()
+{
+ const char* cppCode ="\
+ enum GlobalEnum { A, B };\n\
+ \n\
+ struct A {\n\
+ enum ClassEnum { CA, CB };\n\
+ void method(ClassEnum);\n\
+ };\n\
+ void func(A::ClassEnum);\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <enum-type name='GlobalEnum'/>\n\
+ <value-type name='A'>\n\
+ <enum-type name='ClassEnum'/>\n\
+ </value-type>\n\
+ <function signature='func(A::ClassEnum)'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 1);
+
+ AbstractMetaEnumList globalEnums = builder->globalEnums();
+ QCOMPARE(globalEnums.count(), 1);
+ QCOMPARE(globalEnums.first()->name(), QLatin1String("GlobalEnum"));
+
+ // enum as parameter of a function
+ AbstractMetaFunctionList functions = builder->globalFunctions();
+ QCOMPARE(functions.count(), 1);
+ QCOMPARE(functions.first()->arguments().count(), 1);
+ QCOMPARE(functions.first()->arguments().first()->type()->cppSignature(), QLatin1String("A::ClassEnum"));
+
+ // enum as parameter of a method
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classA->enums().count(), 1);
+ AbstractMetaFunctionList funcs = classA->queryFunctionsByName(QLatin1String("method"));
+ QVERIFY(!funcs.isEmpty());
+ AbstractMetaFunction* method = funcs.first();
+ QVERIFY(method);
+ AbstractMetaArgument* arg = method->arguments().first();
+ QCOMPARE(arg->type()->name(), QLatin1String("ClassEnum"));
+ QCOMPARE(arg->type()->cppSignature(), QLatin1String("A::ClassEnum"));
+ QCOMPARE(functions.first()->arguments().count(), 1);
+ arg = functions.first()->arguments().first();
+ QCOMPARE(arg->type()->name(), QLatin1String("ClassEnum"));
+ QCOMPARE(arg->type()->cppSignature(), QLatin1String("A::ClassEnum"));
+
+ AbstractMetaEnumList classEnums = classA->enums();
+ QCOMPARE(classEnums.first()->name(), QLatin1String("ClassEnum"));
+}
+
+void TestEnum::testEnumWithApiVersion()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ enum ClassEnum { EnumA, EnumB };\n\
+ enum ClassEnum2 { EnumC, EnumD };\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A'>\n\
+ <enum-type name='ClassEnum' since='0.1'/>\n\
+ <enum-type name='ClassEnum2' since='0.2'/>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "0.1"));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 1);
+ QCOMPARE(classes[0]->enums().count(), 1);
+}
+
+void TestEnum::testAnonymousEnum()
+{
+ const char* cppCode ="\
+ enum { Global0, Global1 };\n\
+ struct A {\n\
+ enum { A0, A1 };\n\
+ enum { isThis = true, isThat = false };\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <!-- Uses the first value of the enum to identify it. -->\n\
+ <enum-type identified-by-value='Global0'/>\n\
+ <value-type name='A'>\n\
+ <!-- Uses the second value of the enum to identify it. -->\n\
+ <enum-type identified-by-value='A1'/>\n\
+ <enum-type identified-by-value='isThis'/>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaEnumList globalEnums = builder->globalEnums();
+ QCOMPARE(globalEnums.count(), 1);
+ QCOMPARE(globalEnums.first()->typeEntry()->qualifiedCppName(), QLatin1String("Global0"));
+ QVERIFY(globalEnums.first()->isAnonymous());
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 1);
+ QCOMPARE(classes[0]->enums().count(), 2);
+
+ AbstractMetaEnum* anonEnumA1 = classes[0]->findEnum(QLatin1String("A1"));
+ QVERIFY(anonEnumA1);
+ QVERIFY(anonEnumA1->isAnonymous());
+ QCOMPARE(anonEnumA1->typeEntry()->qualifiedCppName(), QLatin1String("A::A1"));
+
+ AbstractMetaEnumValue* enumValueA0 = anonEnumA1->values().first();
+ QCOMPARE(enumValueA0->name(), QLatin1String("A0"));
+ QCOMPARE(enumValueA0->value(), 0);
+ QCOMPARE(enumValueA0->stringValue(), QString());
+
+ AbstractMetaEnumValue* enumValueA1 = anonEnumA1->values().last();
+ QCOMPARE(enumValueA1->name(), QLatin1String("A1"));
+ QCOMPARE(enumValueA1->value(), 1);
+ QCOMPARE(enumValueA1->stringValue(), QString());
+
+ AbstractMetaEnum* anonEnumIsThis = classes[0]->findEnum(QLatin1String("isThis"));
+ QVERIFY(anonEnumIsThis);
+ QVERIFY(anonEnumIsThis->isAnonymous());
+ QCOMPARE(anonEnumIsThis->typeEntry()->qualifiedCppName(), QLatin1String("A::isThis"));
+
+ AbstractMetaEnumValue* enumValueIsThis = anonEnumIsThis->values().first();
+ QCOMPARE(enumValueIsThis->name(), QLatin1String("isThis"));
+ QCOMPARE(enumValueIsThis->value(), static_cast<int>(true));
+ QCOMPARE(enumValueIsThis->stringValue(), QLatin1String("true"));
+
+ AbstractMetaEnumValue* enumValueIsThat = anonEnumIsThis->values().last();
+ QCOMPARE(enumValueIsThat->name(), QLatin1String("isThat"));
+ QCOMPARE(enumValueIsThat->value(), static_cast<int>(false));
+ QCOMPARE(enumValueIsThat->stringValue(), QLatin1String("false"));
+}
+
+void TestEnum::testGlobalEnums()
+{
+ const char* cppCode ="\
+ enum EnumA { A0, A1 };\n\
+ enum EnumB { B0 = 2, B1 = 0x4 };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <enum-type name='EnumA'/>\n\
+ <enum-type name='EnumB'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaEnumList globalEnums = builder->globalEnums();
+ QCOMPARE(globalEnums.count(), 2);
+
+ AbstractMetaEnum* enumA = globalEnums.first();
+ QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QLatin1String("EnumA"));
+
+ AbstractMetaEnumValue* enumValueA0 = enumA->values().first();
+ QCOMPARE(enumValueA0->name(), QLatin1String("A0"));
+ QCOMPARE(enumValueA0->value(), 0);
+ QCOMPARE(enumValueA0->stringValue(), QString());
+
+ AbstractMetaEnumValue* enumValueA1 = enumA->values().last();
+ QCOMPARE(enumValueA1->name(), QLatin1String("A1"));
+ QCOMPARE(enumValueA1->value(), 1);
+ QCOMPARE(enumValueA1->stringValue(), QString());
+
+ AbstractMetaEnum* enumB = globalEnums.last();
+ QCOMPARE(enumB->typeEntry()->qualifiedCppName(), QLatin1String("EnumB"));
+
+ AbstractMetaEnumValue* enumValueB0 = enumB->values().first();
+ QCOMPARE(enumValueB0->name(), QLatin1String("B0"));
+ QCOMPARE(enumValueB0->value(), 2);
+ QCOMPARE(enumValueB0->stringValue(), QLatin1String("2"));
+
+ AbstractMetaEnumValue* enumValueB1 = enumB->values().last();
+ QCOMPARE(enumValueB1->name(), QLatin1String("B1"));
+ QCOMPARE(enumValueB1->value(), 4);
+ QCOMPARE(enumValueB1->stringValue(), QLatin1String("0x4"));
+}
+
+void TestEnum::testEnumValueFromNeighbourEnum()
+{
+ const char* cppCode ="\
+ namespace A {\n\
+ enum EnumA { ValueA0, ValueA1 };\n\
+ enum EnumB { ValueB0 = A::ValueA1, ValueB1 = ValueA0 };\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <namespace-type name='A'>\n\
+ <enum-type name='EnumA'/>\n\
+ <enum-type name='EnumB'/>\n\
+ </namespace-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 1);
+ QCOMPARE(classes[0]->enums().count(), 2);
+
+ AbstractMetaEnum* enumA = classes[0]->findEnum(QLatin1String("EnumA"));
+ QVERIFY(enumA);
+ QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QLatin1String("A::EnumA"));
+
+ AbstractMetaEnumValue* enumValueA0 = enumA->values().first();
+ QCOMPARE(enumValueA0->name(), QLatin1String("ValueA0"));
+ QCOMPARE(enumValueA0->value(), 0);
+ QCOMPARE(enumValueA0->stringValue(), QString());
+
+ AbstractMetaEnumValue* enumValueA1 = enumA->values().last();
+ QCOMPARE(enumValueA1->name(), QLatin1String("ValueA1"));
+ QCOMPARE(enumValueA1->value(), 1);
+ QCOMPARE(enumValueA1->stringValue(), QString());
+
+ AbstractMetaEnum* enumB = classes[0]->findEnum(QLatin1String("EnumB"));
+ QVERIFY(enumB);
+ QCOMPARE(enumB->typeEntry()->qualifiedCppName(), QLatin1String("A::EnumB"));
+
+ AbstractMetaEnumValue* enumValueB0 = enumB->values().first();
+ QCOMPARE(enumValueB0->name(), QLatin1String("ValueB0"));
+ QCOMPARE(enumValueB0->value(), 1);
+ QCOMPARE(enumValueB0->stringValue(), QLatin1String("A::ValueA1"));
+
+ AbstractMetaEnumValue* enumValueB1 = enumB->values().last();
+ QCOMPARE(enumValueB1->name(), QLatin1String("ValueB1"));
+ QCOMPARE(enumValueB1->value(), 0);
+ QCOMPARE(enumValueB1->stringValue(), QLatin1String("ValueA0"));
+}
+
+void TestEnum::testEnumValueFromExpression()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ enum EnumA {\n\
+ ValueA0 = 3u,\n\
+ ValueA1 = ~3u,\n\
+ ValueA2 = ~3,\n\
+ ValueA3 = 0xf0,\n\
+ ValueA4 = 8 |ValueA3,\n\
+ ValueA5 = ValueA3|32,\n\
+ ValueA6 = ValueA3 >> 1,\n\
+ ValueA7 = ValueA3 << 1\n\
+ };\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A'>\n\
+ <enum-type name='EnumA'/>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ QVERIFY(classA);
+
+ AbstractMetaEnum* enumA = classA->findEnum(QLatin1String("EnumA"));
+ QVERIFY(enumA);
+ QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QLatin1String("A::EnumA"));
+
+ AbstractMetaEnumValue* valueA0 = enumA->values().at(0);
+ QCOMPARE(valueA0->name(), QLatin1String("ValueA0"));
+ QCOMPARE(valueA0->stringValue(), QLatin1String("3u"));
+ QCOMPARE(valueA0->value(), (int) 3u);
+
+ AbstractMetaEnumValue* valueA1 = enumA->values().at(1);
+ QCOMPARE(valueA1->name(), QLatin1String("ValueA1"));
+ QCOMPARE(valueA1->stringValue(), QLatin1String("~3u"));
+ QCOMPARE(valueA1->value(), (int) ~3u);
+
+ AbstractMetaEnumValue* valueA2 = enumA->values().at(2);
+ QCOMPARE(valueA2->name(), QLatin1String("ValueA2"));
+ QCOMPARE(valueA2->stringValue(), QLatin1String("~3"));
+ QCOMPARE(valueA2->value(), ~3);
+
+ AbstractMetaEnumValue* valueA3 = enumA->values().at(3);
+ QCOMPARE(valueA3->name(), QLatin1String("ValueA3"));
+ QCOMPARE(valueA3->stringValue(), QLatin1String("0xf0"));
+ QCOMPARE(valueA3->value(), 0xf0);
+
+ AbstractMetaEnumValue* valueA4 = enumA->values().at(4);
+ QCOMPARE(valueA4->name(), QLatin1String("ValueA4"));
+ QCOMPARE(valueA4->stringValue(), QLatin1String("8|ValueA3"));
+ QCOMPARE(valueA4->value(), 8|0xf0);
+
+ AbstractMetaEnumValue* valueA5 = enumA->values().at(5);
+ QCOMPARE(valueA5->name(), QLatin1String("ValueA5"));
+ QCOMPARE(valueA5->stringValue(), QLatin1String("ValueA3|32"));
+ QCOMPARE(valueA5->value(), 0xf0|32);
+
+ AbstractMetaEnumValue* valueA6 = enumA->values().at(6);
+ QCOMPARE(valueA6->name(), QLatin1String("ValueA6"));
+ QCOMPARE(valueA6->stringValue(), QLatin1String("ValueA3>>1"));
+ QCOMPARE(valueA6->value(), 0xf0 >> 1);
+
+ AbstractMetaEnumValue* valueA7 = enumA->values().at(7);
+ QCOMPARE(valueA7->name(), QLatin1String("ValueA7"));
+ QCOMPARE(valueA7->stringValue(), QLatin1String("ValueA3<<1"));
+ QCOMPARE(valueA7->value(), 0xf0 << 1);
+}
+
+void TestEnum::testPrivateEnum()
+{
+ const char* cppCode ="\
+ class A {\n\
+ private:\n\
+ enum PrivateEnum { Priv0 = 0x0f, Priv1 = 0xf0 };\n\
+ public:\n\
+ enum PublicEnum { Pub0 = Priv0, Pub1 = A::Priv1 };\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A'>\n\
+ <enum-type name='PublicEnum'/>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ QVERIFY(classA);
+ QCOMPARE(classA->enums().count(), 2);
+
+ AbstractMetaEnum* privateEnum = classA->findEnum(QLatin1String("PrivateEnum"));
+ QVERIFY(privateEnum);
+ QVERIFY(privateEnum->isPrivate());
+ QCOMPARE(privateEnum->typeEntry()->qualifiedCppName(), QLatin1String("A::PrivateEnum"));
+
+ AbstractMetaEnum* publicEnum = classA->findEnum(QLatin1String("PublicEnum"));
+ QVERIFY(publicEnum);
+ QCOMPARE(publicEnum->typeEntry()->qualifiedCppName(), QLatin1String("A::PublicEnum"));
+
+ AbstractMetaEnumValue* pub0 = publicEnum->values().first();
+ QCOMPARE(pub0->name(), QLatin1String("Pub0"));
+ QCOMPARE(pub0->value(), 0x0f);
+ QCOMPARE(pub0->stringValue(), QLatin1String("Priv0"));
+
+ AbstractMetaEnumValue* pub1 = publicEnum->values().last();
+ QCOMPARE(pub1->name(), QLatin1String("Pub1"));
+ QCOMPARE(pub1->value(), 0xf0);
+ QCOMPARE(pub1->stringValue(), QLatin1String("A::Priv1"));
+}
+
+void TestEnum::testTypedefEnum()
+{
+ const char* cppCode ="\
+ typedef enum EnumA {\n\
+ A0,\n\
+ A1,\n\
+ } EnumA;\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <enum-type name='EnumA'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaEnumList globalEnums = builder->globalEnums();
+ QEXPECT_FAIL("", "APIExtractor does not handle typedef enum correctly yet", Abort);
+ QCOMPARE(globalEnums.count(), 1);
+
+ AbstractMetaEnum* enumA = globalEnums.first();
+ QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QLatin1String("EnumA"));
+
+ AbstractMetaEnumValue* enumValueA0 = enumA->values().first();
+ QCOMPARE(enumValueA0->name(), QLatin1String("A0"));
+ QCOMPARE(enumValueA0->value(), 0);
+ QCOMPARE(enumValueA0->stringValue(), QLatin1String(""));
+
+ AbstractMetaEnumValue* enumValueA1 = enumA->values().last();
+ QCOMPARE(enumValueA1->name(), QLatin1String("A1"));
+ QCOMPARE(enumValueA1->value(), 1);
+ QCOMPARE(enumValueA1->stringValue(), QString());
+}
+
+QTEST_APPLESS_MAIN(TestEnum)
diff --git a/sources/shiboken2/ApiExtractor/tests/testenum.h b/sources/shiboken2/ApiExtractor/tests/testenum.h
new file mode 100644
index 000000000..8b46b1bd6
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testenum.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTENUM_H
+#define TESTENUM_H
+#include <QObject>
+
+class TestEnum : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testEnumCppSignature();
+ void testEnumWithApiVersion();
+ void testAnonymousEnum();
+ void testGlobalEnums();
+ void testEnumValueFromNeighbourEnum();
+ void testEnumValueFromExpression();
+ void testPrivateEnum();
+ void testTypedefEnum();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp b/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp
new file mode 100644
index 000000000..94158377e
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testextrainclude.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestExtraInclude::testClassExtraInclude()
+{
+ const char* cppCode ="struct A {};\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <value-type name='A'>\n\
+ <extra-includes>\n\
+ <include file-name='header.h' location='global'/>\n\
+ </extra-includes>\n\
+ </value-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+
+ QList<Include> includes = classA->typeEntry()->extraIncludes();
+ QCOMPARE(includes.count(), 1);
+ QCOMPARE(includes.first().name(), QLatin1String("header.h"));
+}
+
+void TestExtraInclude::testGlobalExtraIncludes()
+{
+ const char* cppCode ="struct A {};\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <extra-includes>\n\
+ <include file-name='header1.h' location='global'/>\n\
+ <include file-name='header2.h' location='global'/>\n\
+ </extra-includes>\n\
+ <value-type name='A'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("A")));
+
+ TypeDatabase* td = TypeDatabase::instance();
+ TypeEntry* module = td->findType(QLatin1String("Foo"));
+ QVERIFY(module);
+
+ QList<Include> includes = module->extraIncludes();
+ QCOMPARE(includes.count(), 2);
+ QCOMPARE(includes.first().name(), QLatin1String("header1.h"));
+ QCOMPARE(includes.last().name(), QLatin1String("header2.h"));
+}
+
+QTEST_APPLESS_MAIN(TestExtraInclude)
diff --git a/sources/shiboken2/ApiExtractor/tests/testextrainclude.h b/sources/shiboken2/ApiExtractor/tests/testextrainclude.h
new file mode 100644
index 000000000..c569901e1
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testextrainclude.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTEXTRAINCLUDE_H
+#define TESTEXTRAINCLUDE_H
+
+#include <QObject>
+
+class TestExtraInclude : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testClassExtraInclude();
+ void testGlobalExtraIncludes();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testfunctiontag.cpp b/sources/shiboken2/ApiExtractor/tests/testfunctiontag.cpp
new file mode 100644
index 000000000..a29d740bf
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testfunctiontag.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testfunctiontag.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestFunctionTag::testFunctionTagForSpecificSignature()
+{
+ const char cppCode[] = "void globalFunction(int); void globalFunction(float); void dummy();\n";
+ const char xmlCode[] = "\
+ <typesystem package=\"Foo\">\n\
+ <primitive-type name='int'/>\n\
+ <primitive-type name='float'/>\n\
+ <function signature='globalFunction(int)'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ const TypeEntry *func = TypeDatabase::instance()->findType(QLatin1String("globalFunction"));
+ QVERIFY(func);
+ QCOMPARE(builder->globalFunctions().size(), 1);
+}
+
+void TestFunctionTag::testFunctionTagForAllSignatures()
+{
+ const char cppCode[] = "void globalFunction(int); void globalFunction(float); void dummy();\n";
+ const char xmlCode[] = "\
+ <typesystem package=\"Foo\">\n\
+ <primitive-type name='int'/>\n\
+ <primitive-type name='float'/>\n\
+ <function signature='globalFunction(int)'/>\n\
+ <function signature='globalFunction(float)'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ const TypeEntry *func = TypeDatabase::instance()->findType(QLatin1String("globalFunction"));
+ QVERIFY(func);
+ QCOMPARE(builder->globalFunctions().size(), 2);
+}
+
+void TestFunctionTag::testRenameGlobalFunction()
+{
+ const char* cppCode ="void global_function_with_ugly_name();\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <function signature='global_function_with_ugly_name()' rename='smooth'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ const TypeEntry *func = TypeDatabase::instance()->findType(QLatin1String("global_function_with_ugly_name"));
+ QVERIFY(func);
+
+ QCOMPARE(builder->globalFunctions().size(), 1);
+ const AbstractMetaFunction* metaFunc = builder->globalFunctions().first();
+
+ QVERIFY(metaFunc);
+ QCOMPARE(metaFunc->modifications().size(), 1);
+ QVERIFY(metaFunc->modifications().first().isRenameModifier());
+ QCOMPARE(metaFunc->modifications().first().renamedTo(), QLatin1String("smooth"));
+
+ QCOMPARE(metaFunc->name(), QLatin1String("smooth"));
+ QCOMPARE(metaFunc->originalName(), QLatin1String("global_function_with_ugly_name"));
+ QCOMPARE(metaFunc->minimalSignature(), QLatin1String("global_function_with_ugly_name()"));
+}
+
+QTEST_APPLESS_MAIN(TestFunctionTag)
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testfunctiontag.h b/sources/shiboken2/ApiExtractor/tests/testfunctiontag.h
new file mode 100644
index 000000000..d4b6c7d2c
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testfunctiontag.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTFUNCTIONTAG_H
+#define TESTFUNCTIONTAG_H
+#include <QObject>
+
+class TestFunctionTag : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testFunctionTagForSpecificSignature();
+ void testFunctionTagForAllSignatures();
+ void testRenameGlobalFunction();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp b/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp
new file mode 100644
index 000000000..4438550b2
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testimplicitconversions.h"
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+#include <QtTest/QTest>
+
+void TestImplicitConversions::testWithPrivateCtors()
+{
+ const char* cppCode ="\
+ class B;\n\
+ class C;\n\
+ class A {\n\
+ A(const B&);\n\
+ public:\n\
+ A(const C&);\n\
+ };\n\
+ class B {};\n\
+ class C {};\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <value-type name='A'/>\n\
+ <value-type name='B'/>\n\
+ <value-type name='C'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 3);
+
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, QLatin1String("C"));
+ AbstractMetaFunctionList implicitConvs = classA->implicitConversions();
+ QCOMPARE(implicitConvs.count(), 1);
+ QCOMPARE(implicitConvs.first()->arguments().first()->type()->typeEntry(), classC->typeEntry());
+}
+
+void TestImplicitConversions::testWithModifiedVisibility()
+{
+ const char* cppCode ="\
+ class B;\n\
+ class A {\n\
+ public:\n\
+ A(const B&);\n\
+ };\n\
+ class B {};\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <value-type name='A'>\n\
+ <modify-function signature='A(const B&amp;)'>\n\
+ <access modifier='private'/>\n\
+ </modify-function>\n\
+ </value-type>\n\
+ <value-type name='B'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ AbstractMetaFunctionList implicitConvs = classA->implicitConversions();
+ QCOMPARE(implicitConvs.count(), 1);
+ QCOMPARE(implicitConvs.first()->arguments().first()->type()->typeEntry(), classB->typeEntry());
+}
+
+
+void TestImplicitConversions::testWithAddedCtor()
+{
+ const char* cppCode ="\
+ class B;\n\
+ class A {\n\
+ public:\n\
+ A(const B&);\n\
+ };\n\
+ class B {};\n\
+ class C {};\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <custom-type name='TARGETLANGTYPE'/>\n\
+ <value-type name='A'>\n\
+ <add-function signature='A(const C&amp;)'/>\n\
+ </value-type>\n\
+ <value-type name='B'>\n\
+ <add-function signature='B(TARGETLANGTYPE*)'/>\n\
+ </value-type>\n\
+ <value-type name='C'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 3);
+
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ AbstractMetaFunctionList implicitConvs = classA->implicitConversions();
+ QCOMPARE(implicitConvs.count(), 2);
+
+ // Added constructors with custom types should never result in implicit converters.
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ implicitConvs = classB->implicitConversions();
+ QCOMPARE(implicitConvs.count(), 0);
+}
+
+void TestImplicitConversions::testWithExternalConversionOperator()
+{
+ const char* cppCode ="\
+ class A {};\n\
+ struct B {\n\
+ operator A() const;\n\
+ };\n";
+ const char* xmlCode = "\n\
+ <typesystem package='Foo'>\n\
+ <value-type name='A'/>\n\
+ <value-type name='B'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ AbstractMetaFunctionList implicitConvs = classA->implicitConversions();
+ QCOMPARE(implicitConvs.count(), 1);
+ AbstractMetaFunctionList externalConvOps = classA->externalConversionOperators();
+ QCOMPARE(externalConvOps.count(), 1);
+
+ const AbstractMetaFunction* convOp = 0;
+ foreach(const AbstractMetaFunction* func, classB->functions()) {
+ if (func->isConversionOperator())
+ convOp = func;
+ }
+ QVERIFY(convOp);
+ QCOMPARE(implicitConvs.first(), convOp);
+}
+
+QTEST_APPLESS_MAIN(TestImplicitConversions)
diff --git a/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.h b/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.h
new file mode 100644
index 000000000..657c1a558
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTIMPLICITCONVERSIONS_H
+#define TESTIMPLICITCONVERSIONS_H
+
+#include <QObject>
+
+class AbstractMetaBuilder;
+
+class TestImplicitConversions : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testWithPrivateCtors();
+ void testWithModifiedVisibility();
+ void testWithAddedCtor();
+ void testWithExternalConversionOperator();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testinserttemplate.cpp b/sources/shiboken2/ApiExtractor/tests/testinserttemplate.cpp
new file mode 100644
index 000000000..ecadf311b
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testinserttemplate.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testinserttemplate.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestInsertTemplate::testInsertTemplateOnClassInjectCode()
+{
+ const char* cppCode ="struct A{};\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <template name='code_template'>\n\
+ code template content\n\
+ </template>\n\
+ <value-type name='A'>\n\
+ <inject-code class='native'>\n\
+ <insert-template name='code_template'/>\n\
+ </inject-code>\n\
+ </value-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 1);
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QCOMPARE(classA->typeEntry()->codeSnips().count(), 1);
+ QString code = classA->typeEntry()->codeSnips().first().code();
+ QVERIFY(code.contains(QLatin1String("code template content")));
+}
+
+void TestInsertTemplate::testInsertTemplateOnModuleInjectCode()
+{
+ const char* cppCode ="";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <template name='code_template'>\n\
+ code template content\n\
+ </template>\n\
+ <inject-code class='native'>\n\
+ <insert-template name='code_template'/>\n\
+ </inject-code>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QVERIFY(classes.isEmpty());
+
+ TypeEntry* module = TypeDatabase::instance()->findType(QLatin1String("Foo"));
+ QVERIFY(module);
+ QCOMPARE(module->codeSnips().count(), 1);
+ QString code = module->codeSnips().first().code().trimmed();
+ QVERIFY(code.contains(QLatin1String("code template content")));
+}
+
+void TestInsertTemplate::testInvalidTypeSystemTemplate()
+{
+ const char* cppCode ="";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <inject-code class='native'>\n\
+ <insert-template name='this_code_template_does_not_exists'/>\n\
+ </inject-code>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QVERIFY(classes.isEmpty());
+
+ TypeEntry* module = TypeDatabase::instance()->findType(QLatin1String("Foo"));
+ QVERIFY(module);
+ QCOMPARE(module->codeSnips().count(), 1);
+ QString code = module->codeSnips().first().code().trimmed();
+ QVERIFY(code.isEmpty());
+}
+
+void TestInsertTemplate::testValidAndInvalidTypeSystemTemplate()
+{
+ const char* cppCode ="";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <template name='code_template'>\n\
+ code template content\n\
+ </template>\n\
+ <inject-code class='native'>\n\
+ <insert-template name='this_code_template_does_not_exists'/>\n\
+ <insert-template name='code_template'/>\n\
+ </inject-code>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QVERIFY(classes.isEmpty());
+
+ TypeEntry* module = TypeDatabase::instance()->findType(QLatin1String("Foo"));
+ QVERIFY(module);
+ QCOMPARE(module->codeSnips().count(), 1);
+ QString code = module->codeSnips().first().code().trimmed();
+ QVERIFY(code.contains(QLatin1String("code template content")));
+}
+
+QTEST_APPLESS_MAIN(TestInsertTemplate)
diff --git a/sources/shiboken2/ApiExtractor/tests/testinserttemplate.h b/sources/shiboken2/ApiExtractor/tests/testinserttemplate.h
new file mode 100644
index 000000000..0e2a882fe
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testinserttemplate.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTINSERTTEMPLATE_H
+#define TESTINSERTTEMPLATE_H
+
+#include <QObject>
+
+class TestInsertTemplate : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testInsertTemplateOnClassInjectCode();
+ void testInsertTemplateOnModuleInjectCode();
+ void testInvalidTypeSystemTemplate();
+ void testValidAndInvalidTypeSystemTemplate();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
new file mode 100644
index 000000000..96bd0251b
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testmodifydocumentation.h"
+
+#include <QCoreApplication>
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+#include <qtdocparser.h>
+
+void TestModifyDocumentation::testModifyDocumentation()
+{
+ const char* cppCode ="struct B { void b(); }; class A {};\n";
+ const char* xmlCode = "<typesystem package=\"Foo\">\n\
+ <value-type name='B'>\n\
+ <modify-function signature='b()' remove='all'/>\n\
+ </value-type>\n\
+ <value-type name='A'>\n\
+ <modify-documentation xpath='description/para[3]'>\n\
+ &lt;para>Some changed contents here&lt;/para>\n\
+ </modify-documentation>\n\
+ </value-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ QVERIFY(classA);
+ DocModificationList docMods = classA->typeEntry()->docModifications();
+ QCOMPARE(docMods.count(), 1);
+ QCOMPARE(docMods[0].code().trimmed(), QLatin1String("<para>Some changed contents here</para>"));
+ QCOMPARE(docMods[0].signature(), QString());
+ QtDocParser docParser;
+ docParser.setDocumentationDataDirectory(QDir::currentPath());
+ docParser.fillDocumentation(classA);
+
+ QVERIFY(!classA->documentation().value().trimmed().isEmpty());
+ QCOMPARE(classA->documentation().value(), QLatin1String("<?xml version=\"1.0\"?>\n\
+<description>oi\n\
+ <para>Paragraph number 1</para>\n\
+ <para>Paragraph number 2</para>\n\
+ <para>Some changed contents here</para>\n\
+</description>\n"));
+}
+
+// We expand QTEST_MAIN macro but using QCoreApplication instead of QApplication
+// because this test needs an event loop but can't use QApplication to avoid a crash
+// on our ARMEL/FRAMANTLE buildbot
+int main(int argc, char** argv)
+{
+ QCoreApplication app(argc, argv);
+ TestModifyDocumentation tc;
+ return QTest::qExec(&tc, argc, argv);
+}
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.h b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.h
new file mode 100644
index 000000000..fb8f6fc01
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTMODIFYDOCUMENTATION_H
+#define TESTMODIFYDOCUMENTATION_H
+
+#include <QObject>
+
+class TestModifyDocumentation : public QObject
+{
+Q_OBJECT
+private slots:
+ void testModifyDocumentation();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp
new file mode 100644
index 000000000..0e6bdc248
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testmodifyfunction.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestModifyFunction::testRenameArgument()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ void method(int=0);\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <object-type name='A'>\n\
+ <modify-function signature='method(int)'>\n\
+ <modify-argument index='1'>\n\
+ <rename to='otherArg'/>\n\
+ </modify-argument>\n\
+ </modify-function>\n\
+ </object-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const AbstractMetaFunction* func = classA->findFunction(QLatin1String("method"));
+ Q_ASSERT(func);
+
+ QCOMPARE(func->argumentName(1), QLatin1String("otherArg"));
+}
+
+void TestModifyFunction::testOwnershipTransfer()
+{
+ const char* cppCode ="\
+ struct A {};\n\
+ struct B {\n\
+ virtual A* method();\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <object-type name='A' />\n\
+ <object-type name='B'>\n\
+ <modify-function signature='method()'>\n\
+ <modify-argument index='return'>\n\
+ <define-ownership owner='c++'/>\n\
+ </modify-argument>\n\
+ </modify-function>\n\
+ </object-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const AbstractMetaFunction* func = classB->findFunction(QLatin1String("method"));
+
+ QCOMPARE(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0), TypeSystem::CppOwnership);
+}
+
+
+void TestModifyFunction::invalidateAfterUse()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ virtual void call(int *a);\n\
+ };\n\
+ struct B : A {\n\
+ };\n\
+ struct C : B {\n\
+ virtual void call2(int *a);\n\
+ };\n\
+ struct D : C {\n\
+ virtual void call2(int *a);\n\
+ };\n\
+ struct E : D {\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <object-type name='A'>\n\
+ <modify-function signature='call(int*)'>\n\
+ <modify-argument index='1' invalidate-after-use='true'/>\n\
+ </modify-function>\n\
+ </object-type>\n\
+ <object-type name='B' />\n\
+ <object-type name='C'>\n\
+ <modify-function signature='call2(int*)'>\n\
+ <modify-argument index='1' invalidate-after-use='true'/>\n\
+ </modify-function>\n\
+ </object-type>\n\
+ <object-type name='D'>\n\
+ <modify-function signature='call2(int*)'>\n\
+ <modify-argument index='1' invalidate-after-use='true'/>\n\
+ </modify-function>\n\
+ </object-type>\n\
+ <object-type name='E' />\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, "0.1"));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const AbstractMetaFunction* func = classB->findFunction(QLatin1String("call"));
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+
+ const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, QLatin1String("C"));
+ QVERIFY(classC);
+ func = classC->findFunction(QLatin1String("call"));
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+
+ func = classC->findFunction(QLatin1String("call2"));
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+
+ const AbstractMetaClass *classD = AbstractMetaClass::findClass(classes, QLatin1String("D"));
+ QVERIFY(classD);
+ func = classD->findFunction(QLatin1String("call"));
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+
+ func = classD->findFunction(QLatin1String("call2"));
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+
+ const AbstractMetaClass *classE = AbstractMetaClass::findClass(classes, QLatin1String("E"));
+ QVERIFY(classE);
+ func = classE->findFunction(QLatin1String("call"));
+ QVERIFY(func);
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+
+ func = classE->findFunction(QLatin1String("call2"));
+ QVERIFY(func);
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+}
+
+void TestModifyFunction::testWithApiVersion()
+{
+ const char* cppCode ="\
+ struct A {};\n\
+ struct B {\n\
+ virtual A* method();\n\
+ virtual B* methodB();\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <object-type name='A' />\n\
+ <object-type name='B'>\n\
+ <modify-function signature='method()' since='0.1'>\n\
+ <modify-argument index='return'>\n\
+ <define-ownership owner='c++'/>\n\
+ </modify-argument>\n\
+ </modify-function>\n\
+ <modify-function signature='methodB()' since='0.2'>\n\
+ <modify-argument index='return'>\n\
+ <define-ownership owner='c++'/>\n\
+ </modify-argument>\n\
+ </modify-function>\n\
+ </object-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, "0.1"));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const AbstractMetaFunction* func = classB->findFunction(QLatin1String("method"));
+
+ QCOMPARE(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0), TypeSystem::CppOwnership);
+
+ func = classB->findFunction(QLatin1String("methodB"));
+ QVERIFY(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0) != TypeSystem::CppOwnership);
+}
+
+void TestModifyFunction::testGlobalFunctionModification()
+{
+ const char* cppCode ="\
+ struct A {};\n\
+ void function(A* a = 0);\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='A'/>\n\
+ <function signature='function(A*)'>\n\
+ <modify-function signature='function(A*)'>\n\
+ <modify-argument index='1'>\n\
+ <replace-type modified-type='A'/>\n\
+ <replace-default-expression with='A()'/>\n\
+ </modify-argument>\n\
+ </modify-function>\n\
+ </function>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ QCOMPARE(builder->globalFunctions().size(), 1);
+
+ FunctionModificationList mods = TypeDatabase::instance()->functionModifications(QLatin1String("function(A*)"));
+ QCOMPARE(mods.count(), 1);
+ QList<ArgumentModification> argMods = mods.first().argument_mods;
+ QCOMPARE(argMods.count(), 1);
+ ArgumentModification argMod = argMods.first();
+ QCOMPARE(argMod.replacedDefaultExpression, QLatin1String("A()"));
+
+ const AbstractMetaFunction* func = builder->globalFunctions().first();
+ QVERIFY(func);
+ QCOMPARE(func->arguments().count(), 1);
+ const AbstractMetaArgument* arg = func->arguments().first();
+ QCOMPARE(arg->type()->cppSignature(), QLatin1String("A *"));
+ QCOMPARE(arg->originalDefaultValueExpression(), QLatin1String("0"));
+ QCOMPARE(arg->defaultValueExpression(), QLatin1String("A()"));
+}
+
+QTEST_APPLESS_MAIN(TestModifyFunction)
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h
new file mode 100644
index 000000000..fcaa0f9db
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTABSTRACTMETACLASS_H
+#define TESTABSTRACTMETACLASS_H
+
+#include <QObject>
+
+class TestModifyFunction : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testOwnershipTransfer();
+ void testWithApiVersion();
+ void testRenameArgument();
+ void invalidateAfterUse();
+ void testGlobalFunctionModification();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.cpp b/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.cpp
new file mode 100644
index 000000000..67c9089ce
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testmultipleinheritance.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestMultipleInheritance::testVirtualClass()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ virtual ~A();\n\
+ virtual void theBug();\n\
+ };\n\
+ struct B {\n\
+ virtual ~B();\n\
+ };\n\
+ struct C : A, B {\n\
+ };\n\
+ struct D : C {\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <object-type name='A' />\n\
+ <object-type name='B' />\n\
+ <object-type name='C' />\n\
+ <object-type name='D' />\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 4);
+
+ const AbstractMetaClass *classD = AbstractMetaClass::findClass(classes, QLatin1String("D"));
+ bool functionFound = false;
+ foreach (AbstractMetaFunction* f, classD->functions()) {
+ if (f->name() == QLatin1String("theBug")) {
+ functionFound = true;
+ break;
+ }
+ }
+ QVERIFY(functionFound);
+
+}
+
+QTEST_APPLESS_MAIN(TestMultipleInheritance)
diff --git a/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.h b/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.h
new file mode 100644
index 000000000..2313073bb
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTMULTIPLEINHERITANCE_H
+#define TESTMULTIPLEINHERITANCE_H
+
+#include <QObject>
+
+class AbstractMetaBuilder;
+
+class TestMultipleInheritance : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testVirtualClass();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testnamespace.cpp b/sources/shiboken2/ApiExtractor/tests/testnamespace.cpp
new file mode 100644
index 000000000..ca6ce0589
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testnamespace.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testnamespace.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void NamespaceTest::testNamespaceMembers()
+{
+ const char* cppCode = "\
+ namespace Namespace\n\
+ {\n\
+ enum Option {\n\
+ OpZero,\n\
+ OpOne\n\
+ };\n\
+ void foo(Option opt);\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <namespace-type name='Namespace'>\n\
+ <enum-type name='Option' />\n\
+ </namespace-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ AbstractMetaClass *ns = AbstractMetaClass::findClass(classes, QLatin1String("Namespace"));
+ QVERIFY(ns);
+ const AbstractMetaEnum* metaEnum = ns->findEnum(QLatin1String("Option"));
+ QVERIFY(metaEnum);
+ const AbstractMetaFunction* func = ns->findFunction(QLatin1String("foo"));
+ QVERIFY(func);
+}
+
+void NamespaceTest::testNamespaceInnerClassMembers()
+{
+ const char* cppCode = "\
+ namespace OuterNamespace\n\
+ {\n\
+ namespace InnerNamespace {\n\
+ struct SomeClass {\n\
+ void method();\n\
+ };\n\
+ };\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <namespace-type name='OuterNamespace'>\n\
+ <namespace-type name='InnerNamespace'>\n\
+ <value-type name='SomeClass'/>\n\
+ </namespace-type>\n\
+ </namespace-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *ons = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace"));
+ QVERIFY(ons);
+ const AbstractMetaClass *ins = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace"));
+ QVERIFY(ins);
+ const AbstractMetaClass *sc = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace::SomeClass"));
+ QVERIFY(sc);
+ const AbstractMetaFunction* meth = sc->findFunction(QLatin1String("method"));
+ QVERIFY(meth);
+}
+
+QTEST_APPLESS_MAIN(NamespaceTest)
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testnamespace.h b/sources/shiboken2/ApiExtractor/tests/testnamespace.h
new file mode 100644
index 000000000..d4451a938
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testnamespace.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTNAMESPACE_H
+#define TESTNAMESPACE_H
+
+#include <QObject>
+
+// The class is named 'NamespaceTest' to avoid clashes with Qt COIN using
+// '-qtnamespace TestNamespace'.
+class NamespaceTest : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testNamespaceMembers();
+ void testNamespaceInnerClassMembers();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp b/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp
new file mode 100644
index 000000000..296aa4385
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testnestedtypes.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestNestedTypes::testNestedTypesModifications()
+{
+ const char* cppCode ="\
+ namespace OuterNamespace {\n\
+ namespace InnerNamespace {\n\
+ struct SomeClass {\n\
+ void method() {}\n\
+ };\n\
+ };\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <namespace-type name='OuterNamespace'>\n\
+ <namespace-type name='InnerNamespace'>\n\
+ <inject-code class='native'>custom_code1();</inject-code>\n\
+ <add-function signature='method()' return-type='OuterNamespace::InnerNamespace::SomeClass'>\n\
+ <inject-code class='target'>custom_code2();</inject-code>\n\
+ </add-function>\n\
+ <object-type name='SomeClass' target-lang-name='RenamedSomeClass'>\n\
+ <modify-function signature='method()' remove='all'/>\n\
+ </object-type>\n\
+ </namespace-type>\n\
+ </namespace-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+
+ const AbstractMetaClass *ons = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace"));
+ QVERIFY(ons);
+
+ const AbstractMetaClass *ins = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace"));
+ QVERIFY(ins);
+ QCOMPARE(ins->functions().count(), 1);
+ QCOMPARE(ins->typeEntry()->codeSnips().count(), 1);
+ CodeSnip snip = ins->typeEntry()->codeSnips().first();
+ QCOMPARE(snip.code(), QLatin1String("custom_code1();"));
+
+ AbstractMetaFunction* addedFunc = ins->functions().first();
+ QVERIFY(addedFunc->isUserAdded());
+ QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Public);
+ QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction);
+ QCOMPARE(addedFunc->type()->minimalSignature(), QLatin1String("OuterNamespace::InnerNamespace::SomeClass"));
+
+ QCOMPARE(addedFunc->modifications().size(), 1);
+ QVERIFY(addedFunc->modifications().first().isCodeInjection());
+ snip = addedFunc->modifications().first().snips.first();
+ QCOMPARE(snip.code(), QLatin1String("custom_code2();"));
+
+ const AbstractMetaClass *sc = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace::SomeClass"));
+ QVERIFY(ins);
+ QCOMPARE(sc->functions().count(), 2); // default constructor and removed method
+ AbstractMetaFunction* removedFunc = sc->functions().last();
+ QVERIFY(removedFunc->isModifiedRemoved());
+}
+
+
+void TestNestedTypes::testDuplicationOfNestedTypes()
+{
+ const char* cppCode ="\
+ namespace Namespace {\n\
+ class SomeClass {};\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <namespace-type name='Namespace'>\n\
+ <value-type name='SomeClass'>\n\
+ <add-function signature='createSomeClass(Namespace::SomeClass)'/>\n\
+ </value-type>\n\
+ </namespace-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ const AbstractMetaClass *nspace = AbstractMetaClass::findClass(classes, QLatin1String("Namespace"));
+ QVERIFY(nspace);
+ const AbstractMetaClass *cls1 = AbstractMetaClass::findClass(classes, QLatin1String("SomeClass"));
+ QVERIFY(cls1);
+ const AbstractMetaClass *cls2 = AbstractMetaClass::findClass(classes, QLatin1String("Namespace::SomeClass"));
+ QVERIFY(cls2);
+ QCOMPARE(cls1, cls2);
+ QCOMPARE(cls1->name(), QLatin1String("SomeClass"));
+ QCOMPARE(cls1->qualifiedCppName(), QLatin1String("Namespace::SomeClass"));
+
+ TypeEntry* t1 = TypeDatabase::instance()->findType(QLatin1String("Namespace::SomeClass"));
+ QVERIFY(t1);
+ TypeEntry* t2 = TypeDatabase::instance()->findType(QLatin1String("SomeClass"));
+ QVERIFY(!t2);
+}
+
+QTEST_APPLESS_MAIN(TestNestedTypes)
diff --git a/sources/shiboken2/ApiExtractor/tests/testnestedtypes.h b/sources/shiboken2/ApiExtractor/tests/testnestedtypes.h
new file mode 100644
index 000000000..737e81fab
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testnestedtypes.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTNESTEDTYPES_H
+#define TESTNESTEDTYPES_H
+#include <QObject>
+
+class TestNestedTypes : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testNestedTypesModifications();
+ void testDuplicationOfNestedTypes();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp b/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp
new file mode 100644
index 000000000..3491d5cb4
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testnumericaltypedef.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestNumericalTypedef::testNumericalTypedef()
+{
+ const char* cppCode ="\
+ typedef double real;\n\
+ void funcDouble(double);\n\
+ void funcReal(real);\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='double'/>\n\
+ <primitive-type name='real'/>\n\
+ <function signature='funcDouble(double)'/>\n\
+ <function signature='funcReal(real)'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ QCOMPARE(builder->globalFunctions().size(), 2);
+ const AbstractMetaFunction* funcDouble = builder->globalFunctions().first();
+ QVERIFY(funcDouble);
+ const AbstractMetaFunction* funcReal = builder->globalFunctions().last();
+ QVERIFY(funcReal);
+
+ if (funcDouble->name() == QLatin1String("funcReal"))
+ std::swap(funcDouble, funcReal);
+
+ QCOMPARE(funcDouble->minimalSignature(), QLatin1String("funcDouble(double)"));
+ QCOMPARE(funcReal->minimalSignature(), QLatin1String("funcReal(real)"));
+
+ const AbstractMetaType* doubleType = funcDouble->arguments().first()->type();
+ QVERIFY(doubleType);
+ QCOMPARE(doubleType->cppSignature(), QLatin1String("double"));
+ QVERIFY(doubleType->isPrimitive());
+ QVERIFY(doubleType->typeEntry()->isCppPrimitive());
+
+ const AbstractMetaType* realType = funcReal->arguments().first()->type();
+ QVERIFY(realType);
+ QCOMPARE(realType->cppSignature(), QLatin1String("real"));
+ QVERIFY(realType->isPrimitive());
+ QVERIFY(realType->typeEntry()->isCppPrimitive());
+}
+
+void TestNumericalTypedef::testUnsignedNumericalTypedef()
+{
+ const char* cppCode ="\
+ typedef unsigned short ushort;\n\
+ void funcUnsignedShort(unsigned short);\n\
+ void funcUShort(ushort);\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='short'/>\n\
+ <primitive-type name='unsigned short'/>\n\
+ <primitive-type name='ushort'/>\n\
+ <function signature='funcUnsignedShort(unsigned short)'/>\n\
+ <function signature='funcUShort(ushort)'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ QCOMPARE(builder->globalFunctions().size(), 2);
+ const AbstractMetaFunction* funcUnsignedShort = builder->globalFunctions().first();
+ QVERIFY(funcUnsignedShort);
+ const AbstractMetaFunction* funcUShort = builder->globalFunctions().last();
+ QVERIFY(funcUShort);
+
+ if (funcUnsignedShort->name() == QLatin1String("funcUShort"))
+ std::swap(funcUnsignedShort, funcUShort);
+
+ QCOMPARE(funcUnsignedShort->minimalSignature(), QLatin1String("funcUnsignedShort(unsigned short)"));
+ QCOMPARE(funcUShort->minimalSignature(), QLatin1String("funcUShort(ushort)"));
+
+ const AbstractMetaType* unsignedShortType = funcUnsignedShort->arguments().first()->type();
+ QVERIFY(unsignedShortType);
+ QCOMPARE(unsignedShortType->cppSignature(), QLatin1String("unsigned short"));
+ QVERIFY(unsignedShortType->isPrimitive());
+ QVERIFY(unsignedShortType->typeEntry()->isCppPrimitive());
+
+ const AbstractMetaType* ushortType = funcUShort->arguments().first()->type();
+ QVERIFY(ushortType);
+ QCOMPARE(ushortType->cppSignature(), QLatin1String("ushort"));
+ QVERIFY(ushortType->isPrimitive());
+ QVERIFY(ushortType->typeEntry()->isCppPrimitive());
+}
+
+QTEST_APPLESS_MAIN(TestNumericalTypedef)
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.h b/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.h
new file mode 100644
index 000000000..e8af1fa8e
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTNUMERICALTYPEDEF_H
+#define TESTNUMERICALTYPEDEF_H
+
+#include <QObject>
+
+class TestNumericalTypedef : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testNumericalTypedef();
+ void testUnsignedNumericalTypedef();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.cpp b/sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.cpp
new file mode 100644
index 000000000..7646dd23a
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testprimitivetypetag.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestPrimitiveTypeTag::testPrimitiveTypeDefaultConstructor()
+{
+ const char* cppCode ="\
+ struct A {};\n\
+ struct B {};\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <primitive-type name='A' default-constructor='A()'/>\n\
+ <object-type name='B'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 1);
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classB);
+
+ PrimitiveTypeEntry* typeEntry = TypeDatabase::instance()->findPrimitiveType(QLatin1String("A"));
+ QVERIFY(typeEntry);
+ QVERIFY(typeEntry->hasDefaultConstructor());
+ QCOMPARE(typeEntry->defaultConstructor(), QLatin1String("A()"));
+}
+
+QTEST_APPLESS_MAIN(TestPrimitiveTypeTag)
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.h b/sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.h
new file mode 100644
index 000000000..ea9276de3
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTPRIMITIVETYPETAG_H
+#define TESTPRIMITIVETYPETAG_H
+
+#include <QObject>
+
+class TestPrimitiveTypeTag : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testPrimitiveTypeDefaultConstructor();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp b/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp
new file mode 100644
index 000000000..e9f9f0ab7
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testrefcounttag.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestRefCountTag::testReferenceCountTag()
+{
+ const char* cppCode ="\
+ struct A {};\n\
+ struct B {\n\
+ void keepObject(B* b);\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <object-type name='A'/>\n\
+ <object-type name='B'>\n\
+ <modify-function signature='keepObject(B*)'>\n\
+ <modify-argument index='1'>\n\
+ <reference-count action='add'/>\n\
+ </modify-argument>\n\
+ </modify-function>\n\
+ </object-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const AbstractMetaFunction* func = classB->findFunction(QLatin1String("keepObject"));
+ QVERIFY(func);
+ ReferenceCount refCount = func->modifications().first().argument_mods.first().referenceCounts.first();
+ QCOMPARE(refCount.action, ReferenceCount::Add);
+}
+
+void TestRefCountTag::testWithApiVersion()
+{
+ const char* cppCode ="\
+ struct A {};\n\
+ struct B {\n\
+ void keepObject(B*, B*);\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <object-type name='A'/>\n\
+ <object-type name='B'>\n\
+ <modify-function signature='keepObject(B*, B*)'>\n\
+ <modify-argument index='1' since='0.1'>\n\
+ <reference-count action='add'/>\n\
+ </modify-argument>\n\
+ <modify-argument index='2' since='0.2'>\n\
+ <reference-count action='add'/>\n\
+ </modify-argument>\n\
+ </modify-function>\n\
+ </object-type>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, "0.1"));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const AbstractMetaFunction* func = classB->findFunction(QLatin1String("keepObject"));
+ QVERIFY(func);
+ ReferenceCount refCount = func->modifications().first().argument_mods.first().referenceCounts.first();
+ QCOMPARE(refCount.action, ReferenceCount::Add);
+
+ QCOMPARE(func->modifications().size(), 1);
+}
+
+
+QTEST_APPLESS_MAIN(TestRefCountTag)
+
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testrefcounttag.h b/sources/shiboken2/ApiExtractor/tests/testrefcounttag.h
new file mode 100644
index 000000000..a95661293
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testrefcounttag.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTREFCOUNTTAG_H
+#define TESTREFCOUNTTAG_H
+
+#include <QObject>
+
+class TestRefCountTag : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testReferenceCountTag();
+ void testWithApiVersion();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp b/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp
new file mode 100644
index 000000000..f594cdd25
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testreferencetopointer.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestReferenceToPointer::testReferenceToPointerArgument()
+{
+ const char* cppCode ="\
+ struct A {};\n\
+ struct B {\n\
+ void dummy(A*&);\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <object-type name='A'/>\n\
+ <object-type name='B'/>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classB);
+ const AbstractMetaFunction* func = classB->findFunction(QLatin1String("dummy"));
+ QVERIFY(func);
+ QCOMPARE(func->arguments().first()->type()->minimalSignature(), QLatin1String("A*&"));
+}
+
+QTEST_APPLESS_MAIN(TestReferenceToPointer)
+
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.h b/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.h
new file mode 100644
index 000000000..83b0b6fad
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTREFERENCETOPOINTER_H
+#define TESTREFERENCETOPOINTER_H
+
+#include <QObject>
+
+class TestReferenceToPointer : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testReferenceToPointerArgument();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testremovefield.cpp b/sources/shiboken2/ApiExtractor/tests/testremovefield.cpp
new file mode 100644
index 000000000..7ebe49160
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testremovefield.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testremovefield.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestRemoveField::testRemoveField()
+{
+ const char* cppCode ="\
+ struct A {\n\
+ int fieldA;\n\
+ int fieldB;\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <primitive-type name='int'/>\n\
+ <value-type name='A'>\n\
+ <modify-field name='fieldB' remove='all'/>\n\
+ </value-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QCOMPARE(classA->fields().size(), 1);
+ const AbstractMetaField* fieldA = classA->fields().first();
+ QVERIFY(fieldA);
+ QCOMPARE(fieldA->name(), QLatin1String("fieldA"));
+}
+
+QTEST_APPLESS_MAIN(TestRemoveField)
+
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testremovefield.h b/sources/shiboken2/ApiExtractor/tests/testremovefield.h
new file mode 100644
index 000000000..ea103e0cc
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testremovefield.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTREMOVEFIELD_H
+#define TESTREMOVEFIELD_H
+
+#include <QObject>
+
+class TestRemoveField : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testRemoveField();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp b/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp
new file mode 100644
index 000000000..a81380873
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testremoveimplconv.h"
+#include "testutil.h"
+#include <QtTest/QTest>
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+// When a constructor able to trigger implicity conversions is removed
+// it should not appear in the implicity conversion list.
+void TestRemoveImplConv::testRemoveImplConv()
+{
+ const char* cppCode ="\
+ struct A {};\n\
+ struct B {};\n\
+ struct C {\n\
+ C(const A&);\n\
+ C(const B&);\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A'/>\n\
+ <value-type name='B'/>\n\
+ <value-type name='C'>\n\
+ <modify-function signature='C(const A&amp;)' remove='all'/>\n\
+ </value-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 3);
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classB);
+ const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, QLatin1String("C"));
+ QVERIFY(classC);
+ AbstractMetaFunctionList implConv = classC->implicitConversions();
+ QCOMPARE(implConv.count(), 1);
+ QCOMPARE(implConv.first()->arguments().first()->type()->typeEntry(), classB->typeEntry());
+}
+
+QTEST_APPLESS_MAIN(TestRemoveImplConv)
diff --git a/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.h b/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.h
new file mode 100644
index 000000000..62d5f74e6
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTREMOVEIMPLCONV_H
+#define TESTREMOVEIMPLCONV_H
+
+#include <QObject>
+
+class TestRemoveImplConv : public QObject
+{
+Q_OBJECT
+private slots:
+ void testRemoveImplConv();
+};
+
+#endif // TESTREMOVEIMPLCONV_H
diff --git a/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.cpp b/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.cpp
new file mode 100644
index 000000000..6b27227d6
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testremoveoperatormethod.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestRemoveOperatorMethod::testRemoveOperatorMethod()
+{
+ const char* cppCode ="\
+ #include <stdint.h>\n\
+ \n\
+ struct Char {};\n\
+ struct ByteArray {};\n\
+ struct String {};\n\
+ \n\
+ struct A {\n\
+ A& operator>>(char&);\n\
+ A& operator>>(char*);\n\
+ A& operator>>(short&);\n\
+ A& operator>>(unsigned short&);\n\
+ A& operator>>(int&);\n\
+ A& operator>>(unsigned int&);\n\
+ A& operator>>(int64_t&);\n\
+ A& operator>>(uint64_t&);\n\
+ A& operator>>(float&);\n\
+ A& operator>>(double&);\n\
+ A& operator>>(Char&);\n\
+ A& operator>>(ByteArray&);\n\
+ A& operator>>(String&);\n\
+ };\n";
+ const char* xmlCode = "\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='char'/>\n\
+ <primitive-type name='short'/>\n\
+ <primitive-type name='unsigned short'/>\n\
+ <primitive-type name='int'/>\n\
+ <primitive-type name='unsigned int'/>\n\
+ <primitive-type name='int64_t'/>\n\
+ <primitive-type name='uint64_t'/>\n\
+ <primitive-type name='float'/>\n\
+ <primitive-type name='double'/>\n\
+ <primitive-type name='Char'/>\n\
+ <primitive-type name='String'/>\n\
+ <value-type name='ByteArray'/>\n\
+ <object-type name='A'>\n\
+ <modify-function signature='operator&gt;&gt;(char&amp;)' remove='all'/>\n\
+ <modify-function signature='operator&gt;&gt;(char*)' remove='all'/>\n\
+ <modify-function signature='operator&gt;&gt;(short&amp;)' remove='all'/>\n\
+ <modify-function signature='operator&gt;&gt;(unsigned short&amp;)' remove='all'/>\n\
+ <modify-function signature='operator&gt;&gt;(int&amp;)' remove='all'/>\n\
+ <modify-function signature='operator&gt;&gt;(unsigned int&amp;)' remove='all'/>\n\
+ <modify-function signature='operator&gt;&gt;(int64_t&amp;)' remove='all'/>\n\
+ <modify-function signature='operator&gt;&gt;(uint64_t&amp;)' remove='all'/>\n\
+ <modify-function signature='operator&gt;&gt;(float&amp;)' remove='all'/>\n\
+ <modify-function signature='operator&gt;&gt;(double&amp;)' remove='all'/>\n\
+ <modify-function signature='operator&gt;&gt;(Char&amp;)' remove='all'/>\n\
+ <modify-function signature='operator&gt;&gt;(String&amp;)' remove='all'/>\n\
+ </object-type>\n\
+ </typesystem>\n";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QCOMPARE(classA->functions().size(), 14);
+ QStringList removedSignatures;
+ removedSignatures.append(QLatin1String("operator>>(char&)"));
+ removedSignatures.append(QLatin1String("operator>>(char*)"));
+ removedSignatures.append(QLatin1String("operator>>(short&)"));
+ removedSignatures.append(QLatin1String("operator>>(unsigned short&)"));
+ removedSignatures.append(QLatin1String("operator>>(int&)"));
+ removedSignatures.append(QLatin1String("operator>>(unsigned int&)"));
+ removedSignatures.append(QLatin1String("operator>>(int64_t&)"));
+ removedSignatures.append(QLatin1String("operator>>(uint64_t&)"));
+ removedSignatures.append(QLatin1String("operator>>(float&)"));
+ removedSignatures.append(QLatin1String("operator>>(double&)"));
+ removedSignatures.append(QLatin1String("operator>>(Char&)"));
+ removedSignatures.append(QLatin1String("operator>>(String&)"));
+ int notRemoved = classA->functions().size();
+ foreach (const AbstractMetaFunction* f, classA->functions()) {
+ QCOMPARE(f->isModifiedRemoved(), bool(removedSignatures.contains(f->minimalSignature())));
+ notRemoved -= int(f->isModifiedRemoved());
+ }
+ QCOMPARE(notRemoved, 2);
+}
+
+QTEST_APPLESS_MAIN(TestRemoveOperatorMethod)
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.h b/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.h
new file mode 100644
index 000000000..17ff75d74
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTREMOVEOPERATORMETHOD_H
+#define TESTREMOVEOPERATORMETHOD_H
+
+#include <QObject>
+
+class TestRemoveOperatorMethod : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testRemoveOperatorMethod();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp b/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp
new file mode 100644
index 000000000..69691e860
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testresolvetype.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestResolveType::testResolveReturnTypeFromParentScope()
+{
+ const char* cppCode = "\n\
+ namespace A {\n\
+ struct B {\n\
+ struct C {};\n\
+ };\n\
+ struct D : public B::C {\n\
+ C* foo = 0;\n\
+ C* method();\n\
+ };\n\
+ };";
+ const char* xmlCode = "\n\
+ <typesystem package='Foo'>\n\
+ <namespace-type name='A'/>\n\
+ <value-type name='A::B'/>\n\
+ <value-type name='A::B::C'/>\n\
+ <value-type name='A::D'/>\n\
+ </typesystem>";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classD = AbstractMetaClass::findClass(classes, QLatin1String("A::D"));
+ QVERIFY(classD);
+ const AbstractMetaFunction* meth = classD->findFunction(QLatin1String("method"));
+ QVERIFY(meth);
+}
+
+QTEST_APPLESS_MAIN(TestResolveType)
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testresolvetype.h b/sources/shiboken2/ApiExtractor/tests/testresolvetype.h
new file mode 100644
index 000000000..6164d0074
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testresolvetype.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTRESOLVETYPE_H
+#define TESTRESOLVETYPE_H
+
+#include <QObject>
+
+class TestResolveType : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testResolveReturnTypeFromParentScope();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testreverseoperators.cpp b/sources/shiboken2/ApiExtractor/tests/testreverseoperators.cpp
new file mode 100644
index 000000000..76ba7d3b4
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testreverseoperators.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testreverseoperators.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestReverseOperators::testReverseSum()
+{
+ const char cppCode[] = "struct A {\n\
+ A& operator+(int);\n\
+ };\n\
+ A& operator+(int, const A&);";
+ const char xmlCode[] = "\n\
+ <typesystem package=\"Foo\">\n\
+ <primitive-type name='int' />\n\
+ <value-type name='A' />\n\
+ </typesystem>";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QCOMPARE(classA->functions().count(), 4);
+
+ const AbstractMetaFunction* reverseOp = 0;
+ const AbstractMetaFunction* normalOp = 0;
+ foreach(const AbstractMetaFunction* func, classA->functions()) {
+ if (func->name() == QLatin1String("operator+")) {
+ if (func->isReverseOperator())
+ reverseOp = func;
+ else
+ normalOp = func;
+ }
+ }
+
+ QVERIFY(normalOp);
+ QVERIFY(!normalOp->isReverseOperator());
+ QCOMPARE(normalOp->arguments().count(), 1);
+ QVERIFY(reverseOp);
+ QVERIFY(reverseOp->isReverseOperator());
+ QCOMPARE(reverseOp->arguments().count(), 1);
+}
+
+void TestReverseOperators::testReverseSumWithAmbiguity()
+{
+ const char cppCode[] = "\n\
+ struct A { A operator+(int); };\n\
+ A operator+(int, const A&);\n\
+ struct B {};\n\
+ B operator+(const A&, const B&);\n\
+ B operator+(const B&, const A&);\n\
+ int operator-(int, const A*);\n\
+ int operator/(const A*, int);\n\
+ ";
+ const char xmlCode[] = "\n\
+ <typesystem package=\"Foo\">\n\
+ <primitive-type name='int' />\n\
+ <value-type name='A' />\n\
+ <value-type name='B' />\n\
+ </typesystem>";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QCOMPARE(classA->functions().count(), 6);
+
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classB);
+ QCOMPARE(classB->functions().count(), 4);
+
+ const AbstractMetaFunction* reverseOp = 0;
+ const AbstractMetaFunction* normalOp = 0;
+ foreach(const AbstractMetaFunction* func, classB->functions()) {
+ if (func->name() == QLatin1String("operator+")) {
+ if (func->isReverseOperator())
+ reverseOp = func;
+ else
+ normalOp = func;
+ }
+ }
+ QVERIFY(normalOp);
+ QVERIFY(!normalOp->isReverseOperator());
+ QCOMPARE(normalOp->arguments().count(), 1);
+ QCOMPARE(normalOp->minimalSignature(), QLatin1String("operator+(B,A)"));
+ QVERIFY(reverseOp);
+ QVERIFY(reverseOp->isReverseOperator());
+ QCOMPARE(reverseOp->arguments().count(), 1);
+ QCOMPARE(reverseOp->minimalSignature(), QLatin1String("operator+(A,B)"));
+
+ reverseOp = classA->findFunction(QLatin1String("operator-"));
+ QVERIFY(reverseOp);
+ QCOMPARE(reverseOp->arguments().count(), 1);
+ QVERIFY(reverseOp->isPointerOperator());
+ QVERIFY(reverseOp->isReverseOperator());
+
+ normalOp = classA->findFunction(QLatin1String("operator/"));
+ QVERIFY(normalOp);
+ QCOMPARE(normalOp->arguments().count(), 1);
+ QVERIFY(normalOp->isPointerOperator());
+ QVERIFY(!normalOp->isReverseOperator());
+
+}
+
+
+
+QTEST_APPLESS_MAIN(TestReverseOperators)
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testreverseoperators.h b/sources/shiboken2/ApiExtractor/tests/testreverseoperators.h
new file mode 100644
index 000000000..3bd65fb85
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testreverseoperators.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTREVERSEOPERATORS_H
+#define TESTREVERSEOPERATORS_H
+#include <QObject>
+
+class TestReverseOperators : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testReverseSum();
+ void testReverseSumWithAmbiguity();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
new file mode 100644
index 000000000..cb90383db
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
@@ -0,0 +1,438 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testtemplates.h"
+#include <QtTest/QTest>
+#include <QTemporaryFile>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestTemplates::testTemplateWithNamespace()
+{
+ const char cppCode[] = "\n\
+ template<typename T> struct QList {}; \n\
+ struct Url {\n\
+ void name();\n\
+ };\n\
+ namespace Internet {\n\
+ struct Url{};\n\
+ struct Bookmarks {\n\
+ QList<Url> list();\n\
+ };\n\
+ }";
+ const char xmlCode0[] = "\n\
+ <typesystem package='Pakcage.Network'>\n\
+ <value-type name='Url'/>\n\
+ </typesystem>";
+
+ QTemporaryFile file;
+ QVERIFY(file.open());
+ file.write(xmlCode0);
+ file.close();
+
+ QString xmlCode1 = QString::fromLatin1("\n\
+ <typesystem package='Package.Internet'>\n\
+ <load-typesystem name='%1' generate='no'/>\n\
+ <container-type name='QList' type='list'/>\n\
+ <namespace-type name='Internet' generate='no'/>\n\
+ <value-type name='Internet::Url'/>\n\
+ <value-type name='Internet::Bookmarks'/>\n\
+ </typesystem>").arg(file.fileName());
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, qPrintable(xmlCode1), false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+
+ AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("Bookmarks"));
+ QVERIFY(classB);
+ const AbstractMetaFunction* func = classB->findFunction(QLatin1String("list"));
+ AbstractMetaType* funcType = func->type();
+ QVERIFY(funcType);
+ QCOMPARE(funcType->cppSignature(), QLatin1String("QList<Internet::Url >"));
+}
+
+void TestTemplates::testTemplateOnContainers()
+{
+ const char cppCode[] = "\n\
+ struct Base {};\n\
+ template<typename T> struct QList {}; \n\
+ namespace Namespace {\n\
+ enum SomeEnum { E1, E2 };\n\
+ template<SomeEnum type> struct A {\n\
+ A<type> foo(const QList<A<type> >& a);\n\
+ };\n\
+ typedef A<E1> B;\n\
+ }\n\
+ ";
+ const char xmlCode[] = "\n\
+ <typesystem package=\"Package\">\n\
+ <container-type name='QList' type='list'/>\n\
+ <namespace-type name='Namespace'/>\n\
+ <enum-type name='Namespace::SomeEnum'/>\n\
+ <object-type name='Base'/>\n\
+ <object-type name='Namespace::A' generate='no'/>\n\
+ <object-type name='Namespace::B'/>\n\
+ </typesystem>";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+
+ AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classB);
+ QVERIFY(!classB->baseClass());
+ QVERIFY(classB->baseClassName().isNull());
+ const AbstractMetaFunction* func = classB->findFunction(QLatin1String("foo"));
+ AbstractMetaType* argType = func->arguments().first()->type();
+ QCOMPARE(argType->instantiations().count(), 1);
+ QCOMPARE(argType->typeEntry()->qualifiedCppName(), QLatin1String("QList"));
+
+ const AbstractMetaType* instance1 = argType->instantiations().first();
+ QCOMPARE(instance1->instantiations().count(), 1);
+ QCOMPARE(instance1->typeEntry()->qualifiedCppName(), QLatin1String("Namespace::A"));
+
+ const AbstractMetaType* instance2 = instance1->instantiations().first();
+ QCOMPARE(instance2->instantiations().count(), 0);
+ QCOMPARE(instance2->typeEntry()->qualifiedCppName(), QLatin1String("Namespace::E1"));
+}
+
+void TestTemplates::testTemplateValueAsArgument()
+{
+ const char cppCode[] = "\n\
+ template<typename T> struct List {};\n\
+ void func(List<int> arg) {}\n\
+ ";
+
+ const char xmlCode[] = "\n\
+ <typesystem package='Package'>\n\
+ <primitive-type name='int'/>\n\
+ <container-type name='List' type='list'/>\n\
+ <function signature='func(List&lt;int&gt;)'/>\n\
+ </typesystem>\n\
+ ";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaFunctionList globalFuncs = builder->globalFunctions();
+ QCOMPARE(globalFuncs.count(), 1);
+
+ AbstractMetaFunction* func = globalFuncs.first();
+ QCOMPARE(func->minimalSignature(), QLatin1String("func(List<int>)"));
+ QCOMPARE(func->arguments().first()->type()->cppSignature(), QLatin1String("List<int >"));
+}
+
+void TestTemplates::testTemplatePointerAsArgument()
+{
+ const char cppCode[] = "\n\
+ template<typename T> struct List {};\n\
+ void func(List<int>* arg) {}\n\
+ ";
+
+ const char xmlCode[] = "\n\
+ <typesystem package='Package'>\n\
+ <primitive-type name='int'/>\n\
+ <container-type name='List' type='list'/>\n\
+ <function signature='func(List&lt;int&gt;*)'/>\n\
+ </typesystem>\n\
+ ";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaFunctionList globalFuncs = builder->globalFunctions();
+ QCOMPARE(globalFuncs.count(), 1);
+
+ AbstractMetaFunction* func = globalFuncs.first();
+ QCOMPARE(func->minimalSignature(), QLatin1String("func(List<int>*)"));
+ QCOMPARE(func->arguments().first()->type()->cppSignature(), QLatin1String("List<int > *"));
+}
+
+void TestTemplates::testTemplateReferenceAsArgument()
+{
+ const char cppCode[] = "\n\
+ template<typename T> struct List {};\n\
+ void func(List<int>& arg) {}\n\
+ ";
+
+ const char xmlCode[] = "\n\
+ <typesystem package='Package'>\n\
+ <primitive-type name='int'/>\n\
+ <container-type name='List' type='list'/>\n\
+ <function signature='func(List&lt;int&gt;&amp;)'/>\n\
+ </typesystem>\n\
+ ";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaFunctionList globalFuncs = builder->globalFunctions();
+ QCOMPARE(globalFuncs.count(), 1);
+
+ AbstractMetaFunction* func = globalFuncs.first();
+ QCOMPARE(func->minimalSignature(), QLatin1String("func(List<int>&)"));
+ QCOMPARE(func->arguments().first()->type()->cppSignature(), QLatin1String("List<int > &"));
+}
+
+void TestTemplates::testTemplateParameterFixup()
+{
+ const char cppCode[] = "\n\
+ template<typename T>\n\
+ struct List {\n\
+ struct Iterator {};\n\
+ void append(List l);\n\
+ void erase(List::Iterator it);\n\
+ };\n";
+
+ const char xmlCode[] = "\n\
+ <typesystem package='Package'>\n\
+ <container-type name='List' type='list'/>\n\
+ <value-type name='List::Iterator'/>\n\
+ </typesystem>\n";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ const AbstractMetaClassList templates = builder->templates();
+
+ QCOMPARE(templates.count(), 1);
+ const AbstractMetaClass *list = templates.first();
+ // Verify that the parameter of "void append(List l)" gets fixed to "List<T >"
+ const AbstractMetaFunction *append = list->findFunction(QStringLiteral("append"));
+ QVERIFY(append);
+ QCOMPARE(append->arguments().size(), 1);
+ QCOMPARE(append->arguments().at(0)->type()->cppSignature(), QLatin1String("List<T >"));
+ // Verify that the parameter of "void erase(Iterator)" is not modified
+ const AbstractMetaFunction *erase = list->findFunction(QStringLiteral("erase"));
+ QVERIFY(erase);
+ QCOMPARE(erase->arguments().size(), 1);
+ QCOMPARE(erase->arguments().at(0)->type()->cppSignature(), QLatin1String("List::Iterator"));
+}
+
+void TestTemplates::testInheritanceFromContainterTemplate()
+{
+ const char cppCode[] = "\n\
+ template<typename T>\n\
+ struct ListContainer {\n\
+ inline void push_front(const T& t);\n\
+ inline T& front();\n\
+ };\n\
+ struct FooBar {};\n\
+ struct FooBars : public ListContainer<FooBar> {};\n\
+ ";
+
+ const char xmlCode[] = "\n\
+ <typesystem package='Package'>\n\
+ <container-type name='ListContainer' type='list'/>\n\
+ <value-type name='FooBar'/>\n\
+ <value-type name='FooBars'>\n\
+ <modify-function signature='push_front(FooBar)' remove='all'/>\n\
+ <modify-function signature='front()' remove='all'/>\n\
+ </value-type>\n\
+ </typesystem>\n\
+ ";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ AbstractMetaClassList templates = builder->templates();
+ QCOMPARE(classes.count(), 2);
+ QCOMPARE(templates.count(), 1);
+
+ const AbstractMetaClass* foobars = AbstractMetaClass::findClass(classes, QLatin1String("FooBars"));
+ QCOMPARE(foobars->functions().count(), 4);
+
+ const AbstractMetaClass* lc = templates.first();
+ QCOMPARE(lc->functions().count(), 2);
+}
+
+void TestTemplates::testTemplateInheritanceMixedWithForwardDeclaration()
+{
+ const char cppCode[] = "\n\
+ enum SomeEnum { E1, E2 };\n\
+ template<SomeEnum type> struct Future;\n\
+ template<SomeEnum type>\n\
+ struct A {\n\
+ A();\n\
+ void method();\n\
+ friend struct Future<type>;\n\
+ };\n\
+ typedef A<E1> B;\n\
+ template<SomeEnum type> struct Future {};\n\
+ ";
+ const char xmlCode[] = "\n\
+ <typesystem package='Package'>\n\
+ <enum-type name='SomeEnum'/>\n\
+ <value-type name='A' generate='no'/>\n\
+ <value-type name='B'/>\n\
+ <value-type name='Future' generate='no'/>\n\
+ </typesystem>";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+
+ AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classB);
+ QVERIFY(!classB->baseClass());
+ QVERIFY(classB->baseClassName().isNull());
+ // 3 functions: simple constructor, copy constructor and "method()".
+ QCOMPARE(classB->functions().count(), 3);
+}
+
+void TestTemplates::testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration()
+{
+ const char cppCode[] = "\n\
+ namespace Namespace {\n\
+ enum SomeEnum { E1, E2 };\n\
+ template<SomeEnum type> struct Future;\n\
+ template<SomeEnum type>\n\
+ struct A {\n\
+ A();\n\
+ void method();\n\
+ friend struct Future<type>;\n\
+ };\n\
+ typedef A<E1> B;\n\
+ template<SomeEnum type> struct Future {};\n\
+ };\n\
+ ";
+ const char xmlCode[] = "\n\
+ <typesystem package='Package'>\n\
+ <namespace-type name='Namespace'/>\n\
+ <enum-type name='Namespace::SomeEnum'/>\n\
+ <value-type name='Namespace::A' generate='no'/>\n\
+ <value-type name='Namespace::B'/>\n\
+ <value-type name='Namespace::Future' generate='no'/>\n\
+ </typesystem>";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+
+ AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("Namespace::B"));
+ QVERIFY(classB);
+ QVERIFY(!classB->baseClass());
+ QVERIFY(classB->baseClassName().isNull());
+ // 3 functions: simple constructor, copy constructor and "method()".
+ QCOMPARE(classB->functions().count(), 3);
+}
+
+void TestTemplates::testTypedefOfInstantiationOfTemplateClass()
+{
+ const char cppCode[] = "\n\
+ namespace NSpace {\n\
+ enum ClassType {\n\
+ TypeOne\n\
+ };\n\
+ template<ClassType CLASS_TYPE>\n\
+ struct BaseTemplateClass {\n\
+ inline ClassType getClassType() const { CLASS_TYPE; }\n\
+ };\n\
+ typedef BaseTemplateClass<TypeOne> TypeOneClass;\n\
+ }\n\
+ ";
+
+ const char xmlCode[] = "\n\
+ <typesystem package='Package'>\n\
+ <namespace-type name='NSpace'>\n\
+ <enum-type name='ClassType'/>\n\
+ <object-type name='BaseTemplateClass' generate='no'/>\n\
+ <object-type name='TypeOneClass'/>\n\
+ </namespace-type>\n\
+ </typesystem>\n\
+ ";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 3);
+
+ const AbstractMetaClass* base = AbstractMetaClass::findClass(classes, QLatin1String("BaseTemplateClass"));
+ QVERIFY(base);
+ const AbstractMetaClass* one = AbstractMetaClass::findClass(classes, QLatin1String("TypeOneClass"));
+ QVERIFY(one);
+ QCOMPARE(one->templateBaseClass(), base);
+ QCOMPARE(one->functions().count(), base->functions().count());
+ QVERIFY(one->isTypeDef());
+ const ComplexTypeEntry* oneType = one->typeEntry();
+ const ComplexTypeEntry* baseType = base->typeEntry();
+ QCOMPARE(oneType->baseContainerType(), baseType);
+ QCOMPARE(one->baseClassNames(), QStringList(QLatin1String("BaseTemplateClass<TypeOne>")));
+
+ QVERIFY(one->hasTemplateBaseClassInstantiations());
+ AbstractMetaTypeList instantiations = one->templateBaseClassInstantiations();
+ QCOMPARE(instantiations.count(), 1);
+ const AbstractMetaType* inst = instantiations.first();
+ QVERIFY(inst);
+ QVERIFY(!inst->isEnum());
+ QVERIFY(!inst->typeEntry()->isEnum());
+ QVERIFY(inst->typeEntry()->isEnumValue());
+ QCOMPARE(inst->cppSignature(), QLatin1String("NSpace::TypeOne"));
+}
+
+void TestTemplates::testContainerTypeIncompleteArgument()
+{
+ const char* cppCode ="\n\
+ template<typename T>\n\
+ class Vector {\n\
+ void method(const Vector& vector);\n\
+ Vector otherMethod();\n\
+ };\n\
+ template <typename T>\n\
+ void Vector<T>::method(const Vector<T>& vector) {}\n\
+ template <typename T>\n\
+ Vector<T> Vector<T>::otherMethod() { return Vector<T>(); }\n\
+ typedef Vector<int> IntVector;\n\
+ ";
+ const char* xmlCode = "\n\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int'/>\n\
+ <container-type name='Vector' type='vector'/>\n\
+ <value-type name='IntVector'/>\n\
+ </typesystem>";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 1);
+
+ AbstractMetaClass* vector = AbstractMetaClass::findClass(classes, QLatin1String("IntVector"));
+ QVERIFY(vector);
+ QVERIFY(vector->typeEntry()->baseContainerType());
+ QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(vector->typeEntry()->baseContainerType())->type(), ContainerTypeEntry::VectorContainer);
+ QCOMPARE(vector->functions().count(), 4);
+
+ const AbstractMetaFunction* method = vector->findFunction(QLatin1String("method"));
+ QVERIFY(method);
+ QCOMPARE(method->signature(), QLatin1String("method(const Vector<int > & vector)"));
+
+ const AbstractMetaFunction* otherMethod = vector->findFunction(QLatin1String("otherMethod"));
+ QVERIFY(otherMethod);
+ QCOMPARE(otherMethod->signature(), QLatin1String("otherMethod()"));
+ QVERIFY(otherMethod->type());
+ QCOMPARE(otherMethod->type()->cppSignature(), QLatin1String("Vector<int >"));
+}
+
+QTEST_APPLESS_MAIN(TestTemplates)
diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.h b/sources/shiboken2/ApiExtractor/tests/testtemplates.h
new file mode 100644
index 000000000..7b0d0f3b3
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTTEMPLATES_H
+#define TESTTEMPLATES_H
+
+#include <QObject>
+
+class TestTemplates : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testTemplateOnContainers();
+ void testTemplateWithNamespace();
+ void testTemplateValueAsArgument();
+ void testTemplatePointerAsArgument();
+ void testTemplateReferenceAsArgument();
+ void testTemplateParameterFixup();
+ void testInheritanceFromContainterTemplate();
+ void testTemplateInheritanceMixedWithForwardDeclaration();
+ void testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration();
+ void testTypedefOfInstantiationOfTemplateClass();
+ void testContainerTypeIncompleteArgument();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testtoposort.cpp b/sources/shiboken2/ApiExtractor/tests/testtoposort.cpp
new file mode 100644
index 000000000..30d368a8a
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testtoposort.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testtoposort.h"
+#include <QtTest/QTest>
+#include "graph.h"
+#include <QDebug>
+
+void TestTopoSort::testTopoSort()
+{
+ QLinkedList<int> result;
+ {
+ Graph g(3);
+ g.addEdge(1, 2);
+ g.addEdge(0, 1);
+ result = g.topologicalSort();
+ QCOMPARE(result.size(), 3);
+ QLinkedList<int>::iterator it = result.begin();
+ QCOMPARE(*it, 0);
+ QCOMPARE(*(++it), 1);
+ QCOMPARE(*(++it), 2);
+ }
+ {
+ Graph g(2);
+ result = g.topologicalSort();
+ QCOMPARE(result.size(), 2);
+ QLinkedList<int>::iterator it = result.begin();
+ QCOMPARE(*it, 1);
+ QCOMPARE(*(++it), 0);
+ }
+}
+
+void TestTopoSort::testCiclicGraph()
+{
+ Graph g(3);
+ g.addEdge(0, 1);
+ g.addEdge(1, 2);
+ g.addEdge(2, 0);
+ QLinkedList<int> result = g.topologicalSort();
+ QVERIFY(result.isEmpty());
+}
+
+QTEST_APPLESS_MAIN(TestTopoSort)
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testtoposort.h b/sources/shiboken2/ApiExtractor/tests/testtoposort.h
new file mode 100644
index 000000000..ae8a2bab8
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testtoposort.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTTOPOSORT_H
+#define TESTTOPOSORT_H
+
+#include <QObject>
+
+class TestTopoSort : public QObject
+{
+Q_OBJECT
+private slots:
+ void testTopoSort();
+ void testCiclicGraph();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp b/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp
new file mode 100644
index 000000000..804683140
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testtyperevision.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestTypeRevision::testRevisionAttr()
+{
+ const char* cppCode = "class Rev_0 {};"
+ "class Rev_1 {};"
+ "class Rev_2 { public: enum Rev_3 { X }; enum Rev_5 { Y }; };";
+ const char* xmlCode = "<typesystem package=\"Foo\">"
+ "<value-type name=\"Rev_0\"/>"
+ "<value-type name=\"Rev_1\" revision=\"1\"/>"
+ "<object-type name=\"Rev_2\" revision=\"2\">"
+ " <enum-type name=\"Rev_3\" revision=\"3\" flags=\"Flag_4\" flags-revision=\"4\" />"
+ " <enum-type name=\"Rev_5\" revision=\"5\" flags=\"Flag_5\" />"
+ "</object-type>"
+ "</typesystem>";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *rev0 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_0"));
+ QCOMPARE(getTypeRevision(rev0->typeEntry()), 0);
+
+ const AbstractMetaClass *rev1 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_1"));
+ QCOMPARE(getTypeRevision(rev1->typeEntry()), 1);
+
+ AbstractMetaClass *rev2 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_2"));
+ QCOMPARE(getTypeRevision(rev2->typeEntry()), 2);
+
+ AbstractMetaEnum* rev3 = rev2->findEnum(QLatin1String("Rev_3"));
+ QCOMPARE(getTypeRevision(rev3->typeEntry()), 3);
+ FlagsTypeEntry* rev4 = rev3->typeEntry()->flags();
+ QCOMPARE(getTypeRevision(rev4), 4);
+ AbstractMetaEnum* rev5 = rev2->findEnum(QLatin1String("Rev_5"));
+ QCOMPARE(getTypeRevision(rev5->typeEntry()), 5);
+ QCOMPARE(getTypeRevision(rev5->typeEntry()->flags()), 5);
+}
+
+QTEST_APPLESS_MAIN(TestTypeRevision)
+
+
diff --git a/sources/shiboken2/ApiExtractor/tests/testtyperevision.h b/sources/shiboken2/ApiExtractor/tests/testtyperevision.h
new file mode 100644
index 000000000..dcb2d8794
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testtyperevision.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTTYPEREVISION_H
+#define TESTTYPEREVISION_H
+
+#include <QObject>
+
+class TestTypeRevision : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void testRevisionAttr();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testutil.h b/sources/shiboken2/ApiExtractor/tests/testutil.h
new file mode 100644
index 000000000..d4eb2fdf6
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testutil.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTUTIL_H
+#define TESTUTIL_H
+#include <QtCore/QBuffer>
+#include "abstractmetabuilder.h"
+#include "reporthandler.h"
+#include "typedatabase.h"
+
+namespace TestUtil
+{
+ static AbstractMetaBuilder *parse(const char *cppCode, const char *xmlCode,
+ bool silent = true,
+ const char *apiVersion = Q_NULLPTR,
+ const QStringList &dropTypeEntries = QStringList())
+ {
+ ReportHandler::setSilent(silent);
+ TypeDatabase* td = TypeDatabase::instance(true);
+ if (apiVersion && !td->setApiVersion(QLatin1String("*"), QLatin1String(apiVersion)))
+ return Q_NULLPTR;
+ td->setDropTypeEntries(dropTypeEntries);
+ QBuffer buffer;
+ // parse typesystem
+ buffer.setData(xmlCode);
+ if (!buffer.open(QIODevice::ReadOnly))
+ return Q_NULLPTR;
+ td->parseFile(&buffer);
+ buffer.close();
+ // parse C++ code
+ buffer.setData(cppCode);
+ AbstractMetaBuilder *builder = new AbstractMetaBuilder;
+ if (!builder->build(&buffer)) {
+ delete builder;
+ return Q_NULLPTR;
+ }
+ return builder;
+ }
+} // namespace TestUtil
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.cpp b/sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.cpp
new file mode 100644
index 000000000..627255d37
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testvaluetypedefaultctortag.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestValueTypeDefaultCtorTag::testValueTypeDefaultCtorTagArgument()
+{
+ const char* cppCode ="\n\
+ struct A {\n\
+ A(int,int);\n\
+ };\n\
+ struct B {};\n\
+ ";
+ const char* xmlCode = "\n\
+ <typesystem package='Foo'>\n\
+ <primitive-type name='int' />\n\
+ <value-type name='A' default-constructor='A(0, 0)' />\n\
+ <value-type name='B' />\n\
+ </typesystem>";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ AbstractMetaClassList classes = builder->classes();
+
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ QVERIFY(classA->typeEntry()->hasDefaultConstructor());
+ QCOMPARE(classA->typeEntry()->defaultConstructor(), QLatin1String("A(0, 0)"));
+
+ const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QVERIFY(classB);
+ QVERIFY(!classB->typeEntry()->hasDefaultConstructor());
+}
+
+QTEST_APPLESS_MAIN(TestValueTypeDefaultCtorTag)
diff --git a/sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.h b/sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.h
new file mode 100644
index 000000000..2d2efe79d
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTVALUETYPEDEFAULTCTORTAG_H
+#define TESTVALUETYPEDEFAULTCTORTAG_H
+
+#include <QObject>
+
+class TestValueTypeDefaultCtorTag : public QObject
+{
+ Q_OBJECT
+ private slots:
+ void testValueTypeDefaultCtorTagArgument();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testvoidarg.cpp b/sources/shiboken2/ApiExtractor/tests/testvoidarg.cpp
new file mode 100644
index 000000000..5f0b47389
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testvoidarg.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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 "testvoidarg.h"
+#include <QtTest/QTest>
+#include "testutil.h"
+#include <abstractmetalang.h>
+#include <typesystem.h>
+
+void TestVoidArg::testVoidParsedFunction()
+{
+ const char cppCode[] = "struct A { void a(void); };";
+ const char xmlCode[] = "\n\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A'/>\n\
+ </typesystem>";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("a"));
+ QCOMPARE(addedFunc->arguments().count(), 0);
+}
+
+void TestVoidArg::testVoidAddedFunction()
+{
+ const char cppCode[] = "struct A { };";
+ const char xmlCode[] = "\n\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A' >\n\
+ <add-function signature=\"a(void)\"/>\n\
+ </value-type>\n\
+ </typesystem>";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("a"));
+ QCOMPARE(addedFunc->arguments().count(), 0);
+
+}
+
+void TestVoidArg::testVoidPointerParsedFunction()
+{
+ const char cppCode[] = "struct A { void a(void*); };";
+ const char xmlCode[] = "\n\
+ <typesystem package=\"Foo\">\n\
+ <value-type name='A' />\n\
+ </typesystem>";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+ const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("a"));
+ QCOMPARE(addedFunc->arguments().count(), 1);
+
+}
+
+QTEST_APPLESS_MAIN(TestVoidArg)
diff --git a/sources/shiboken2/ApiExtractor/tests/testvoidarg.h b/sources/shiboken2/ApiExtractor/tests/testvoidarg.h
new file mode 100644
index 000000000..40d96a4ff
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testvoidarg.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of PySide2.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef TESTVOIDARG_H
+#define TESTVOIDARG_H
+#include <QObject>
+
+class TestVoidArg : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testVoidParsedFunction();
+ void testVoidPointerParsedFunction();
+ void testVoidAddedFunction();
+};
+
+#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/utf8code.txt b/sources/shiboken2/ApiExtractor/tests/utf8code.txt
new file mode 100644
index 000000000..6d5fa9dcf
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/utf8code.txt
@@ -0,0 +1 @@
+áéíóú \ No newline at end of file