This repository has been archived by the owner on Jun 24, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
object_match.py
40 lines (30 loc) · 1.54 KB
/
object_match.py
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
""" ObjectMatch: test an object for a partial match """
class ObjectMatch:
""" Unit test helper: an object for == comparisons with other objects field by field.
Receives custom fields. When compared to another object, performs a field-by-field comparison.
Only checks the fields from itself; any additional fields that the other object may contain are ignored.
Example:
models.User(...) == ObjectMatch(id=Parameter(), login='kolypto', ...)
"""
__slots__ = '_fields',
def __init__(self, **fields):
self._fields = fields
def __eq__(self, other: object):
# Iterate our fields only. This will provide the "partial matching" behavior
for name, value in self._fields.items():
# will recurse into ObjectMatch.__eq__ if one is encountered
other_value = getattr(other, name)
# Compare
# Catch errors in case subsequent checks fail
try:
values_are_equal = value == other_value
except Exception as e:
raise
# raise AssertionError(f'Error comparing values of attribute {name!r}') from e # too much nesting
# Finally, assert
assert values_are_equal, f'{other!r} == {self!r} because of `{name}` {value!r} != {other_value}'
# if value != getattr(other, name):
# return False
return True
def __repr__(self):
return '{type}({fields})'.format(type='Object', fields=', '.join(f'{k}={v!r}' for k, v in self._fields.items()))