teddecor.UnitTest.Asserts.AssertThat
1from __future__ import annotations 2 3from typing import Any, Callable, Union, Dict 4 5from ...TED.markup import TED 6from ...Exceptions import RangedException 7 8 9__all__ = ["assertThat", "Matcher", "Raises", "eq", "gt", "lt"] 10 11 12def stringify(value: Union[tuple[Any], list[Any], Dict[str, Any]]) -> str: 13 output = [] 14 if type(value) in (tuple, list): 15 for elem in value: 16 output.append(str(elem)) 17 elif isinstance(value, dict): 18 for key, elem in value.items(): 19 output.append(f"{key}={elem}") 20 21 return ", ".join(output) 22 23 24def check_args( 25 args: Union[list[Any], tuple[Any]], 26 kwargs: Dict[str, Any], 27 arg_count: int = 1, 28 arg_and_kwarg: bool = False, 29 vkwargs: list[str] = [], 30) -> bool: 31 params = [stringify(args), stringify(kwargs)] 32 if "" in params: 33 params.remove("") 34 params = ", ".join(params) 35 if not arg_and_kwarg and len(args) > 0 and len(kwargs) > 0: 36 RangedException( 37 TED.encode(f"_is({params})"), 38 "Too many values to compare", 39 5, 40 5 + len(params), 41 "Can not have args and kwargs at the same time", 42 ).throw() 43 elif len(args) > arg_count: 44 RangedException( 45 TED.encode(f"_is({params})"), 46 "Too many values to compare", 47 5, 48 5 + len(params), 49 "Too many arguments", 50 ).throw() 51 else: 52 for key, value in kwargs.items(): 53 if key not in vkwargs: 54 RangedException( 55 TED.encode(f"{key}={value}"), 56 "Too many values to compare", 57 0, 58 len(f"{key}"), 59 "Invalid keyword argument", 60 ).throw() 61 62 return True 63 64 65def Matcher(func: Callable): 66 """Wraps a matcher for assertThat. 67 68 Args: 69 func (Callable): The matcher function that will return a callable to match against the actual value in assertThat. 70 71 Note: 72 Matchers must return functions that raise AssertionError when a condition is not met. 73 """ 74 75 def inner(*args, **kwargs): 76 return func(*args, **kwargs) 77 78 return inner 79 80 81def assertThat(actual: Any, matcher: Matcher) -> None: 82 """Passes the actual value into the matcher. 83 84 Args: 85 actual (Any): The value to pass to the matcher 86 matcher (Matcher): Matcher function that checks a condition 87 88 Raises: 89 AssertionError: If the matcher's condition fails 90 """ 91 matcher(actual) 92 93 94@Matcher 95def eq(*args, **kwargs) -> Callable: 96 """Assert that the actual value is equal to the expected value. 97 98 Returns: 99 Callable: A matcher that checks if the actual is equal to the expected. 100 """ 101 102 def equal(actual: Any): 103 """Assert that the actual value is the same type and equal to the expected value. 104 105 Args: 106 actual (Any): Any value that is matched against the argument value. 107 108 Raises: 109 AssertionError: If the actual value is the incorrect type. 110 AssertionError: If the actual value does not equal the expected. 111 """ 112 113 expected: Any = args[0] 114 """Expected value that actual should match""" 115 116 if not isinstance(actual, type(expected)): 117 raise AssertionError(f"Expected {type(expected)} but found {type(actual)}") 118 elif actual != expected: 119 raise AssertionError("Actual value is not equal to the expected value.") 120 121 if check_args(args=args, kwargs=kwargs): 122 return equal 123 124 125class Raises: 126 """Assert that the code ran inside the `with` keyword raises an exception.""" 127 128 def __init__(self, exception: Exception = Exception): 129 self._exception = exception 130 131 def __enter__(self): 132 return self 133 134 def __exit__(self, exc_type, exc_val, exc_tb): 135 if exc_val is not None: 136 if not isinstance(exc_val, self._exception): 137 raise AssertionError( 138 f"Unexpected exception raised {exc_val.__class__}" 139 ) from exc_val 140 else: 141 return True 142 else: 143 raise AssertionError("No exception raised") 144 145 146@Matcher 147def gt(*args, **kwargs) -> Callable: 148 """Assert that the actual value is greater than the expected value. 149 150 Returns: 151 Callable: A matcher that checks if the actual is greater than the expected. 152 """ 153 154 def greater_than(actual: Any): 155 """Assert that the actual value is the same type and greater than the expected value. 156 157 Args: 158 actual (Any): Any value that is matched against the argument value. 159 160 Raises: 161 AssertionError: If the actual value is the incorrect type. 162 AssertionError: If the actual value is less than the expected. 163 """ 164 165 expected: Any = args[0] 166 """Expected value that actual should match""" 167 168 if not isinstance(actual, type(expected)): 169 raise AssertionError(f"Expected {type(expected)} but found {type(actual)}") 170 elif actual < expected: 171 raise AssertionError("Actual value is less than the expected value.") 172 173 if check_args(args=args, kwargs=kwargs): 174 return greater_than 175 176 177@Matcher 178def lt(*args, **kwargs) -> Callable: 179 """Assert that the actual value is less than the expected value. 180 181 Returns: 182 Callable: A matcher that checks if the actual is less than the expected. 183 """ 184 185 def less_than(actual: Any): 186 """Assert that the actual value is the same type and less than the expected value. 187 188 Args: 189 actual (Any): Any value that is matched against the argument value. 190 191 Raises: 192 AssertionError: If the actual value is the incorrect type. 193 AssertionError: If the actual value is greater than the expected. 194 """ 195 196 expected: Any = args[0] 197 """Expected value that actual should match""" 198 199 if not isinstance(actual, type(expected)): 200 raise AssertionError(f"Expected {type(expected)} but found {type(actual)}") 201 elif actual > expected: 202 raise AssertionError("Actual value is greater than the expected value.") 203 204 if check_args(args=args, kwargs=kwargs): 205 return less_than
def
assertThat(actual: Any, matcher: <function Matcher>) -> None:
82def assertThat(actual: Any, matcher: Matcher) -> None: 83 """Passes the actual value into the matcher. 84 85 Args: 86 actual (Any): The value to pass to the matcher 87 matcher (Matcher): Matcher function that checks a condition 88 89 Raises: 90 AssertionError: If the matcher's condition fails 91 """ 92 matcher(actual)
Passes the actual value into the matcher.
Args: actual (Any): The value to pass to the matcher matcher (Matcher): Matcher function that checks a condition
Raises: AssertionError: If the matcher's condition fails
def
Matcher(func: Callable)
66def Matcher(func: Callable): 67 """Wraps a matcher for assertThat. 68 69 Args: 70 func (Callable): The matcher function that will return a callable to match against the actual value in assertThat. 71 72 Note: 73 Matchers must return functions that raise AssertionError when a condition is not met. 74 """ 75 76 def inner(*args, **kwargs): 77 return func(*args, **kwargs) 78 79 return inner
Wraps a matcher for assertThat.
Args: func (Callable): The matcher function that will return a callable to match against the actual value in assertThat.
Note: Matchers must return functions that raise AssertionError when a condition is not met.
class
Raises:
126class Raises: 127 """Assert that the code ran inside the `with` keyword raises an exception.""" 128 129 def __init__(self, exception: Exception = Exception): 130 self._exception = exception 131 132 def __enter__(self): 133 return self 134 135 def __exit__(self, exc_type, exc_val, exc_tb): 136 if exc_val is not None: 137 if not isinstance(exc_val, self._exception): 138 raise AssertionError( 139 f"Unexpected exception raised {exc_val.__class__}" 140 ) from exc_val 141 else: 142 return True 143 else: 144 raise AssertionError("No exception raised")
Assert that the code ran inside the with
keyword raises an exception.
def
eq(*args, **kwargs)
def
gt(*args, **kwargs)
def
lt(*args, **kwargs)