diff options
author | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-13 10:48:37 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-13 10:48:37 -0300 |
commit | 14e2207a58e79360bd48507b5e386ec944d8dd74 (patch) | |
tree | 2e903282fef303d610ebfb6b7913e9a0b5a84825 /ApiExtractor/tests | |
parent | 744d018dd857543f93f3961cf9e7f70adcc7ce65 (diff) |
Move ApiExtractor into ApiExtractor directory to ease the merge into Shiboken.
Diffstat (limited to 'ApiExtractor/tests')
74 files changed, 6395 insertions, 0 deletions
diff --git a/ApiExtractor/tests/CMakeLists.txt b/ApiExtractor/tests/CMakeLists.txt new file mode 100644 index 000000000..dd3a32663 --- /dev/null +++ b/ApiExtractor/tests/CMakeLists.txt @@ -0,0 +1,54 @@ + +macro(declare_test testname) + qt4_automoc("${testname}.cpp") + add_executable(${testname} "${testname}.cpp") + include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${apiextractor_SOURCE_DIR}) + target_link_libraries(${testname} ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} 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/ApiExtractor/tests/a.xml b/ApiExtractor/tests/a.xml new file mode 100644 index 000000000..1c6d62a17 --- /dev/null +++ b/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/ApiExtractor/tests/testabstractmetaclass.cpp b/ApiExtractor/tests/testabstractmetaclass.cpp new file mode 100644 index 000000000..11e17d989 --- /dev/null +++ b/ApiExtractor/tests/testabstractmetaclass.cpp @@ -0,0 +1,446 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testabstractmetaclass.h" +#include "abstractmetabuilder.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestAbstractMetaClass::testClassName() +{ + const char* cppCode ="class ClassName {};"; + const char* xmlCode = "<typesystem package=\"Foo\"><value-type name=\"ClassName\"/></typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 1); + QCOMPARE(classes[0]->name(), QString("ClassName")); +} + +void TestAbstractMetaClass::testClassNameUnderNamespace() +{ + const char* cppCode ="namespace Namespace { class ClassName {}; }"; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <namespace-type name=\"Namespace\"/> \ + <value-type name=\"Namespace::ClassName\"/> \ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); // 1 namespace + 1 class + if (classes.first()->name() != "ClassName") + classes.swap(0, 1); + + QCOMPARE(classes[0]->name(), QString("ClassName")); + QCOMPARE(classes[0]->qualifiedCppName(), QString("Namespace::ClassName")); + QCOMPARE(classes[1]->name(), QString("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() != "ClassName()") + ctors.swap(0, 1); + + QCOMPARE(ctors[0]->arguments().size(), 0); + QCOMPARE(ctors[0]->minimalSignature(), QString("ClassName()")); + QCOMPARE(ctors[1]->arguments().size(), 1); + QCOMPARE(ctors[1]->minimalSignature(), QString("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 {\ + public:\ + virtual int pureVirtual() const = 0;\ + };\ + class B : public A {};\ + class C : public B {\ + public:\ + int pureVirtual() const { return 0; }\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <primitive-type name='int' />\ + <object-type name='A'/> \ + <object-type name='B'/> \ + <object-type name='C'/> \ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 3); + AbstractMetaClass* a = classes.findClass("A"); + AbstractMetaClass* b = classes.findClass("B"); + AbstractMetaClass* c = classes.findClass("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 {\ + class B {};\ + void method(B b = B());\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <value-type name='A'/> \ + <value-type name='A::B'/> \ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + AbstractMetaClass* classA = classes.findClass("A"); + QCOMPARE(classA->queryFunctionsByName("method").count(), 1); + AbstractMetaFunction* method = classA->queryFunctionsByName("method").first(); + AbstractMetaArgument* arg = method->arguments().first(); + QCOMPARE(arg->defaultValueExpression(), arg->originalDefaultValueExpression()); +} + +void TestAbstractMetaClass::testModifiedDefaultValues() +{ + const char* cppCode ="\ + struct A {\ + class B {};\ + void method(B b = B());\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <value-type name='A'> \ + <modify-function signature='method(A::B)'>\ + <modify-argument index='1'>\ + <replace-default-expression with='Hello'/>\ + </modify-argument>\ + </modify-function>\ + </value-type>\ + <value-type name='A::B'/> \ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + AbstractMetaClass* classA = classes.findClass("A"); + QCOMPARE(classA->queryFunctionsByName("method").count(), 1); + AbstractMetaFunction* method = classA->queryFunctionsByName("method").first(); + AbstractMetaArgument* arg = method->arguments().first(); + QCOMPARE(arg->defaultValueExpression(), QString("Hello")); + QCOMPARE(arg->originalDefaultValueExpression(), QString("A::B()")); +} + +void TestAbstractMetaClass::testInnerClassOfAPolymorphicOne() +{ + const char* cppCode ="\ + struct A {\ + class B {};\ + virtual void method();\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <object-type name='A' /> \ + <value-type name='A::B' /> \ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + QVERIFY(classA->isPolymorphic()); + AbstractMetaClass* classB = classes.findClass("A::B"); + QVERIFY(classB); + QVERIFY(!classB->isPolymorphic()); +} + +void TestAbstractMetaClass::testClassDefaultConstructors() +{ + const char* cppCode ="\ + struct A {};\ + \ + struct B {\ + B();\ + private: \ + B(const B&);\ + };\ + \ + struct C {\ + C(const C&);\ + };\ + \ + struct D {\ + private: \ + D(const D&);\ + };\ + \ + struct E {\ + private: \ + ~E();\ + };\ + \ + struct F {\ + F(int, int);\ + };\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <primitive-type name='int' />\ + <value-type name='A' /> \ + <object-type name='B' /> \ + <value-type name='C' /> \ + <object-type name='D' /> \ + <object-type name='E' /> \ + <value-type name='F' /> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 6); + + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + QCOMPARE(classA->functions().size(), 2); + + AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors); + QCOMPARE(ctors.size(), 2); + if (ctors.first()->minimalSignature() != "A()") + ctors.swap(0, 1); + + QCOMPARE(ctors[0]->arguments().size(), 0); + QCOMPARE(ctors[0]->minimalSignature(), QString("A()")); + QCOMPARE(ctors[1]->arguments().size(), 1); + QCOMPARE(ctors[1]->minimalSignature(), QString("A(A)")); + + AbstractMetaClass* classB = classes.findClass("B"); + QVERIFY(classB); + QCOMPARE(classB->functions().size(), 2); + QCOMPARE(classB->functions().first()->minimalSignature(), QString("B()")); + + AbstractMetaClass* classC = classes.findClass("C"); + QVERIFY(classC); + QCOMPARE(classC->functions().size(), 1); + QCOMPARE(classC->functions().first()->minimalSignature(), QString("C(C)")); + + AbstractMetaClass* classD = classes.findClass("D"); + QVERIFY(classD); + QCOMPARE(classD->functions().size(), 1); + QCOMPARE(classD->functions().first()->minimalSignature(), QString("D(D)")); + QVERIFY(classD->functions().first()->isPrivate()); + + AbstractMetaClass* classE = classes.findClass("E"); + QVERIFY(classE); + QVERIFY(classE->hasPrivateDestructor()); + QCOMPARE(classE->functions().size(), 0); + + AbstractMetaClass* classF = classes.findClass("F"); + QVERIFY(classF); + + ctors = classF->queryFunctions(AbstractMetaClass::Constructors); + QCOMPARE(ctors.size(), 2); + if (ctors.first()->minimalSignature() != "F(int,int)") + ctors.swap(0, 1); + + QCOMPARE(ctors[0]->arguments().size(), 2); + QCOMPARE(ctors[0]->minimalSignature(), QString("F(int,int)")); + QCOMPARE(ctors[1]->arguments().size(), 1); + QCOMPARE(ctors[1]->minimalSignature(), QString("F(F)")); +} + +void TestAbstractMetaClass::testClassInheritedDefaultConstructors() +{ + const char* cppCode ="\ + struct A {\ + A();\ + private: \ + A(const A&);\ + };\ + struct B : public A {};\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <object-type name='A' /> \ + <object-type name='B' /> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + + AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors); + QCOMPARE(ctors.size(), 2); + if (ctors.first()->minimalSignature() != "A()") + ctors.swap(0, 1); + + QCOMPARE(ctors[0]->arguments().size(), 0); + QCOMPARE(ctors[0]->minimalSignature(), QString("A()")); + QCOMPARE(ctors[1]->arguments().size(), 1); + QCOMPARE(ctors[1]->minimalSignature(), QString("A(A)")); + QVERIFY(ctors[1]->isPrivate()); + + AbstractMetaClass* classB = classes.findClass("B"); + QVERIFY(classB); + + ctors = classB->queryFunctions(AbstractMetaClass::Constructors); + QCOMPARE(ctors.size(), 1); + QCOMPARE(ctors.first()->arguments().size(), 0); + QCOMPARE(ctors.first()->minimalSignature(), QString("B()")); +} + +void TestAbstractMetaClass::testAbstractClassDefaultConstructors() +{ + const char* cppCode ="\ + struct A {\ + virtual method() = 0;\ + };\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <object-type name='A' /> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 1); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + + AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors); + QCOMPARE(ctors.size(), 1); + QCOMPARE(ctors.first()->arguments().size(), 0); + QCOMPARE(ctors.first()->minimalSignature(), QString("A()")); +} + +void TestAbstractMetaClass::testObjectTypesMustNotHaveCopyConstructors() +{ + const char* cppCode ="struct A {};"; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <object-type name='A' /> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 1); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + + AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors); + QCOMPARE(ctors.size(), 1); + QCOMPARE(ctors.first()->arguments().size(), 0); + QCOMPARE(ctors.first()->minimalSignature(), QString("A()")); +} + +void TestAbstractMetaClass::testIsPolymorphic() +{ + const char* cppCode = "\ + class A\ + {\ + public:\ + A();\ + inline bool abc() const {}\ + };\ + \ + class B : public A\ + {\ + public:\ + B();\ + inline bool abc() const {}\ + };"; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <primitive-type name='bool' />\ + <value-type name='A' />\ + <value-type name='B' />\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + AbstractMetaClass* b = classes.findClass("A"); + + QVERIFY(!b->isPolymorphic()); + AbstractMetaClass* a = classes.findClass("B"); + QVERIFY(!a->isPolymorphic()); +} + +QTEST_APPLESS_MAIN(TestAbstractMetaClass) + +#include "testabstractmetaclass.moc" diff --git a/ApiExtractor/tests/testabstractmetaclass.h b/ApiExtractor/tests/testabstractmetaclass.h new file mode 100644 index 000000000..d725c46ed --- /dev/null +++ b/ApiExtractor/tests/testabstractmetaclass.h @@ -0,0 +1,48 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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 testClassDefaultConstructors(); + void testClassInheritedDefaultConstructors(); + void testAbstractClassDefaultConstructors(); + void testObjectTypesMustNotHaveCopyConstructors(); + void testIsPolymorphic(); +}; + +#endif // TESTABSTRACTMETACLASS_H diff --git a/ApiExtractor/tests/testabstractmetatype.cpp b/ApiExtractor/tests/testabstractmetatype.cpp new file mode 100644 index 000000000..1e9ce81eb --- /dev/null +++ b/ApiExtractor/tests/testabstractmetatype.cpp @@ -0,0 +1,206 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testabstractmetatype.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestAbstractMetaType::testConstCharPtrType() +{ + const char* cppCode ="const char* justAtest();"; + const char* xmlCode = "<typesystem package=\"Foo\">\ + <primitive-type name='char'/>\ + <function signature='justAtest()' />\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + QCOMPARE(t.builder()->globalFunctions().size(), 1); + AbstractMetaFunction* func = t.builder()->globalFunctions().first(); + AbstractMetaType* rtype = func->type(); + // Test properties of const char* + QVERIFY(rtype); + QCOMPARE(rtype->package(), QString("Foo")); + QCOMPARE(rtype->name(), QString("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()); + QVERIFY(!rtype->isReference()); + QVERIFY(!rtype->isValue()); + QVERIFY(!rtype->isValuePointer()); +} + +void TestAbstractMetaType::testApiVersionSupported() +{ + const char* cppCode ="class foo {}; class foo2 {};\ + void justAtest(); void justAtest3();"; + const char* xmlCode = "<typesystem package='Foo'>\ + <value-type name='foo' since='0.1'/>\ + <value-type name='foo2' since='1.0'/>\ + <value-type name='foo3' since='1.1'/>\ + <function signature='justAtest()' since='0.1'/>\ + <function signature='justAtest2()' since='1.1'/>\ + <function signature='justAtest3()'/>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false, "1.0"); + + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.size(), 2); + + + AbstractMetaFunctionList functions = t.builder()->globalFunctions(); + QCOMPARE(functions.size(), 2); +} + + +void TestAbstractMetaType::testApiVersionNotSupported() +{ + const char* cppCode ="class object {};"; + const char* xmlCode = "<typesystem package='Foo'>\ + <value-type name='object' since='0.1'/>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, true, "0.1"); + + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.size(), 1); +} + +void TestAbstractMetaType::testCharType() +{ + const char* cppCode ="char justAtest(); class A {};"; + const char* xmlCode = "<typesystem package=\"Foo\">\ + <primitive-type name='char'/>\ + <value-type name='A' />\ + <function signature='justAtest()' />\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.size(), 1); + QCOMPARE(classes.first()->package(), QString("Foo")); + + AbstractMetaFunctionList functions = t.builder()->globalFunctions(); + QCOMPARE(functions.size(), 1); + AbstractMetaFunction* func = functions.first(); + AbstractMetaType* rtype = func->type(); + // Test properties of const char* + QVERIFY(rtype); + QCOMPARE(rtype->package(), QString("Foo")); + QCOMPARE(rtype->name(), QString("char")); + QVERIFY(!rtype->isConstant()); + QVERIFY(!rtype->isArray()); + QVERIFY(!rtype->isContainer()); + QVERIFY(!rtype->isObject()); + QVERIFY(rtype->isPrimitive()); + QVERIFY(!rtype->isNativePointer()); + QVERIFY(!rtype->isQObject()); + QVERIFY(!rtype->isReference()); + QVERIFY(!rtype->isValue()); + QVERIFY(!rtype->isValuePointer()); +} + +void TestAbstractMetaType::testTypedef() +{ + const char* cppCode ="\ + struct A {\ + void someMethod();\ + };\ + typedef A B;\ + typedef B C;"; + const char* xmlCode = "<typesystem package=\"Foo\">\ + <value-type name='C' />\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.size(), 1); + AbstractMetaClass* c = classes.findClass("C"); + QVERIFY(c); + QVERIFY(c->isTypeAlias()); +} + +void TestAbstractMetaType::testTypedefWithTemplates() +{ + const char* cppCode ="\ + template<typename T>\ + class A {};\ + \ + class B {};\ + typedef A<B> C;\ + \ + void func(C c);\ + "; + const char* xmlCode = "<typesystem package=\"Foo\">\ + <container-type name='A' type='list'/>\ + <value-type name='B' />\ + <function signature='func(A<B>)' />\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.size(), 1); + AbstractMetaFunctionList functions = t.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(), QString("A<B >")); +} + + +void TestAbstractMetaType::testObjectTypeUsedAsValue() +{ + const char* cppCode ="\ + class A {\ + void method(A);\ + };\ + "; + const char* xmlCode = "<typesystem package='Foo'>\ + <object-type name='A' />\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.size(), 1); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + AbstractMetaFunctionList overloads = classA->queryFunctionsByName("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(), QString("A")); + QVERIFY(metaType->isValue()); + QVERIFY(metaType->typeEntry()->isObject()); +} + +QTEST_APPLESS_MAIN(TestAbstractMetaType) + +#include "testabstractmetatype.moc" diff --git a/ApiExtractor/tests/testabstractmetatype.h b/ApiExtractor/tests/testabstractmetatype.h new file mode 100644 index 000000000..f543172cc --- /dev/null +++ b/ApiExtractor/tests/testabstractmetatype.h @@ -0,0 +1,42 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/testaddfunction.cpp b/ApiExtractor/tests/testaddfunction.cpp new file mode 100644 index 000000000..c1189c346 --- /dev/null +++ b/ApiExtractor/tests/testaddfunction.cpp @@ -0,0 +1,432 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testaddfunction.h" +#include <QtTest/QTest> +#include "testutil.h" + + +void TestAddFunction::testParsingFuncNameAndConstness() +{ + // generic test... + const char sig1[] = "func(type1, const type2, const type3* const)"; + AddedFunction f1(sig1, "void", 0); + QCOMPARE(f1.name(), QString("func")); + QCOMPARE(f1.arguments().count(), 3); + AddedFunction::TypeInfo retval = f1.returnType(); + QCOMPARE(retval.name, QString("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(sig2, "const Abc<int& , C<char*> * > * *", 0); + QCOMPARE(f2.name(), QString("_fu__nc_")); + QList< AddedFunction::TypeInfo > args = f2.arguments(); + QCOMPARE(args.count(), 4); + retval = f2.returnType(); + QCOMPARE(retval.name, QString("Abc<int& , C<char*> * >")); + QCOMPARE(retval.indirections, 2); + QCOMPARE(retval.isConstant, true); + QCOMPARE(retval.isReference, false); + retval = args[2]; + QCOMPARE(retval.name, QString("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(sig3, "void", 0); + QCOMPARE(f3.name(), QString("func")); + QCOMPARE(f3.arguments().count(), 0); +} + +void TestAddFunction::testAddFunction() +{ + const char cppCode[] = "struct B {}; struct A { void a(int); };"; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <primitive-type name='int' />\ + <primitive-type name='float' />\ + <value-type name='B' />\ + <value-type name='A'>\ + <add-function signature='b(int, float = 4.6, const B&)' return-type='int' access='protected'>\ + </add-function>\ + </value-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + TypeDatabase* typeDb = TypeDatabase::instance(); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("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(), uint(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("int")); + AbstractMetaArgumentList args = addedFunc->arguments(); + QCOMPARE(args.count(), 3); + QCOMPARE(args[0]->type()->typeEntry(), returnType->typeEntry()); + QCOMPARE(args[1]->defaultValueExpression(), QString("4.6")); + QCOMPARE(args[2]->type()->typeEntry(), typeDb->findType("B")); +} + +void TestAddFunction::testAddFunctionConstructor() +{ + const char cppCode[] = "struct A { A() {} };"; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <primitive-type name='int' />\ + <value-type name='A'>\ + <add-function signature='A(int)' />\ + </value-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + QCOMPARE(classA->functions().count(), 3); // default and added ctors + AbstractMetaFunction* addedFunc = classA->functions().last(); + QCOMPARE(addedFunc->visibility(), uint(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 {};"; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <value-type name='A'>\ + <add-function signature='func()' />\ + </value-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("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(), uint(AbstractMetaFunction::Public)); + QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction); + QVERIFY(addedFunc->isUserAdded()); + QVERIFY(!addedFunc->type()); +} + +void TestAddFunction::testAddFunctionCodeSnippets() +{ + const char cppCode[] = "struct A {};"; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <value-type name='A'>\ + <add-function signature='func()'>\ + <inject-code class='target' position='end'>Hi!, I am the code.</inject-code>\ + </add-function>\ + </value-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + AbstractMetaFunction* addedFunc = classA->functions().last(); + QVERIFY(addedFunc->hasInjectedCode()); +} + +void TestAddFunction::testAddFunctionWithoutParenteses() +{ + const char sig1[] = "func"; + AddedFunction f1(sig1, "void", 0); + + QCOMPARE(f1.name(), QString("func")); + QCOMPARE(f1.arguments().count(), 0); + QCOMPARE(f1.isConstant(), false); + + const char cppCode[] = "struct A {};"; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <value-type name='A'>\ + <add-function signature='func'>\ + <inject-code class='target' position='end'>Hi!, I am the code.</inject-code>\ + </add-function>\ + </value-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + const AbstractMetaFunction* addedFunc = classA->findFunction("func"); + QVERIFY(addedFunc); + QVERIFY(addedFunc->hasInjectedCode()); + QCOMPARE(addedFunc->injectedCodeSnips(CodeSnip::Any, TypeSystem::TargetLangCode).count(), 1); +} + +void TestAddFunction::testAddFunctionWithDefaultArgs() +{ + const char sig1[] = "func"; + AddedFunction f1(sig1, "void", 0); + + QCOMPARE(f1.name(), QString("func")); + QCOMPARE(f1.arguments().count(), 0); + QCOMPARE(f1.isConstant(), false); + + const char cppCode[] = "struct A { };"; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <primitive-type name='int'/> \ + <value-type name='A'>\ + <add-function signature='func(int, int)'>\ + <modify-argument index='2'>\ + <replace-default-expression with='2'/> \ + </modify-argument> \ + </add-function>\ + </value-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + const AbstractMetaFunction* addedFunc = classA->findFunction("func"); + QVERIFY(addedFunc); + AbstractMetaArgument *arg = addedFunc->arguments()[1]; + QCOMPARE(arg->defaultValueExpression(), QString("2")); +} + +void TestAddFunction::testAddFunctionAtModuleLevel() +{ + const char cppCode[] = "struct A { };"; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <primitive-type name='int'/> \ + <value-type name='A'/>\ + <add-function signature='func(int, int)'>\ + <inject-code class='target' position='beginning'>custom_code();</inject-code>\ + </add-function>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + + TypeDatabase* typeDb = TypeDatabase::instance(); + + AddedFunctionList addedFuncs = typeDb->findGlobalUserFunctions("func"); + + QCOMPARE(addedFuncs.size(), 1); + + FunctionModificationList mods = typeDb->functionModifications("func(int,int)"); + + QCOMPARE(mods.size(), 1); + QVERIFY(mods.first().isCodeInjection()); + CodeSnip snip = mods.first().snips.first(); + QCOMPARE(snip.code(), QString("custom_code();")); +} + +void TestAddFunction::testAddFunctionWithVarargs() +{ + const char sig1[] = "func(int,char,...)"; + AddedFunction f1(sig1, "void", 0); + + QCOMPARE(f1.name(), QString("func")); + QCOMPARE(f1.arguments().count(), 3); + QVERIFY(!f1.isConstant()); + + const char cppCode[] = "struct A {};"; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <primitive-type name='int'/> \ + <primitive-type name='char'/> \ + <value-type name='A'>\ + <add-function signature='func(int,char,...)'/>\ + </value-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + const AbstractMetaFunction* addedFunc = classA->findFunction("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 { };"; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <primitive-type name='int'/> \ + <value-type name='A'>\ + <add-function signature='func(int, int)' static='yes'>\ + <inject-code class='target' position='beginning'>custom_code();</inject-code>\ + </add-function>\ + </value-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + const AbstractMetaFunction* addedFunc = classA->findFunction("func"); + QVERIFY(addedFunc); + QVERIFY(addedFunc->isStatic()); +} + +void TestAddFunction::testAddGlobalFunction() +{ + const char cppCode[] = "struct A { };struct B {};"; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <primitive-type name='int'/> \ + <value-type name='A' />\ + <add-function signature='globalFunc(int, int)' static='yes'>\ + <inject-code class='target' position='beginning'>custom_code();</inject-code>\ + </add-function>\ + <add-function signature='globalFunc2(int, int)' static='yes'>\ + <inject-code class='target' position='beginning'>custom_code();</inject-code>\ + </add-function>\ + <value-type name='B' />\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaFunctionList globalFuncs = t.builder()->globalFunctions(); + QCOMPARE(globalFuncs.count(), 2); + QVERIFY(!t.builder()->classes().findClass("B")->findFunction("globalFunc")); + QVERIFY(!t.builder()->classes().findClass("B")->findFunction("globalFunc2")); + QVERIFY(!globalFuncs[0]->injectedCodeSnips().isEmpty()); + QVERIFY(!globalFuncs[1]->injectedCodeSnips().isEmpty()); +} + +void TestAddFunction::testAddFunctionWithApiVersion() +{ + const char cppCode[] = ""; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <primitive-type name='int'/> \ + <add-function signature='globalFunc(int, int)' static='yes' since='1.3'>\ + <inject-code class='target' position='beginning'>custom_code();</inject-code>\ + </add-function>\ + <add-function signature='globalFunc2(int, int)' static='yes' since='0.1'>\ + <inject-code class='target' position='beginning'>custom_code();</inject-code>\ + </add-function>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, true, "0.1"); + AbstractMetaFunctionList globalFuncs = t.builder()->globalFunctions(); + QCOMPARE(globalFuncs.count(), 1); +} + +void TestAddFunction::testModifyAddedFunction() +{ + const char cppCode[] = "class Foo { };"; + const char xmlCode[] = "\ + <typesystem package='Package'>\ + <primitive-type name='float'/>\ + <primitive-type name='int'/>\ + <value-type name='Foo'>\ + <add-function signature='method(float, int)'>\ + <inject-code class='target' position='beginning'>custom_code();</inject-code>\ + <modify-argument index='2'>\ + <replace-default-expression with='0' />\ + <rename to='varName' />\ + </modify-argument>\ + </add-function>\ + </value-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* foo = classes.findClass("Foo"); + const AbstractMetaFunction* method = foo->findFunction("method"); + QCOMPARE(method->arguments().size(), 2); + AbstractMetaArgument* arg = method->arguments().at(1); + QCOMPARE(arg->defaultValueExpression(), QString("0")); + QCOMPARE(arg->name(), QString("varName")); + QCOMPARE(method->argumentName(2), QString("varName")); +} + +void TestAddFunction::testAddFunctionOnTypedef() +{ + const char cppCode[] = "template<class T> class Foo { }; typedef Foo<int> FooInt;"; + const char xmlCode[] = "\ + <typesystem package='Package'>\ + <custom-type name='PySequence'/>\ + <primitive-type name='int'/>\ + <value-type name='FooInt'>\ + <add-function signature='FooInt(PySequence)'>\ + <inject-code class='target' position='beginning'>custom_code();</inject-code>\ + </add-function>\ + <add-function signature='method()'>\ + <inject-code class='target' position='beginning'>custom_code();</inject-code>\ + </add-function>\ + </value-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* foo = classes.findClass("FooInt"); + 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("method"); + QVERIFY(method); +} + +void TestAddFunction::testAddFunctionWithTemplateArg() +{ + const char cppCode[] = "template<class T> class Foo { };"; + const char xmlCode[] = "\ + <typesystem package='Package'>\ + <primitive-type name='int'/>\ + <container-type name='Foo' type='list'/>\ + <add-function signature='func(Foo<int>)' />\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + QCOMPARE(t.builder()->globalFunctions().size(), 1); + AbstractMetaFunction* func = t.builder()->globalFunctions().first(); + AbstractMetaArgument* arg = func->arguments().first(); + QCOMPARE(arg->type()->instantiations().count(), 1); +} + +QTEST_APPLESS_MAIN(TestAddFunction) + +#include "testaddfunction.moc" + diff --git a/ApiExtractor/tests/testaddfunction.h b/ApiExtractor/tests/testaddfunction.h new file mode 100644 index 000000000..ce8c1fe41 --- /dev/null +++ b/ApiExtractor/tests/testaddfunction.h @@ -0,0 +1,49 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/testarrayargument.cpp b/ApiExtractor/tests/testarrayargument.cpp new file mode 100644 index 000000000..7750ded59 --- /dev/null +++ b/ApiExtractor/tests/testarrayargument.cpp @@ -0,0 +1,121 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testarrayargument.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestArrayArgument::testArrayArgumentWithSizeDefinedByInteger() +{ + const char* cppCode ="\ + struct A { \ + enum SomeEnum { Value0, Value1, NValues }; \ + void method(double[3]); \ + };"; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <primitive-type name='double'/>\ + <object-type name='A'>\ + <enum-type name='SomeEnum'/>\ + </object-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClass* classA = t.builder()->classes().findClass("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(), QString("double")); +} + +void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValue() +{ + const char* cppCode ="\ + struct A { \ + enum SomeEnum { Value0, Value1, NValues }; \ + void method(double[NValues]); \ + };"; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <primitive-type name='double'/>\ + <object-type name='A'>\ + <enum-type name='SomeEnum'/>\ + </object-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClass* classA = t.builder()->classes().findClass("A"); + QVERIFY(classA); + + AbstractMetaEnum* someEnum = classA->findEnum("SomeEnum"); + QVERIFY(someEnum); + AbstractMetaEnumValue* nvalues = classA->findEnumValue("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(), QString("double")); +}; + +void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnum() +{ + const char* cppCode ="\ + enum SomeEnum { Value0, Value1, NValues }; \ + struct A { \ + void method(double[NValues]); \ + };"; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <primitive-type name='double'/>\ + <enum-type name='SomeEnum'/>\ + <object-type name='A'>\ + </object-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClass* classA = t.builder()->classes().findClass("A"); + QVERIFY(classA); + + AbstractMetaEnum* someEnum = t.builder()->globalEnums().first(); + QVERIFY(someEnum); + AbstractMetaEnumValue* nvalues = 0; + foreach (AbstractMetaEnumValue* enumValue, someEnum->values()) { + if (enumValue->name() == "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(), QString("double")); +}; + +QTEST_APPLESS_MAIN(TestArrayArgument) + +#include "testarrayargument.moc" diff --git a/ApiExtractor/tests/testarrayargument.h b/ApiExtractor/tests/testarrayargument.h new file mode 100644 index 000000000..44cb6a6cb --- /dev/null +++ b/ApiExtractor/tests/testarrayargument.h @@ -0,0 +1,37 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/testcodeinjection.cpp b/ApiExtractor/tests/testcodeinjection.cpp new file mode 100644 index 000000000..ed2c379c2 --- /dev/null +++ b/ApiExtractor/tests/testcodeinjection.cpp @@ -0,0 +1,98 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testcodeinjection.h" +#include <QFileInfo> +#include <QDir> +#include <QtTest/QTest> +#include "testutil.h" + +void TestCodeInjections::testReadFileUtf8() +{ + const char* cppCode ="struct A {};"; + int argc = 0; + char *argv[] = {NULL}; + QCoreApplication app(argc, argv); + QString filePath = QDir::currentPath(); + QString xmlCode = "\ + <typesystem package=\"Foo\"> \ + <value-type name='A'> \ + <conversion-rule file='"+filePath+"/utf8code.txt'/>\ + <inject-code class='target' file='"+filePath+"/utf8code.txt' />\ + </value-type>\ + <value-type name='A::B'/> \ + </typesystem>"; + TestUtil t(cppCode, xmlCode.toLocal8Bit().constData()); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("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 {};"; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <value-type name='A'> \ + <inject-code class='target' since='1.0'>\ + test Inject code\ + </inject-code>\ + </value-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, true, "1.0"); + + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QCOMPARE(classA->typeEntry()->codeSnips().count(), 1); +} + +void TestCodeInjections::testInjectWithInvalidApiVersion() +{ + const char* cppCode ="struct A {};"; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <value-type name='A'> \ + <inject-code class='target' since='1.0'>\ + test Inject code\ + </inject-code>\ + </value-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, true, "0.1"); + + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QCOMPARE(classA->typeEntry()->codeSnips().count(), 0); +} + + + +QTEST_APPLESS_MAIN(TestCodeInjections) + +#include "testcodeinjection.moc" diff --git a/ApiExtractor/tests/testcodeinjection.h b/ApiExtractor/tests/testcodeinjection.h new file mode 100644 index 000000000..e12b40d2d --- /dev/null +++ b/ApiExtractor/tests/testcodeinjection.h @@ -0,0 +1,40 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/testcontainer.cpp b/ApiExtractor/tests/testcontainer.cpp new file mode 100644 index 000000000..3d31f8a61 --- /dev/null +++ b/ApiExtractor/tests/testcontainer.cpp @@ -0,0 +1,99 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testcontainer.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestContainer::testContainerType() +{ + const char* cppCode ="\ + namespace std {\ + template<class T>\ + class list { \ + T get(int x) { return 0; }\ + };\ + }\ + class A : public std::list<int> {\ + };\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <namespace-type name='std' generate='no' /> \ + <container-type name='std::list' type='list' /> \ + <object-type name='A'/> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, true); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + //search for class A + AbstractMetaClass* classA = classes.findClass("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 {\ + template<class T>\ + class list { \ + T get(int x) { return 0; }\ + };\ + }\ + class ValueType {};\ + class A : public std::list<ValueType> {\ + };\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <namespace-type name='std' generate='no' /> \ + <container-type name='std::list' type='list' /> \ + <value-type name='ValueType'/> \ + <value-type name='A'/> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, true); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 3); + + AbstractMetaClass* classA = classes.findClass("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()); + QVERIFY(!templateInstanceType->isReference()); + QVERIFY(!templateInstanceType->isObject()); + QVERIFY(!templateInstanceType->isValuePointer()); + QVERIFY(templateInstanceType->isValue()); +} + +QTEST_APPLESS_MAIN(TestContainer) + +#include "testcontainer.moc" diff --git a/ApiExtractor/tests/testcontainer.h b/ApiExtractor/tests/testcontainer.h new file mode 100644 index 000000000..22e47eeba --- /dev/null +++ b/ApiExtractor/tests/testcontainer.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTCONTAINER_H +#define TESTCONTAINER_H +#include <QObject> + +class TestContainer : public QObject +{ + Q_OBJECT +private slots: + void testContainerType(); + void testListOfValueType(); +}; + +#endif diff --git a/ApiExtractor/tests/testconversionoperator.cpp b/ApiExtractor/tests/testconversionoperator.cpp new file mode 100644 index 000000000..e14388e30 --- /dev/null +++ b/ApiExtractor/tests/testconversionoperator.cpp @@ -0,0 +1,179 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testconversionoperator.h" +#include <QtTest/QTest> +#include "testutil.h" + + +void TestConversionOperator::testConversionOperator() +{ + const char cppCode[] = "\ + struct A {\ + };\ + struct B {\ + operator A() const;\ + };\ + struct C {\ + operator A() const;\ + };"; + const char xmlCode[] = "\ + <typesystem package=\"Foo\">\ + <value-type name='A' />\ + <value-type name='B' />\ + <value-type name='C' />\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + AbstractMetaClass* classB = classes.findClass("B"); + AbstractMetaClass* classC = classes.findClass("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 {\ + };\ + struct B {\ + operator A() const;\ + };"; + const char xmlCode[] = "\ + <typesystem package=\"Foo\">\ + <value-type name='A' />\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + QCOMPARE(classA->externalConversionOperators().count(), 0); +} + +void TestConversionOperator::testRemovedConversionOperator() +{ + const char cppCode[] = "\ + struct A {\ + };\ + struct B {\ + operator A() const;\ + };"; + const char xmlCode[] = "\ + <typesystem package=\"Foo\">\ + <value-type name='A' />\ + <value-type name='B'>\ + <modify-function signature='operator A() const' remove='all' />\ + </value-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + AbstractMetaClass* classB = classes.findClass("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 {};\ + struct B {\ + operator A&() const;\ + };"; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <value-type name='A' />\ + <value-type name='B' />\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + AbstractMetaClass* classB = classes.findClass("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(), QString("A")); + QCOMPARE(classA->externalConversionOperators().first()->ownerClass()->name(), QString("B")); + QCOMPARE(classA->implicitConversions().count(), 1); + QCOMPARE(classA->implicitConversions().first()->type()->cppSignature(), QString("A")); + QCOMPARE(classA->implicitConversions().first()->ownerClass()->name(), QString("B")); +} + +void TestConversionOperator::testConversionOperatorReturningConstReference() +{ + const char cppCode[] = "\ + struct A {};\ + struct B {\ + operator const A&() const;\ + };"; + const char xmlCode[] = "\ + <typesystem package='Foo'>\ + <value-type name='A' />\ + <value-type name='B' />\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + AbstractMetaClass* classB = classes.findClass("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(), QString("A")); + QCOMPARE(classA->externalConversionOperators().first()->ownerClass()->name(), QString("B")); + QCOMPARE(classA->implicitConversions().count(), 1); + QCOMPARE(classA->implicitConversions().first()->type()->cppSignature(), QString("A")); + QCOMPARE(classA->implicitConversions().first()->ownerClass()->name(), QString("B")); +} + +QTEST_APPLESS_MAIN(TestConversionOperator) + +#include "testconversionoperator.moc" diff --git a/ApiExtractor/tests/testconversionoperator.h b/ApiExtractor/tests/testconversionoperator.h new file mode 100644 index 000000000..a901f3099 --- /dev/null +++ b/ApiExtractor/tests/testconversionoperator.h @@ -0,0 +1,39 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/testconversionruletag.cpp b/ApiExtractor/tests/testconversionruletag.cpp new file mode 100644 index 000000000..6228ef287 --- /dev/null +++ b/ApiExtractor/tests/testconversionruletag.cpp @@ -0,0 +1,230 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testconversionruletag.h" +#include <QtTest/QTest> +#include "testutil.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 {};"; + QString xmlCode = "\ + <typesystem package='Foo'>\ + <value-type name='A'>\ + <conversion-rule file='"+ file.fileName() +"' />\ + </value-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode.toLocal8Bit().data()); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + const ComplexTypeEntry* typeEntry = classA->typeEntry(); + QVERIFY(typeEntry->hasConversionRule()); + QCOMPARE(typeEntry->conversionRule(), QString(conversionData)); +} + +void TestConversionRuleTag::testConversionRuleTagReplace() +{ + const char cppCode[] = "\ + struct A {\ + A();\ + A(const char*, int);\ + };\ + struct B {\ + A createA();\ + };\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <primitive-type name='int'/>\ + <primitive-type name='char'/>\ + <primitive-type name='A'>\ + <conversion-rule>\ + <native-to-target>\ + DoThis();\ + return ConvertFromCppToPython(%IN);\ + </native-to-target>\ + <target-to-native>\ + <add-conversion type='TargetNone' check='%IN == Target_None'>\ + DoThat();\ + DoSomething();\ + %OUT = A();\ + </add-conversion>\ + <add-conversion type='B' check='CheckIfInputObjectIsB(%IN)'>\ + %OUT = %IN.createA();\ + </add-conversion>\ + <add-conversion type='String' check='String_Check(%IN)'>\ + %OUT = new A(String_AsString(%IN), String_GetSize(%IN));\ + </add-conversion>\ + </target-to-native>\ + </conversion-rule>\ + </primitive-type>\ + <value-type name='B'/>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + TypeDatabase* typeDb = TypeDatabase::instance(); + PrimitiveTypeEntry* typeA = typeDb->findPrimitiveType("A"); + QVERIFY(typeA); + + CustomConversion* conversion = typeA->customConversion(); + QVERIFY(conversion); + + QCOMPARE(typeA, conversion->ownerType()); + QCOMPARE(conversion->nativeToTargetConversion().trimmed(), QString("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(), QString("TargetNone")); + QVERIFY(toNative->isCustomType()); + QCOMPARE(toNative->sourceType(), (const TypeEntry*)0); + QCOMPARE(toNative->sourceTypeCheck(), QString("%IN == Target_None")); + QCOMPARE(toNative->conversion().trimmed(), QString("DoThat(); DoSomething(); %OUT = A();")); + + toNative = conversion->targetToNativeConversions().at(1); + QVERIFY(toNative); + QCOMPARE(toNative->sourceTypeName(), QString("B")); + QVERIFY(!toNative->isCustomType()); + TypeEntry* typeB = typeDb->findType("B"); + QVERIFY(typeB); + QCOMPARE(toNative->sourceType(), typeB); + QCOMPARE(toNative->sourceTypeCheck(), QString("CheckIfInputObjectIsB(%IN)")); + QCOMPARE(toNative->conversion().trimmed(), QString("%OUT = %IN.createA();")); + + toNative = conversion->targetToNativeConversions().at(2); + QVERIFY(toNative); + QCOMPARE(toNative->sourceTypeName(), QString("String")); + QVERIFY(toNative->isCustomType()); + QCOMPARE(toNative->sourceType(), (const TypeEntry*)0); + QCOMPARE(toNative->sourceTypeCheck(), QString("String_Check(%IN)")); + QCOMPARE(toNative->conversion().trimmed(), QString("%OUT = new A(String_AsString(%IN), String_GetSize(%IN));")); +} + +void TestConversionRuleTag::testConversionRuleTagAdd() +{ + const char cppCode[] = "\ + struct Date {\ + Date();\ + Date(int, int, int);\ + };\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <primitive-type name='int'/>\ + <value-type name='Date'>\ + <conversion-rule>\ + <target-to-native replace='no'>\ + <add-conversion type='TargetDate' check='TargetDate_Check(%IN)'>\ + if (!TargetDateTimeAPI) TargetDateTime_IMPORT;\ + %OUT = new Date(TargetDate_Day(%IN), TargetDate_Month(%IN), TargetDate_Year(%IN));\ + </add-conversion>\ + </target-to-native>\ + </conversion-rule>\ + </value-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClass* classA = t.builder()->classes().findClass("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(), QString("TargetDate")); + QVERIFY(toNative->isCustomType()); + QCOMPARE(toNative->sourceType(), (const TypeEntry*)0); + QCOMPARE(toNative->sourceTypeCheck(), QString("TargetDate_Check(%IN)")); + QCOMPARE(toNative->conversion().trimmed(), QString("if (!TargetDateTimeAPI) TargetDateTime_IMPORT; %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'>\ + <primitive-type name='int'/>\ + <template name='native_to_target'>\ + return ConvertFromCppToPython(%IN);\ + </template>\ + <template name='target_to_native'>\ + %OUT = %IN.createA();\ + </template>\ + <primitive-type name='A'>\ + <conversion-rule>\ + <native-to-target>\ + <insert-template name='native_to_target'/>\ + </native-to-target>\ + <target-to-native>\ + <add-conversion type='TargetType'>\ + <insert-template name='target_to_native'/>\ + </add-conversion>\ + </target-to-native>\ + </conversion-rule>\ + </primitive-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + TypeDatabase* typeDb = TypeDatabase::instance(); + PrimitiveTypeEntry* typeA = typeDb->findPrimitiveType("A"); + QVERIFY(typeA); + + CustomConversion* conversion = typeA->customConversion(); + QVERIFY(conversion); + + QCOMPARE(typeA, conversion->ownerType()); + QCOMPARE(conversion->nativeToTargetConversion().trimmed(), + QString("// TEMPLATE - native_to_target - START return ConvertFromCppToPython(%IN); // TEMPLATE - native_to_target - END")); + + QVERIFY(conversion->hasTargetToNativeConversions()); + QCOMPARE(conversion->targetToNativeConversions().size(), 1); + + CustomConversion::TargetToNativeConversion* toNative = conversion->targetToNativeConversions().first(); + QVERIFY(toNative); + QCOMPARE(toNative->conversion().trimmed(), + QString("// TEMPLATE - target_to_native - START %OUT = %IN.createA(); // TEMPLATE - target_to_native - END")); +} + +QTEST_APPLESS_MAIN(TestConversionRuleTag) + +#include "testconversionruletag.moc" diff --git a/ApiExtractor/tests/testconversionruletag.h b/ApiExtractor/tests/testconversionruletag.h new file mode 100644 index 000000000..8ab1481b1 --- /dev/null +++ b/ApiExtractor/tests/testconversionruletag.h @@ -0,0 +1,38 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/testctorinformation.cpp b/ApiExtractor/tests/testctorinformation.cpp new file mode 100644 index 000000000..09d57eb84 --- /dev/null +++ b/ApiExtractor/tests/testctorinformation.cpp @@ -0,0 +1,71 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testctorinformation.h" +#include "abstractmetabuilder.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestCtorInformation::testCtorIsPrivate() +{ + const char* cppCode = "class Control { public: Control() {} };\ + class Subject { private: Subject() {} };\ + class CtorLess { };"; + const char* xmlCode = "<typesystem package='Foo'>\ + <value-type name='Control'/>\ + <object-type name='Subject'/>\ + <value-type name='CtorLess'/>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 3); + QCOMPARE(classes.findClass("Control")->hasNonPrivateConstructor(), true); + QCOMPARE(classes.findClass("Subject")->hasNonPrivateConstructor(), false); + QCOMPARE(classes.findClass("CtorLess")->hasNonPrivateConstructor(), true); +} + +void TestCtorInformation::testHasNonPrivateCtor() +{ + const char* cppCode = "template<typename T>\ + struct Base { Base(double) {} };\ + typedef Base<int> Derived;\ + "; + const char* xmlCode = "<typesystem package='Foo'>\ + <primitive-type name='int' />\ + <primitive-type name='double' />\ + <object-type name='Base' generate='no'/>\ + <object-type name='Derived'/>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + AbstractMetaClass* base = classes.findClass("Base"); + QCOMPARE(base->hasNonPrivateConstructor(), true); + AbstractMetaClass* derived = classes.findClass("Derived"); + QCOMPARE(derived->hasNonPrivateConstructor(), true); +} + +QTEST_APPLESS_MAIN(TestCtorInformation) + +#include "testctorinformation.moc" + diff --git a/ApiExtractor/tests/testctorinformation.h b/ApiExtractor/tests/testctorinformation.h new file mode 100644 index 000000000..12d2529af --- /dev/null +++ b/ApiExtractor/tests/testctorinformation.h @@ -0,0 +1,39 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/testdroptypeentries.cpp b/ApiExtractor/tests/testdroptypeentries.cpp new file mode 100644 index 000000000..5e646eac9 --- /dev/null +++ b/ApiExtractor/tests/testdroptypeentries.cpp @@ -0,0 +1,138 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testdroptypeentries.h" +#include <QtTest/QTest> +#include "testutil.h" + +static const char* cppCode ="\ + struct ValueA {};\ + struct ValueB {};\ + struct ObjectA {};\ + struct ObjectB {};\ + namespace NamespaceA {\ + struct InnerClassA {};\ + namespace InnerNamespaceA {}\ + }\ + namespace NamespaceB {}\ + enum EnumA { Value0 };\ + enum EnumB { Value1 };\ + void funcA();\ + void funcB();\ +"; + +static const char* xmlCode = "\ +<typesystem package='Foo'>\ + <value-type name='ValueA' />\ + <value-type name='ValueB' />\ + <object-type name='ObjectA' />\ + <object-type name='ObjectB' />\ + <namespace-type name='NamespaceA'>\ + <value-type name='InnerClassA' />\ + <namespace-type name='InnerNamespaceA' />\ + </namespace-type>\ + <namespace-type name='NamespaceB' />\ + <enum-type name='EnumA' />\ + <enum-type name='EnumB' />\ + <function signature='funcA()' />\ + <function signature='funcB()' />\ +</typesystem>"; + +void TestDropTypeEntries::testDropEntries() +{ + QStringList droppedEntries("Foo.ValueB"); + droppedEntries << "Foo.ObjectB" << "Foo.NamespaceA.InnerClassA"; + droppedEntries << "Foo.NamespaceB" << "Foo.EnumB" << "Foo.funcB()"; + droppedEntries << "Foo.NamespaceA.InnerNamespaceA"; + TestUtil t(cppCode, xmlCode, false, 0, droppedEntries); + + AbstractMetaClassList classes = t.builder()->classes(); + QVERIFY(classes.findClass("ValueA")); + QVERIFY(!classes.findClass("ValueB")); + QVERIFY(classes.findClass("ObjectA")); + QVERIFY(!classes.findClass("ObjectB")); + QVERIFY(classes.findClass("NamespaceA")); + QVERIFY(!classes.findClass("NamespaceA::InnerClassA")); + QVERIFY(!classes.findClass("NamespaceB")); + + AbstractMetaEnumList globalEnums = t.builder()->globalEnums(); + QCOMPARE(globalEnums.count(), 1); + QCOMPARE(globalEnums.first()->name(), QString("EnumA")); + + TypeDatabase* td = TypeDatabase::instance(); + QVERIFY(td->findType("funcA")); + QVERIFY(!td->findType("funcB")); +} + +void TestDropTypeEntries::testDontDropEntries() +{ + TestUtil t(cppCode, xmlCode, false); + + AbstractMetaClassList classes = t.builder()->classes(); + QVERIFY(classes.findClass("ValueA")); + QVERIFY(classes.findClass("ValueB")); + QVERIFY(classes.findClass("ObjectA")); + QVERIFY(classes.findClass("ObjectB")); + QVERIFY(classes.findClass("NamespaceA")); + QVERIFY(classes.findClass("NamespaceA::InnerClassA")); + QVERIFY(classes.findClass("NamespaceB")); + + QCOMPARE(t.builder()->globalEnums().size(), 2); + + TypeDatabase* td = TypeDatabase::instance(); + QVERIFY(td->findType("funcA")); + QVERIFY(td->findType("funcB")); +} + +static const char* cppCode2 ="\ + struct ValueA {\ + void func();\ + };\ +"; + +static const char* xmlCode2 = "\ +<typesystem package='Foo'>\ + <value-type name='ValueA'>\ + <modify-function signature='func()'>\ + <remove class='all' />\ + </modify-function>\ + </value-type>\ +</typesystem>"; + +void TestDropTypeEntries::testDropEntryWithChildTags() +{ + QStringList droppedEntries("Foo.ValueA"); + TestUtil t(cppCode2, xmlCode2, false, 0, droppedEntries); + QVERIFY(!t.builder()->classes().findClass("ValueA")); +} + +void TestDropTypeEntries::testDontDropEntryWithChildTags() +{ + TestUtil t(cppCode2, xmlCode2, false); + QVERIFY(t.builder()->classes().findClass("ValueA")); +} + +QTEST_APPLESS_MAIN(TestDropTypeEntries) + +#include "testdroptypeentries.moc" + diff --git a/ApiExtractor/tests/testdroptypeentries.h b/ApiExtractor/tests/testdroptypeentries.h new file mode 100644 index 000000000..e91292c12 --- /dev/null +++ b/ApiExtractor/tests/testdroptypeentries.h @@ -0,0 +1,39 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/testdtorinformation.cpp b/ApiExtractor/tests/testdtorinformation.cpp new file mode 100644 index 000000000..1aaeb91dc --- /dev/null +++ b/ApiExtractor/tests/testdtorinformation.cpp @@ -0,0 +1,76 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testdtorinformation.h" +#include "abstractmetabuilder.h" +#include <QtTest/QTest> +#include "testutil.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>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + QCOMPARE(classes.findClass("Control")->hasPrivateDestructor(), false); + QCOMPARE(classes.findClass("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>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + QCOMPARE(classes.findClass("Control")->hasProtectedDestructor(), false); + QCOMPARE(classes.findClass("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>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + QCOMPARE(classes.findClass("Control")->hasVirtualDestructor(), false); + QCOMPARE(classes.findClass("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>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + QCOMPARE(classes.findClass("Control")->isPolymorphic(), true); + QCOMPARE(classes.findClass("Subject")->isPolymorphic(), true); +} + +QTEST_APPLESS_MAIN(TestDtorInformation) + +#include "testdtorinformation.moc" + diff --git a/ApiExtractor/tests/testdtorinformation.h b/ApiExtractor/tests/testdtorinformation.h new file mode 100644 index 000000000..2e378001b --- /dev/null +++ b/ApiExtractor/tests/testdtorinformation.h @@ -0,0 +1,41 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/testenum.cpp b/ApiExtractor/tests/testenum.cpp new file mode 100644 index 000000000..85796a1e9 --- /dev/null +++ b/ApiExtractor/tests/testenum.cpp @@ -0,0 +1,378 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testenum.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestEnum::testEnumCppSignature() +{ + const char* cppCode ="\ + enum GlobalEnum { A, B };\ + \ + struct A {\ + enum ClassEnum { A, B };\ + void method(ClassEnum);\ + };\ + void func(A::ClassEnum);\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <enum-type name='GlobalEnum' />\ + <value-type name='A'> \ + <enum-type name='ClassEnum' />\ + </value-type> \ + <function signature='func(A::ClassEnum)' />\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 1); + + AbstractMetaEnumList globalEnums = t.builder()->globalEnums(); + QCOMPARE(globalEnums.count(), 1); + QCOMPARE(globalEnums.first()->name(), QString("GlobalEnum")); + + // enum as parameter of a function + AbstractMetaFunctionList functions = t.builder()->globalFunctions(); + QCOMPARE(functions.count(), 1); + QCOMPARE(functions.first()->arguments().count(), 1); + QCOMPARE(functions.first()->arguments().first()->type()->cppSignature(), QString("A::ClassEnum")); + + // enum as parameter of a method + AbstractMetaClass* classA = classes.findClass("A"); + QCOMPARE(classA->enums().count(), 1); + AbstractMetaFunctionList funcs = classA->queryFunctionsByName("method"); + QVERIFY(!funcs.isEmpty()); + AbstractMetaFunction* method = funcs.first(); + QVERIFY(method); + AbstractMetaArgument* arg = method->arguments().first(); + QCOMPARE(arg->type()->name(), QString("ClassEnum")); + QCOMPARE(arg->type()->cppSignature(), QString("A::ClassEnum")); + QCOMPARE(functions.first()->arguments().count(), 1); + arg = functions.first()->arguments().first(); + QCOMPARE(arg->type()->name(), QString("ClassEnum")); + QCOMPARE(arg->type()->cppSignature(), QString("A::ClassEnum")); + + AbstractMetaEnumList classEnums = classA->enums(); + QCOMPARE(classEnums.first()->name(), QString("ClassEnum")); +} + +void TestEnum::testEnumWithApiVersion() +{ + const char* cppCode ="\ + struct A {\ + enum ClassEnum { EnumA, EnumB };\ + enum ClassEnum2 { EnumC, EnumD };\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <value-type name='A'> \ + <enum-type name='ClassEnum' since='0.1'/>\ + <enum-type name='ClassEnum2' since='0.2'/>\ + </value-type> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, true, "0.1"); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 1); + QCOMPARE(classes[0]->enums().count(), 1); +} + +void TestEnum::testAnonymousEnum() +{ + const char* cppCode ="\ + enum { Global0, Global1 }; \ + struct A {\ + enum { A0, A1 };\ + enum { isThis = true, isThat = false };\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <!-- Uses the first value of the enum to identify it. -->\ + <enum-type identified-by-value='Global0'/>\ + <value-type name='A'> \ + <!-- Uses the second value of the enum to identify it. -->\ + <enum-type identified-by-value='A1'/>\ + <enum-type identified-by-value='isThis'/>\ + </value-type> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + + AbstractMetaEnumList globalEnums = t.builder()->globalEnums(); + QCOMPARE(globalEnums.count(), 1); + QCOMPARE(globalEnums.first()->typeEntry()->qualifiedCppName(), QString("Global0")); + QVERIFY(globalEnums.first()->isAnonymous()); + + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 1); + QCOMPARE(classes[0]->enums().count(), 2); + + AbstractMetaEnum* anonEnumA1 = classes[0]->findEnum("A1"); + QVERIFY(anonEnumA1); + QVERIFY(anonEnumA1->isAnonymous()); + QCOMPARE(anonEnumA1->typeEntry()->qualifiedCppName(), QString("A::A1")); + + AbstractMetaEnumValue* enumValueA0 = anonEnumA1->values().first(); + QCOMPARE(enumValueA0->name(), QString("A0")); + QCOMPARE(enumValueA0->value(), 0); + QCOMPARE(enumValueA0->stringValue(), QString("")); + + AbstractMetaEnumValue* enumValueA1 = anonEnumA1->values().last(); + QCOMPARE(enumValueA1->name(), QString("A1")); + QCOMPARE(enumValueA1->value(), 1); + QCOMPARE(enumValueA1->stringValue(), QString("")); + + AbstractMetaEnum* anonEnumIsThis = classes[0]->findEnum("isThis"); + QVERIFY(anonEnumIsThis); + QVERIFY(anonEnumIsThis->isAnonymous()); + QCOMPARE(anonEnumIsThis->typeEntry()->qualifiedCppName(), QString("A::isThis")); + + AbstractMetaEnumValue* enumValueIsThis = anonEnumIsThis->values().first(); + QCOMPARE(enumValueIsThis->name(), QString("isThis")); + QCOMPARE(enumValueIsThis->value(), static_cast<int>(true)); + QCOMPARE(enumValueIsThis->stringValue(), QString("true")); + + AbstractMetaEnumValue* enumValueIsThat = anonEnumIsThis->values().last(); + QCOMPARE(enumValueIsThat->name(), QString("isThat")); + QCOMPARE(enumValueIsThat->value(), static_cast<int>(false)); + QCOMPARE(enumValueIsThat->stringValue(), QString("false")); +} + +void TestEnum::testGlobalEnums() +{ + const char* cppCode ="\ + enum EnumA { A0, A1 }; \ + enum EnumB { B0 = 2, B1 = 0x4 }; \ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <enum-type name='EnumA'/>\ + <enum-type name='EnumB'/>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + + AbstractMetaEnumList globalEnums = t.builder()->globalEnums(); + QCOMPARE(globalEnums.count(), 2); + + AbstractMetaEnum* enumA = globalEnums.first(); + QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QString("EnumA")); + + AbstractMetaEnumValue* enumValueA0 = enumA->values().first(); + QCOMPARE(enumValueA0->name(), QString("A0")); + QCOMPARE(enumValueA0->value(), 0); + QCOMPARE(enumValueA0->stringValue(), QString("")); + + AbstractMetaEnumValue* enumValueA1 = enumA->values().last(); + QCOMPARE(enumValueA1->name(), QString("A1")); + QCOMPARE(enumValueA1->value(), 1); + QCOMPARE(enumValueA1->stringValue(), QString("")); + + AbstractMetaEnum* enumB = globalEnums.last(); + QCOMPARE(enumB->typeEntry()->qualifiedCppName(), QString("EnumB")); + + AbstractMetaEnumValue* enumValueB0 = enumB->values().first(); + QCOMPARE(enumValueB0->name(), QString("B0")); + QCOMPARE(enumValueB0->value(), 2); + QCOMPARE(enumValueB0->stringValue(), QString("2")); + + AbstractMetaEnumValue* enumValueB1 = enumB->values().last(); + QCOMPARE(enumValueB1->name(), QString("B1")); + QCOMPARE(enumValueB1->value(), 4); + QCOMPARE(enumValueB1->stringValue(), QString("0x4")); +} + +void TestEnum::testEnumValueFromNeighbourEnum() +{ + const char* cppCode ="\ + namespace A {\ + enum EnumA { ValueA0, ValueA1 };\ + enum EnumB { ValueB0 = A::ValueA1, ValueB1 = ValueA0 };\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <namespace-type name='A'> \ + <enum-type name='EnumA'/>\ + <enum-type name='EnumB'/>\ + </namespace-type> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 1); + QCOMPARE(classes[0]->enums().count(), 2); + + AbstractMetaEnum* enumA = classes[0]->findEnum("EnumA"); + QVERIFY(enumA); + QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QString("A::EnumA")); + + AbstractMetaEnumValue* enumValueA0 = enumA->values().first(); + QCOMPARE(enumValueA0->name(), QString("ValueA0")); + QCOMPARE(enumValueA0->value(), 0); + QCOMPARE(enumValueA0->stringValue(), QString("")); + + AbstractMetaEnumValue* enumValueA1 = enumA->values().last(); + QCOMPARE(enumValueA1->name(), QString("ValueA1")); + QCOMPARE(enumValueA1->value(), 1); + QCOMPARE(enumValueA1->stringValue(), QString("")); + + AbstractMetaEnum* enumB = classes[0]->findEnum("EnumB"); + QVERIFY(enumB); + QCOMPARE(enumB->typeEntry()->qualifiedCppName(), QString("A::EnumB")); + + AbstractMetaEnumValue* enumValueB0 = enumB->values().first(); + QCOMPARE(enumValueB0->name(), QString("ValueB0")); + QCOMPARE(enumValueB0->value(), 1); + QCOMPARE(enumValueB0->stringValue(), QString("A::ValueA1")); + + AbstractMetaEnumValue* enumValueB1 = enumB->values().last(); + QCOMPARE(enumValueB1->name(), QString("ValueB1")); + QCOMPARE(enumValueB1->value(), 0); + QCOMPARE(enumValueB1->stringValue(), QString("ValueA0")); +} + +void TestEnum::testEnumValueFromExpression() +{ + const char* cppCode ="\ + struct A {\ + enum EnumA {\ + ValueA0 = 3u,\ + ValueA1 = ~3u,\ + ValueA2 = ~3,\ + ValueA3 = 0xf0,\ + ValueA4 = 8 |ValueA3,\ + ValueA5 = ValueA3|32,\ + ValueA6 = ValueA3 >> 1,\ + ValueA7 = ValueA3 << 1\ + };\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <value-type name='A'> \ + <enum-type name='EnumA'/>\ + </value-type> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + + AbstractMetaClass* classA = t.builder()->classes().findClass("A"); + QVERIFY(classA); + + AbstractMetaEnum* enumA = classA->findEnum("EnumA"); + QVERIFY(enumA); + QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QString("A::EnumA")); + + AbstractMetaEnumValue* valueA0 = enumA->values().at(0); + QCOMPARE(valueA0->name(), QString("ValueA0")); + QCOMPARE(valueA0->stringValue(), QString("3u")); + QCOMPARE(valueA0->value(), (int) 3u); + + AbstractMetaEnumValue* valueA1 = enumA->values().at(1); + QCOMPARE(valueA1->name(), QString("ValueA1")); + QCOMPARE(valueA1->stringValue(), QString("~3u")); + QCOMPARE(valueA1->value(), (int) ~3u); + + AbstractMetaEnumValue* valueA2 = enumA->values().at(2); + QCOMPARE(valueA2->name(), QString("ValueA2")); + QCOMPARE(valueA2->stringValue(), QString("~3")); + QCOMPARE(valueA2->value(), ~3); + + AbstractMetaEnumValue* valueA3 = enumA->values().at(3); + QCOMPARE(valueA3->name(), QString("ValueA3")); + QCOMPARE(valueA3->stringValue(), QString("0xf0")); + QCOMPARE(valueA3->value(), 0xf0); + + AbstractMetaEnumValue* valueA4 = enumA->values().at(4); + QCOMPARE(valueA4->name(), QString("ValueA4")); + QCOMPARE(valueA4->stringValue(), QString("8|ValueA3")); + QCOMPARE(valueA4->value(), 8|0xf0); + + AbstractMetaEnumValue* valueA5 = enumA->values().at(5); + QCOMPARE(valueA5->name(), QString("ValueA5")); + QCOMPARE(valueA5->stringValue(), QString("ValueA3|32")); + QCOMPARE(valueA5->value(), 0xf0|32); + + AbstractMetaEnumValue* valueA6 = enumA->values().at(6); + QCOMPARE(valueA6->name(), QString("ValueA6")); + QCOMPARE(valueA6->stringValue(), QString("ValueA3>>1")); + QCOMPARE(valueA6->value(), 0xf0 >> 1); + + AbstractMetaEnumValue* valueA7 = enumA->values().at(7); + QCOMPARE(valueA7->name(), QString("ValueA7")); + QCOMPARE(valueA7->stringValue(), QString("ValueA3<<1")); + QCOMPARE(valueA7->value(), 0xf0 << 1); +} + +void TestEnum::testPrivateEnum() +{ + const char* cppCode ="\ + class A {\ + private:\ + enum PrivateEnum { Priv0 = 0x0f, Priv1 = 0xf0 };\ + public:\ + enum PublicEnum { Pub0 = Priv0, Pub1 = A::Priv1 };\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <value-type name='A'> \ + <enum-type name='PublicEnum'/>\ + </value-type> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + + AbstractMetaClass* classA = t.builder()->classes().findClass("A"); + QVERIFY(classA); + QCOMPARE(classA->enums().count(), 2); + + AbstractMetaEnum* privateEnum = classA->findEnum("PrivateEnum"); + QVERIFY(privateEnum); + QVERIFY(privateEnum->isPrivate()); + QCOMPARE(privateEnum->typeEntry()->qualifiedCppName(), QString("A::PrivateEnum")); + + AbstractMetaEnum* publicEnum = classA->findEnum("PublicEnum"); + QVERIFY(publicEnum); + QCOMPARE(publicEnum->typeEntry()->qualifiedCppName(), QString("A::PublicEnum")); + + AbstractMetaEnumValue* pub0 = publicEnum->values().first(); + QCOMPARE(pub0->name(), QString("Pub0")); + QCOMPARE(pub0->value(), 0x0f); + QCOMPARE(pub0->stringValue(), QString("Priv0")); + + AbstractMetaEnumValue* pub1 = publicEnum->values().last(); + QCOMPARE(pub1->name(), QString("Pub1")); + QCOMPARE(pub1->value(), 0xf0); + QCOMPARE(pub1->stringValue(), QString("A::Priv1")); +} + +QTEST_APPLESS_MAIN(TestEnum) + +#include "testenum.moc" diff --git a/ApiExtractor/tests/testenum.h b/ApiExtractor/tests/testenum.h new file mode 100644 index 000000000..7bf3a9eb5 --- /dev/null +++ b/ApiExtractor/tests/testenum.h @@ -0,0 +1,41 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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(); +}; + +#endif diff --git a/ApiExtractor/tests/testextrainclude.cpp b/ApiExtractor/tests/testextrainclude.cpp new file mode 100644 index 000000000..b9e6ad318 --- /dev/null +++ b/ApiExtractor/tests/testextrainclude.cpp @@ -0,0 +1,79 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testextrainclude.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestExtraInclude::testClassExtraInclude() +{ + const char* cppCode ="struct A {};"; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <value-type name='A'> \ + <extra-includes>\ + <include file-name='header.h' location='global' />\ + </extra-includes>\ + </value-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + const AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + + QList<Include> includes = classA->typeEntry()->extraIncludes(); + QCOMPARE(includes.count(), 1); + QCOMPARE(includes.first().name(), QString("header.h")); +} + +void TestExtraInclude::testGlobalExtraIncludes() +{ + const char* cppCode ="struct A {};"; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <extra-includes>\ + <include file-name='header1.h' location='global' />\ + <include file-name='header2.h' location='global' />\ + </extra-includes>\ + <value-type name='A' />\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + QVERIFY(classes.findClass("A")); + + TypeDatabase* td = TypeDatabase::instance(); + TypeEntry* module = td->findType("Foo"); + QVERIFY(module); + + QList<Include> includes = module->extraIncludes(); + QCOMPARE(includes.count(), 2); + QCOMPARE(includes.first().name(), QString("header1.h")); + QCOMPARE(includes.last().name(), QString("header2.h")); +} + +QTEST_APPLESS_MAIN(TestExtraInclude) + +#include "testextrainclude.moc" + diff --git a/ApiExtractor/tests/testextrainclude.h b/ApiExtractor/tests/testextrainclude.h new file mode 100644 index 000000000..d397f5fcc --- /dev/null +++ b/ApiExtractor/tests/testextrainclude.h @@ -0,0 +1,37 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTEXTRAINCLUDE_H +#define TESTEXTRAINCLUDE_H + +#include <QObject> + +class TestExtraInclude : public QObject +{ + Q_OBJECT + private slots: + void testClassExtraInclude(); + void testGlobalExtraIncludes(); +}; + +#endif diff --git a/ApiExtractor/tests/testfunctiontag.cpp b/ApiExtractor/tests/testfunctiontag.cpp new file mode 100644 index 000000000..378baf479 --- /dev/null +++ b/ApiExtractor/tests/testfunctiontag.cpp @@ -0,0 +1,89 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testfunctiontag.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestFunctionTag::testFunctionTagForSpecificSignature() +{ + const char cppCode[] = "void globalFunction(int); void globalFunction(float); void dummy()"; + const char xmlCode[] = "\ + <typesystem package=\"Foo\">\ + <primitive-type name='int'/> \ + <primitive-type name='float'/> \ + <function signature='globalFunction(int)'/>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + + FunctionTypeEntry* func = (FunctionTypeEntry*) TypeDatabase::instance()->findType("globalFunction"); + QVERIFY(func); + QCOMPARE(t.builder()->globalFunctions().size(), 1); +} + +void TestFunctionTag::testFunctionTagForAllSignatures() +{ + const char cppCode[] = "void globalFunction(int); void globalFunction(float); void dummy();"; + const char xmlCode[] = "\ + <typesystem package=\"Foo\">\ + <primitive-type name='int'/> \ + <primitive-type name='float'/> \ + <function signature='globalFunction(int)'/>\ + <function signature='globalFunction(float)'/>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + + FunctionTypeEntry* func = (FunctionTypeEntry*) TypeDatabase::instance()->findType("globalFunction"); + QVERIFY(func); + QCOMPARE(t.builder()->globalFunctions().size(), 2); +} + +void TestFunctionTag::testRenameGlobalFunction() +{ + const char* cppCode ="void global_function_with_ugly_name();"; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <function signature='global_function_with_ugly_name()' rename='smooth' />\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + + FunctionTypeEntry* func = (FunctionTypeEntry*) TypeDatabase::instance()->findType("global_function_with_ugly_name"); + QVERIFY(func); + + QCOMPARE(t.builder()->globalFunctions().size(), 1); + const AbstractMetaFunction* metaFunc = t.builder()->globalFunctions().first(); + + QVERIFY(metaFunc); + QCOMPARE(metaFunc->modifications().size(), 1); + QVERIFY(metaFunc->modifications().first().isRenameModifier()); + QCOMPARE(metaFunc->modifications().first().renamedTo(), QString("smooth")); + + QCOMPARE(metaFunc->name(), QString("smooth")); + QCOMPARE(metaFunc->originalName(), QString("global_function_with_ugly_name")); + QCOMPARE(metaFunc->minimalSignature(), QString("global_function_with_ugly_name()")); +} + +QTEST_APPLESS_MAIN(TestFunctionTag) + +#include "testfunctiontag.moc" + diff --git a/ApiExtractor/tests/testfunctiontag.h b/ApiExtractor/tests/testfunctiontag.h new file mode 100644 index 000000000..2edd1c4de --- /dev/null +++ b/ApiExtractor/tests/testfunctiontag.h @@ -0,0 +1,37 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/testimplicitconversions.cpp b/ApiExtractor/tests/testimplicitconversions.cpp new file mode 100644 index 000000000..4bc4d73fc --- /dev/null +++ b/ApiExtractor/tests/testimplicitconversions.cpp @@ -0,0 +1,158 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testimplicitconversions.h" +#include "testutil.h" +#include <QtTest/QTest> + +void TestImplicitConversions::testWithPrivateCtors() +{ + const char* cppCode ="\ + class B;\ + class C;\ + class A {\ + A(const B&);\ + public:\ + A(const C&);\ + };\ + class B {};\ + class C {};\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <value-type name='A'/> \ + <value-type name='B'/> \ + <value-type name='C'/> \ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 3); + + AbstractMetaClass* classA = classes.findClass("A"); + AbstractMetaClass* classC = classes.findClass("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;\ + class A {\ + public:\ + A(const B&);\ + };\ + class B {};\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <value-type name='A'>\ + <modify-function signature='A(const B&)'>\ + <access modifier='private' />\ + </modify-function>\ + </value-type>\ + <value-type name='B'/>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + AbstractMetaClass* classA = classes.findClass("A"); + AbstractMetaClass* classB = classes.findClass("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;\ + class A {\ + public:\ + A(const B&);\ + };\ + class B {};\ + class C {};\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <custom-type name='TARGETLANGTYPE' />\ + <value-type name='A'>\ + <add-function signature='A(const C&)' />\ + </value-type>\ + <value-type name='B'>\ + <add-function signature='B(TARGETLANGTYPE*)' />\ + </value-type>\ + <value-type name='C'/>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 3); + + AbstractMetaClass* classA = classes.findClass("A"); + AbstractMetaFunctionList implicitConvs = classA->implicitConversions(); + QCOMPARE(implicitConvs.count(), 2); + + // Added constructors with custom types should never result in implicit converters. + AbstractMetaClass* classB = classes.findClass("B"); + implicitConvs = classB->implicitConversions(); + QCOMPARE(implicitConvs.count(), 0); +} + +void TestImplicitConversions::testWithExternalConversionOperator() +{ + const char* cppCode ="\ + class A {};\ + struct B {\ + operator A() const;\ + };\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <value-type name='A'/>\ + <value-type name='B'/>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + AbstractMetaClass* classA = classes.findClass("A"); + AbstractMetaClass* classB = classes.findClass("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) + +#include "testimplicitconversions.moc" diff --git a/ApiExtractor/tests/testimplicitconversions.h b/ApiExtractor/tests/testimplicitconversions.h new file mode 100644 index 000000000..69bef4952 --- /dev/null +++ b/ApiExtractor/tests/testimplicitconversions.h @@ -0,0 +1,41 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/testinserttemplate.cpp b/ApiExtractor/tests/testinserttemplate.cpp new file mode 100644 index 000000000..e3aade5a4 --- /dev/null +++ b/ApiExtractor/tests/testinserttemplate.cpp @@ -0,0 +1,121 @@ +/* + * This file is part of the API Extractor project. + * + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team <contact@pyside.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "testinserttemplate.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestInsertTemplate::testInsertTemplateOnClassInjectCode() +{ + const char* cppCode ="struct A{};"; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <template name='code_template'>\ + code template content\ + </template>\ + <value-type name='A'>\ + <inject-code class='native'>\ + <insert-template name='code_template'/>\ + </inject-code>\ + </value-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 1); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + QCOMPARE(classA->typeEntry()->codeSnips().count(), 1); + QString code = classA->typeEntry()->codeSnips().first().code(); + QVERIFY(code.contains("code template content")); +} + +void TestInsertTemplate::testInsertTemplateOnModuleInjectCode() +{ + const char* cppCode =""; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <template name='code_template'>\ + code template content\ + </template>\ + <inject-code class='native'>\ + <insert-template name='code_template'/>\ + </inject-code>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + QVERIFY(classes.isEmpty()); + + TypeEntry* module = TypeDatabase::instance()->findType("Foo"); + QVERIFY(module); + QCOMPARE(module->codeSnips().count(), 1); + QString code = module->codeSnips().first().code().trimmed(); + QVERIFY(code.contains("code template content")); +} + +void TestInsertTemplate::testInvalidTypeSystemTemplate() +{ + const char* cppCode =""; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <inject-code class='native'>\ + <insert-template name='this_code_template_does_not_exists'/>\ + </inject-code>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + QVERIFY(classes.isEmpty()); + + TypeEntry* module = TypeDatabase::instance()->findType("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'>\ + <template name='code_template'>\ + code template content\ + </template>\ + <inject-code class='native'>\ + <insert-template name='this_code_template_does_not_exists'/>\ + <insert-template name='code_template'/>\ + </inject-code>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + QVERIFY(classes.isEmpty()); + + TypeEntry* module = TypeDatabase::instance()->findType("Foo"); + QVERIFY(module); + QCOMPARE(module->codeSnips().count(), 1); + QString code = module->codeSnips().first().code().trimmed(); + QVERIFY(code.contains("code template content")); +} + +QTEST_APPLESS_MAIN(TestInsertTemplate) + +#include "testinserttemplate.moc" diff --git a/ApiExtractor/tests/testinserttemplate.h b/ApiExtractor/tests/testinserttemplate.h new file mode 100644 index 000000000..fd3ca1d72 --- /dev/null +++ b/ApiExtractor/tests/testinserttemplate.h @@ -0,0 +1,39 @@ +/* + * This file is part of the API Extractor project. + * + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team <contact@pyside.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#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/ApiExtractor/tests/testmodifydocumentation.cpp b/ApiExtractor/tests/testmodifydocumentation.cpp new file mode 100644 index 000000000..7cab9daf2 --- /dev/null +++ b/ApiExtractor/tests/testmodifydocumentation.cpp @@ -0,0 +1,75 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testmodifydocumentation.h" + +#include <QCoreApplication> +#include <QtTest/QTest> +#include "testutil.h" +#include <qtdocparser.h> + +void TestModifyDocumentation::testModifyDocumentation() +{ + const char* cppCode ="struct B { void b(); }; class A {};"; + const char* xmlCode = "<typesystem package=\"Foo\">\ + <value-type name='B'>\ + <modify-function signature='b()' remove='all' />\ + </value-type>\ + <value-type name='A'>\ + <modify-documentation xpath='description/para[3]'>\ + <para>Some changed contents here</para>\ + </modify-documentation>\ + </value-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + + AbstractMetaClass* classA = t.builder()->classes().findClass("A"); + QVERIFY(classA); + DocModificationList docMods = classA->typeEntry()->docModifications(); + QCOMPARE(docMods.count(), 1); + QCOMPARE(docMods[0].code().trimmed(), QString("<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(), QString("<?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); +} + +#include "testmodifydocumentation.moc" diff --git a/ApiExtractor/tests/testmodifydocumentation.h b/ApiExtractor/tests/testmodifydocumentation.h new file mode 100644 index 000000000..14bb0c69d --- /dev/null +++ b/ApiExtractor/tests/testmodifydocumentation.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTMODIFYDOCUMENTATION_H +#define TESTMODIFYDOCUMENTATION_H + +#include <QObject> + +class TestModifyDocumentation : public QObject +{ +Q_OBJECT +private slots: + void testModifyDocumentation(); +}; + +#endif diff --git a/ApiExtractor/tests/testmodifyfunction.cpp b/ApiExtractor/tests/testmodifyfunction.cpp new file mode 100644 index 000000000..93dae7536 --- /dev/null +++ b/ApiExtractor/tests/testmodifyfunction.cpp @@ -0,0 +1,244 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testmodifyfunction.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestModifyFunction::testRenameArgument() +{ + const char* cppCode ="\ + struct A {\ + void method(int=0);\ + };\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <primitive-type name='int'/>\ + <object-type name='A'> \ + <modify-function signature='method(int)'>\ + <modify-argument index='1'>\ + <rename to='otherArg' />\ + </modify-argument>\ + </modify-function>\ + </object-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + const AbstractMetaFunction* func = classA->findFunction("method"); + Q_ASSERT(func); + + QCOMPARE(func->argumentName(1), QString("otherArg")); +} + +void TestModifyFunction::testOwnershipTransfer() +{ + const char* cppCode ="\ + struct A {};\ + struct B {\ + virtual A* method();\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <object-type name='A' /> \ + <object-type name='B'> \ + <modify-function signature='method()'>\ + <modify-argument index='return'>\ + <define-ownership owner='c++' /> \ + </modify-argument>\ + </modify-function>\ + </object-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classB = classes.findClass("B"); + const AbstractMetaFunction* func = classB->findFunction("method"); + + QCOMPARE(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0), TypeSystem::CppOwnership); +} + + +void TestModifyFunction::invalidateAfterUse() +{ + const char* cppCode ="\ + struct A {\ + virtual void call(int *a);\ + };\ + struct B : A {\ + };\ + struct C : B {\ + virtual void call2(int *a);\ + };\ + struct D : C {\ + virtual void call2(int *a);\ + };\ + struct E : D {\ + };\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <primitive-type name='int'/>\ + <object-type name='A'> \ + <modify-function signature='call(int*)'>\ + <modify-argument index='1' invalidate-after-use='true'/>\ + </modify-function>\ + </object-type>\ + <object-type name='B' /> \ + <object-type name='C'> \ + <modify-function signature='call2(int*)'>\ + <modify-argument index='1' invalidate-after-use='true'/>\ + </modify-function>\ + </object-type>\ + <object-type name='D'> \ + <modify-function signature='call2(int*)'>\ + <modify-argument index='1' invalidate-after-use='true'/>\ + </modify-function>\ + </object-type>\ + <object-type name='E' /> \ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false, "0.1"); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classB = classes.findClass("B"); + const AbstractMetaFunction* func = classB->findFunction("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); + + AbstractMetaClass* classC = classes.findClass("C"); + QVERIFY(classC); + func = classC->findFunction("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("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); + + AbstractMetaClass* classD = classes.findClass("D"); + QVERIFY(classD); + func = classD->findFunction("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("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); + + AbstractMetaClass* classE = classes.findClass("E"); + QVERIFY(classE); + func = classE->findFunction("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("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 {};\ + struct B {\ + virtual A* method();\ + virtual B* methodB();\ + };\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <object-type name='A' /> \ + <object-type name='B'> \ + <modify-function signature='method()' since='0.1'>\ + <modify-argument index='return'>\ + <define-ownership owner='c++' /> \ + </modify-argument>\ + </modify-function>\ + <modify-function signature='methodB()' since='0.2'>\ + <modify-argument index='return'>\ + <define-ownership owner='c++' /> \ + </modify-argument>\ + </modify-function>\ + </object-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false, "0.1"); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classB = classes.findClass("B"); + const AbstractMetaFunction* func = classB->findFunction("method"); + + QCOMPARE(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0), TypeSystem::CppOwnership); + + func = classB->findFunction("methodB"); + QVERIFY(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0) != TypeSystem::CppOwnership); +} + +void TestModifyFunction::testGlobalFunctionModification() +{ + const char* cppCode ="\ + struct A {};\ + void function(A* a = 0);\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <primitive-type name='A'/>\ + <function signature='function(A*)'>\ + <modify-function signature='function(A*)'>\ + <modify-argument index='1'>\ + <replace-type modified-type='A'/>\ + <replace-default-expression with='A()'/>\ + </modify-argument>\ + </modify-function>\ + </function>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + QCOMPARE(t.builder()->globalFunctions().size(), 1); + + FunctionModificationList mods = TypeDatabase::instance()->functionModifications("function(A*)"); + QCOMPARE(mods.count(), 1); + QList<ArgumentModification> argMods = mods.first().argument_mods; + QCOMPARE(argMods.count(), 1); + ArgumentModification argMod = argMods.first(); + QCOMPARE(argMod.replacedDefaultExpression, QString("A()")); + + const AbstractMetaFunction* func = t.builder()->globalFunctions().first(); + QVERIFY(func); + QCOMPARE(func->arguments().count(), 1); + const AbstractMetaArgument* arg = func->arguments().first(); + QCOMPARE(arg->type()->cppSignature(), QString("A *")); + QCOMPARE(arg->originalDefaultValueExpression(), QString("0")); + QCOMPARE(arg->defaultValueExpression(), QString("A()")); +} + +QTEST_APPLESS_MAIN(TestModifyFunction) + +#include "testmodifyfunction.moc" diff --git a/ApiExtractor/tests/testmodifyfunction.h b/ApiExtractor/tests/testmodifyfunction.h new file mode 100644 index 000000000..d72a41ddc --- /dev/null +++ b/ApiExtractor/tests/testmodifyfunction.h @@ -0,0 +1,40 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/testmultipleinheritance.cpp b/ApiExtractor/tests/testmultipleinheritance.cpp new file mode 100644 index 000000000..5464fc446 --- /dev/null +++ b/ApiExtractor/tests/testmultipleinheritance.cpp @@ -0,0 +1,69 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testmultipleinheritance.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestMultipleInheritance::testVirtualClass() +{ + const char* cppCode ="\ + struct A {\ + virtual ~A();\ + virtual void theBug();\ + };\ + struct B {\ + virtual ~B();\ + };\ + struct C : A, B {\ + };\ + struct D : C {\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <object-type name='A' /> \ + <object-type name='B' /> \ + <object-type name='C' /> \ + <object-type name='D' /> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 4); + + AbstractMetaClass* classD = classes.findClass("D"); + bool functionFound = false; + foreach (AbstractMetaFunction* f, classD->functions()) { + if (f->name() == "theBug") { + functionFound = true; + break; + } + } + QVERIFY(functionFound); + +} + +QTEST_APPLESS_MAIN(TestMultipleInheritance) + +#include "testmultipleinheritance.moc" diff --git a/ApiExtractor/tests/testmultipleinheritance.h b/ApiExtractor/tests/testmultipleinheritance.h new file mode 100644 index 000000000..3a1bd388d --- /dev/null +++ b/ApiExtractor/tests/testmultipleinheritance.h @@ -0,0 +1,38 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTMULTIPLEINHERITANCE_H +#define TESTMULTIPLEINHERITANCE_H + +#include <QObject> + +class AbstractMetaBuilder; + +class TestMultipleInheritance : public QObject +{ + Q_OBJECT + private slots: + void testVirtualClass(); +}; + +#endif diff --git a/ApiExtractor/tests/testnamespace.cpp b/ApiExtractor/tests/testnamespace.cpp new file mode 100644 index 000000000..7fc457db0 --- /dev/null +++ b/ApiExtractor/tests/testnamespace.cpp @@ -0,0 +1,89 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testnamespace.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestNamespace::testNamespaceMembers() +{ + const char* cppCode = "\ + namespace Namespace\ + {\ + enum Option {\ + OpZero,\ + OpOne\ + };\ + void foo(Option opt);\ + };"; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <namespace-type name='Namespace'>\ + <enum-type name='Option' /> \ + </namespace-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* ns = classes.findClass("Namespace"); + QVERIFY(ns); + const AbstractMetaEnum* metaEnum = ns->findEnum("Option"); + QVERIFY(metaEnum); + const AbstractMetaFunction* func = ns->findFunction("foo"); + QVERIFY(func); +} + +void TestNamespace::testNamespaceInnerClassMembers() +{ + const char* cppCode = "\ + namespace OuterNamespace\ + {\ + namespace InnerNamespace {\ + struct SomeClass {\ + void method();\ + };\ + };\ + };"; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <namespace-type name='OuterNamespace'>\ + <namespace-type name='InnerNamespace'>\ + <value-type name='SomeClass' /> \ + </namespace-type>\ + </namespace-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* ons = classes.findClass("OuterNamespace"); + QVERIFY(ons); + AbstractMetaClass* ins = classes.findClass("OuterNamespace::InnerNamespace"); + QVERIFY(ins); + AbstractMetaClass* sc = classes.findClass("OuterNamespace::InnerNamespace::SomeClass"); + QVERIFY(sc); + const AbstractMetaFunction* meth = sc->findFunction("method"); + QVERIFY(meth); +} + +QTEST_APPLESS_MAIN(TestNamespace) + +#include "testnamespace.moc" + diff --git a/ApiExtractor/tests/testnamespace.h b/ApiExtractor/tests/testnamespace.h new file mode 100644 index 000000000..77f24eb9b --- /dev/null +++ b/ApiExtractor/tests/testnamespace.h @@ -0,0 +1,37 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTNAMESPACE_H +#define TESTNAMESPACE_H + +#include <QObject> + +class TestNamespace : public QObject +{ + Q_OBJECT + private slots: + void testNamespaceMembers(); + void testNamespaceInnerClassMembers(); +}; + +#endif diff --git a/ApiExtractor/tests/testnestedtypes.cpp b/ApiExtractor/tests/testnestedtypes.cpp new file mode 100644 index 000000000..83512f7db --- /dev/null +++ b/ApiExtractor/tests/testnestedtypes.cpp @@ -0,0 +1,122 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testnestedtypes.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestNestedTypes::testNestedTypesModifications() +{ + const char* cppCode ="\ + namespace OuterNamespace {\ + namespace InnerNamespace {\ + struct SomeClass {\ + void method() {}\ + };\ + };\ + };\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <namespace-type name='OuterNamespace'>\ + <namespace-type name='InnerNamespace'>\ + <inject-code class='native'>custom_code1();</inject-code>\ + <add-function signature='method()' return-type='OuterNamespace::InnerNamespace::SomeClass'>\ + <inject-code class='target'>custom_code2();</inject-code>\ + </add-function>\ + <object-type name='SomeClass' target-lang-name='RenamedSomeClass'>\ + <modify-function signature='method()' remove='all'/>\ + </object-type>\ + </namespace-type>\ + </namespace-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + + AbstractMetaClass* ons = classes.findClass("OuterNamespace"); + QVERIFY(ons); + + AbstractMetaClass* ins = classes.findClass("OuterNamespace::InnerNamespace"); + QVERIFY(ins); + QCOMPARE(ins->functions().count(), 1); + QCOMPARE(ins->typeEntry()->codeSnips().count(), 1); + CodeSnip snip = ins->typeEntry()->codeSnips().first(); + QCOMPARE(snip.code(), QString("custom_code1();")); + + AbstractMetaFunction* addedFunc = ins->functions().first(); + QVERIFY(addedFunc->isUserAdded()); + QCOMPARE(addedFunc->visibility(), uint(AbstractMetaFunction::Public)); + QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction); + QCOMPARE(addedFunc->type()->minimalSignature(), QString("OuterNamespace::InnerNamespace::SomeClass")); + + QCOMPARE(addedFunc->modifications().size(), 1); + QVERIFY(addedFunc->modifications().first().isCodeInjection()); + snip = addedFunc->modifications().first().snips.first(); + QCOMPARE(snip.code(), QString("custom_code2();")); + + AbstractMetaClass* sc = classes.findClass("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 {\ + class SomeClass {};\ + };"; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <namespace-type name='Namespace'>\ + <value-type name='SomeClass'>\ + <add-function signature='createSomeClass(Namespace::SomeClass)'/>\ + </value-type>\ + </namespace-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 2); + AbstractMetaClass* nspace = classes.findClass("Namespace"); + QVERIFY(nspace); + AbstractMetaClass* cls1 = classes.findClass("SomeClass"); + QVERIFY(cls1); + AbstractMetaClass* cls2 = classes.findClass("Namespace::SomeClass"); + QVERIFY(cls2); + QCOMPARE(cls1, cls2); + QCOMPARE(cls1->name(), QString("SomeClass")); + QCOMPARE(cls1->qualifiedCppName(), QString("Namespace::SomeClass")); + + TypeEntry* t1 = TypeDatabase::instance()->findType("Namespace::SomeClass"); + QVERIFY(t1); + TypeEntry* t2 = TypeDatabase::instance()->findType("SomeClass"); + QVERIFY(!t2); +} + +QTEST_APPLESS_MAIN(TestNestedTypes) + +#include "testnestedtypes.moc" diff --git a/ApiExtractor/tests/testnestedtypes.h b/ApiExtractor/tests/testnestedtypes.h new file mode 100644 index 000000000..d0b828b0c --- /dev/null +++ b/ApiExtractor/tests/testnestedtypes.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTNESTEDTYPES_H +#define TESTNESTEDTYPES_H +#include <QObject> + +class TestNestedTypes : public QObject +{ + Q_OBJECT +private slots: + void testNestedTypesModifications(); + void testDuplicationOfNestedTypes(); +}; + +#endif diff --git a/ApiExtractor/tests/testnumericaltypedef.cpp b/ApiExtractor/tests/testnumericaltypedef.cpp new file mode 100644 index 000000000..e48796726 --- /dev/null +++ b/ApiExtractor/tests/testnumericaltypedef.cpp @@ -0,0 +1,113 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testnumericaltypedef.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestNumericalTypedef::testNumericalTypedef() +{ + const char* cppCode ="\ + typedef double real;\ + void funcDouble(double);\ + void funcReal(real);\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <primitive-type name='double' /> \ + <primitive-type name='real' /> \ + <function signature='funcDouble(double)' />\ + <function signature='funcReal(real)' />\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + + QCOMPARE(t.builder()->globalFunctions().size(), 2); + const AbstractMetaFunction* funcDouble = t.builder()->globalFunctions().first(); + QVERIFY(funcDouble); + const AbstractMetaFunction* funcReal = t.builder()->globalFunctions().last(); + QVERIFY(funcReal); + + if (funcDouble->name() == "funcReal") + std::swap(funcDouble, funcReal); + + QCOMPARE(funcDouble->minimalSignature(), QString("funcDouble(double)")); + QCOMPARE(funcReal->minimalSignature(), QString("funcReal(real)")); + + const AbstractMetaType* doubleType = funcDouble->arguments().first()->type(); + QVERIFY(doubleType); + QCOMPARE(doubleType->cppSignature(), QString("double")); + QVERIFY(doubleType->isPrimitive()); + QVERIFY(doubleType->typeEntry()->isCppPrimitive()); + + const AbstractMetaType* realType = funcReal->arguments().first()->type(); + QVERIFY(realType); + QCOMPARE(realType->cppSignature(), QString("real")); + QVERIFY(realType->isPrimitive()); + QVERIFY(realType->typeEntry()->isCppPrimitive()); +} + +void TestNumericalTypedef::testUnsignedNumericalTypedef() +{ + const char* cppCode ="\ + typedef unsigned short ushort;\ + void funcUnsignedShort(unsigned short);\ + void funcUShort(ushort);\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <primitive-type name='short' /> \ + <primitive-type name='unsigned short' /> \ + <primitive-type name='ushort' /> \ + <function signature='funcUnsignedShort(unsigned short)' />\ + <function signature='funcUShort(ushort)' />\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + + QCOMPARE(t.builder()->globalFunctions().size(), 2); + const AbstractMetaFunction* funcUnsignedShort = t.builder()->globalFunctions().first(); + QVERIFY(funcUnsignedShort); + const AbstractMetaFunction* funcUShort = t.builder()->globalFunctions().last(); + QVERIFY(funcUShort); + + if (funcUnsignedShort->name() == "funcUShort") + std::swap(funcUnsignedShort, funcUShort); + + QCOMPARE(funcUnsignedShort->minimalSignature(), QString("funcUnsignedShort(unsigned short)")); + QCOMPARE(funcUShort->minimalSignature(), QString("funcUShort(ushort)")); + + const AbstractMetaType* unsignedShortType = funcUnsignedShort->arguments().first()->type(); + QVERIFY(unsignedShortType); + QCOMPARE(unsignedShortType->cppSignature(), QString("unsigned short")); + QVERIFY(unsignedShortType->isPrimitive()); + QVERIFY(unsignedShortType->typeEntry()->isCppPrimitive()); + + const AbstractMetaType* ushortType = funcUShort->arguments().first()->type(); + QVERIFY(ushortType); + QCOMPARE(ushortType->cppSignature(), QString("ushort")); + QVERIFY(ushortType->isPrimitive()); + QVERIFY(ushortType->typeEntry()->isCppPrimitive()); +} + +QTEST_APPLESS_MAIN(TestNumericalTypedef) + +#include "testnumericaltypedef.moc" diff --git a/ApiExtractor/tests/testnumericaltypedef.h b/ApiExtractor/tests/testnumericaltypedef.h new file mode 100644 index 000000000..a1d1bbe59 --- /dev/null +++ b/ApiExtractor/tests/testnumericaltypedef.h @@ -0,0 +1,37 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTNUMERICALTYPEDEF_H +#define TESTNUMERICALTYPEDEF_H + +#include <QObject> + +class TestNumericalTypedef : public QObject +{ + Q_OBJECT + private slots: + void testNumericalTypedef(); + void testUnsignedNumericalTypedef(); +}; + +#endif diff --git a/ApiExtractor/tests/testprimitivetypetag.cpp b/ApiExtractor/tests/testprimitivetypetag.cpp new file mode 100644 index 000000000..ebd245bf9 --- /dev/null +++ b/ApiExtractor/tests/testprimitivetypetag.cpp @@ -0,0 +1,55 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testprimitivetypetag.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestPrimitiveTypeTag::testPrimitiveTypeDefaultConstructor() +{ + const char* cppCode ="\ + struct A {};\ + struct B {};\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <primitive-type name='A' default-constructor='A()'/> \ + <object-type name='B' /> \ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 1); + AbstractMetaClass* classB = classes.findClass("B"); + QVERIFY(classB); + + PrimitiveTypeEntry* typeEntry = TypeDatabase::instance()->findPrimitiveType("A"); + QVERIFY(typeEntry); + QVERIFY(typeEntry->hasDefaultConstructor()); + QCOMPARE(typeEntry->defaultConstructor(), QString("A()")); +} + +QTEST_APPLESS_MAIN(TestPrimitiveTypeTag) + +#include "testprimitivetypetag.moc" + diff --git a/ApiExtractor/tests/testprimitivetypetag.h b/ApiExtractor/tests/testprimitivetypetag.h new file mode 100644 index 000000000..676174ddd --- /dev/null +++ b/ApiExtractor/tests/testprimitivetypetag.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTPRIMITIVETYPETAG_H +#define TESTPRIMITIVETYPETAG_H + +#include <QObject> + +class TestPrimitiveTypeTag : public QObject +{ + Q_OBJECT + private slots: + void testPrimitiveTypeDefaultConstructor(); +}; + +#endif diff --git a/ApiExtractor/tests/testrefcounttag.cpp b/ApiExtractor/tests/testrefcounttag.cpp new file mode 100644 index 000000000..9e05cee93 --- /dev/null +++ b/ApiExtractor/tests/testrefcounttag.cpp @@ -0,0 +1,94 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testrefcounttag.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestRefCountTag::testReferenceCountTag() +{ + const char* cppCode ="\ + struct A {};\ + struct B {\ + void keepObject(B* b);\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <object-type name='A' /> \ + <object-type name='B'> \ + <modify-function signature='keepObject(B*)'>\ + <modify-argument index='1'>\ + <reference-count action='add' /> \ + </modify-argument>\ + </modify-function>\ + </object-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classB = classes.findClass("B"); + const AbstractMetaFunction* func = classB->findFunction("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 {};\ + struct B {\ + void keepObject(B*, B*);\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <object-type name='A' /> \ + <object-type name='B'> \ + <modify-function signature='keepObject(B*, B*)'>\ + <modify-argument index='1' since='0.1'>\ + <reference-count action='add' /> \ + </modify-argument>\ + <modify-argument index='2' since='0.2'>\ + <reference-count action='add' /> \ + </modify-argument>\ + </modify-function>\ + </object-type>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false, "0.1"); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classB = classes.findClass("B"); + const AbstractMetaFunction* func = classB->findFunction("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) + +#include "testrefcounttag.moc" + diff --git a/ApiExtractor/tests/testrefcounttag.h b/ApiExtractor/tests/testrefcounttag.h new file mode 100644 index 000000000..1fcdd3dfb --- /dev/null +++ b/ApiExtractor/tests/testrefcounttag.h @@ -0,0 +1,37 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTREFCOUNTTAG_H +#define TESTREFCOUNTTAG_H + +#include <QObject> + +class TestRefCountTag : public QObject +{ + Q_OBJECT + private slots: + void testReferenceCountTag(); + void testWithApiVersion(); +}; + +#endif diff --git a/ApiExtractor/tests/testreferencetopointer.cpp b/ApiExtractor/tests/testreferencetopointer.cpp new file mode 100644 index 000000000..cd4b63b0a --- /dev/null +++ b/ApiExtractor/tests/testreferencetopointer.cpp @@ -0,0 +1,53 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testreferencetopointer.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestReferenceToPointer::testReferenceToPointerArgument() +{ + const char* cppCode ="\ + struct A {};\ + struct B {\ + void dummy(A*&);\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <object-type name='A' /> \ + <object-type name='B' /> \ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classB = classes.findClass("B"); + QVERIFY(classB); + const AbstractMetaFunction* func = classB->findFunction("dummy"); + QVERIFY(func); + QCOMPARE(func->arguments().first()->type()->minimalSignature(), QString("A*&")); +} + +QTEST_APPLESS_MAIN(TestReferenceToPointer) + +#include "testreferencetopointer.moc" + diff --git a/ApiExtractor/tests/testreferencetopointer.h b/ApiExtractor/tests/testreferencetopointer.h new file mode 100644 index 000000000..b682285b5 --- /dev/null +++ b/ApiExtractor/tests/testreferencetopointer.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTREFERENCETOPOINTER_H +#define TESTREFERENCETOPOINTER_H + +#include <QObject> + +class TestReferenceToPointer : public QObject +{ + Q_OBJECT + private slots: + void testReferenceToPointerArgument(); +}; + +#endif diff --git a/ApiExtractor/tests/testremovefield.cpp b/ApiExtractor/tests/testremovefield.cpp new file mode 100644 index 000000000..1b1ae9c6a --- /dev/null +++ b/ApiExtractor/tests/testremovefield.cpp @@ -0,0 +1,56 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testremovefield.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestRemoveField::testRemoveField() +{ + const char* cppCode ="\ + struct A {\ + int fieldA;\ + int fieldB;\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <primitive-type name='int' />\ + <value-type name='A'> \ + <modify-field name='fieldB' remove='all' />\ + </value-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + QCOMPARE(classA->fields().size(), 1); + const AbstractMetaField* fieldA = classA->fields().first(); + QVERIFY(fieldA); + QCOMPARE(fieldA->name(), QString("fieldA")); +} + +QTEST_APPLESS_MAIN(TestRemoveField) + +#include "testremovefield.moc" + diff --git a/ApiExtractor/tests/testremovefield.h b/ApiExtractor/tests/testremovefield.h new file mode 100644 index 000000000..301150c6f --- /dev/null +++ b/ApiExtractor/tests/testremovefield.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTREMOVEFIELD_H +#define TESTREMOVEFIELD_H + +#include <QObject> + +class TestRemoveField : public QObject +{ + Q_OBJECT + private slots: + void testRemoveField(); +}; + +#endif diff --git a/ApiExtractor/tests/testremoveimplconv.cpp b/ApiExtractor/tests/testremoveimplconv.cpp new file mode 100644 index 000000000..48c7640d2 --- /dev/null +++ b/ApiExtractor/tests/testremoveimplconv.cpp @@ -0,0 +1,64 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testremoveimplconv.h" +#include "testutil.h" +#include <QtTest/QTest> + +// 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 {};\ + struct B {};\ + struct C {\ + C(const A&);\ + C(const B&);\ + };\ + "; + const char* xmlCode = "\ + <typesystem package=\"Foo\"> \ + <value-type name='A' /> \ + <value-type name='B' /> \ + <value-type name='C'> \ + <modify-function signature='C(const A&)' remove='all' />\ + </value-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 3); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + AbstractMetaClass* classB = classes.findClass("B"); + QVERIFY(classB); + AbstractMetaClass* classC = classes.findClass("C"); + QVERIFY(classC); + AbstractMetaFunctionList implConv = classC->implicitConversions(); + QCOMPARE(implConv.count(), 1); + QCOMPARE(implConv.first()->arguments().first()->type()->typeEntry(), classB->typeEntry()); +} + +QTEST_APPLESS_MAIN(TestRemoveImplConv) + +#include "testremoveimplconv.moc" diff --git a/ApiExtractor/tests/testremoveimplconv.h b/ApiExtractor/tests/testremoveimplconv.h new file mode 100644 index 000000000..bacc2a250 --- /dev/null +++ b/ApiExtractor/tests/testremoveimplconv.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTREMOVEIMPLCONV_H +#define TESTREMOVEIMPLCONV_H + +#include <QObject> + +class TestRemoveImplConv : public QObject +{ +Q_OBJECT +private slots: + void testRemoveImplConv(); +}; + +#endif // TESTREMOVEIMPLCONV_H diff --git a/ApiExtractor/tests/testremoveoperatormethod.cpp b/ApiExtractor/tests/testremoveoperatormethod.cpp new file mode 100644 index 000000000..35caea788 --- /dev/null +++ b/ApiExtractor/tests/testremoveoperatormethod.cpp @@ -0,0 +1,115 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testremoveoperatormethod.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestRemoveOperatorMethod::testRemoveOperatorMethod() +{ + const char* cppCode ="\ + struct A {\ + A& operator>>(char&);\ + A& operator>>(char*);\ + A& operator>>(signed short&);\ + A& operator>>(unsigned short&);\ + A& operator>>(signed int&);\ + A& operator>>(unsigned int&);\ + A& operator>>(signed long&);\ + A& operator>>(unsigned long&);\ + A& operator>>(__int64&);\ + A& operator>>(unsigned __int64&);\ + A& operator>>(float&);\ + A& operator>>(double&);\ + A& operator>>(Char&);\ + A& operator>>(ByteArray&);\ + A& operator>>(String&);\ + };\ + struct Char {};\ + struct ByteArray {};\ + struct String {};\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <primitive-type name='char' />\ + <primitive-type name='signed short' />\ + <primitive-type name='unsigned short' />\ + <primitive-type name='signed int' />\ + <primitive-type name='unsigned int' />\ + <primitive-type name='signed long' />\ + <primitive-type name='unsigned long' />\ + <primitive-type name='__int64' />\ + <primitive-type name='unsigned __int64' />\ + <primitive-type name='float' />\ + <primitive-type name='double' />\ + <primitive-type name='Char' />\ + <primitive-type name='String' />\ + <value-type name='ByteArray' />\ + <object-type name='A'>\ + <modify-function signature='operator>>(char&)' remove='all'/>\ + <modify-function signature='operator>>(char*)' remove='all'/>\ + <modify-function signature='operator>>(signed short&)' remove='all'/>\ + <modify-function signature='operator>>(unsigned short&)' remove='all'/>\ + <modify-function signature='operator>>(signed int&)' remove='all'/>\ + <modify-function signature='operator>>(unsigned int&)' remove='all'/>\ + <modify-function signature='operator>>(signed long&)' remove='all'/>\ + <modify-function signature='operator>>(unsigned long&)' remove='all'/>\ + <modify-function signature='operator>>(__int64&)' remove='all'/>\ + <modify-function signature='operator>>(unsigned __int64&)' remove='all'/>\ + <modify-function signature='operator>>(float&)' remove='all'/>\ + <modify-function signature='operator>>(double&)' remove='all'/>\ + <modify-function signature='operator>>(Char&)' remove='all'/>\ + <modify-function signature='operator>>(String&)' remove='all'/>\ + </object-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + QCOMPARE(classA->functions().size(), 15); + QStringList removedSignatures; + removedSignatures.append("operator>>(char&)"); + removedSignatures.append("operator>>(char*)"); + removedSignatures.append("operator>>(signed short&)"); + removedSignatures.append("operator>>(unsigned short&)"); + removedSignatures.append("operator>>(signed int&)"); + removedSignatures.append("operator>>(unsigned int&)"); + removedSignatures.append("operator>>(signed long&)"); + removedSignatures.append("operator>>(unsigned long&)"); + removedSignatures.append("operator>>(__int64&)"); + removedSignatures.append("operator>>(unsigned __int64&)"); + removedSignatures.append("operator>>(float&)"); + removedSignatures.append("operator>>(double&)"); + removedSignatures.append("operator>>(Char&)"); + removedSignatures.append("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) + +#include "testremoveoperatormethod.moc" diff --git a/ApiExtractor/tests/testremoveoperatormethod.h b/ApiExtractor/tests/testremoveoperatormethod.h new file mode 100644 index 000000000..1833ff11c --- /dev/null +++ b/ApiExtractor/tests/testremoveoperatormethod.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTREMOVEOPERATORMETHOD_H +#define TESTREMOVEOPERATORMETHOD_H + +#include <QObject> + +class TestRemoveOperatorMethod : public QObject +{ + Q_OBJECT + private slots: + void testRemoveOperatorMethod(); +}; + +#endif diff --git a/ApiExtractor/tests/testresolvetype.cpp b/ApiExtractor/tests/testresolvetype.cpp new file mode 100644 index 000000000..11880e1b1 --- /dev/null +++ b/ApiExtractor/tests/testresolvetype.cpp @@ -0,0 +1,58 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testresolvetype.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestResolveType::testResolveReturnTypeFromParentScope() +{ + const char* cppCode = "\ + namespace A {\ + struct B {\ + struct C {};\ + };\ + struct D : public B::C {\ + C* foo = 0;\ + C* method();\ + };\ + };"; + const char* xmlCode = "\ + <typesystem package='Foo'> \ + <namespace-type name='A' />\ + <value-type name='A::B' /> \ + <value-type name='A::B::C' /> \ + <value-type name='A::D' /> \ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classD = classes.findClass("A::D"); + QVERIFY(classD); + const AbstractMetaFunction* meth = classD->findFunction("method"); + QVERIFY(meth); +} + +QTEST_APPLESS_MAIN(TestResolveType) + +#include "testresolvetype.moc" + diff --git a/ApiExtractor/tests/testresolvetype.h b/ApiExtractor/tests/testresolvetype.h new file mode 100644 index 000000000..8dc1c0a01 --- /dev/null +++ b/ApiExtractor/tests/testresolvetype.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTRESOLVETYPE_H +#define TESTRESOLVETYPE_H + +#include <QObject> + +class TestResolveType : public QObject +{ + Q_OBJECT + private slots: + void testResolveReturnTypeFromParentScope(); +}; + +#endif diff --git a/ApiExtractor/tests/testreverseoperators.cpp b/ApiExtractor/tests/testreverseoperators.cpp new file mode 100644 index 000000000..ab9cee0ff --- /dev/null +++ b/ApiExtractor/tests/testreverseoperators.cpp @@ -0,0 +1,130 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testreverseoperators.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestReverseOperators::testReverseSum() +{ + const char cppCode[] = "struct A {\ + A& operator+(int);\ + };\ + A& operator+(int, const A&);"; + const char xmlCode[] = "\ + <typesystem package=\"Foo\">\ + <primitive-type name='int' />\ + <value-type name='A' />\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("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() == "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[] = "\ + struct A { A operator+(int); };\ + A operator+(int, const A&);\ + struct B {};\ + B operator+(const A&, const B&);\ + B operator+(const B&, const A&);\ + int operator-(int, const A*);\ + int operator/(const A*, int);\ + "; + const char xmlCode[] = "\ + <typesystem package=\"Foo\">\ + <primitive-type name='int' />\ + <value-type name='A' />\ + <value-type name='B' />\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + QCOMPARE(classA->functions().count(), 6); + + AbstractMetaClass* classB = classes.findClass("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() == "operator+") { + if (func->isReverseOperator()) + reverseOp = func; + else + normalOp = func; + } + } + QVERIFY(normalOp); + QVERIFY(!normalOp->isReverseOperator()); + QCOMPARE(normalOp->arguments().count(), 1); + QCOMPARE(normalOp->minimalSignature(), QString("operator+(B,A)")); + QVERIFY(reverseOp); + QVERIFY(reverseOp->isReverseOperator()); + QCOMPARE(reverseOp->arguments().count(), 1); + QCOMPARE(reverseOp->minimalSignature(), QString("operator+(A,B)")); + + reverseOp = classA->findFunction("operator-"); + QVERIFY(reverseOp); + QCOMPARE(reverseOp->arguments().count(), 1); + QVERIFY(reverseOp->isPointerOperator()); + QVERIFY(reverseOp->isReverseOperator()); + + normalOp = classA->findFunction("operator/"); + QVERIFY(normalOp); + QCOMPARE(normalOp->arguments().count(), 1); + QVERIFY(normalOp->isPointerOperator()); + QVERIFY(!normalOp->isReverseOperator()); + +} + + + +QTEST_APPLESS_MAIN(TestReverseOperators) + +#include "testreverseoperators.moc" diff --git a/ApiExtractor/tests/testreverseoperators.h b/ApiExtractor/tests/testreverseoperators.h new file mode 100644 index 000000000..d5bdd9a1c --- /dev/null +++ b/ApiExtractor/tests/testreverseoperators.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTREVERSEOPERATORS_H +#define TESTREVERSEOPERATORS_H +#include <QObject> + +class TestReverseOperators : public QObject +{ + Q_OBJECT +private slots: + void testReverseSum(); + void testReverseSumWithAmbiguity(); +}; + +#endif diff --git a/ApiExtractor/tests/testtemplates.cpp b/ApiExtractor/tests/testtemplates.cpp new file mode 100644 index 000000000..c6a65d888 --- /dev/null +++ b/ApiExtractor/tests/testtemplates.cpp @@ -0,0 +1,383 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testtemplates.h" +#include <QtTest/QTest> +#include <QTemporaryFile> +#include "testutil.h" + +void TestTemplates::testTemplateWithNamespace() +{ + const char cppCode[] = "\ + struct Url {\ + void name();\ + };\ + namespace Internet {\ + struct Url{};\ + struct Bookmarks {\ + QList<Url> list();\ + };\ + }"; + const char xmlCode0[] = "\ + <typesystem package='Pakcage.Network'>\ + <value-type name='Url' />\ + </typesystem>"; + + QTemporaryFile file; + QVERIFY(file.open()); + file.write(xmlCode0); + file.close(); + + QString xmlCode1 = QString("\ + <typesystem package='Package.Internet'>\ + <load-typesystem name='%1' generate='no'/>\ + <container-type name='QList' type='list'/> \ + <namespace-type name='Internet' generate='no' />\ + <value-type name='Internet::Url'/>\ + <value-type name='Internet::Bookmarks'/>\ + </typesystem>").arg(file.fileName()); + + TestUtil t(cppCode, qPrintable(xmlCode1), false); + AbstractMetaClassList classes = t.builder()->classes(); + + AbstractMetaClass* classB = classes.findClass("Bookmarks"); + QVERIFY(classB); + const AbstractMetaFunction* func = classB->findFunction("list"); + AbstractMetaType* funcType = func->type(); + QVERIFY(funcType); + QCOMPARE(funcType->cppSignature(), QString("QList<Internet::Url >")); +} + +void TestTemplates::testTemplateOnContainers() +{ + const char cppCode[] = "\ + struct Base {};\ + namespace Namespace {\ + enum SomeEnum { E1, E2 };\ + template<SomeEnum type> struct A {\ + A<type> foo(const QList<A<type> >& a);\ + };\ + typedef A<E1> B;\ + }\ + "; + const char xmlCode[] = "\ + <typesystem package=\"Package\">\ + <container-type name='QList' type='list'/> \ + <namespace-type name='Namespace' />\ + <enum-type name='Namespace::SomeEnum'/>\ + <object-type name='Base' />\ + <object-type name='Namespace::A' generate='no'/> \ + <object-type name='Namespace::B'/> \ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + + AbstractMetaClass* classB = classes.findClass("B"); + QVERIFY(!classB->baseClass()); + QVERIFY(classB->baseClassName().isNull()); + const AbstractMetaFunction* func = classB->findFunction("foo"); + AbstractMetaType* argType = func->arguments().first()->type(); + QCOMPARE(argType->instantiations().count(), 1); + QCOMPARE(argType->typeEntry()->qualifiedCppName(), QString("QList")); + + const AbstractMetaType* instance1 = argType->instantiations().first(); + QCOMPARE(instance1->instantiations().count(), 1); + QCOMPARE(instance1->typeEntry()->qualifiedCppName(), QString("Namespace::A")); + + const AbstractMetaType* instance2 = instance1->instantiations().first(); + QCOMPARE(instance2->instantiations().count(), 0); + QCOMPARE(instance2->typeEntry()->qualifiedCppName(), QString("Namespace::E1")); +} + +void TestTemplates::testTemplateValueAsArgument() +{ + const char cppCode[] = "\ + template<typename T> struct List() {};\ + void func(List<int> arg) {}\ + "; + + const char xmlCode[] = "\ + <typesystem package='Package'>\ + <primitive-type name='int' />\ + <container-type name='List' type='list' />\ + <function signature='func(List<int>)' />\ + </typesystem>\ + "; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaFunctionList globalFuncs = t.builder()->globalFunctions(); + QCOMPARE(globalFuncs.count(), 1); + + AbstractMetaFunction* func = globalFuncs.first(); + QCOMPARE(func->minimalSignature(), QString("func(List<int>)")); + QCOMPARE(func->arguments().first()->type()->cppSignature(), QString("List<int >")); +} + +void TestTemplates::testTemplatePointerAsArgument() +{ + const char cppCode[] = "\ + template<typename T> struct List() {};\ + void func(List<int>* arg) {}\ + "; + + const char xmlCode[] = "\ + <typesystem package='Package'>\ + <primitive-type name='int' />\ + <container-type name='List' type='list' />\ + <function signature='func(List<int>*)' />\ + </typesystem>\ + "; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaFunctionList globalFuncs = t.builder()->globalFunctions(); + QCOMPARE(globalFuncs.count(), 1); + + AbstractMetaFunction* func = globalFuncs.first(); + QCOMPARE(func->minimalSignature(), QString("func(List<int>*)")); + QCOMPARE(func->arguments().first()->type()->cppSignature(), QString("List<int > *")); +} + +void TestTemplates::testTemplateReferenceAsArgument() +{ + const char cppCode[] = "\ + template<typename T> struct List() {};\ + void func(List<int>& arg) {}\ + "; + + const char xmlCode[] = "\ + <typesystem package='Package'>\ + <primitive-type name='int' />\ + <container-type name='List' type='list' />\ + <function signature='func(List<int>&)' />\ + </typesystem>\ + "; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaFunctionList globalFuncs = t.builder()->globalFunctions(); + QCOMPARE(globalFuncs.count(), 1); + + AbstractMetaFunction* func = globalFuncs.first(); + QCOMPARE(func->minimalSignature(), QString("func(List<int>&)")); + QCOMPARE(func->arguments().first()->type()->cppSignature(), QString("List<int > &")); +} + +void TestTemplates::testInheritanceFromContainterTemplate() +{ + const char cppCode[] = "\ + template<typename T>\ + struct ListContainer {\ + inline void push_front(const T& t);\ + inline T& front();\ + };\ + struct FooBar {};\ + struct FooBars : public ListContainer<FooBar> {};\ + "; + + const char xmlCode[] = "\ + <typesystem package='Package'>\ + <container-type name='ListContainer' type='list' /> \ + <value-type name='FooBar' />\ + <value-type name='FooBars'>\ + <modify-function signature='push_front(FooBar)' remove='all' />\ + <modify-function signature='front()' remove='all' />\ + </value-type>\ + </typesystem>\ + "; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClassList templates = t.builder()->templates(); + QCOMPARE(classes.count(), 2); + QCOMPARE(templates.count(), 1); + + const AbstractMetaClass* foobars = classes.findClass("FooBars"); + QCOMPARE(foobars->functions().count(), 4); + + const AbstractMetaClass* lc = templates.first(); + QCOMPARE(lc->functions().count(), 2); +} + +void TestTemplates::testTemplateInheritanceMixedWithForwardDeclaration() +{ + const char cppCode[] = "\ + enum SomeEnum { E1, E2 };\ + template<SomeEnum type> struct Future;\ + template<SomeEnum type>\ + struct A {\ + A();\ + void method();\ + friend struct Future<type>;\ + };\ + typedef A<E1> B;\ + template<SomeEnum type> struct Future {};\ + "; + const char xmlCode[] = "\ + <typesystem package='Package'>\ + <enum-type name='SomeEnum' />\ + <value-type name='A' generate='no' />\ + <value-type name='B' />\ + <value-type name='Future' generate='no' />\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + + AbstractMetaClass* classB = classes.findClass("B"); + 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[] = "\ + namespace Namespace {\ + enum SomeEnum { E1, E2 };\ + template<SomeEnum type> struct Future;\ + template<SomeEnum type>\ + struct A {\ + A();\ + void method();\ + friend struct Future<type>;\ + };\ + typedef A<E1> B;\ + template<SomeEnum type> struct Future {};\ + };\ + "; + const char xmlCode[] = "\ + <typesystem package='Package'>\ + <namespace-type name='Namespace' />\ + <enum-type name='Namespace::SomeEnum' />\ + <value-type name='Namespace::A' generate='no' />\ + <value-type name='Namespace::B' />\ + <value-type name='Namespace::Future' generate='no' />\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + + AbstractMetaClass* classB = classes.findClass("Namespace::B"); + 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[] = "\ + namespace NSpace {\ + enum ClassType {\ + TypeOne\ + };\ + template<ClassType CLASS_TYPE>\ + struct BaseTemplateClass {\ + inline ClassType getClassType() const { CLASS_TYPE; }\ + };\ + typedef BaseTemplateClass<TypeOne> TypeOneClass;\ + }\ + "; + + const char xmlCode[] = "\ + <typesystem package='Package'>\ + <namespace-type name='NSpace'>\ + <enum-type name='ClassType'/>\ + <object-type name='BaseTemplateClass' generate='no'/>\ + <object-type name='TypeOneClass'/>\ + </namespace-type>\ + </typesystem>\ + "; + + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 3); + + const AbstractMetaClass* base = classes.findClass("BaseTemplateClass"); + QVERIFY(base); + const AbstractMetaClass* one = classes.findClass("TypeOneClass"); + QVERIFY(one); + QCOMPARE(one->templateBaseClass(), base); + QCOMPARE(one->functions().count(), base->functions().count()); + QVERIFY(one->isTypeAlias()); + const ComplexTypeEntry* oneType = one->typeEntry(); + const ComplexTypeEntry* baseType = base->typeEntry(); + QCOMPARE(oneType->baseContainerType(), baseType); + QCOMPARE(one->baseClassNames(), QStringList("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(), QString("NSpace::TypeOne")); +} + +void TestTemplates::testContainerTypeIncompleteArgument() +{ + const char* cppCode ="\ + template<typename T>\ + class Vector {\ + void method(const Vector& vector);\ + Vector otherMethod();\ + };\ + template <typename T>\ + void Vector<T>::method(const Vector<T>& vector) {}\ + Vector Vector<T>::otherMethod() { return Vector<T>(); }\ + typedef Vector<int> IntVector;\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <primitive-type name='int'/>\ + <container-type name='Vector' type='vector'/>\ + <value-type name='IntVector'/>\ + </typesystem>"; + + TestUtil t(cppCode, xmlCode, true); + AbstractMetaClassList classes = t.builder()->classes(); + QCOMPARE(classes.count(), 1); + + AbstractMetaClass* vector = classes.findClass("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("method"); + QVERIFY(method); + QCOMPARE(method->signature(), QString("method(const Vector<int > & vector)")); + + const AbstractMetaFunction* otherMethod = vector->findFunction("otherMethod"); + QVERIFY(otherMethod); + QCOMPARE(otherMethod->signature(), QString("otherMethod()")); + QVERIFY(otherMethod->type()); + QCOMPARE(otherMethod->type()->cppSignature(), QString("Vector<int >")); +} + +QTEST_APPLESS_MAIN(TestTemplates) + +#include "testtemplates.moc" diff --git a/ApiExtractor/tests/testtemplates.h b/ApiExtractor/tests/testtemplates.h new file mode 100644 index 000000000..578691169 --- /dev/null +++ b/ApiExtractor/tests/testtemplates.h @@ -0,0 +1,45 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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 testInheritanceFromContainterTemplate(); + void testTemplateInheritanceMixedWithForwardDeclaration(); + void testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration(); + void testTypedefOfInstantiationOfTemplateClass(); + void testContainerTypeIncompleteArgument(); +}; + +#endif diff --git a/ApiExtractor/tests/testtoposort.cpp b/ApiExtractor/tests/testtoposort.cpp new file mode 100644 index 000000000..d33786720 --- /dev/null +++ b/ApiExtractor/tests/testtoposort.cpp @@ -0,0 +1,65 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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) + +#include "testtoposort.moc" diff --git a/ApiExtractor/tests/testtoposort.h b/ApiExtractor/tests/testtoposort.h new file mode 100644 index 000000000..ad6447abd --- /dev/null +++ b/ApiExtractor/tests/testtoposort.h @@ -0,0 +1,37 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTTOPOSORT_H +#define TESTTOPOSORT_H + +#include <QObject> + +class TestTopoSort : public QObject +{ +Q_OBJECT +private slots: + void testTopoSort(); + void testCiclicGraph(); +}; + +#endif diff --git a/ApiExtractor/tests/testtyperevision.cpp b/ApiExtractor/tests/testtyperevision.cpp new file mode 100644 index 000000000..6fadfa9fa --- /dev/null +++ b/ApiExtractor/tests/testtyperevision.cpp @@ -0,0 +1,64 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ + +#include "testtyperevision.h" +#include <QtTest/QTest> +#include "testutil.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>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* rev0 = classes.findClass("Rev_0"); + QCOMPARE(getTypeRevision(rev0->typeEntry()), 0); + + AbstractMetaClass* rev1 = classes.findClass("Rev_1"); + QCOMPARE(getTypeRevision(rev1->typeEntry()), 1); + + AbstractMetaClass* rev2 = classes.findClass("Rev_2"); + QCOMPARE(getTypeRevision(rev2->typeEntry()), 2); + + AbstractMetaEnum* rev3 = rev2->findEnum("Rev_3"); + QCOMPARE(getTypeRevision(rev3->typeEntry()), 3); + FlagsTypeEntry* rev4 = rev3->typeEntry()->flags(); + QCOMPARE(getTypeRevision(rev4), 4); + AbstractMetaEnum* rev5 = rev2->findEnum("Rev_5"); + QCOMPARE(getTypeRevision(rev5->typeEntry()), 5); + QCOMPARE(getTypeRevision(rev5->typeEntry()->flags()), 5); +} + +QTEST_APPLESS_MAIN(TestTypeRevision) + +#include "testtyperevision.moc" + diff --git a/ApiExtractor/tests/testtyperevision.h b/ApiExtractor/tests/testtyperevision.h new file mode 100644 index 000000000..24e94739f --- /dev/null +++ b/ApiExtractor/tests/testtyperevision.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ + +#ifndef TESTTYPEREVISION_H +#define TESTTYPEREVISION_H + +#include <QObject> + +class TestTypeRevision : public QObject +{ + Q_OBJECT + +private slots: + void testRevisionAttr(); +}; + +#endif diff --git a/ApiExtractor/tests/testutil.h b/ApiExtractor/tests/testutil.h new file mode 100644 index 000000000..9519fb8b2 --- /dev/null +++ b/ApiExtractor/tests/testutil.h @@ -0,0 +1,72 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTUTIL_H +#define TESTUTIL_H +#include <QtCore/QBuffer> +#include "abstractmetabuilder.h" +#include "reporthandler.h" +#include "typedatabase.h" + +class TestUtil +{ +public: + TestUtil(const char* cppCode, const char* xmlCode, + bool silent = true, const char* apiVersion = 0, + QStringList dropTypeEntries = QStringList()) + : m_builder(0) + { + ReportHandler::setSilent(silent); + m_builder = new AbstractMetaBuilder; + TypeDatabase* td = TypeDatabase::instance(true); + if (apiVersion) + td->setApiVersion("*", apiVersion); + td->setDropTypeEntries(dropTypeEntries); + QBuffer buffer; + // parse typesystem + buffer.setData(xmlCode); + td->parseFile(&buffer); + buffer.close(); + // parse C++ code + buffer.setData(cppCode); + bool res = m_builder->build(&buffer); + Q_UNUSED(res); + Q_ASSERT(res); + } + + ~TestUtil() + { + delete m_builder; + m_builder = 0; + } + + AbstractMetaBuilder* builder() + { + return m_builder; + } + +private: + AbstractMetaBuilder* m_builder; +}; + +#endif diff --git a/ApiExtractor/tests/testvaluetypedefaultctortag.cpp b/ApiExtractor/tests/testvaluetypedefaultctortag.cpp new file mode 100644 index 000000000..e8f8d83ee --- /dev/null +++ b/ApiExtractor/tests/testvaluetypedefaultctortag.cpp @@ -0,0 +1,57 @@ +/* + * This file is part of the API Extractor project. + * + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team <contact@pyside.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "testvaluetypedefaultctortag.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestValueTypeDefaultCtorTag::testValueTypeDefaultCtorTagArgument() +{ + const char* cppCode ="\ + struct A {\ + A(int,int);\ + };\ + struct B {};\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <primitive-type name='int' />\ + <value-type name='A' default-constructor='A(0, 0)' />\ + <value-type name='B' />\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + QVERIFY(classA->typeEntry()->hasDefaultConstructor()); + QCOMPARE(classA->typeEntry()->defaultConstructor(), QString("A(0, 0)")); + + AbstractMetaClass* classB = classes.findClass("B"); + QVERIFY(classB); + QVERIFY(!classB->typeEntry()->hasDefaultConstructor()); +} + +QTEST_APPLESS_MAIN(TestValueTypeDefaultCtorTag) + +#include "testvaluetypedefaultctortag.moc" diff --git a/ApiExtractor/tests/testvaluetypedefaultctortag.h b/ApiExtractor/tests/testvaluetypedefaultctortag.h new file mode 100644 index 000000000..a271d5f8f --- /dev/null +++ b/ApiExtractor/tests/testvaluetypedefaultctortag.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTVALUETYPEDEFAULTCTORTAG_H +#define TESTVALUETYPEDEFAULTCTORTAG_H + +#include <QObject> + +class TestValueTypeDefaultCtorTag : public QObject +{ + Q_OBJECT + private slots: + void testValueTypeDefaultCtorTagArgument(); +}; + +#endif diff --git a/ApiExtractor/tests/testvoidarg.cpp b/ApiExtractor/tests/testvoidarg.cpp new file mode 100644 index 000000000..7f9256ad9 --- /dev/null +++ b/ApiExtractor/tests/testvoidarg.cpp @@ -0,0 +1,81 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2009,2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include "testvoidarg.h" +#include <QtTest/QTest> +#include "testutil.h" + + +void TestVoidArg::testVoidParsedFunction() +{ + const char cppCode[] = "struct A { void a(void); };"; + const char xmlCode[] = "\ + <typesystem package=\"Foo\">\ + <value-type name='A'/>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + const AbstractMetaFunction* addedFunc = classA->findFunction("a"); + QCOMPARE(addedFunc->arguments().count(), 0); +} + +void TestVoidArg::testVoidAddedFunction() +{ + const char cppCode[] = "struct A { };"; + const char xmlCode[] = "\ + <typesystem package=\"Foo\">\ + <value-type name='A' >\ + <add-function signature=\"a(void)\"/>\ + </value-type>\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + const AbstractMetaFunction* addedFunc = classA->findFunction("a"); + QCOMPARE(addedFunc->arguments().count(), 0); + +} + +void TestVoidArg::testVoidPointerParsedFunction() +{ + const char cppCode[] = "struct A { void a(void*); };"; + const char xmlCode[] = "\ + <typesystem package=\"Foo\">\ + <value-type name='A' />\ + </typesystem>"; + TestUtil t(cppCode, xmlCode); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + const AbstractMetaFunction* addedFunc = classA->findFunction("a"); + QCOMPARE(addedFunc->arguments().count(), 1); + +} + +QTEST_APPLESS_MAIN(TestVoidArg) + +#include "testvoidarg.moc" + diff --git a/ApiExtractor/tests/testvoidarg.h b/ApiExtractor/tests/testvoidarg.h new file mode 100644 index 000000000..589a3572d --- /dev/null +++ b/ApiExtractor/tests/testvoidarg.h @@ -0,0 +1,37 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#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/ApiExtractor/tests/utf8code.txt b/ApiExtractor/tests/utf8code.txt new file mode 100644 index 000000000..6d5fa9dcf --- /dev/null +++ b/ApiExtractor/tests/utf8code.txt @@ -0,0 +1 @@ +áéíóú
\ No newline at end of file |