aboutsummaryrefslogtreecommitdiffstats
path: root/tests/samplebinding
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2009-08-17 19:31:37 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2009-08-17 19:31:37 -0300
commite0c29962e6f334452f0c9db2caaf6ed18065de85 (patch)
treecee27801c196fbcacf6130ad64216af133b555dd /tests/samplebinding
The End Is the Beginning Is the End
Diffstat (limited to 'tests/samplebinding')
-rw-r--r--tests/samplebinding/CMakeLists.txt44
-rwxr-xr-xtests/samplebinding/abstract_test.py62
-rw-r--r--tests/samplebinding/complex_conversions.h23
-rwxr-xr-xtests/samplebinding/complex_test.py42
-rwxr-xr-xtests/samplebinding/derived_test.py113
-rwxr-xr-xtests/samplebinding/enum_test.py36
-rw-r--r--tests/samplebinding/global.h14
-rwxr-xr-xtests/samplebinding/implicitconv_test.py27
-rw-r--r--tests/samplebinding/list_conversions.h29
-rwxr-xr-xtests/samplebinding/modifications_test.py115
-rw-r--r--tests/samplebinding/pair_conversions.h25
-rwxr-xr-xtests/samplebinding/point_test.py42
-rwxr-xr-xtests/samplebinding/reference_test.py28
-rwxr-xr-xtests/samplebinding/sample_test.py37
-rwxr-xr-xtests/samplebinding/size_test.py83
-rw-r--r--tests/samplebinding/typesystem_sample.xml216
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, &amp;__ok__);
+ </template>
+
+ <template name="boolptr_at_start_fix_beginning">
+ bool __ok__;
+ %0 = ((%TYPE*) ((Shiboken::PyBaseWrapper*) self)->cptr)->
+ %TYPE::%FUNCTION_NAME(&amp;__ok__, %ARGUMENT_NAMES);
+ </template>
+
+ <template name="boolptr_fix_end">
+ PyObject* _item_;
+ PyObject* _tuple_ = PyTuple_New(2);
+ _item_ = Shiboken::Converter&lt; %RETURN_TYPE &gt;::toPython(Shiboken::ValueHolder&lt; %RETURN_TYPE &gt;(%0));
+ PyTuple_SET_ITEM(_tuple_, 0, _item_);
+ _item_ = Shiboken::Converter&lt;bool&gt;::toPython(Shiboken::ValueHolder&lt;bool&gt;(__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&lt;int&gt;)"/>
+ <rejection class="ListUser" function-name="sumList(std::list&lt;double&gt;)"/>
+
+ <rejection class="" function-name="gimmeComplexList()"/>
+ <rejection class="" function-name="makeCString()"/>
+ <rejection class="" function-name="returnCString()"/>
+</typesystem>
+