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 methods that receive references to objects.'''
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 *
43
44class ExtendedReference(Reference):
45    def __init__(self):
46        Reference.__init__(self)
47        self.uses_reference_virtual_called = False
48        self.uses_const_reference_virtual_called = False
49        self.reference_inc = 1
50        self.const_reference_inc = 2
51        self.multiplier = 333
52
53    def usesReferenceVirtual(self, ref, inc):
54        self.uses_reference_virtual_called = True
55        return ref.objId() + inc + self.reference_inc
56
57    def usesConstReferenceVirtual(self, ref, inc):
58        self.uses_const_reference_virtual_called = True
59        return ref.objId() + inc + self.const_reference_inc
60
61    def alterReferenceIdVirtual(self, ref):
62        ref.setObjId(ref.objId() * self.multiplier)
63
64
65class ReferenceTest(unittest.TestCase):
66    '''Test case for methods that receive references to objects.'''
67
68    def testMethodThatReceivesReference(self):
69        '''Test a method that receives a reference to an object as argument.'''
70        objId = 123
71        r = Reference(objId)
72        self.assertEqual(Reference.usesReference(r), objId)
73
74    def testCantSegFaultWhenReceiveNone(self):
75        '''do not segfault when receiving None as argument.'''
76        s = Str()
77        self.assertTrue(None == s)
78
79    def testMethodThatReceivesConstReference(self):
80        '''Test a method that receives a const reference to an object as argument.'''
81        objId = 123
82        r = Reference(objId)
83        self.assertEqual(Reference.usesConstReference(r), objId)
84
85    def testModificationOfReference(self):
86        '''Tests if the identity of a reference argument is preserved when passing it to be altered in C++.'''
87        objId = 123
88        r1 = Reference(objId)
89        r1.alterReferenceIdVirtual(r1)
90        self.assertEqual(r1.objId(), objId * Reference.multiplier())
91
92    def testModificationOfReferenceCallingAVirtualIndirectly(self):
93        '''Tests if the identity of a reference argument is preserved when passing it to be altered in C++ through a method that calls a virtual method.'''
94        objId = 123
95        r1 = Reference(objId)
96        r1.callAlterReferenceIdVirtual(r1)
97        self.assertEqual(r1.objId(), objId * Reference.multiplier())
98
99    def testModificationOfReferenceCallingAReimplementedVirtualIndirectly(self):
100        '''Test if a Python override of a virtual method with a reference parameter called from C++ alters the argument properly.'''
101        objId = 123
102        r = Reference(objId)
103        er = ExtendedReference()
104        result = er.callAlterReferenceIdVirtual(r)
105        self.assertEqual(r.objId(), objId * er.multiplier)
106
107    def testReimplementedVirtualMethodCallWithReferenceParameter(self):
108        '''Test if a Python override of a virtual method with a reference parameter is correctly called from C++.'''
109        inc = 9
110        objId = 123
111        r = Reference(objId)
112        er = ExtendedReference()
113        result = er.callUsesReferenceVirtual(r, inc)
114        self.assertEqual(result, objId + inc + er.reference_inc)
115
116    def testReimplementedVirtualMethodCallWithConstReferenceParameter(self):
117        '''Test if a Python override of a virtual method with a const reference parameter is correctly called from C++.'''
118        inc = 9
119        objId = 123
120        r = Reference(objId)
121        er = ExtendedReference()
122        result = er.callUsesConstReferenceVirtual(r, inc)
123        self.assertEqual(result, objId + inc + er.const_reference_inc)
124
125if __name__ == '__main__':
126    unittest.main()
127
128