1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# 4############################################################################# 5## 6## Copyright (C) 2016 The Qt Company Ltd. 7## Contact: https://www.qt.io/licensing/ 8## 9## This file is part of the test suite of Qt for Python. 10## 11## $QT_BEGIN_LICENSE:GPL-EXCEPT$ 12## Commercial License Usage 13## Licensees holding valid commercial Qt licenses may use this file in 14## accordance with the commercial license agreement provided with the 15## Software or, alternatively, in accordance with the terms contained in 16## a written agreement between you and The Qt Company. For licensing terms 17## and conditions see https://www.qt.io/terms-conditions. For further 18## information use the contact form at https://www.qt.io/contact-us. 19## 20## GNU General Public License Usage 21## Alternatively, this file may be used under the terms of the GNU 22## General Public License version 3 as published by the Free Software 23## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 24## included in the packaging of this file. Please review the following 25## information to ensure the GNU General Public License requirements will 26## be met: https://www.gnu.org/licenses/gpl-3.0.html. 27## 28## $QT_END_LICENSE$ 29## 30############################################################################# 31 32'''Test cases for multiple inheritance''' 33 34import os 35import sys 36import unittest 37 38sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 39from shiboken_paths import init_paths 40init_paths() 41 42from sample import Base1, Base2, Base3, Base4, Base5, Base6 43from sample import MDerived1, MDerived2, MDerived3, MDerived4, MDerived5, SonOfMDerived1 44 45class ExtMDerived1(MDerived1): 46 def __init__(self): 47 MDerived1.__init__(self) 48 self.multiplier = 20 49 self.base2Method_called = False 50 def base2Method(self): 51 return Base2.base2Method(self) * self.multiplier 52 53class MultipleDerivedTest(unittest.TestCase): 54 '''Test cases for multiple inheritance''' 55 56 def testIsInstance(self): 57 '''MDerived1 is instance of its parents Base1 and Base2.''' 58 a = MDerived1() 59 self.assertTrue(isinstance(a, MDerived1)) 60 self.assertTrue(isinstance(a, Base1)) 61 self.assertTrue(isinstance(a, Base2)) 62 63 def testIsSubclass(self): 64 '''MDerived1 is subclass of its parents Base1 and Base2.''' 65 self.assertTrue(issubclass(MDerived1, Base1)) 66 self.assertTrue(issubclass(MDerived1, Base2)) 67 68 def testCallToFunctionWithBase1ArgumentThatCastsBackToMDerived1(self): 69 '''MDerived1 is passed as an Base1 argument to a method that returns it casted back to MDerived1.''' 70 a = MDerived1() 71 b = MDerived1.transformFromBase1(a) 72 self.assertEqual(a, b) 73 74 def testCallToFunctionWithBase2ArgumentThatCastsBackToMDerived1(self): 75 '''MDerived1 is passed as an Base2 argument to a method that returns it casted back to MDerived1.''' 76 a = MDerived1() 77 b = MDerived1.transformFromBase2(a) 78 self.assertEqual(a, b) 79 80 def testPythonClassIsInstance(self): 81 '''Python defined class ExtMDerived1 is instance of its parents MDerived1, Base1 and Base2.''' 82 a = ExtMDerived1() 83 self.assertTrue(isinstance(a, ExtMDerived1)) 84 self.assertTrue(isinstance(a, MDerived1)) 85 self.assertTrue(isinstance(a, Base1)) 86 self.assertTrue(isinstance(a, Base2)) 87 88 def testPythonClassIsSubclass(self): 89 '''Python defined class ExtMDerived1 is subclass of its parents MDerived1, Base1 and Base2.''' 90 self.assertTrue(issubclass(ExtMDerived1, MDerived1)) 91 self.assertTrue(issubclass(ExtMDerived1, Base1)) 92 self.assertTrue(issubclass(ExtMDerived1, Base2)) 93 94 def testCastFromMDerived1ToBases(self): 95 '''MDerived1 is casted by C++ to its parents and the binding must return the MDerived1 wrapper.''' 96 a = MDerived1() 97 refcnt = sys.getrefcount(a) 98 b1 = a.castToBase1() 99 b2 = a.castToBase2() 100 self.assertTrue(isinstance(b1, MDerived1)) 101 self.assertTrue(isinstance(b2, MDerived1)) 102 self.assertEqual(a, b1) 103 self.assertEqual(a, b2) 104 self.assertEqual(sys.getrefcount(a), refcnt + 2) 105 106 def testCastFromExtMDerived1ToMDerived1Bases(self): 107 '''Python defined class ExtMDerived1 is casted by C++ to MDerived1 parents and the binding must return the correct ExtMDerived1 instance.''' 108 a = ExtMDerived1() 109 refcnt = sys.getrefcount(a) 110 b1 = a.castToBase1() 111 self.assertTrue(isinstance(b1, MDerived1)) 112 self.assertTrue(isinstance(b1, ExtMDerived1)) 113 b2 = a.castToBase2() 114 self.assertTrue(isinstance(b2, MDerived1)) 115 self.assertTrue(isinstance(b2, ExtMDerived1)) 116 self.assertEqual(a, b1) 117 self.assertEqual(a, b2) 118 self.assertEqual(sys.getrefcount(a), refcnt + 2) 119 120 def testCastFromSonOfMDerived1ToBases(self): 121 '''SonOfMDerived1 is casted by C++ to its parents and the binding must return the SonOfMDerived1 wrapper.''' 122 a = SonOfMDerived1() 123 refcnt = sys.getrefcount(a) 124 md1 = a.castToMDerived1() 125 b1 = a.castToBase1() 126 b2 = a.castToBase2() 127 self.assertTrue(isinstance(md1, SonOfMDerived1)) 128 self.assertTrue(isinstance(b2, SonOfMDerived1)) 129 self.assertTrue(isinstance(b2, SonOfMDerived1)) 130 self.assertEqual(a, md1) 131 self.assertEqual(a, b1) 132 self.assertEqual(a, b2) 133 self.assertEqual(sys.getrefcount(a), refcnt + 3) 134 135 def testReimplementedBase2VirtualMethodOnClassInheritingFromMDerived1(self): 136 a = ExtMDerived1() 137 value = a.base2Method() 138 self.assertTrue(value, Base2.base2Method(a) * a.multiplier) 139 140 def testCastFromMDerived2ToBases(self): 141 '''MDerived2 is casted by C++ to its parents and the binding must return the MDerived2 wrapper.''' 142 a = MDerived2() 143 refcnt = sys.getrefcount(a) 144 b3 = a.castToBase3() 145 b4 = a.castToBase4() 146 b5 = a.castToBase5() 147 b6 = a.castToBase6() 148 self.assertTrue(isinstance(b3, MDerived2)) 149 self.assertTrue(isinstance(b4, MDerived2)) 150 self.assertTrue(isinstance(b5, MDerived2)) 151 self.assertTrue(isinstance(b6, MDerived2)) 152 self.assertEqual(a, b3) 153 self.assertEqual(a, b4) 154 self.assertEqual(a, b5) 155 self.assertEqual(a, b6) 156 self.assertEqual(sys.getrefcount(a), refcnt + 4) 157 158 def testCastFromMDerived3ToBases(self): 159 '''MDerived3 is casted by C++ to its parents and the binding must return the MDerived3 wrapper.''' 160 a = MDerived3() 161 refcnt = sys.getrefcount(a) 162 md1 = a.castToMDerived1() 163 md2 = a.castToMDerived2() 164 b1 = a.castToBase1() 165 b2 = a.castToBase2() 166 b3 = a.castToBase3() 167 b4 = a.castToBase4() 168 b5 = a.castToBase5() 169 b6 = a.castToBase6() 170 self.assertTrue(isinstance(md1, MDerived3)) 171 self.assertTrue(isinstance(md2, MDerived3)) 172 self.assertTrue(isinstance(b1, MDerived3)) 173 self.assertTrue(isinstance(b2, MDerived3)) 174 self.assertTrue(isinstance(b3, MDerived3)) 175 self.assertTrue(isinstance(b4, MDerived3)) 176 self.assertTrue(isinstance(b5, MDerived3)) 177 self.assertTrue(isinstance(b6, MDerived3)) 178 self.assertEqual(a, md1) 179 self.assertEqual(a, md2) 180 self.assertEqual(a, b1) 181 self.assertEqual(a, b2) 182 self.assertEqual(a, b3) 183 self.assertEqual(a, b4) 184 self.assertEqual(a, b5) 185 self.assertEqual(a, b6) 186 self.assertEqual(sys.getrefcount(a), refcnt + 8) 187 188 def testCastFromMDerived4ToBases(self): 189 '''MDerived4 is casted by C++ to its parents and the binding must return the MDerived4 wrapper.''' 190 a = MDerived4() 191 refcnt = sys.getrefcount(a) 192 b3 = a.castToBase3() 193 b4 = a.castToBase4() 194 self.assertTrue(isinstance(b3, MDerived4)) 195 self.assertTrue(isinstance(b4, MDerived4)) 196 self.assertEqual(a, b3) 197 self.assertEqual(a, b4) 198 self.assertEqual(sys.getrefcount(a), refcnt + 2) 199 200 def testCastFromMDerived5ToBases(self): 201 '''MDerived5 is casted by C++ to its parents and the binding must return the MDerived5 wrapper.''' 202 a = MDerived5() 203 refcnt = sys.getrefcount(a) 204 b3 = a.castToBase3() 205 b4 = a.castToBase4() 206 self.assertTrue(isinstance(b3, MDerived5)) 207 self.assertTrue(isinstance(b4, MDerived5)) 208 self.assertEqual(a, b3) 209 self.assertEqual(a, b4) 210 self.assertEqual(sys.getrefcount(a), refcnt + 2) 211 212 def testCastFromMDerived3ToBase3(self): 213 '''MDerived3 is casted by C++ to Base3 grandparent using both the inherited and reimplement castToBase3 methods.''' 214 a = MDerived3() 215 refcnt = sys.getrefcount(a) 216 b3_reimplemented = a.castToBase3() 217 b3_inherited = MDerived2.castToBase3(a) 218 self.assertTrue(isinstance(b3_reimplemented, MDerived3)) 219 self.assertTrue(isinstance(b3_inherited, MDerived3)) 220 self.assertEqual(a, b3_reimplemented) 221 self.assertEqual(a, b3_inherited) 222 self.assertEqual(sys.getrefcount(a), refcnt + 2) 223 224if __name__ == '__main__': 225 unittest.main() 226 227