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.txt17
-rw-r--r--sources/shiboken2/ApiExtractor/tests/injectedcode.txt5
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp37
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp3
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp45
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcodeinjection.h3
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcodeinjection.qrc6
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp6
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testenum.cpp3
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.qrc5
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp99
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp3
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtemplates.cpp119
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtemplates.h2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp49
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtyperevision.h2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testutil.h11
20 files changed, 381 insertions, 40 deletions
diff --git a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
index 860a37d9d..e100ef493 100644
--- a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
+++ b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
@@ -4,13 +4,18 @@ find_package(Qt5Test)
find_package(Qt5Xml)
find_package(Qt5XmlPatterns)
+set(CMAKE_AUTORCC ON)
+
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")
+ set(SOURCES "${testname}.cpp")
+ if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${testname}.h")
+ list(APPEND SOURCES "${testname}.h")
+ endif ()
+ if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${testname}.qrc")
+ list(APPEND SOURCES "${testname}.qrc")
endif ()
+ add_executable(${testname} ${SOURCES})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${apiextractor_SOURCE_DIR}
@@ -35,8 +40,6 @@ 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)
@@ -68,7 +71,5 @@ 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/injectedcode.txt b/sources/shiboken2/ApiExtractor/tests/injectedcode.txt
new file mode 100644
index 000000000..872898810
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/injectedcode.txt
@@ -0,0 +1,5 @@
+// Bla
+// @snippet label
+code line
+// @snippet label
+// Bla
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
index 7f1361a7d..fc67ebba5 100644
--- a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
@@ -31,6 +31,37 @@
#include "testutil.h"
#include <abstractmetalang.h>
#include <typesystem.h>
+#include <parser/codemodel.h>
+#include <typeparser.h>
+
+void TestAbstractMetaType::parsing_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("output");
+ QTest::newRow("primitive")
+ << QString::fromLatin1("int") << QString::fromLatin1("int");
+ QTest::newRow("ref")
+ << QString::fromLatin1("int &") << QString::fromLatin1("int&");
+ QTest::newRow("pointer")
+ << QString::fromLatin1("int **") << QString::fromLatin1("int**");
+ QTest::newRow("const ref")
+ << QString::fromLatin1("const int &") << QString::fromLatin1("const int&");
+ QTest::newRow("const pointer")
+ << QString::fromLatin1("const int **") << QString::fromLatin1("const int**");
+ QTest::newRow("const pointer const")
+ << QString::fromLatin1("const int *const*") << QString::fromLatin1("const int*const*");
+}
+
+void TestAbstractMetaType::parsing()
+{
+ QFETCH(QString, input);
+ QFETCH(QString, output);
+ QString errorMessage;
+ const TypeInfo ti = TypeParser::parse(input, &errorMessage);
+ QVERIFY2(errorMessage.isEmpty(), qPrintable(errorMessage));
+ const QString actual = ti.toString();
+ QCOMPARE(actual, output);
+}
void TestAbstractMetaType::testConstCharPtrType()
{
@@ -72,7 +103,8 @@ void TestAbstractMetaType::testApiVersionSupported()
<function signature='justAtest2()' since='1.1'/>\n\
<function signature='justAtest3()'/>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, "1.0"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ false, QLatin1String("1.0")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
@@ -90,7 +122,8 @@ void TestAbstractMetaType::testApiVersionNotSupported()
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"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ true, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h
index b2aa7544f..b39a27a54 100644
--- a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h
@@ -35,6 +35,8 @@ class TestAbstractMetaType : public QObject
{
Q_OBJECT
private slots:
+ void parsing_data();
+ void parsing();
void testConstCharPtrType();
void testCharType();
void testTypedef();
diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
index 2a953243e..db49942c9 100644
--- a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
@@ -366,7 +366,8 @@ void TestAddFunction::testAddFunctionWithApiVersion()
<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"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ true, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaFunctionList globalFuncs = builder->globalFunctions();
QCOMPARE(globalFuncs.count(), 1);
diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
index 7bbde3bd4..9f71b495a 100644
--- a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
@@ -34,19 +34,43 @@
#include <abstractmetalang.h>
#include <typesystem.h>
-void TestCodeInjections::testReadFileUtf8()
+void TestCodeInjections::testReadFile_data()
{
+ QTest::addColumn<QString>("filePath");
+ QTest::addColumn<QString>("snippet");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("utf8")
+ << QString::fromLatin1(":/utf8code.txt")
+ << QString()
+ << QString::fromUtf8("\xC3\xA1\xC3\xA9\xC3\xAD\xC3\xB3\xC3\xBA");
+
+ QTest::newRow("snippet")
+ << QString::fromLatin1(":/injectedcode.txt")
+ << QString::fromLatin1("label")
+ << QString::fromLatin1("code line");
+}
+
+void TestCodeInjections::testReadFile()
+{
+ QFETCH(QString, filePath);
+ QFETCH(QString, snippet);
+ QFETCH(QString, expected);
+
const char* cppCode ="struct A {};\n";
int argc = 0;
char *argv[] = {NULL};
QCoreApplication app(argc, argv);
- QString filePath = QDir::currentPath();
+
+ QString attribute = QLatin1String("file='") + filePath + QLatin1Char('\'');
+ if (!snippet.isEmpty())
+ attribute += QLatin1String(" snippet='") + snippet + QLatin1Char('\'');
+
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\
+ <conversion-rule ") + attribute + QLatin1String("/>\n\
+ <inject-code class='target' ") + attribute + QLatin1String("/>\n\
</value-type>\n\
<value-type name='A::B'/>\n\
</typesystem>\n");
@@ -56,10 +80,9 @@ void TestCodeInjections::testReadFileUtf8()
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);
+ QVERIFY(code.indexOf(expected) != -1);
code = classA->typeEntry()->conversionRule();
- QVERIFY(code.indexOf(utf8Data) != -1);
+ QVERIFY(code.indexOf(expected) != -1);
}
void TestCodeInjections::testInjectWithValidApiVersion()
@@ -74,7 +97,8 @@ void TestCodeInjections::testInjectWithValidApiVersion()
</value-type>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "1.0"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ true, QLatin1String("1.0")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
@@ -93,7 +117,8 @@ void TestCodeInjections::testInjectWithInvalidApiVersion()
</value-type>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "0.1"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ true, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h
index bd5e7ece1..1ac873970 100644
--- a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h
+++ b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h
@@ -37,7 +37,8 @@ class TestCodeInjections : public QObject
{
Q_OBJECT
private slots:
- void testReadFileUtf8();
+ void testReadFile_data();
+ void testReadFile();
void testInjectWithValidApiVersion();
void testInjectWithInvalidApiVersion();
};
diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.qrc b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.qrc
new file mode 100644
index 000000000..fd7616bd2
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource>
+ <file>utf8code.txt</file>
+ <file>injectedcode.txt</file>
+ </qresource>
+</RCC>
diff --git a/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp b/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp
index b46c23f56..6abebb922 100644
--- a/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp
@@ -70,7 +70,8 @@ void TestDropTypeEntries::testDropEntries()
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));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false,
+ QString(), droppedEntries));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
@@ -129,7 +130,8 @@ static const char* xmlCode2 = "\
void TestDropTypeEntries::testDropEntryWithChildTags()
{
QStringList droppedEntries(QLatin1String("Foo.ValueA"));
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false, Q_NULLPTR, droppedEntries));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false,
+ QString(), droppedEntries));
QVERIFY(!builder.isNull());
QVERIFY(!AbstractMetaClass::findClass(builder->classes(), QLatin1String("ValueA")));
}
diff --git a/sources/shiboken2/ApiExtractor/tests/testenum.cpp b/sources/shiboken2/ApiExtractor/tests/testenum.cpp
index 87f2608a1..ebdcf8d81 100644
--- a/sources/shiboken2/ApiExtractor/tests/testenum.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testenum.cpp
@@ -104,7 +104,8 @@ void TestEnum::testEnumWithApiVersion()
</value-type>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "0.1"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ true, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.count(), 1);
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
index 7911a5eb1..f615befb4 100644
--- a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
@@ -60,7 +60,7 @@ R"(<typesystem package="Foo">
QCOMPARE(docMods[1].code().trimmed(), QLatin1String("<para>Some changed contents here</para>"));
QCOMPARE(docMods[1].signature(), QString());
QtDocParser docParser;
- docParser.setDocumentationDataDirectory(QDir::currentPath());
+ docParser.setDocumentationDataDirectory(QLatin1String(":"));
docParser.fillDocumentation(classA);
const QString actualDocSimplified = classA->documentation().value().simplified();
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.qrc b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.qrc
new file mode 100644
index 000000000..76b1bfc61
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource>
+ <file>a.xml</file>
+ </qresource>
+</RCC>
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp
index d0a0c9c7a..af24689fe 100644
--- a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp
@@ -136,7 +136,8 @@ void TestModifyFunction::invalidateAfterUse()
</object-type>\n\
<object-type name='E' />\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, "0.1"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ false, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
@@ -208,7 +209,8 @@ void TestModifyFunction::testWithApiVersion()
</modify-function>\n\
</object-type>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, "0.1"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ false, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
@@ -220,6 +222,61 @@ void TestModifyFunction::testWithApiVersion()
QVERIFY(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0) != TypeSystem::CppOwnership);
}
+void TestModifyFunction::testAllowThread()
+{
+ const char cppCode[] =R"CPP(\
+struct A {
+ void f1();
+ void f2();
+ void f3();
+ int getter1() const;
+ int getter2() const;
+};
+)CPP";
+
+ const char xmlCode[] = R"XML(
+<typesystem package='Foo'>
+ <primitive-type name='int'/>
+ <object-type name='A'>
+ <modify-function signature='f2()' allow-thread='auto'/>
+ <modify-function signature='f3()' allow-thread='no'/>
+ <modify-function signature='getter2()const' allow-thread='yes'/>
+ </object-type>
+</typesystem>
+)XML";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ false, QLatin1String("0.1")));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+
+ // Nothing specified, true
+ const AbstractMetaFunction *f1 = classA->findFunction(QLatin1String("f1"));
+ QVERIFY(f1);
+ QVERIFY(f1->allowThread());
+
+ // 'auto' specified, should be true for nontrivial function
+ const AbstractMetaFunction *f2 = classA->findFunction(QLatin1String("f2"));
+ QVERIFY(f2);
+ QVERIFY(f2->allowThread());
+
+ // 'no' specified, should be false
+ const AbstractMetaFunction *f3 = classA->findFunction(QLatin1String("f3"));
+ QVERIFY(f3);
+ QVERIFY(!f3->allowThread());
+
+ // Nothing specified, should be false for simple getter
+ const AbstractMetaFunction *getter1 = classA->findFunction(QLatin1String("getter1"));
+ QVERIFY(getter1);
+ QVERIFY(!getter1->allowThread());
+
+ // Forced to true simple getter
+ const AbstractMetaFunction *getter2 = classA->findFunction(QLatin1String("getter2"));
+ QVERIFY(getter2);
+ QVERIFY(getter2->allowThread()); // Forced to true simple getter
+}
+
void TestModifyFunction::testGlobalFunctionModification()
{
const char* cppCode ="\
@@ -258,4 +315,42 @@ void TestModifyFunction::testGlobalFunctionModification()
QCOMPARE(arg->defaultValueExpression(), QLatin1String("A()"));
}
+void TestModifyFunction::testExceptionSpecification()
+{
+ const char cppCode[] = R"CPP(
+struct A {
+ void unspecified();
+ void nonThrowing() noexcept;
+ void throwing() throw(int);
+};
+)CPP";
+ const char xmlCode[] = R"XML(
+<typesystem package="Foo">
+ <primitive-type name='int'/>
+ <object-type name='A'>
+ <modify-function signature='throwing()' exception-handling='auto-on'/>
+ </object-type>
+</typesystem>)XML";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ QVERIFY(classA);
+
+ const AbstractMetaFunction *f = classA->findFunction(QStringLiteral("unspecified"));
+ QVERIFY(f);
+ QCOMPARE(f->exceptionSpecification(), ExceptionSpecification::Unknown);
+ QVERIFY(!f->generateExceptionHandling());
+
+ f = classA->findFunction(QStringLiteral("nonThrowing"));
+ QVERIFY(f);
+ QCOMPARE(f->exceptionSpecification(), ExceptionSpecification::NoExcept);
+ QVERIFY(!f->generateExceptionHandling());
+
+ f = classA->findFunction(QStringLiteral("throwing"));
+ QVERIFY(f);
+ QCOMPARE(f->exceptionSpecification(), ExceptionSpecification::Throws);
+ QVERIFY(f->generateExceptionHandling());
+}
+
QTEST_APPLESS_MAIN(TestModifyFunction)
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h
index f116b5124..494f31991 100644
--- a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h
@@ -37,10 +37,12 @@ class TestModifyFunction : public QObject
private slots:
void testOwnershipTransfer();
void testWithApiVersion();
+ void testAllowThread();
void testRenameArgument_data();
void testRenameArgument();
void invalidateAfterUse();
void testGlobalFunctionModification();
+ void testExceptionSpecification();
};
#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp b/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp
index 11cda3317..38099c455 100644
--- a/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp
@@ -82,7 +82,8 @@ void TestRefCountTag::testWithApiVersion()
</object-type>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, "0.1"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ false, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
index 8d869e3f9..b1b171bae 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
@@ -28,6 +28,7 @@
#include "testtemplates.h"
#include <QtTest/QTest>
+#include <QtCore/QTextStream>
#include <QTemporaryFile>
#include "testutil.h"
#include <abstractmetalang.h>
@@ -438,4 +439,122 @@ typedef Vector<int> IntVector;
QCOMPARE(otherMethod->type()->cppSignature(), QLatin1String("Vector<int >"));
}
+// Perform checks on template inheritance; a typedef of a template class
+// should result in rewritten types.
+void TestTemplates::testTemplateTypeDefs_data()
+{
+ QTest::addColumn<QString>("cpp");
+ QTest::addColumn<QString>("xml");
+
+ const char optionalClassDef[] = R"CPP(
+template<class T> // Some value type similar to std::optional
+class Optional {
+public:
+ T value() const { return m_value; }
+ operator bool() const { return m_success; }
+
+ T m_value;
+ bool m_success = false;
+};
+)CPP";
+
+ const char xmlPrefix[] = R"XML(
+<typesystem package='Foo'>
+ <primitive-type name='int'/>
+ <primitive-type name='bool'/>
+)XML";
+
+ const char xmlOptionalDecl[] = "<value-type name='Optional' generate='no'/>\n";
+ const char xmlOptionalIntDecl[] = "<value-type name='IntOptional'/>\n";
+ const char xmlPostFix[] = "</typesystem>\n";
+
+ // Flat, global namespace
+ QString cpp;
+ QTextStream(&cpp) << optionalClassDef
+ << "typedef Optional<int> IntOptional;\n";
+ QString xml;
+ QTextStream(&xml) << xmlPrefix << xmlOptionalDecl << xmlOptionalIntDecl
+ << "<typedef-type name='XmlIntOptional' source='Optional&lt;int&gt;'/>"
+ << xmlPostFix;
+ QTest::newRow("global-namespace")
+ << cpp << xml;
+
+ // Typedef from namespace Std
+ cpp.clear();
+ QTextStream(&cpp) << "namespace Std {\n" << optionalClassDef << "}\n"
+ << "typedef Std::Optional<int> IntOptional;\n";
+ xml.clear();
+ QTextStream(&xml) << xmlPrefix
+ << "<namespace-type name='Std'>\n" << xmlOptionalDecl
+ << "</namespace-type>\n" << xmlOptionalIntDecl
+ << "<typedef-type name='XmlIntOptional' source='Std::Optional&lt;int&gt;'/>"
+ << xmlPostFix;
+ QTest::newRow("namespace-Std")
+ << cpp << xml;
+
+ // Typedef from nested class
+ cpp.clear();
+ QTextStream(&cpp) << "class Outer {\npublic:\n" << optionalClassDef << "\n};\n"
+ << "typedef Outer::Optional<int> IntOptional;\n";
+ xml.clear();
+ QTextStream(&xml) << xmlPrefix
+ << "<object-type name='Outer'>\n" << xmlOptionalDecl
+ << "</object-type>\n" << xmlOptionalIntDecl
+ << "<typedef-type name='XmlIntOptional' source='Outer::Optional&lt;int&gt;'/>"
+ << xmlPostFix;
+ QTest::newRow("nested-class")
+ << cpp << xml;
+}
+
+void TestTemplates::testTemplateTypeDefs()
+{
+ QFETCH(QString, cpp);
+ QFETCH(QString, xml);
+
+ const QByteArray cppBa = cpp.toLocal8Bit();
+ const QByteArray xmlBa = xml.toLocal8Bit();
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppBa.constData(), xmlBa.constData(), true));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+
+ const AbstractMetaClass *optional = AbstractMetaClass::findClass(classes, QLatin1String("Optional"));
+ QVERIFY(optional);
+
+ // Find the typedef'ed class
+ const AbstractMetaClass *optionalInt =
+ AbstractMetaClass::findClass(classes, QLatin1String("IntOptional"));
+ QVERIFY(optionalInt);
+ QCOMPARE(optionalInt->templateBaseClass(), optional);
+
+ // Find the class typedef'ed in the typesystem XML
+ const AbstractMetaClass *xmlOptionalInt =
+ AbstractMetaClass::findClass(classes, QLatin1String("XmlIntOptional"));
+ QVERIFY(xmlOptionalInt);
+ QCOMPARE(xmlOptionalInt->templateBaseClass(), optional);
+
+ // Check whether the value() method now has an 'int' return
+ const AbstractMetaFunction *valueMethod =
+ optionalInt->findFunction(QLatin1String("value"));
+ QVERIFY(valueMethod);
+ QCOMPARE(valueMethod->type()->cppSignature(), QLatin1String("int"));
+
+ // ditto for typesystem XML
+ const AbstractMetaFunction *xmlValueMethod =
+ xmlOptionalInt->findFunction(QLatin1String("value"));
+ QVERIFY(xmlValueMethod);
+ QCOMPARE(xmlValueMethod->type()->cppSignature(), QLatin1String("int"));
+
+ // Check whether the m_value field is of type 'int'
+ const AbstractMetaField *valueField =
+ optionalInt->findField(QLatin1String("m_value"));
+ QVERIFY(valueField);
+ QCOMPARE(valueField->type()->cppSignature(), QLatin1String("int"));
+
+ // ditto for typesystem XML
+ const AbstractMetaField *xmlValueField =
+ xmlOptionalInt->findField(QLatin1String("m_value"));
+ QVERIFY(xmlValueField);
+ QCOMPARE(xmlValueField->type()->cppSignature(), QLatin1String("int"));
+}
+
QTEST_APPLESS_MAIN(TestTemplates)
diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.h b/sources/shiboken2/ApiExtractor/tests/testtemplates.h
index 3e1565933..df3de18b9 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtemplates.h
+++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.h
@@ -46,6 +46,8 @@ private slots:
void testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration();
void testTypedefOfInstantiationOfTemplateClass();
void testContainerTypeIncompleteArgument();
+ void testTemplateTypeDefs_data();
+ void testTemplateTypeDefs();
};
#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp b/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp
index 1ec7ce025..a7e88e437 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp
@@ -31,6 +31,7 @@
#include "testutil.h"
#include <abstractmetalang.h>
#include <typesystem.h>
+#include <typedatabase.h>
void TestTypeRevision::testRevisionAttr()
{
@@ -49,21 +50,55 @@ void TestTypeRevision::testRevisionAttr()
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
const AbstractMetaClass *rev0 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_0"));
- QCOMPARE(getTypeRevision(rev0->typeEntry()), 0);
+ QCOMPARE(rev0->typeEntry()->revision(), 0);
const AbstractMetaClass *rev1 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_1"));
- QCOMPARE(getTypeRevision(rev1->typeEntry()), 1);
+ QCOMPARE(rev1->typeEntry()->revision(), 1);
AbstractMetaClass *rev2 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_2"));
- QCOMPARE(getTypeRevision(rev2->typeEntry()), 2);
+ QCOMPARE(rev2->typeEntry()->revision(), 2);
AbstractMetaEnum* rev3 = rev2->findEnum(QLatin1String("Rev_3"));
- QCOMPARE(getTypeRevision(rev3->typeEntry()), 3);
+ QCOMPARE(rev3->typeEntry()->revision(), 3);
FlagsTypeEntry* rev4 = rev3->typeEntry()->flags();
- QCOMPARE(getTypeRevision(rev4), 4);
+ QCOMPARE(rev4->revision(), 4);
AbstractMetaEnum* rev5 = rev2->findEnum(QLatin1String("Rev_5"));
- QCOMPARE(getTypeRevision(rev5->typeEntry()), 5);
- QCOMPARE(getTypeRevision(rev5->typeEntry()->flags()), 5);
+ const EnumTypeEntry *revEnumTypeEntry = rev5->typeEntry();
+ QCOMPARE(revEnumTypeEntry->revision(), 5);
+ QCOMPARE(revEnumTypeEntry->flags()->revision(), 5);
+}
+
+
+void TestTypeRevision::testVersion_data()
+{
+ QTest::addColumn<QString>("version");
+ QTest::addColumn<int>("expectedClassCount");
+
+ QTest::newRow("none") << QString() << 2;
+ QTest::newRow("1.0") << QString::fromLatin1("1.0") << 1; // Bar20 excluded
+ QTest::newRow("2.0") << QString::fromLatin1("2.0") << 2;
+}
+
+void TestTypeRevision::testVersion()
+{
+ QFETCH(QString, version);
+ QFETCH(int, expectedClassCount);
+
+ const char cppCode[] = R"CPP(
+class Bar {};
+class Bar20 {};
+)CPP";
+ const char xmlCode[] = R"XML(
+<typesystem package="Foo">
+ <value-type name="Bar"/>
+ <value-type name="Bar20" since="2.0"/>
+</typesystem>
+)XML";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, version));
+ QVERIFY(!builder.isNull());
+
+ QCOMPARE(builder->classes().size(), expectedClassCount);
}
QTEST_APPLESS_MAIN(TestTypeRevision)
diff --git a/sources/shiboken2/ApiExtractor/tests/testtyperevision.h b/sources/shiboken2/ApiExtractor/tests/testtyperevision.h
index 4dfa241e3..3832c3883 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtyperevision.h
+++ b/sources/shiboken2/ApiExtractor/tests/testtyperevision.h
@@ -37,6 +37,8 @@ class TestTypeRevision : public QObject
private slots:
void testRevisionAttr();
+ void testVersion_data();
+ void testVersion();
};
#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testutil.h b/sources/shiboken2/ApiExtractor/tests/testutil.h
index 6152793f5..c6ad19d7e 100644
--- a/sources/shiboken2/ApiExtractor/tests/testutil.h
+++ b/sources/shiboken2/ApiExtractor/tests/testutil.h
@@ -40,20 +40,23 @@ namespace TestUtil
{
static AbstractMetaBuilder *parse(const char *cppCode, const char *xmlCode,
bool silent = true,
- const char *apiVersion = Q_NULLPTR,
+ const QString &apiVersion = QString(),
const QStringList &dropTypeEntries = QStringList())
{
ReportHandler::setSilent(silent);
TypeDatabase* td = TypeDatabase::instance(true);
- if (apiVersion && !td->setApiVersion(QLatin1String("*"), QLatin1String(apiVersion)))
- return Q_NULLPTR;
+ if (apiVersion.isEmpty())
+ TypeDatabase::clearApiVersions();
+ else if (!td->setApiVersion(QLatin1String("*"), apiVersion))
+ return nullptr;
td->setDropTypeEntries(dropTypeEntries);
QBuffer buffer;
// parse typesystem
buffer.setData(xmlCode);
if (!buffer.open(QIODevice::ReadOnly))
return Q_NULLPTR;
- td->parseFile(&buffer);
+ if (!td->parseFile(&buffer))
+ return nullptr;
buffer.close();
// parse C++ code
QTemporaryFile tempSource(QDir::tempPath() + QLatin1String("/st_XXXXXX_main.cpp"));