TestClsFunction.test_multiple_args()   A
last analyzed

Complexity

Conditions 3

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
from typing import Tuple, Any, Union
2
from unittest import TestCase
3
4
from typish import ClsDict, EllipsisType, Literal, ClsFunction
5
6
7
class TestClsFunction(TestCase):
8
    def test_invalid_initialization(self):
9
        # Only ClsDict or dict is allowed
10
        with self.assertRaises(TypeError):
11
            ClsFunction(123)
12
13
    def test_instantiation_with_no_callable(self):
14
        with self.assertRaises(TypeError):
15
            ClsFunction({
16
                int: lambda: 1,
17
                str: lambda: 2,
18
                object: 3,  # Invalid!
19
            })
20
21
    def test_with_dict(self):
22
        function = ClsFunction({
23
            int: lambda x: x * 2,
24
            str: lambda x: '{}_'.format(x),
25
        })
26
27
        self.assertEqual(4, function(2))
28
        self.assertEqual('2_', function('2'))
29
30
    def test_with_cls_dict(self):
31
        function = ClsFunction(ClsDict({
32
            int: lambda x: x * 2,
33
            str: lambda x: '{}_'.format(x),
34
        }))
35
36
        self.assertEqual(4, function(2))
37
        self.assertEqual('2_', function('2'))
38
39
    def test_with_iterable_of_tuples(self):
40
        body = [
41
            (int, lambda x: x * 2),
42
            (str, lambda x: '{}_'.format(x)),
43
        ]
44
45
        function_tuple = ClsFunction(body)
46
        function_set = ClsFunction(set(body))
47
        function_list = ClsFunction(list(body))
48
49
        self.assertEqual(4, function_tuple(2))
50
        self.assertEqual('2_', function_tuple('2'))
51
        self.assertEqual(4, function_set(2))
52
        self.assertEqual('2_', function_set('2'))
53
        self.assertEqual(4, function_list(2))
54
        self.assertEqual('2_', function_list('2'))
55
56
    def test_with_callables(self):
57
        def f1(x: int):
58
            return 1
59
60
        class C:
61
            def m1(self, x: str):
62
                return 2
63
64
            @classmethod
65
            def m2(cls, x: float):
66
                return 3
67
68
            @staticmethod
69
            def m3(x: list):
70
                return 4
71
72
        def f2(x):  # No type hint
73
            return 5
74
75
        function = ClsFunction([f1, C().m1, C.m2, C.m3, f2])
76
        self.assertEqual(1, function(42))
77
        self.assertEqual(2, function('hello'))
78
        self.assertEqual(3, function(42.0))
79
        self.assertEqual(4, function([42]))
80
        self.assertEqual(5, function({}))
81
82
    def test_with_invalid_callables(self):
83
        def f():
84
            ...
85
86
        with self.assertRaises(TypeError):
87
            ClsFunction([f])
88
89
    def test_multiple_args(self):
90
        function = ClsFunction({
91
            int: lambda x, y: x * y,
92
            str: lambda x, y: '{}{}'.format(x, y),
93
        })
94
95
        self.assertEqual(6, function(2, 3))
96
        self.assertEqual('23', function('2', 3))
97
98
    def test_understands(self):
99
        function = ClsFunction({
100
            int: lambda _: ...,
101
            str: lambda _: ...,
102
        })
103
        self.assertTrue(function.understands(1))
104
        self.assertTrue(function.understands('2'))
105
        self.assertTrue(not function.understands(3.0))
106
107
    def test_call_no_args(self):
108
        function = ClsFunction({
109
            int: lambda x: 1,
110
        })
111
112
        with self.assertRaises(TypeError):
113
            function()
114
115
    def test_call_invalid_args(self):
116
        function = ClsFunction({
117
            int: lambda x: 1,
118
        })
119
120
        with self.assertRaises(TypeError):
121
            function(1, 2)  # The lambda expects only 1 argument.
122
123
    def test_complex_cls_function(self):
124
        # Test if a more complex ClsFunction can be created without problems.
125
        _Size = Union[int, Literal[Any]]
126
        _Type = Union[type, Literal[Any]]
127
128
        ClsFunction({
129
            _Size: lambda: 1,
130
            _Type: lambda: 2,
131
            Tuple[_Size, _Type]: lambda: 3,
132
            Tuple[_Size, ...]: lambda: 4,
133
            Tuple[Tuple[_Size, ...], _Type]: lambda: 5,
134
            Tuple[Tuple[_Size, EllipsisType], _Type]: lambda: 6,
135
            Tuple[Tuple[Literal[Any], EllipsisType], Literal[Any]]: lambda: 7,
136
        })
137