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
|
from typing import Tuple, Any, Union
from unittest import TestCase
from typish import ClsDict, EllipsisType, Literal, ClsFunction
class TestClsFunction(TestCase):
def test_invalid_initialization(self):
# Only ClsDict or dict is allowed
with self.assertRaises(TypeError):
ClsFunction(123)
def test_instantiation_with_no_callable(self):
with self.assertRaises(TypeError):
ClsFunction({
int: lambda: 1,
str: lambda: 2,
object: 3, # Invalid!
})
def test_with_dict(self):
function = ClsFunction({
int: lambda x: x * 2,
str: lambda x: '{}_'.format(x),
})
self.assertEqual(4, function(2))
self.assertEqual('2_', function('2'))
def test_with_cls_dict(self):
function = ClsFunction(ClsDict({
int: lambda x: x * 2,
str: lambda x: '{}_'.format(x),
}))
self.assertEqual(4, function(2))
self.assertEqual('2_', function('2'))
def test_with_iterable_of_tuples(self):
body = [
(int, lambda x: x * 2),
(str, lambda x: '{}_'.format(x)),
]
function_tuple = ClsFunction(body)
function_set = ClsFunction(set(body))
function_list = ClsFunction(list(body))
self.assertEqual(4, function_tuple(2))
self.assertEqual('2_', function_tuple('2'))
self.assertEqual(4, function_set(2))
self.assertEqual('2_', function_set('2'))
self.assertEqual(4, function_list(2))
self.assertEqual('2_', function_list('2'))
def test_with_callables(self):
def f1(x: int):
return 1
class C:
def m1(self, x: str):
return 2
@classmethod
def m2(cls, x: float):
return 3
@staticmethod
def m3(x: list):
return 4
def f2(x): # No type hint
return 5
function = ClsFunction([f1, C().m1, C.m2, C.m3, f2])
self.assertEqual(1, function(42))
self.assertEqual(2, function('hello'))
self.assertEqual(3, function(42.0))
self.assertEqual(4, function([42]))
self.assertEqual(5, function({}))
def test_with_invalid_callables(self):
def f():
...
with self.assertRaises(TypeError):
ClsFunction([f])
def test_multiple_args(self):
function = ClsFunction({
int: lambda x, y: x * y,
str: lambda x, y: '{}{}'.format(x, y),
})
self.assertEqual(6, function(2, 3))
self.assertEqual('23', function('2', 3))
def test_understands(self):
function = ClsFunction({
int: lambda _: ...,
str: lambda _: ...,
})
self.assertTrue(function.understands(1))
self.assertTrue(function.understands('2'))
self.assertTrue(not function.understands(3.0))
def test_call_no_args(self):
function = ClsFunction({
int: lambda x: 1,
})
with self.assertRaises(TypeError):
function()
def test_call_invalid_args(self):
function = ClsFunction({
int: lambda x: 1,
})
with self.assertRaises(TypeError):
function(1, 2) # The lambda expects only 1 argument.
def test_complex_cls_function(self):
# Test if a more complex ClsFunction can be created without problems.
_Size = Union[int, Literal[Any]]
_Type = Union[type, Literal[Any]]
ClsFunction({
_Size: lambda: 1,
_Type: lambda: 2,
Tuple[_Size, _Type]: lambda: 3,
Tuple[_Size, ...]: lambda: 4,
Tuple[Tuple[_Size, ...], _Type]: lambda: 5,
Tuple[Tuple[_Size, EllipsisType], _Type]: lambda: 6,
Tuple[Tuple[Literal[Any], EllipsisType], Literal[Any]]: lambda: 7,
})
|