def test_keyword_arguments(): @contract(pre=lambda: 'mobile' in others) def contact(id, email, **others): pass assert contact(0, '@', mobile='123456789') is None raised_with_message(lambda: contact(email='@', id=99), "'mobile' in others")
def test_simple_init_fails(): class Class(object): __metaclass__ = Invariant __conditions = (lambda: self._property == 'hello', ) def __init__(self): self._property = 'world' raised_with_message(lambda: Class(), "self._property == 'hello'")
def test_named_function(): def is_number(result): return isinstance(result, int) or isinstance(result, float) @contract(post=is_number) def add(a, b): return a assert add(0, 0) == 0 raised_with_message(lambda: add(None, 0), 'is_number')
def test_simple_inheritance(): class Super(object): __metaclass__ = Invariant __conditions = (lambda: self._value == 'value', ) class Sub(Super): def __init__(self): self._value = -9999 raised_with_message(lambda: Sub(), "self._value == 'value'")
def test_simple_del_fails(): class Class(object): __metaclass__ = Invariant __conditions = (lambda: self._resource is None, ) _resource = NotImplemented def __del__(self): pass raised_with_message(lambda: Class().__del__(), 'self._resource is None')
def test_default_arguments(): @contract(pre=(lambda: isinstance(left, int) or isinstance(left, float), lambda: isinstance(right, int) or isinstance(right, float))) def counter(left=0, right=0): pass assert counter() is None assert counter(12) is None assert counter(right=99) is None assert counter(4, 6) is None assert counter(right=7, left=3) is None raised_with_message(lambda: counter(None), 'isinstance(left, int) or isinstance(left, float)') raised_with_message(lambda: counter(right=None), 'isinstance(right, int) or isinstance(right, float)')
def test_with_contract(): class Class(object): __metaclass__ = Invariant __conditions = (lambda: self._property is None, ) def __init__(self): self._property = None @contract(pre=lambda: 0 < argument < 9) def method(self, argument, property): self._property = property raised_with_message(lambda: Class().method(11, None), '0 < argument < 9') raised_with_message(lambda: Class().method(5, True), 'self._property is None')
def test_mutated_postcondition(): @contract(pre=lambda: len(mutable) == 0, mut=lambda: len(mutable) == 1) def mutator(mutable): mutable.append(None) assert mutator([]) is None class BlackHole(object): def __len__(self): return 0 def append(self, *args, **kwargs): pass raised_with_message(lambda: mutator(BlackHole()), 'len(mutable) == 1')
def test_complex_inheritance_meta(): class Meta(Invariant): def __new__(self, name, bases, attributes): def special_fails(self): self._property = -9999 attributes['special_fails'] = special_fails return super(Meta, self).__new__(self, name, bases, attributes) class Class(object): __metaclass__ = Meta __conditions = (lambda: self._property == 11, ) _property = 11 raised_with_message(lambda: Class().special_fails(), 'self._property == 11')
def test_positional_arguments(): @contract(pre=(lambda: x >= 0, lambda: y is not None, lambda: isinstance(y, int), lambda: z < 10, lambda: isinstance( z # multiline , # closure float))) def vector(x, y, z): pass raised_with_message(lambda: vector(-1, 0, 0), 'x >= 0') raised_with_message(lambda: vector(0, None, 0), 'y is not None') raised_with_message(lambda: vector(0, type, 0), 'isinstance(y, int)') raised_with_message(lambda: vector(0, 0, 10), 'z < 10') raised_with_message(lambda: vector(0, 0, 9), 'isinstance(z, float)') assert vector(0, 0, 0.0) is None
def test_simple_inheritance_extend_invariant(): class Super(object): __metaclass__ = Invariant __conditions = (lambda: self._alpha == 0, ) class Sub(Super): __conditions = (lambda: self._beta == 1, ) _alpha = 0 _beta = 1 def fails_super(self): self._alpha = -9999 def fails_sub(self): self._beta = -9999 raised_with_message(lambda: Sub().fails_super(), 'self._alpha == 0') raised_with_message(lambda: Sub().fails_sub(), 'self._beta == 1')
def test_invariant(): class Triangle: __metaclass__ = Invariant __conditions = (lambda: self.a > 0, lambda: self.b > 0, lambda: self.c > 0, lambda: self.a + self.b > self.c, lambda: self.a + self.c > self.b, lambda: self.b + self.c > self.a) def __init__(self, a, b, c): self.a = a self.b = b self.c = c @property def area(self): pass # Here goes the implementation of Heron's Formula t = Triangle(3, 4, 5) t.a = 9 raised_with_message(lambda: t.area, 'self.b + self.c > self.a')
def test_simple_method(): class Class(object): __metaclass__ = Invariant __conditions = (lambda: self._alpha is None, lambda: self._beta is NotImplemented) def __init__(self): self._alpha = None self._beta = NotImplemented def passes(self): self._alpha = None self._beta = NotImplemented def fails_1(self): self._alpha = -9999 def fails_2(self): self._beta = -9999 Class().passes() raised_with_message(lambda: Class().fails_1(), 'self._alpha is None') raised_with_message(lambda: Class().fails_2(), 'self._beta is NotImplemented') c = Class() c._alpha = -9999 raised_with_message(lambda: c.passes(), 'self._alpha is None')
def test_simple_property(): class Class(object): __metaclass__ = Invariant __conditions = (lambda: self._protected == 'this', ) _protected = 'this' @property def violate(self): self._protected = 'that' @violate.setter def violate(self, other): self._protected = other @violate.deleter def violate(self): self._protected = 'that' raised_with_message(lambda: Class().violate, "self._protected == 'this'") def case_1(): Class().violate = 'that' raised_with_message(case_1, "self._protected == 'this'") def case_2(): del Class().violate raised_with_message(case_2, "self._protected == 'this'")
def test_variable_arguments(): @contract(pre=(lambda: isinstance(prefix, str), lambda: infix is None or isinstance(infix, str), lambda: all(isinstance(c, str) for c in words))) def write(prefix, infix=None, *words): pass assert write(*'hello') is None raised_with_message(lambda: write(True), 'isinstance(prefix, str)') raised_with_message(lambda: write('', True), 'infix is None or isinstance(infix, str)') raised_with_message(lambda: write('', None, [1]), 'all((isinstance(c, str) for c in words))')
def test_complex_inheritance_multiple_inheritance_meta(): class Super1(object): __metaclass__ = Invariant __conditions = (lambda: self._number % 2 == 0, ) class Super2(object): __metaclass__ = Invariant __conditions = (lambda: self._number % 3 == 0, ) class Sub(Super1, Super2): __conditions = (lambda: self._number % 5 == 0, ) def __init__(self, number): self._number = number raised_with_message(lambda: Sub(15), 'self._number % 2 == 0') raised_with_message(lambda: Sub(10), 'self._number % 3 == 0') raised_with_message(lambda: Sub(6), 'self._number % 5 == 0')