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 137 138 139 140 141 142
|
import re
class Comparator(object):
def equals(self, other):
raise NotImplementedError()
def __eq__(self, other):
return self.equals(other)
def __ne__(self, other):
return not (self == other)
def __repr__(self):
return "<Comparator %s>" % (type(self).__name__)
class Is(Comparator):
def __init__(self, obj):
super(Is, self).__init__()
self._obj = obj
def equals(self, other):
return self._obj is other
def __repr__(self):
return "<Is %r (id=0x%x)>" % (self._obj, id(self._obj))
class IsA(Comparator):
def __init__(self, klass):
super(IsA, self).__init__()
self._class = klass
def equals(self, other):
try:
return isinstance(other, self._class)
except TypeError:
return self._class is type(other)
def __repr__(self):
return "<Is instance of %r >" % (self._class,)
class RegexpMatches(Comparator):
def __init__(self, regexp, flags=0):
super(RegexpMatches, self).__init__()
self._regexp = regexp
self._flags = flags
def equals(self, other):
if not isinstance(other, str):
return False
return re.match(self._regexp, other, self._flags)
def __repr__(self):
return "<Matches %r>" % (self._regexp,)
class RegexpSearches(Comparator):
def __init__(self, regexp, flags=0):
super(RegexpSearches, self).__init__()
self._regexp = regexp
self._flags = flags
def equals(self, other):
if not isinstance(other, str):
return False
return re.search(self._regexp, other, self._flags)
def __repr__(self):
return "<Searches %r>" % (self._regexp,)
class Func(Comparator):
def __init__(self, func):
super(Func, self).__init__()
self._func = func
def equals(self, other):
return self._func(other)
def __repr__(self):
return "<Function predicate %s>" % (self._func,)
class IsAlmost(Comparator):
def __init__(self, value, places=7):
super(IsAlmost, self).__init__()
self._value = value
self._places = places
def equals(self, other):
try:
return round(self._value - other, self._places) == 0
except TypeError:
return False
class Contains(Comparator):
def __init__(self, *objs):
super(Contains, self).__init__()
self._objs = objs
def equals(self, other):
try:
return all(obj in other for obj in self._objs)
except TypeError:
return False
class HasKeyValue(Comparator):
def __init__(self, key, value):
super(HasKeyValue, self).__init__()
self._key = key
self._value = value
def equals(self, other):
try:
return other[self._key] == self._value
except TypeError:
return False
except KeyError:
return False
class HasAttributeValue(Comparator):
def __init__(self, attr, value):
super(HasAttributeValue, self).__init__()
self._attr = attr
self._value = value
def equals(self, other):
try:
return getattr(other, self._attr) == self._value
except TypeError:
return False
except AttributeError:
return False
class Anything(Comparator):
def equals(self, other):
return True
class And(Comparator):
def __init__(self, *comparators):
super(And, self).__init__()
if not comparators:
raise TypeError("At least one comparator must be specified for And()")
self.comparators = comparators
def equals(self, other):
return all(c.equals(other) for c in self.comparators)
StrContains = lambda *xs: And(IsA(str), Contains(*xs))
class Or(Comparator):
def __init__(self, *comparators):
super(Or, self).__init__()
if not comparators:
raise TypeError("At least one comparator must be specified for Or()")
self.comparators = comparators
def equals(self, other):
return any(c.equals(other) for c in self.comparators)
class Not(Comparator):
def __init__(self, comparator):
super(Not, self).__init__()
self.comparator = comparator
def equals(self, other):
return not self.comparator.equals(other)
|