aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2009-11-22 13:33:54 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2009-11-23 11:48:03 -0300
commit8f76c2ace7d74c6382b398126f1dcd8cda617d29 (patch)
tree490ad3f97380d9ec4dff967747076a8cf2078d35
parentc48f9163b42c20c91c33183a1835e0b356f104dc (diff)
Added a great deal of tests to virtual method modification cases.
-rw-r--r--tests/libsample/str.cpp7
-rw-r--r--tests/libsample/str.h1
-rw-r--r--tests/libsample/virtualmethods.h33
-rwxr-xr-xtests/samplebinding/modifiedvirtualmethods_test.py210
-rw-r--r--tests/samplebinding/typesystem_sample.xml51
5 files changed, 300 insertions, 2 deletions
diff --git a/tests/libsample/str.cpp b/tests/libsample/str.cpp
index 5c77979b9..bd7076087 100644
--- a/tests/libsample/str.cpp
+++ b/tests/libsample/str.cpp
@@ -80,6 +80,13 @@ Str::append(const Str& s)
return *this;
}
+Str&
+Str::prepend(const Str& s)
+{
+ m_str = s.m_str + m_str;
+ return *this;
+}
+
const char*
Str::cstring() const
{
diff --git a/tests/libsample/str.h b/tests/libsample/str.h
index f40e79eee..31266753e 100644
--- a/tests/libsample/str.h
+++ b/tests/libsample/str.h
@@ -46,6 +46,7 @@ public:
Str arg(const Str& s) const;
Str& append(const Str& s);
+ Str& prepend(const Str& s);
const char* cstring() const;
char get_char(int pos) const;
diff --git a/tests/libsample/virtualmethods.h b/tests/libsample/virtualmethods.h
index 299cf5a86..8bd4b93f2 100644
--- a/tests/libsample/virtualmethods.h
+++ b/tests/libsample/virtualmethods.h
@@ -37,6 +37,7 @@
#include "point.h"
#include "complex.h"
+#include "str.h"
class VirtualMethods
{
@@ -49,6 +50,38 @@ public:
{
return virtualMethod0(pt, val, cpx, b);
}
+
+ // Binding modification: rename.
+ virtual int sum0(int a0, int a1, int a2) { return a0 + a1 + a2; }
+ int callSum0(int a0, int a1, int a2) { return sum0(a0, a1, a2); }
+
+ // Binding modification: set default value for the last argument.
+ virtual int sum1(int a0, int a1, int a2) { return a0 + a1 + a2; }
+ int callSum1(int a0, int a1, int a2) { return sum1(a0, a1, a2); }
+
+ // Binding modification: remove the last argument and set a default value for it.
+ virtual int sum2(int a0, int a1, int a2) { return a0 + a1 + a2; }
+ int callSum2(int a0, int a1, int a2) { return sum2(a0, a1, a2); }
+
+ // Binding modification: remove the second argument.
+ virtual int sum3(int a0, int a1, int a2) { return a0 + a1 + a2; }
+ int callSum3(int a0, int a1, int a2) { return sum3(a0, a1, a2); }
+
+ // Binding modification: remove the second argument and set its default
+ // value, then inject code on the binding reimplementation of the virtual
+ // (with a native inject-code) to sum the value of the removed
+ // argument to the first argument before the method is called.
+ virtual int sum4(int a0, int a1, int a2) { return a0 + a1 + a2; }
+ int callSum4(int a0, int a1, int a2) { return sum4(a0, a1, a2); }
+
+ // Binding modification: prepend a string to the results of a Python override.
+ virtual Str name() { return Str("VirtualMethods"); }
+ Str callName() { return name(); }
+
+ // Binding modification: code injection that calls the Python override by itself.
+ virtual void callMe() {}
+ void callCallMe() { callMe(); }
+
};
#endif // VIRTUALMETHODS_H
diff --git a/tests/samplebinding/modifiedvirtualmethods_test.py b/tests/samplebinding/modifiedvirtualmethods_test.py
new file mode 100755
index 000000000..128c7d1d3
--- /dev/null
+++ b/tests/samplebinding/modifiedvirtualmethods_test.py
@@ -0,0 +1,210 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# This file is part of the Shiboken Python Bindings Generator 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 Lesser General Public License
+# version 2.1 as published by the Free Software Foundation. Please
+# review the following information to ensure the GNU Lesser General
+# Public License version 2.1 requirements will be met:
+# http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+# #
+# 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser 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
+
+'''Test cases for modified virtual methods.'''
+
+import sys
+import unittest
+
+from sample import VirtualMethods, Point, Str
+
+class ExtendedVirtualMethods(VirtualMethods):
+ def __init__(self):
+ VirtualMethods.__init__(self)
+ self.name_called = False
+ self.sum0_called = False
+ self.sum1_called = False
+ self.sum2_called = False
+ self.sum3_called = False
+ self.sum4_called = False
+ self.sumThree_called = False
+ self.callMe_called = 0
+ self.multiplier = 12345
+
+ def sum0(self, a0, a1, a2):
+ self.sum0_called = True
+ return VirtualMethods.sumThree(self, a0, a1, a2) * self.multiplier
+
+ def sumThree(self, a0, a1, a2):
+ self.sumThree_called = True
+ return VirtualMethods.sumThree(self, a0, a1, a2) * self.multiplier
+
+ def sum1(self, a0, a1, a2):
+ self.sum1_called = True
+ return VirtualMethods.sum1(self, a0, a1, a2) * self.multiplier
+
+ def sum2(self, a0, a1):
+ self.sum2_called = True
+ return VirtualMethods.sum2(self, a0, a1) * self.multiplier
+
+ def sum3(self, a0, a1):
+ self.sum3_called = True
+ return VirtualMethods.sum3(self, a0, a1) * self.multiplier
+
+ def sum4(self, a0, a1):
+ self.sum4_called = True
+ return VirtualMethods.sum4(self, a0, a1) * self.multiplier
+
+ def name(self):
+ self.name_called = True
+ return Str('ExtendedVirtualMethods')
+
+ def callMe(self):
+ self.callMe_called += 1
+
+
+class VirtualMethodsTest(unittest.TestCase):
+ '''Test case for modified virtual methods.'''
+
+ def setUp(self):
+ self.vm = VirtualMethods()
+ self.evm = ExtendedVirtualMethods()
+
+ def tearDown(self):
+ del self.vm
+ del self.evm
+
+ def testModifiedVirtualMethod0(self):
+ '''Renamed virtual method.'''
+ a0, a1, a2 = 2, 3, 5
+ result0 = self.vm.callSum0(a0, a1, a2)
+ result1 = self.vm.sumThree(a0, a1, a2)
+ self.assertEqual(result0, a0 + a1 + a2)
+ self.assertEqual(result0, result1)
+ self.assertRaises(AttributeError, lambda : self.vm.sum0(a0, a1, a2))
+
+ def testReimplementedModifiedVirtualMethod0(self):
+ '''Override of a renamed virtual method.'''
+ a0, a1, a2 = 2, 3, 5
+ result0 = self.vm.callSum0(a0, a1, a2)
+ result1 = self.vm.sumThree(a0, a1, a2)
+ result2 = self.evm.callSum0(a0, a1, a2)
+ self.assertEqual(result0, result1)
+ self.assertEqual(result0 * self.evm.multiplier, result2)
+ self.assert_(self.evm.sumThree_called)
+ self.assertFalse(self.evm.sum0_called)
+
+ def testModifiedVirtualMethod1(self):
+ '''Virtual method with three arguments and the last one changed to have the default value set to 1000.'''
+ a0, a1, a2 = 2, 3, 5
+ result0 = self.vm.sum1(a0, a1)
+ self.assertEqual(result0, a0 + a1 + 1000)
+ result1 = self.vm.sum1(a0, a1, a2)
+ result2 = self.vm.callSum1(a0, a1, a2)
+ self.assertEqual(result1, result2)
+
+ def testReimplementedModifiedVirtualMethod1(self):
+ '''Override of the virtual method with three arguments and the last one changed to have the default value set to 1000.'''
+ a0, a1 = 2, 3
+ result0 = self.vm.sum1(a0, a1)
+ result1 = self.evm.callSum1(a0, a1, 1000)
+ self.assertEqual(result0 * self.evm.multiplier, result1)
+ self.assert_(self.evm.sum1_called)
+
+ def testModifiedVirtualMethod2(self):
+ '''Virtual method originally with three arguments, the last one was removed and the default value set to 2000.'''
+ a0, a1 = 1, 2
+ result0 = self.vm.sum2(a0, a1)
+ self.assertEqual(result0, a0 + a1 + 2000)
+ result1 = self.vm.sum2(a0, a1)
+ result2 = self.vm.callSum2(a0, a1, 2000)
+ self.assertEqual(result1, result2)
+ self.assertRaises(TypeError, lambda : self.vm.sum2(1, 2, 3))
+
+ def testReimplementedModifiedVirtualMethod2(self):
+ '''Override of the virtual method originally with three arguments, the last one was removed and the default value set to 2000.'''
+ a0, a1 = 1, 2
+ ignored = 54321
+ result0 = self.vm.sum2(a0, a1)
+ result1 = self.evm.callSum2(a0, a1, ignored)
+ self.assertEqual(result0 * self.evm.multiplier, result1)
+ self.assert_(self.evm.sum2_called)
+
+ def testModifiedVirtualMethod3(self):
+ '''Virtual method originally with three arguments have the second one removed and replaced
+ by custom code that replaces it by the sum of the first and the last arguments.'''
+ a0, a1 = 1, 2
+ result0 = self.vm.sum3(a0, a1)
+ self.assertEqual(result0, a0 + (a0 + a1) + a1)
+ result1 = self.vm.callSum3(a0, 10, a1)
+ self.assertNotEqual(result0, result1)
+ result2 = self.vm.callSum3(a0, a0 + a1, a1)
+ self.assertEqual(result0, result2)
+ self.assertRaises(TypeError, lambda : self.vm.sum3(1, 2, 3))
+
+ def testReimplementedModifiedVirtualMethod3(self):
+ '''Override of the virtual method originally with three arguments have the second one removed and replaced
+ by custom code that replaces it by the sum of the first and the last arguments.'''
+ a0, a1 = 1, 2
+ ignored = 54321
+ result0 = self.vm.sum3(a0, a1)
+ result1 = self.evm.callSum3(a0, ignored, a1)
+ self.assertEqual(result0 * self.evm.multiplier, result1)
+ self.assert_(self.evm.sum3_called)
+
+ def testModifiedVirtualMethod4(self):
+ '''Virtual method originally with three arguments, the last one was removed and the default
+ value set to 3000.'''
+ a0, a1 = 1, 2
+ default_value = 3000
+ result0 = self.vm.sum4(a0, a1)
+ self.assertEqual(result0, a0 + default_value + a1)
+ removed_arg_value = 100
+ result1 = self.vm.callSum4(a0, removed_arg_value, a1)
+ self.assertEqual(result1, a0 + removed_arg_value + a1)
+ self.assertRaises(TypeError, lambda : self.vm.sum4(1, 2, 3))
+
+ def testReimplementedModifiedVirtualMethod4(self):
+ '''Override of the virtual method originally with three arguments, the last one was removed
+ and the default value set to 3000. The method was modified with code injection on the binding
+ override (the one that receives calls from C++ with the original signature and forwards it
+ to Python overrides) that subtracts the value of the second argument (removed in Python)
+ from the value of the first before sending them to Python.'''
+ a0, a1 = 1, 2
+ removed_arg_value = 2011
+ default_value = 3000
+ result = self.evm.callSum4(a0, removed_arg_value, a1)
+ self.assertEqual(result, (a0 - removed_arg_value + a1 + default_value) * self.evm.multiplier)
+ self.assert_(self.evm.sum4_called)
+
+ def testOverridenMethodResultModification(self):
+ '''Injected code modifies the result of a call to a virtual method overriden in Python.'''
+ orig_name = self.vm.callName()
+ self.assertEqual(orig_name, 'VirtualMethods')
+ name = self.evm.callName()
+ self.assertEqual(name, 'PimpedExtendedVirtualMethods')
+ self.assertEqual(name, Str('PimpedExtendedVirtualMethods'))
+ self.assert_(self.evm.name_called)
+
+ def testInjectCodeCallsPythonVirtualMethodOverride(self):
+ '''When injected code calls the Python override by itself
+ no code for the method call should be generated.'''
+ self.evm.callCallMe()
+ self.assertEqual(self.evm.callMe_called, 1)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml
index 1e89fab1f..f24441edf 100644
--- a/tests/samplebinding/typesystem_sample.xml
+++ b/tests/samplebinding/typesystem_sample.xml
@@ -367,9 +367,56 @@
</object-type>
<value-type name="Reference"/>
- <value-type name="VirtualMethods"/>
-
<value-type name="ImplicitConv"/>
+
+ <value-type name="VirtualMethods">
+ <modify-function signature="sum0(int, int, int)" rename="sumThree"/>
+ <modify-function signature="sum1(int, int, int)">
+ <modify-argument index="3">
+ <replace-default-expression with="1000"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="sum2(int, int, int)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <replace-default-expression with="2000"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="sum3(int, int, int)">
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ %0 = %CONVERTTOPYTHON[%RETURN_TYPE](
+ %CPPSELF.%TYPE::%FUNCTION_NAME(%1, %1+%3, %3)
+ );
+ </inject-code>
+ </modify-function>
+ <modify-function signature="sum4(int, int, int)">
+ <modify-argument index="2">
+ <remove-argument/>
+ <replace-default-expression with="3000"/>
+ </modify-argument>
+ <inject-code class="native" position="beginning">
+ PyObject* new_arg0 = PyInt_FromLong(PyInt_AS_LONG(%PYARG_1) - %2);
+ Py_DECREF(%PYARG_1);
+ %PYARG_1 = new_arg0;
+ </inject-code>
+ </modify-function>
+ <modify-function signature="name()">
+ <inject-code class="native" position="end">
+ PyStr_cptr(%0)->prepend(Str("Pimped"));
+ </inject-code>
+ </modify-function>
+ <modify-function signature="callMe()">
+ <inject-code class="native" position="end">
+ PyGILState_STATE gil_state = PyGILState_Ensure();
+ PyObject_Call(%PYTHON_METHOD_OVERRIDE, %PYTHON_ARGUMENTS, NULL);
+ PyGILState_Release(gil_state);
+ </inject-code>
+ </modify-function>
+ </value-type>
+
<value-type name="InjectCode">
<!--
Various tests for inject codes.