aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp')
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp229
1 files changed, 229 insertions, 0 deletions
diff --git a/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp
new file mode 100644
index 000000000..2c320c874
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp
@@ -0,0 +1,229 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "testabstractmetatype.h"
+#include "testutil.h"
+#include <abstractmetaargument.h>
+#include <abstractmetafunction.h>
+#include <abstractmetalang.h>
+#include <abstractmetatype.h>
+#include <typesystem.h>
+#include <parser/codemodel.h>
+#include <typeparser.h>
+
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
+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()
+{
+ 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);
+ QCOMPARE(builder->globalFunctions().size(), 1);
+ const auto func = builder->globalFunctions().constFirst();
+ AbstractMetaType rtype = func->type();
+ // Test properties of const char*
+ QVERIFY(!rtype.isVoid());
+ QCOMPARE(rtype.package(), u"Foo");
+ QCOMPARE(rtype.name(), u"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());
+ 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, u"1.0"_s));
+ QVERIFY(builder);
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.size(), 2);
+
+
+ QCOMPARE(builder->globalFunctions().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, u"0.1"_s));
+ QVERIFY(builder);
+
+ 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);
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.size(), 1);
+ QCOMPARE(classes.constFirst()->package(), u"Foo");
+
+ const auto functions = builder->globalFunctions();
+ QCOMPARE(functions.size(), 1);
+ const auto func = functions.constFirst();
+ AbstractMetaType rtype = func->type();
+ // Test properties of const char*
+ QVERIFY(!rtype.isVoid());
+ QCOMPARE(rtype.package(), u"Foo");
+ QCOMPARE(rtype.name(), u"char");
+ QVERIFY(!rtype.isConstant());
+ QVERIFY(!rtype.isArray());
+ QVERIFY(!rtype.isContainer());
+ QVERIFY(!rtype.isObject());
+ QVERIFY(rtype.isPrimitive());
+ QVERIFY(!rtype.isNativePointer());
+ 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);
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.size(), 1);
+ const auto c = AbstractMetaClass::findClass(classes, "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);
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.size(), 1);
+ const auto functions = builder->globalFunctions();
+ QCOMPARE(functions.size(), 1);
+ const auto function = functions.constFirst();
+ AbstractMetaArgumentList args = function->arguments();
+ QCOMPARE(args.size(), 1);
+ const AbstractMetaArgument &arg = args.constFirst();
+ AbstractMetaType metaType = arg.type();
+ QCOMPARE(metaType.cppSignature(), u"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);
+
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.size(), 1);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ QVERIFY(classA);
+ const auto overloads = classA->queryFunctionsByName(u"method"_s);
+ QCOMPARE(overloads.size(), 1);
+ const auto method = overloads.constFirst();
+ QVERIFY(method);
+ AbstractMetaArgumentList args = method->arguments();
+ QCOMPARE(args.size(), 1);
+ const AbstractMetaArgument &arg = args.constFirst();
+ AbstractMetaType metaType = arg.type();
+ QCOMPARE(metaType.cppSignature(), u"A");
+ QVERIFY(metaType.isValue());
+ QVERIFY(metaType.typeEntry()->isObject());
+}
+
+QTEST_APPLESS_MAIN(TestAbstractMetaType)