aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/tests/samplebinding/multiple_derived_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/tests/samplebinding/multiple_derived_test.py')
-rw-r--r--sources/shiboken6/tests/samplebinding/multiple_derived_test.py223
1 files changed, 223 insertions, 0 deletions
diff --git a/sources/shiboken6/tests/samplebinding/multiple_derived_test.py b/sources/shiboken6/tests/samplebinding/multiple_derived_test.py
new file mode 100644
index 000000000..7497714a8
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/multiple_derived_test.py
@@ -0,0 +1,223 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for multiple inheritance'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from shiboken_paths import init_paths
+init_paths()
+
+from sample import Base1, Base2
+from sample import MDerived1, MDerived2, MDerived3, MDerived4, MDerived5, SonOfMDerived1
+
+
+class ExtMDerived1(MDerived1):
+ def __init__(self):
+ MDerived1.__init__(self)
+ self.multiplier = 20
+ self.base2Method_called = False
+
+ def base2Method(self):
+ return Base2.base2Method(self) * self.multiplier
+
+
+class MultipleDerivedTest(unittest.TestCase):
+ '''Test cases for multiple inheritance'''
+
+ def testIsInstance(self):
+ '''MDerived1 is instance of its parents Base1 and Base2.'''
+ a = MDerived1()
+ self.assertTrue(isinstance(a, MDerived1))
+ self.assertTrue(isinstance(a, Base1))
+ self.assertTrue(isinstance(a, Base2))
+
+ def testIsSubclass(self):
+ '''MDerived1 is subclass of its parents Base1 and Base2.'''
+ self.assertTrue(issubclass(MDerived1, Base1))
+ self.assertTrue(issubclass(MDerived1, Base2))
+
+ def testCallToFunctionWithBase1ArgumentThatCastsBackToMDerived1(self):
+ '''MDerived1 is passed as an Base1 argument to a method that returns
+ it casted back to MDerived1.'''
+ a = MDerived1()
+ b = MDerived1.transformFromBase1(a)
+ self.assertEqual(a, b)
+
+ def testCallToFunctionWithBase2ArgumentThatCastsBackToMDerived1(self):
+ '''MDerived1 is passed as an Base2 argument to a method that returns
+ it casted back to MDerived1.'''
+ a = MDerived1()
+ b = MDerived1.transformFromBase2(a)
+ self.assertEqual(a, b)
+
+ def testPythonClassIsInstance(self):
+ '''Python defined class ExtMDerived1 is instance of its parents
+ MDerived1, Base1 and Base2.'''
+ a = ExtMDerived1()
+ self.assertTrue(isinstance(a, ExtMDerived1))
+ self.assertTrue(isinstance(a, MDerived1))
+ self.assertTrue(isinstance(a, Base1))
+ self.assertTrue(isinstance(a, Base2))
+
+ def testPythonClassIsSubclass(self):
+ '''Python defined class ExtMDerived1 is subclass of its parents
+ MDerived1, Base1 and Base2.'''
+ self.assertTrue(issubclass(ExtMDerived1, MDerived1))
+ self.assertTrue(issubclass(ExtMDerived1, Base1))
+ self.assertTrue(issubclass(ExtMDerived1, Base2))
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromMDerived1ToBases(self):
+ '''MDerived1 is casted by C++ to its parents and the binding must return the
+ MDerived1 wrapper.'''
+ a = MDerived1()
+ refcnt = sys.getrefcount(a)
+ b1 = a.castToBase1()
+ b2 = a.castToBase2()
+ self.assertTrue(isinstance(b1, MDerived1))
+ self.assertTrue(isinstance(b2, MDerived1))
+ self.assertEqual(a, b1)
+ self.assertEqual(a, b2)
+ self.assertEqual(sys.getrefcount(a), refcnt + 2)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromExtMDerived1ToMDerived1Bases(self):
+ '''Python defined class ExtMDerived1 is casted by C++ to MDerived1 parents
+ and the binding must return the correct ExtMDerived1 instance.'''
+ a = ExtMDerived1()
+ refcnt = sys.getrefcount(a)
+ b1 = a.castToBase1()
+ self.assertTrue(isinstance(b1, MDerived1))
+ self.assertTrue(isinstance(b1, ExtMDerived1))
+ b2 = a.castToBase2()
+ self.assertTrue(isinstance(b2, MDerived1))
+ self.assertTrue(isinstance(b2, ExtMDerived1))
+ self.assertEqual(a, b1)
+ self.assertEqual(a, b2)
+ self.assertEqual(sys.getrefcount(a), refcnt + 2)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromSonOfMDerived1ToBases(self):
+ '''SonOfMDerived1 is casted by C++ to its parents and the binding must return
+ the SonOfMDerived1 wrapper.'''
+ a = SonOfMDerived1()
+ refcnt = sys.getrefcount(a)
+ md1 = a.castToMDerived1()
+ b1 = a.castToBase1()
+ b2 = a.castToBase2()
+ self.assertTrue(isinstance(md1, SonOfMDerived1))
+ self.assertTrue(isinstance(b2, SonOfMDerived1))
+ self.assertTrue(isinstance(b2, SonOfMDerived1))
+ self.assertEqual(a, md1)
+ self.assertEqual(a, b1)
+ self.assertEqual(a, b2)
+ self.assertEqual(sys.getrefcount(a), refcnt + 3)
+
+ def testReimplementedBase2VirtualMethodOnClassInheritingFromMDerived1(self):
+ a = ExtMDerived1()
+ value = a.base2Method()
+ self.assertTrue(value, Base2.base2Method(a) * a.multiplier)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromMDerived2ToBases(self):
+ '''MDerived2 is casted by C++ to its parents and the binding must
+ return the MDerived2 wrapper.'''
+ a = MDerived2()
+ refcnt = sys.getrefcount(a)
+ b3 = a.castToBase3()
+ b4 = a.castToBase4()
+ b5 = a.castToBase5()
+ b6 = a.castToBase6()
+ self.assertTrue(isinstance(b3, MDerived2))
+ self.assertTrue(isinstance(b4, MDerived2))
+ self.assertTrue(isinstance(b5, MDerived2))
+ self.assertTrue(isinstance(b6, MDerived2))
+ self.assertEqual(a, b3)
+ self.assertEqual(a, b4)
+ self.assertEqual(a, b5)
+ self.assertEqual(a, b6)
+ self.assertEqual(sys.getrefcount(a), refcnt + 4)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromMDerived3ToBases(self):
+ '''MDerived3 is casted by C++ to its parents and the binding must
+ return the MDerived3 wrapper.'''
+ a = MDerived3()
+ refcnt = sys.getrefcount(a)
+ md1 = a.castToMDerived1()
+ md2 = a.castToMDerived2()
+ b1 = a.castToBase1()
+ b2 = a.castToBase2()
+ b3 = a.castToBase3()
+ b4 = a.castToBase4()
+ b5 = a.castToBase5()
+ b6 = a.castToBase6()
+ self.assertTrue(isinstance(md1, MDerived3))
+ self.assertTrue(isinstance(md2, MDerived3))
+ self.assertTrue(isinstance(b1, MDerived3))
+ self.assertTrue(isinstance(b2, MDerived3))
+ self.assertTrue(isinstance(b3, MDerived3))
+ self.assertTrue(isinstance(b4, MDerived3))
+ self.assertTrue(isinstance(b5, MDerived3))
+ self.assertTrue(isinstance(b6, MDerived3))
+ self.assertEqual(a, md1)
+ self.assertEqual(a, md2)
+ self.assertEqual(a, b1)
+ self.assertEqual(a, b2)
+ self.assertEqual(a, b3)
+ self.assertEqual(a, b4)
+ self.assertEqual(a, b5)
+ self.assertEqual(a, b6)
+ self.assertEqual(sys.getrefcount(a), refcnt + 8)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromMDerived4ToBases(self):
+ '''MDerived4 is casted by C++ to its parents and the binding must
+ return the MDerived4 wrapper.'''
+ a = MDerived4()
+ refcnt = sys.getrefcount(a)
+ b3 = a.castToBase3()
+ b4 = a.castToBase4()
+ self.assertTrue(isinstance(b3, MDerived4))
+ self.assertTrue(isinstance(b4, MDerived4))
+ self.assertEqual(a, b3)
+ self.assertEqual(a, b4)
+ self.assertEqual(sys.getrefcount(a), refcnt + 2)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromMDerived5ToBases(self):
+ '''MDerived5 is casted by C++ to its parents and the binding must
+ return the MDerived5 wrapper.'''
+ a = MDerived5()
+ refcnt = sys.getrefcount(a)
+ b3 = a.castToBase3()
+ b4 = a.castToBase4()
+ self.assertTrue(isinstance(b3, MDerived5))
+ self.assertTrue(isinstance(b4, MDerived5))
+ self.assertEqual(a, b3)
+ self.assertEqual(a, b4)
+ self.assertEqual(sys.getrefcount(a), refcnt + 2)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromMDerived3ToBase3(self):
+ '''MDerived3 is casted by C++ to Base3 grandparent using both the inherited
+ and reimplement castToBase3 methods.'''
+ a = MDerived3()
+ refcnt = sys.getrefcount(a)
+ b3_reimplemented = a.castToBase3()
+ b3_inherited = MDerived2.castToBase3(a)
+ self.assertTrue(isinstance(b3_reimplemented, MDerived3))
+ self.assertTrue(isinstance(b3_inherited, MDerived3))
+ self.assertEqual(a, b3_reimplemented)
+ self.assertEqual(a, b3_inherited)
+ self.assertEqual(sys.getrefcount(a), refcnt + 2)
+
+
+if __name__ == '__main__':
+ unittest.main()