diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2009-08-17 19:31:37 -0300 |
---|---|---|
committer | Marcelo Lira <marcelo.lira@openbossa.org> | 2009-08-17 19:31:37 -0300 |
commit | e0c29962e6f334452f0c9db2caaf6ed18065de85 (patch) | |
tree | cee27801c196fbcacf6130ad64216af133b555dd /tests/samplebinding |
The End Is the Beginning Is the End
Diffstat (limited to 'tests/samplebinding')
-rw-r--r-- | tests/samplebinding/CMakeLists.txt | 44 | ||||
-rwxr-xr-x | tests/samplebinding/abstract_test.py | 62 | ||||
-rw-r--r-- | tests/samplebinding/complex_conversions.h | 23 | ||||
-rwxr-xr-x | tests/samplebinding/complex_test.py | 42 | ||||
-rwxr-xr-x | tests/samplebinding/derived_test.py | 113 | ||||
-rwxr-xr-x | tests/samplebinding/enum_test.py | 36 | ||||
-rw-r--r-- | tests/samplebinding/global.h | 14 | ||||
-rwxr-xr-x | tests/samplebinding/implicitconv_test.py | 27 | ||||
-rw-r--r-- | tests/samplebinding/list_conversions.h | 29 | ||||
-rwxr-xr-x | tests/samplebinding/modifications_test.py | 115 | ||||
-rw-r--r-- | tests/samplebinding/pair_conversions.h | 25 | ||||
-rwxr-xr-x | tests/samplebinding/point_test.py | 42 | ||||
-rwxr-xr-x | tests/samplebinding/reference_test.py | 28 | ||||
-rwxr-xr-x | tests/samplebinding/sample_test.py | 37 | ||||
-rwxr-xr-x | tests/samplebinding/size_test.py | 83 | ||||
-rw-r--r-- | tests/samplebinding/typesystem_sample.xml | 216 |
16 files changed, 936 insertions, 0 deletions
diff --git a/tests/samplebinding/CMakeLists.txt b/tests/samplebinding/CMakeLists.txt new file mode 100644 index 000000000..e89d7d765 --- /dev/null +++ b/tests/samplebinding/CMakeLists.txt @@ -0,0 +1,44 @@ +project(sample) + +set(sample_TYPESYSTEM +${CMAKE_CURRENT_SOURCE_DIR}/typesystem_sample.xml +) + +set(sample_SRC +${CMAKE_CURRENT_BINARY_DIR}/sample/abstractmodifications_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/sample/abstract_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/sample/derived_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/sample/implicitconv_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/sample/listuser_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/sample/modifications_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/sample/pairuser_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/sample/point_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/sample/reference_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/sample/sample_module_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/sample/size_wrapper.cpp +) + +add_custom_command(OUTPUT ${sample_SRC} +COMMAND ${CMAKE_BINARY_DIR}/shiboken + ${CMAKE_CURRENT_SOURCE_DIR}/global.h + --include-paths=${libsample_SOURCE_DIR} + --typesystem-paths=${CMAKE_CURRENT_SOURCE_DIR} + --output-directory=${CMAKE_CURRENT_BINARY_DIR} + ${sample_TYPESYSTEM} +WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +COMMENT "Running generator for test binding..." +) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR} + ${PYTHON_INCLUDE_PATH} + ${libsample_SOURCE_DIR} + ${libshiboken_SOURCE_DIR}) +add_library(sample MODULE ${sample_SRC}) +set_property(TARGET sample PROPERTY PREFIX "") +target_link_libraries(sample + libsample + ${PYTHON_LIBRARIES} + libshiboken) + diff --git a/tests/samplebinding/abstract_test.py b/tests/samplebinding/abstract_test.py new file mode 100755 index 000000000..9d4c51f2c --- /dev/null +++ b/tests/samplebinding/abstract_test.py @@ -0,0 +1,62 @@ +#!/usr/bin/python + +'''Test cases for Abstract class''' + +import sys +import unittest + +from sample import Abstract + +class Incomplete(Abstract): + def __init__(self): + Abstract.__init__(self) + +class Concrete(Abstract): + def __init__(self): + Abstract.__init__(self) + self.pure_virtual_called = False + self.unpure_virtual_called = False + + def pureVirtual(self): + self.pure_virtual_called = True + + def unpureVirtual(self): + self.unpure_virtual_called = True + + +class AbstractTest(unittest.TestCase): + '''Test case for Abstract class''' + + def testAbstractPureVirtualMethodAvailability(self): + '''Test if Abstract class pure virtual method was properly wrapped.''' + self.assert_('pureVirtual' in dir(Abstract)) + + def testAbstractInstanciation(self): + '''Test if instanciation of an abstract class raises the correct exception.''' + self.assertRaises(NotImplementedError, Abstract) + + def testUnimplementedPureVirtualMethodCall(self): + '''Test if calling a pure virtual method raises the correct exception.''' + i = Incomplete() + self.assertRaises(NotImplementedError, i.pureVirtual) + + def testReimplementedVirtualMethodCall(self): + '''Test if instanciation of an abstract class raises the correct exception.''' + i = Concrete() + self.assertRaises(NotImplementedError, i.callPureVirtual) + + def testReimplementedVirtualMethodCall(self): + '''Test if a Python override of a virtual method is correctly called from C++.''' + c = Concrete() + c.callUnpureVirtual() + self.assert_(c.unpure_virtual_called) + + def testImplementedPureVirtualMethodCall(self): + '''Test if a Python override of a pure virtual method is correctly called from C++.''' + c = Concrete() + c.callPureVirtual() + self.assert_(c.pure_virtual_called) + +if __name__ == '__main__': + unittest.main() + diff --git a/tests/samplebinding/complex_conversions.h b/tests/samplebinding/complex_conversions.h new file mode 100644 index 000000000..8caaef03b --- /dev/null +++ b/tests/samplebinding/complex_conversions.h @@ -0,0 +1,23 @@ +template<> +struct Converter<Complex> +{ + static PyObject* toPython(ValueHolder<Complex> cpx) + { + /* + fprintf(stderr, "[%s:%d] cpx.real: %f, cpx.imag: %f\n", + __PRETTY_FUNCTION__, __LINE__, cpx.value.real(), cpx.value.imag()); + PyObject* result = PyComplex_FromDoubles(cpx.value.real(), cpx.value.imag()); + fprintf(stderr, "[%s:%d]", __PRETTY_FUNCTION__, __LINE__); + PyObject_Print(result, stderr, 0); + fprintf(stderr, "\n"); + return result; + */ + return PyComplex_FromDoubles(cpx.value.real(), cpx.value.imag()); + } + static Complex toCpp(PyObject* pyobj) + { + double real = PyComplex_RealAsDouble(pyobj); + double imag = PyComplex_ImagAsDouble(pyobj); + return Complex(real, imag); + } +}; diff --git a/tests/samplebinding/complex_test.py b/tests/samplebinding/complex_test.py new file mode 100755 index 000000000..92da61090 --- /dev/null +++ b/tests/samplebinding/complex_test.py @@ -0,0 +1,42 @@ +#!/usr/bin/python + +'''Test cases for Complex class''' + +import sys +import unittest + +import sample +from sample import Point + +class ComplexTest(unittest.TestCase): + '''Test case for conversions between C++ Complex class to Python complex class''' + + def testFunctionReturningComplexObject(self): + '''Test function returning a C++ Complex object.''' + cpx = sample.transmutePointIntoComplex(Point(5.0, 2.3)) + self.assertEqual(cpx, complex(5.0, 2.3)) + + def testFunctionReceivingComplexObjectAsArgument(self): + '''Test function returning a C++ Complex object.''' + pt = sample.transmuteComplexIntoPoint(complex(1.2, 3.4)) + # these assertions intentionally avoids to test the == operator, + # it should have its own test cases. + self.assertEqual(pt.x(), 1.2) + self.assertEqual(pt.y(), 3.4) + + def testComplexList(self): + '''Test list of C++ Complex objects conversion to a list of Python complex objects.''' + # the global function gimmeComplexList() is expected to return a list + # containing the following Complex values: [0j, 1.1+2.2j, 1.3+2.4j] + cpxlist = sample.gimmeComplexList() + self.assertEqual(cpxlist, [complex(), complex(1.1, 2.2), complex(1.3, 2.4)]) + + def testSumComplexPair(self): + '''Test sum of a tuple containing two complex objects.''' + cpx1 = complex(1.2, 3.4) + cpx2 = complex(5.6, 7.8) + self.assertEqual(sample.sumComplexPair((cpx1, cpx2)), cpx1 + cpx2) + +if __name__ == '__main__': + unittest.main() + diff --git a/tests/samplebinding/derived_test.py b/tests/samplebinding/derived_test.py new file mode 100755 index 000000000..22d49470f --- /dev/null +++ b/tests/samplebinding/derived_test.py @@ -0,0 +1,113 @@ +#!/usr/bin/python + +'''Test cases for Derived class''' + +import sys +import unittest + +import sample +from sample import Abstract, Derived, PolymorphicFuncEnum + +class Deviant(Derived): + def __init__(self): + Derived.__init__(self) + self.pure_virtual_called = False + self.unpure_virtual_called = False + + def pureVirtual(self): + self.pure_virtual_called = True + + def unpureVirtual(self): + self.unpure_virtual_called = True + + def className(self): + return 'Deviant' + +class DerivedTest(unittest.TestCase): + '''Test case for Derived class''' + + def testParentClassMethodsAvailability(self): + '''Test if Derived class really inherits its methods from parent.''' + inherited_methods = set(['callPureVirtual', 'callUnpureVirtual', + 'id_', 'pureVirtual', 'unpureVirtual']) + self.assert_(inherited_methods.issubset(dir(Derived))) + + def testPolymorphicMethodCall(self): + '''Test if the correct polymorphic method is being called.''' + derived = Derived() + + result = derived.polymorphic(1, 2) + self.assertEqual(type(result), PolymorphicFuncEnum) + self.assertEqual(result, sample.PolymorphicFunc_ii) + + result = derived.polymorphic(3) + self.assertEqual(type(result), PolymorphicFuncEnum) + self.assertEqual(result, sample.PolymorphicFunc_ii) + + result = derived.polymorphic(4.4) + self.assertEqual(type(result), PolymorphicFuncEnum) + self.assertEqual(result, sample.PolymorphicFunc_d) + + def testOtherPolymorphicMethodCall(self): + '''Another test to check polymorphic method calling, just to double check.''' + derived = Derived() + + result = derived.otherPolymorphic(1, 2, True, 3.3) + self.assertEqual(type(result), Derived.OtherPolymorphicFuncEnum) + self.assertEqual(result, sample.Derived.OtherPolymorphicFunc_iibd) + + result = derived.otherPolymorphic(1, 2.2) + self.assertEqual(type(result), Derived.OtherPolymorphicFuncEnum) + self.assertEqual(result, Derived.OtherPolymorphicFunc_id) + + def testPolymorphicMethodCallWithDifferentNumericTypes(self): + '''Test if the correct polymorphic method accepts a different numeric type as argument.''' + derived = Derived() + result = derived.polymorphic(1.1, 2.2) + self.assertEqual(type(result), PolymorphicFuncEnum) + self.assertEqual(result, sample.PolymorphicFunc_ii) + + def testPolymorphicMethodCallWithWrongNumberOfArguments(self): + '''Test if a call to a polymorphic method with the wrong number of arguments raises an exception.''' + derived = Derived() + self.assertRaises(TypeError, lambda : derived.otherPolymorphic(1, 2, True)) + + def testReimplementedPureVirtualMethodCall(self): + '''Test if a Python override of a implemented pure virtual method is correctly called from C++.''' + d = Deviant() + d.callPureVirtual() + self.assert_(d.pure_virtual_called) + + def testReimplementedVirtualMethodCall(self): + '''Test if a Python override of a reimplemented virtual method is correctly called from C++.''' + d = Deviant() + d.callUnpureVirtual() + self.assert_(d.unpure_virtual_called) + + def testVirtualMethodCallString(self): + '''Test virtual method call returning string.''' + d = Derived() + self.assertEqual(d.className(), 'Derived') + self.assertEqual(d.getClassName(), 'Derived') + + def testReimplementedVirtualMethodCallReturningString(self): + '''Test if a Python override of a reimplemented virtual method is correctly called from C++.''' + d = Deviant() + self.assertEqual(d.className(), 'Deviant') + self.assertEqual(d.getClassName(), 'Deviant') + + def testSingleArgument(self): + '''Test singleArgument call.''' + d = Derived() + self.assert_(d.singleArgument(False)) + self.assert_(not d.singleArgument(True)) + + def testMethodCallWithDefaultValue(self): + '''Test method call with default value.''' + d = Derived() + self.assertEqual(d.defaultValue(3), 3.1) + self.assertEqual(d.defaultValue(), 0.1) + +if __name__ == '__main__': + unittest.main() + diff --git a/tests/samplebinding/enum_test.py b/tests/samplebinding/enum_test.py new file mode 100755 index 000000000..699adceda --- /dev/null +++ b/tests/samplebinding/enum_test.py @@ -0,0 +1,36 @@ +#!/usr/bin/python + +'''Test cases for Python representation of C++ enums''' + +import sys +import unittest + +from sample import SampleNamespace + +class EnumTest(unittest.TestCase): + '''Test case for Abstract class''' + + def testPassingIntegerOnEnumArgument(self): + '''Test if replacing an enum argument with an integer raises an exception.''' + self.assertRaises(TypeError, lambda : SampleNamespace.getNumber(1)) + + def testExtendingEnum(self): + '''Test if can create new items for an enum declared as extensible on the typesystem file.''' + name, value = 'NewItem', 13 + enumitem = SampleNamespace.Option(name, value) + self.assert_(type(enumitem), SampleNamespace.Option) + self.assert_(enumitem.name, name) + self.assert_(int(enumitem), value) + + def testExtendingNonExtensibleEnum(self): + '''Test if trying to create a new enum item for an unextensible enum raises an exception.''' + self.assertRaises(TypeError, lambda : SampleNamespace.InValue(13)) + + def testEnumConversionToAndFromPython(self): + '''Test conversion of enum objects to Python and C++ in both directions.''' + enumout = SampleNamespace.enumInEnumOut(SampleNamespace.TwoIn) + self.assert_(enumout, SampleNamespace.TwoOut) + +if __name__ == '__main__': + unittest.main() + diff --git a/tests/samplebinding/global.h b/tests/samplebinding/global.h new file mode 100644 index 000000000..b5ae6a8a0 --- /dev/null +++ b/tests/samplebinding/global.h @@ -0,0 +1,14 @@ +#include "abstract.h" +#include "derived.h" +#include "point.h" +#include "size.h" +#include "complex.h" +#include "functions.h" +#include "kindergarten.h" +#include "pairuser.h" +#include "listuser.h" +#include "samplenamespace.h" +#include "modifications.h" +#include "implicitconv.h" +#include "reference.h" + diff --git a/tests/samplebinding/implicitconv_test.py b/tests/samplebinding/implicitconv_test.py new file mode 100755 index 000000000..30dd870e3 --- /dev/null +++ b/tests/samplebinding/implicitconv_test.py @@ -0,0 +1,27 @@ +#!/usr/bin/python + +'''Test cases for implicit conversions''' + +import sys +import unittest + +from sample import ImplicitConv + +class ImplicitConvTest(unittest.TestCase): + '''Test case for implicit conversions''' + + def testImplicitConversions(self): + '''Test if polymorphic function call decisor takes implicit conversions into account.''' + ic = ImplicitConv.implicitConvCommon(ImplicitConv()) + self.assertEqual(ic.ctorEnum(), ImplicitConv.CtorNone) + + ic = ImplicitConv.implicitConvCommon(3) + self.assertEqual(ic.ctorEnum(), ImplicitConv.CtorOne) + self.assertEqual(ic.objId(), 3) + + ic = ImplicitConv.implicitConvCommon(ImplicitConv.CtorThree) + self.assertEqual(ic.ctorEnum(), ImplicitConv.CtorThree) + +if __name__ == '__main__': + unittest.main() + diff --git a/tests/samplebinding/list_conversions.h b/tests/samplebinding/list_conversions.h new file mode 100644 index 000000000..f512f98ad --- /dev/null +++ b/tests/samplebinding/list_conversions.h @@ -0,0 +1,29 @@ +template <typename StdList> +struct Converter_std_list +{ + static PyObject* toPython(ValueHolder<StdList> holder) + { + PyObject* result = PyList_New((int) holder.value.size()); + typedef typename StdList::iterator IT; + IT it; + int idx = 0; + for (it = holder.value.begin(); it != holder.value.end(); it++) { + ValueHolder<typename StdList::value_type> vh(*it); + PyList_SET_ITEM(result, idx, Converter<typename StdList::value_type>::toPython(vh)); + idx++; + } + return result; + } + static StdList toCpp(PyObject* pyobj) + { + StdList result; + for (int i = 0; i < PyTuple_GET_SIZE(pyobj); i++) { + PyObject* pyItem = PyTuple_GET_ITEM(pyobj, i); + result.push_back(Converter<typename StdList::value_type>::toCpp(pyItem)); + } + return result; + } +}; + +template<typename T> +struct Converter<std::list<T> > : Converter_std_list<std::list<T> > {}; diff --git a/tests/samplebinding/modifications_test.py b/tests/samplebinding/modifications_test.py new file mode 100755 index 000000000..33d420f37 --- /dev/null +++ b/tests/samplebinding/modifications_test.py @@ -0,0 +1,115 @@ +#!/usr/bin/python + +'''Test cases for method modifications performed as described on typesystem. ''' + +import sys +import unittest + +from sample import Modifications, Point + +class ExtModifications(Modifications): + def __init__(self): + Modifications.__init__(self) + + def name(self): + return 'ExtModifications' + + +class ModificationsTest(unittest.TestCase): + '''Test cases for method modifications performed as described on typesystem. ''' + + def setUp(self): + self.mods = Modifications() + + def tearDown(self): + del self.mods + + def testClassMembersAvailability(self): + '''Test if Modified class really have the expected members.''' + expected_members = set(['PolymorphicModFunc', 'PolymorphicNone', + 'Polymorphic_ibiP', 'Polymorphic_ibib', + 'Polymorphic_ibid', 'Polymorphic_ibii', + 'calculateArea', 'doublePlus', 'increment', + 'multiplyPointCoordsPlusValue', 'name', + 'pointToPair', 'polymorphic', 'power', + 'timesTen']) + self.assert_(expected_members.issubset(dir(Modifications))) + + def testRenamedMethodAvailability(self): + '''Test if Modification class really have renamed the 'className' virtual method to 'name'.''' + self.assert_('className' not in dir(Modifications)) + self.assert_('name' in dir(Modifications)) + + def testReimplementationOfRenamedVirtualMethod(self): + '''Test if class inheriting from Modification class have the reimplementation of renamed virtual method called.''' + em = ExtModifications() + self.assertEqual(self.mods.name(), 'Modifications') + self.assertEqual(em.name(), 'ExtModifications') + + def testRegularMethodRenaming(self): + '''Test if Modifications::cppMultiply was correctly renamed to calculateArea.''' + self.assert_('cppMultiply' not in dir(Modifications)) + self.assert_('calculateArea' in dir(Modifications)) + self.assertEqual(self.mods.calculateArea(3, 6), 3 * 6) + + def testRegularMethodRemoval(self): + '''Test if 'Modifications::exclusiveCppStuff' was removed from Python bindings.''' + self.assert_('exclusiveCppStuff' not in dir(Modifications)) + + def testArgumentRemoval(self): + '''Test if second argument of Modifications::doublePlus(int, int) was removed.''' + self.assertRaises(TypeError, lambda : self.mods.doublePlus(3, 7)) + self.assertEqual(self.mods.doublePlus(7), 14) + + def testDefaultValueRemoval(self): + '''Test if default value was removed from first argument of Modifications::increment(int).''' + self.assertRaises(TypeError, self.mods.increment) + self.assertEqual(self.mods.increment(7), 8) + + def testDefaultValueReplacement(self): + '''Test if default values for both arguments of Modifications::power(int, int) were modified.''' + # original default values: int power(int base = 1, int exponent = 0); + self.assertNotEqual(self.mods.power(4), 1) + # modified default values: int power(int base = 2, int exponent = 1); + self.assertEqual(self.mods.power(), 2) + self.assertEqual(self.mods.power(3), 3) + self.assertEqual(self.mods.power(5, 3), 5**3) + + def testSetNewDefaultValue(self): + '''Test if default value was correctly set to 10 for first argument of Modifications::timesTen(int).''' + self.assertEqual(self.mods.timesTen(7), 70) + self.assertEqual(self.mods.timesTen(), 100) + + def testArgumentRemovalAndReturnTypeModificationWithTypesystemTemplates1(self): + '''Test modifications to method signature and return value using typesystem templates (case 1).''' + result, ok = self.mods.pointToPair(Point(2, 5)) + self.assertEqual(type(ok), bool) + self.assertEqual(type(result), tuple) + self.assertEqual(len(result), 2) + self.assertEqual(type(result[0]), float) + self.assertEqual(type(result[1]), float) + self.assertEqual(result[0], 2.0) + self.assertEqual(result[1], 5.0) + + def testArgumentRemovalAndReturnTypeModificationWithTypesystemTemplates2(self): + '''Test modifications to method signature and return value using typesystem templates (case 2).''' + result, ok = self.mods.multiplyPointCoordsPlusValue(Point(2, 5), 4.1) + self.assertEqual(type(ok), bool) + self.assertEqual(type(result), float) + self.assertEqual(result, 14.1) + + def testPolymorphicMethodModifications(self): + '''Tests modifications to a polymorphic method''' + # polymorphic(int, bool[removed], int, double) + self.assertEqual(self.mods.polymorphic(1, 2, 3.1), Modifications.Polymorphic_ibid) + # polymorphic(int, bool, int[removed,default=321], int) + self.assertEqual(self.mods.polymorphic(1, True, 2), Modifications.Polymorphic_ibii) + # the others weren't modified + self.assertEqual(self.mods.polymorphic(1, True, 2, False), Modifications.Polymorphic_ibib) + self.assertEqual(self.mods.polymorphic(1, False, 2, Point(3, 4)), Modifications.Polymorphic_ibiP) + self.assertRaises(TypeError, lambda : self.mods.polymorphic(1, True, Point(2, 3), Point(4, 5))) + self.assertEqual(self.mods.poly(1, True, Point(2, 3), Point(4, 5)), Modifications.Polymorphic_ibPP) + +if __name__ == '__main__': + unittest.main() + diff --git a/tests/samplebinding/pair_conversions.h b/tests/samplebinding/pair_conversions.h new file mode 100644 index 000000000..8adf2f6f3 --- /dev/null +++ b/tests/samplebinding/pair_conversions.h @@ -0,0 +1,25 @@ +template <typename StdPair> +struct Converter_std_pair +{ + static PyObject* toPython(ValueHolder<StdPair> holder) + { + ValueHolder<typename StdPair::first_type> first(holder.value.first); + ValueHolder<typename StdPair::second_type> second(holder.value.second); + PyObject* tuple = PyTuple_New(2); + PyTuple_SET_ITEM(tuple, 0, Converter<typename StdPair::first_type>::toPython(first)); + PyTuple_SET_ITEM(tuple, 1, Converter<typename StdPair::second_type>::toPython(second)); + return tuple; + } + static StdPair toCpp(PyObject* pyobj) + { + StdPair result; + PyObject* pyFirst = PyTuple_GET_ITEM(pyobj, 0); + PyObject* pySecond = PyTuple_GET_ITEM(pyobj, 1); + result.first = Converter<typename StdPair::first_type>::toCpp(pyFirst); + result.second = Converter<typename StdPair::second_type>::toCpp(pySecond); + return result; + } +}; + +template<typename FT, typename ST> +struct Converter<std::pair<FT, ST> > : Converter_std_pair<std::pair<FT, ST> > {}; diff --git a/tests/samplebinding/point_test.py b/tests/samplebinding/point_test.py new file mode 100755 index 000000000..69ef1eefb --- /dev/null +++ b/tests/samplebinding/point_test.py @@ -0,0 +1,42 @@ +#!/usr/bin/python + +'''Test cases for Point class''' + +import sys +import unittest + +from sample import Point + +class PointTest(unittest.TestCase): + '''Test case for Point class, including operator overloads.''' + + def testConstructor(self): + '''Test Point class constructor.''' + pt = Point(5.0, 2.3) + self.assertEqual(pt.x(), 5.0) + self.assertEqual(pt.y(), 2.3) + + def testPlusOperator(self): + '''Test Point class + operator.''' + pt1 = Point(5.0, 2.3) + pt2 = Point(0.5, 3.2) + self.assertEqual(pt1 + pt2, Point(5.0 + 0.5, 2.3 + 3.2)) + + def testEqualOperator(self): + '''Test Point class == operator.''' + pt1 = Point(5.0, 2.3) + pt2 = Point(5.0, 2.3) + pt3 = Point(0.5, 3.2) + self.assertTrue(pt1 == pt1) + self.assertTrue(pt1 == pt2) + self.assertFalse(pt1 == pt3) + + def testNotEqualOperator(self): + '''Test Point class != operator.''' + pt1 = Point(5.0, 2.3) + pt2 = Point(5.0, 2.3) + self.assertRaises(NotImplementedError, lambda : pt1.__ne__(pt2)) + +if __name__ == '__main__': + unittest.main() + diff --git a/tests/samplebinding/reference_test.py b/tests/samplebinding/reference_test.py new file mode 100755 index 000000000..ed4c5cbc8 --- /dev/null +++ b/tests/samplebinding/reference_test.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +'''Test cases for methods that receive references to objects.''' + +import sys +import unittest + +from sample import Reference + +class ReferenceTest(unittest.TestCase): + '''Test case for methods that receive references to objects.''' + + def testMethodThatReceivesReference(self): + '''Test a method that receives a reference to an object as argument.''' + objId = 123 + r = Reference(objId) + self.assertEqual(Reference.usesReference(r), objId) + + def testMethodThatReceivesConstReference(self): + '''Test a method that receives a const reference to an object as argument.''' + objId = 123 + r = Reference(objId) + self.assertEqual(Reference.usesConstReference(r), objId) + + +if __name__ == '__main__': + unittest.main() + diff --git a/tests/samplebinding/sample_test.py b/tests/samplebinding/sample_test.py new file mode 100755 index 000000000..9de201a24 --- /dev/null +++ b/tests/samplebinding/sample_test.py @@ -0,0 +1,37 @@ +#!/usr/bin/python + +'''Test cases for libsample bindings module''' + +import sys +import unittest + +import sample + +class ModuleTest(unittest.TestCase): + '''Test case for module and global functions''' + + def testModuleMembers(self): + '''Test availability of classes, global functions and other members on binding''' + expected_members = set(['Abstract', 'Derived', 'ListUser', 'PairUser', + 'Point', 'gimmeComplexList', 'gimmeDouble', + 'gimmeInt', 'makeCString', 'multiplyPair', + 'returnCString', 'transmuteComplexIntoPoint', + 'transmutePointIntoComplex', 'sumComplexPair', + 'SampleNamespace', 'GlobalEnum', 'NoThing', + 'FirstThing', 'SecondThing', 'ThirdThing']) + self.assert_(expected_members.issubset(dir(sample))) + + def testAbstractPrintFormatEnum(self): + '''Test availability of PrintFormat enum from Abstract class''' + enum_members = set(['PrintFormat', 'Short', 'Verbose', + 'OnlyId', 'ClassNameAndId']) + self.assert_(enum_members.issubset(dir(sample.Abstract))) + + def testSampleNamespaceOptionEnum(self): + '''Test availability of Option enum from SampleNamespace namespace''' + enum_members = set(['Option', 'None', 'RandomNumber', 'UnixTime']) + self.assert_(enum_members.issubset(dir(sample.SampleNamespace))) + +if __name__ == '__main__': + unittest.main() + diff --git a/tests/samplebinding/size_test.py b/tests/samplebinding/size_test.py new file mode 100755 index 000000000..dcfc9d9d3 --- /dev/null +++ b/tests/samplebinding/size_test.py @@ -0,0 +1,83 @@ +#!/usr/bin/python + +'''Test cases for operator overloads on Size class''' + +import sys +import unittest + +from sample import Size + +class PointTest(unittest.TestCase): + '''Test case for Size class, including operator overloads.''' + + def testConstructor(self): + '''Test Size class constructor.''' + width, height = (5.0, 2.3) + size = Size(width, height) + self.assertEqual(size.width(), width) + self.assertEqual(size.height(), height) + self.assertEqual(size.calculateArea(), width * height) + + def testPlusOperator(self): + '''Test Size class + operator.''' + s1 = Size(5.0, 2.3) + s2 = Size(0.5, 3.2) + self.assertEqual(s1 + s2, Size(5.0 + 0.5, 2.3 + 3.2)) + + def testEqualOperator(self): + '''Test Size class == operator.''' + s1 = Size(5.0, 2.3) + s2 = Size(5.0, 2.3) + s3 = Size(0.5, 3.2) + self.assertTrue(s1 == s1) + self.assertTrue(s1 == s2) + self.assertFalse(s1 == s3) + + def testNotEqualOperator(self): + '''Test Size class != operator.''' + s1 = Size(5.0, 2.3) + s2 = Size(5.0, 2.3) + s3 = Size(0.5, 3.2) + self.assertFalse(s1 != s1) + self.assertFalse(s1 != s2) + self.assertTrue(s1 != s3) + + def testMinorEqualOperator(self): + '''Test Size class <= operator.''' + s1 = Size(5.0, 2.3) + s2 = Size(5.0, 2.3) + s3 = Size(0.5, 3.2) + self.assertTrue(s1 <= s1) + self.assertTrue(s1 <= s2) + self.assertTrue(s3 <= s1) + self.assertFalse(s1 <= s3) + + def testMinorOperator(self): + '''Test Size class < operator.''' + s1 = Size(5.0, 2.3) + s2 = Size(0.5, 3.2) + self.assertFalse(s1 < s1) + self.assertFalse(s1 < s2) + self.assertTrue(s2 < s1) + + def testMajorEqualOperator(self): + '''Test Size class >= operator.''' + s1 = Size(5.0, 2.3) + s2 = Size(5.0, 2.3) + s3 = Size(0.5, 3.2) + self.assertTrue(s1 >= s1) + self.assertTrue(s1 >= s2) + self.assertTrue(s1 >= s3) + self.assertFalse(s3 >= s1) + + def testMajorOperator(self): + '''Test Size class > operator.''' + s1 = Size(5.0, 2.3) + s2 = Size(0.5, 3.2) + self.assertFalse(s1 > s1) + self.assertTrue(s1 > s2) + self.assertFalse(s2 > s1) + +if __name__ == '__main__': + unittest.main() + diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml new file mode 100644 index 000000000..c049ea9eb --- /dev/null +++ b/tests/samplebinding/typesystem_sample.xml @@ -0,0 +1,216 @@ +<?xml version="1.0"?> +<typesystem package="sample"> + <primitive-type name="bool"/> + <primitive-type name="double"/> + <primitive-type name="int"/> + <primitive-type name="char"/> + + <primitive-type name="Complex" target-lang-api-name="PyComplex"> + <conversion-rule file="complex_conversions.h"/> + </primitive-type> + + <container-type name="std::pair" type="pair"> + <conversion-rule file="pair_conversions.h"/> + <include file-name="utility" location="global"/> + </container-type> + <container-type name="std::list" type="list"> + <conversion-rule file="list_conversions.h"/> + <include file-name="list" location="global"/> + </container-type> + + <enum-type name="Abstract::PrintFormat"/> + <enum-type name="PolymorphicFuncEnum"/> + <enum-type name="Derived::OtherPolymorphicFuncEnum"/> + <enum-type name="Modifications::PolymorphicModFunc"/> + <enum-type name="ImplicitConv::CtorEnum"/> + <!-- BUG: + renaming the ICPolymorphicFuncEnum to the same name + of a global enum causes the generator to confuse the + two types. + --> + <enum-type name="ImplicitConv::ICPolymorphicFuncEnum"/> + <enum-type name="SampleNamespace::Option" extensible="yes"/> + <enum-type name="SampleNamespace::InValue"/> + <enum-type name="SampleNamespace::OutValue"/> + <enum-type name="GlobalEnum"/> + <enum-type name="GlobalPolyFuncEnum"/> + + <namespace-type name="SampleNamespace"/> + + <object-type name="Abstract"> + <modify-function signature="id()" rename="id_"/> + </object-type> + + <object-type name="Derived"/> + + <template name="boolptr_at_end_fix_beginning"> + bool __ok__; + %0 = ((%TYPE*) ((Shiboken::PyBaseWrapper*) self)->cptr)-> + %TYPE::%FUNCTION_NAME(%ARGUMENT_NAMES, &__ok__); + </template> + + <template name="boolptr_at_start_fix_beginning"> + bool __ok__; + %0 = ((%TYPE*) ((Shiboken::PyBaseWrapper*) self)->cptr)-> + %TYPE::%FUNCTION_NAME(&__ok__, %ARGUMENT_NAMES); + </template> + + <template name="boolptr_fix_end"> + PyObject* _item_; + PyObject* _tuple_ = PyTuple_New(2); + _item_ = Shiboken::Converter< %RETURN_TYPE >::toPython(Shiboken::ValueHolder< %RETURN_TYPE >(%0)); + PyTuple_SET_ITEM(_tuple_, 0, _item_); + _item_ = Shiboken::Converter<bool>::toPython(Shiboken::ValueHolder<bool>(__ok__)); + PyTuple_SET_ITEM(_tuple_, 1, _item_); + return _tuple_; + </template> + + <object-type name="Modifications"> + + <modify-function signature="polymorphic(int, bool, int, double)"> + <modify-argument index="2"> + <remove-argument/> + </modify-argument> + <inject-code class="native" position="beginning"> + %0 = ((%TYPE*) ((Shiboken::PyBaseWrapper*) self)->cptr)-> + %TYPE::%FUNCTION_NAME(%1, true, %3, %4); + </inject-code> + </modify-function> + + <modify-function signature="polymorphic(int, bool, int, int)"> + <modify-argument index="3"> + <remove-argument/> + <replace-default-expression with="321"/> + </modify-argument> + <!-- + <modify-argument index="4"> + <remove-default-expression/> + </modify-argument> + --> + </modify-function> + + <!-- + this alteration will trigger an interesting + compile time error on the binding + --> + <!-- + <modify-function signature="polymorphic(int, bool, Point, Point)"> + <modify-argument index="3"> + <remove-argument/> + </modify-argument> + </modify-function> + --> + + <!-- + renaming this signature should remove it from the other + polymorphic methods decision tree + --> + <modify-function signature="polymorphic(int, bool, Point, Point)" rename="poly"/> + + <!-- + 'ok' must be removed and the return value will be changed + to a tuple (PyObject*) containing the expected result plus + the 'ok' value as a Python boolean + --> + <modify-function signature="pointToPair(Point, bool*)"> + <modify-argument index="2"> + <remove-argument/> + </modify-argument> + <modify-argument index="return"> + <replace-type modified-type="PyObject*"/> + </modify-argument> + <inject-code class="native" position="beginning"> + <insert-template name="boolptr_at_end_fix_beginning"/> + </inject-code> + <inject-code class="native" position="end"> + <insert-template name="boolptr_fix_end"/> + </inject-code> + </modify-function> + + <!-- same as 'pointToPair' except that this time 'ok' is the first argument --> + <modify-function signature="multiplyPointCoordsPlusValue(bool*, Point, double)"> + <modify-argument index="1"> + <remove-argument/> + </modify-argument> + <modify-argument index="return"> + <replace-type modified-type="PyObject*"/> + </modify-argument> + <inject-code class="native" position="beginning"> + <insert-template name="boolptr_at_start_fix_beginning"/> + </inject-code> + <inject-code class="native" position="end"> + <insert-template name="boolptr_fix_end"/> + </inject-code> + </modify-function> + + <!-- completely remove 'plus' from the Python side --> + <modify-function signature="doublePlus(int, int)"> + <modify-argument index="2"> + <remove-argument/> + </modify-argument> + </modify-function> + + <!-- the default value for both arguments must be changed in Python --> + <modify-function signature="power(int, int)"> + <modify-argument index="1"> + <replace-default-expression with="2"/> + </modify-argument> + <modify-argument index="2"> + <replace-default-expression with="1"/> + </modify-argument> + </modify-function> + + <!-- in Python set argument default value to 10 --> + <modify-function signature="timesTen(int)"> + <modify-argument index="1"> + <replace-default-expression with="10"/> + </modify-argument> + </modify-function> + + <!-- in Python remove the argument default value --> + <modify-function signature="increment(int)"> + <modify-argument index="1"> + <remove-default-expression/> + </modify-argument> + </modify-function> + + <!-- don't export this method to Python --> + <modify-function signature="exclusiveCppStuff()" remove="all"/> + + <!-- change the name of this regular method --> + <modify-function signature="cppMultiply(int, int)" rename="calculateArea"/> + + <!-- change the name of this virtual method --> + <modify-function signature="className()" rename="name"/> + </object-type> + + <object-type name="AbstractModifications"> + <!-- + completely removing the pure virtual method from this + class will generate an #error directive. + --> + <!-- + <modify-function signature="pointlessPureVirtualMethod()" remove="all"/> + --> + </object-type> + + <value-type name="Reference"/> + + <value-type name="ImplicitConv"/> + + <value-type name="Point"/> + <value-type name="Size"/> + <value-type name="PairUser"/> + <value-type name="ListUser"/> + + <rejection class="ListUser" function-name="createList()"/> + <rejection class="ListUser" function-name="callCreateList()"/> + <rejection class="ListUser" function-name="createComplexList(Complex, Complex)"/> + <rejection class="ListUser" function-name="sumList(std::list<int>)"/> + <rejection class="ListUser" function-name="sumList(std::list<double>)"/> + + <rejection class="" function-name="gimmeComplexList()"/> + <rejection class="" function-name="makeCString()"/> + <rejection class="" function-name="returnCString()"/> +</typesystem> + |