aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py
blob: 0816662814cb5fe0c551e02976fc31603ce3ea4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/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 case for inplicit converting C++ numeric types.'''

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()
import sys
import sample

# Hardcode the limits of the underlying C-types depending on architecture and memory
# model (taking MSVC using LLP64 into account).
cIntMin = -2147483648
cIntMax = 2147483647
cLongMin = cIntMin
cLongMax = cIntMax
maxRepresentableInt = sys.maxsize
is64bitArchitecture = maxRepresentableInt > 2**32
if is64bitArchitecture and sys.platform != 'win32':
    cLongMin = -9223372036854775808
    cLongMax = 9223372036854775807


class NumericTester(unittest.TestCase):
    '''Helper class for numeric comparison testing'''

    def assertRaises(self, *args, **kwds):
        if not hasattr(sys, "pypy_version_info"):
            # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
            return super().assertRaises(*args, **kwds)

    def check_value(self, source, expected, callback, desired_type=None):
        result = callback(source)
        self.assertEqual(result, expected)

        if desired_type:
            self.assertEqual(type(result), desired_type)


class FloatImplicitConvert(NumericTester):
    '''Test case for implicit converting C++ numeric types.'''

    def testFloatAsInt(self):
        '''Float as Int'''
        self.check_value(3.14, 3, sample.acceptInt, int)
        self.assertRaises(OverflowError, sample.acceptInt, cIntMax + 400)

    def testFloatAsLong(self):
        '''Float as Long'''
        #C++ longs are python ints for us
        self.check_value(3.14, 3, sample.acceptLong, int)
        self.assertRaises(OverflowError, sample.acceptLong, cLongMax + 400)

    def testFloatAsUInt(self):
        '''Float as unsigned Int'''
        self.check_value(3.14, 3, sample.acceptUInt, int)
        self.assertRaises(OverflowError, sample.acceptUInt, -3.14)

    def testFloatAsULong(self):
        '''Float as unsigned Long'''
        #FIXME Breaking with SystemError "bad argument to internal function"
        self.check_value(3.14, 3, sample.acceptULong, int)
        self.assertRaises(OverflowError, sample.acceptULong, -3.14)

    def testFloatAsDouble(self):
        '''Float as double'''
        self.check_value(3.14, 3.14, sample.acceptDouble, float)


class IntImplicitConvert(NumericTester):
    '''Test case for implicit converting C++ numeric types.'''

    def testIntAsInt(self):
        '''Int as Int'''
        self.check_value(3, 3, sample.acceptInt, int)

    def testIntAsLong(self):
        '''Int as Long'''
        self.check_value(3, 3, sample.acceptLong, int)

        # cLongMax goes here as CPython implements int as a C long
        self.check_value(cLongMax, cLongMax, sample.acceptLong, int)
        self.check_value(cLongMin, cLongMin, sample.acceptLong, int)

    def testIntAsUInt(self):
        '''Int as unsigned Int'''
        self.check_value(3, 3, sample.acceptUInt, int)
        self.assertRaises(OverflowError, sample.acceptUInt, -3)

    def testIntAsULong(self):
        '''Int as unsigned Long'''
        self.check_value(3, 3, sample.acceptULong, int)
        self.assertRaises(OverflowError, sample.acceptULong, -3)

    def testFloatAsDouble(self):
        '''Float as double'''
        self.check_value(3.14, 3.14, sample.acceptDouble, float)


class LongImplicitConvert(NumericTester):
    '''Test case for implicit converting C++ numeric types.'''

    def testLongAsInt(self):
        '''Long as Int'''
        self.check_value(24224, 24224, sample.acceptInt, int)
        self.assertRaises(OverflowError, sample.acceptInt, cIntMax + 20)

    def testLongAsLong(self):
        '''Long as Long'''
        self.check_value(2405, 2405, sample.acceptLong, int)
        self.assertRaises(OverflowError, sample.acceptLong, cLongMax + 20)

    def testLongAsUInt(self):
        '''Long as unsigned Int'''
        self.check_value(260, 260, sample.acceptUInt, int)
        self.assertRaises(OverflowError, sample.acceptUInt, -42)

    def testLongAsULong(self):
        '''Long as unsigned Long'''
        self.check_value(128, 128, sample.acceptULong, int)
        self.assertRaises(OverflowError, sample.acceptULong, -334)

    def testLongAsDouble(self):
        '''Float as double'''
        self.check_value(42, 42, sample.acceptDouble, float)


if __name__ == '__main__':
    unittest.main()