Passed
Pull Request — master (#13)
by Ramon
01:32
created

TestClsFunction.test_with_callables()   A

Complexity

Conditions 1

Size

Total Lines 26
Code Lines 20

Duplication

Lines 26
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 20
nop 1
dl 26
loc 26
rs 9.4
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 View Code Duplication
class TestClsFunction(TestCase):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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
58
        def f1(x: int):
59
            return 1
60
61
        class C:
62
            def m1(self, x: str):
63
                return 2
64
65
            @classmethod
66
            def m2(cls, x: float):
67
                return 3
68
69
            @staticmethod
70
            def m3(x: list):
71
                return 4
72
73
        def f2(x):  # No type hint
74
            return 5
75
76
        function = ClsFunction([f1, C().m1, C.m2, C.m3, f2])
77
        self.assertEqual(1, function(42))
78
        self.assertEqual(2, function('hello'))
79
        self.assertEqual(3, function(42.0))
80
        self.assertEqual(4, function([42]))
81
        self.assertEqual(5, function({}))
82
83
    def test_with_invalid_callables(self):
84
        def f():
85
            ...
86
87
        with self.assertRaises(TypeError):
88
            ClsFunction([f])
89
90
    def test_multiple_args(self):
91
        function = ClsFunction({
92
            int: lambda x, y: x * y,
93
            str: lambda x, y: '{}{}'.format(x, y),
94
        })
95
96
        self.assertEqual(6, function(2, 3))
97
        self.assertEqual('23', function('2', 3))
98
99
    def test_understands(self):
100
        function = ClsFunction({
101
            int: lambda _: ...,
102
            str: lambda _: ...,
103
        })
104
        self.assertTrue(function.understands(1))
105
        self.assertTrue(function.understands('2'))
106
        self.assertTrue(not function.understands(3.0))
107
108
    def test_call_no_args(self):
109
        function = ClsFunction({
110
            int: lambda x: 1,
111
        })
112
113
        with self.assertRaises(TypeError):
114
            function()
115
116
    def test_call_invalid_args(self):
117
        function = ClsFunction({
118
            int: lambda x: 1,
119
        })
120
121
        with self.assertRaises(TypeError):
122
            function(1, 2)  # The lambda expects only 1 argument.
123
124
    def test_complex_cls_function(self):
125
        # Test if a more complex ClsFunction can be created without problems.
126
        _Size = Union[int, Literal[Any]]
127
        _Type = Union[type, Literal[Any]]
128
129
        ClsFunction({
130
            _Size: lambda: 1,
131
            _Type: lambda: 2,
132
            Tuple[_Size, _Type]: lambda: 3,
133
            Tuple[_Size, ...]: lambda: 4,
134
            Tuple[Tuple[_Size, ...], _Type]: lambda: 5,
135
            Tuple[Tuple[_Size, EllipsisType], _Type]: lambda: 6,
136
            Tuple[Tuple[Literal[Any], EllipsisType], Literal[Any]]: lambda: 7,
137
        })
138