aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp')
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp228
1 files changed, 228 insertions, 0 deletions
diff --git a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp
new file mode 100644
index 000000000..16f50e69d
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp
@@ -0,0 +1,228 @@
+// 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 "testdroptypeentries.h"
+#include "testutil.h"
+#include <abstractmetaenum.h>
+#include <abstractmetalang.h>
+#include <typesystem.h>
+#include <conditionalstreamreader.h>
+
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
+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()
+{
+ const QStringList droppedEntries{u"Foo.ValueB"_s,
+ u"ObjectB"_s, // Check whether module can be omitted
+ u"Foo.NamespaceA.InnerClassA"_s,
+ u"Foo.NamespaceB"_s, u"Foo.EnumB"_s,
+ u"Foo.funcB()"_s,
+ u"Foo.NamespaceA.InnerNamespaceA"_s};
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false,
+ QString(), droppedEntries));
+ QVERIFY(builder);
+
+ AbstractMetaClassList classes = builder->classes();
+ QVERIFY(AbstractMetaClass::findClass(classes, "ValueA"));
+ QVERIFY(!AbstractMetaClass::findClass(classes, "ValueB"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "ObjectA"));
+ QVERIFY(!AbstractMetaClass::findClass(classes, "ObjectB"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "NamespaceA"));
+ QVERIFY(!AbstractMetaClass::findClass(classes, "NamespaceA::InnerClassA"));
+ QVERIFY(!AbstractMetaClass::findClass(classes, "NamespaceB"));
+
+ AbstractMetaEnumList globalEnums = builder->globalEnums();
+ QCOMPARE(globalEnums.size(), 1);
+ QCOMPARE(globalEnums.constFirst().name(), u"EnumA");
+
+ auto *td = TypeDatabase::instance();
+ QVERIFY(td->findType(u"funcA"_s));
+ QVERIFY(!td->findType(u"funcB"_s));
+}
+
+void TestDropTypeEntries::testDontDropEntries()
+{
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(builder);
+
+ AbstractMetaClassList classes = builder->classes();
+ QVERIFY(AbstractMetaClass::findClass(classes, "ValueA"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "ValueB"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "ObjectA"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "ObjectB"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "NamespaceA"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "NamespaceA::InnerClassA"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "NamespaceB"));
+
+ QCOMPARE(builder->globalEnums().size(), 2);
+
+ auto *td = TypeDatabase::instance();
+ QVERIFY(td->findType(u"funcA"_s));
+ QVERIFY(td->findType(u"funcB"_s));
+}
+
+static const char cppCode2[] = "\
+ struct ValueA {\n\
+ void func();\n\
+ };\n";
+
+static const char xmlCode2[] = R"(
+<typesystem package='Foo'>
+ <value-type name='ValueA'>
+ <modify-function signature='func()' remove='all'/>
+ </value-type>
+</typesystem>
+)";
+
+void TestDropTypeEntries::testDropEntryWithChildTags()
+{
+ QStringList droppedEntries(u"Foo.ValueA"_s);
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false,
+ QString(), droppedEntries));
+ QVERIFY(builder);
+ QVERIFY(!AbstractMetaClass::findClass(builder->classes(), "ValueA"));
+}
+
+
+void TestDropTypeEntries::testDontDropEntryWithChildTags()
+{
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false));
+ QVERIFY(builder);
+ QVERIFY(AbstractMetaClass::findClass(builder->classes(), "ValueA"));
+}
+
+void TestDropTypeEntries::testConditionalParsing_data()
+{
+ const QString xml = R"(<?xml version="1.0" encoding="UTF-8"?>
+<root>
+ <tag1>text</tag1>
+ <?if keyword1?>
+ <tag2>text</tag2>
+ <?if keyword2?>
+ <tag3>text</tag3>
+ <?endif?>
+ <?if keyword1 !keyword2?>
+ <tag4>text</tag4>
+ <?endif?>
+ <?endif?>
+ <tag5>text</tag5>
+ <?if !keyword99?> <!-- Exclusion only -->
+ <tag6>text</tag6>
+ <?endif?>
+</root>)"_L1;
+
+ constexpr auto root = "root"_L1;
+ constexpr auto tag1 = "tag1"_L1;
+ constexpr auto tag2 = "tag2"_L1;
+ constexpr auto tag3 = "tag3"_L1;
+ constexpr auto tag4 = "tag4"_L1;
+ constexpr auto tag5 = "tag5"_L1;
+ constexpr auto tag6 = "tag6"_L1;
+ constexpr auto keyword1 = "keyword1"_L1;
+ constexpr auto keyword2 = "keyword2"_L1;
+
+ QTest::addColumn<QString>("xml");
+ QTest::addColumn<QStringList>("keywords");
+ QTest::addColumn<QStringList>("expectedTags");
+
+ QTest::newRow("no-keywords")
+ << xml << QStringList{} << QStringList{root, tag1, tag5, tag6};
+
+ QTest::newRow("skip-nested-condition")
+ << xml << QStringList{keyword1}
+ << QStringList{root, tag1, tag2, tag4, tag5, tag6};
+
+ QTest::newRow("both/check-not")
+ << xml << QStringList{keyword1, keyword2}
+ << QStringList{root, tag1, tag2, tag3, tag5, tag6};
+}
+
+// Parse XML and return a list of tags encountered
+static QStringList parseXml(const QString &xml, const QStringList &keywords)
+{
+ QStringList tags;
+ ConditionalStreamReader reader(xml);
+ reader.setConditions(keywords);
+ while (!reader.atEnd()) {
+ auto t = reader.readNext();
+ switch (t) {
+ case QXmlStreamReader::StartElement:
+ tags.append(reader.name().toString());
+ break;
+ default:
+ break;
+ }
+ }
+ return tags;
+}
+
+void TestDropTypeEntries::testConditionalParsing()
+{
+ QFETCH(QString, xml);
+ QFETCH(QStringList, keywords);
+ QFETCH(QStringList, expectedTags);
+
+ const QStringList actualTags = parseXml(xml, keywords);
+ QCOMPARE(actualTags, expectedTags);
+}
+
+void TestDropTypeEntries::testEntityParsing()
+{
+ const QString xml = R"(<?xml version="1.0" encoding="UTF-8"?>
+<root>
+ <?entity testentity word1 word2?>
+ <text>bla &testentity;</text>
+</root>)"_L1;
+
+ QString actual;
+ ConditionalStreamReader reader(xml);
+ while (!reader.atEnd()) {
+ auto t = reader.readNext();
+ switch (t) {
+ case QXmlStreamReader::Characters:
+ actual.append(reader.text());
+ default:
+ break;
+ }
+ }
+ QVERIFY2(!reader.hasError(), qPrintable(reader.errorString()));
+ QCOMPARE(actual.trimmed(), u"bla word1 word2");
+}
+
+QTEST_APPLESS_MAIN(TestDropTypeEntries)