def testBasics(self): class I(Interface): def foo(self, a, b=None): '' def bar(self): '' class C(object): ImplementsInterface(I) def foo(self, a, b=None): '' def bar(self): '' class C2(object): def foo(self, a, b=None): '' def bar(self): '' class D(object): '' assert IsImplementation(I(C()), I) == True # OK assert IsImplementation(C, I) == True # OK assert IsImplementation(C2, I) == False # Does not declare assert not IsImplementation(D, I) == True # nope assert I(C) is C assert I(C2) is C2 with pytest.raises(InterfaceError): I() with pytest.raises(BadImplementationError): I(D) # Now declare that C2 implements I DeclareClassImplements(C2, I) assert IsImplementation(C2, I) == True # Does not declare
def testClassImplementMethod(self): ''' Tests replacing a method that implements an interface with a class. The class must be derived from "Method" in order to be accepted as a valid implementation. ''' class My(object): ImplementsInterface(_InterfM1) def m1(self): '' class MyRightMethod(Method): def __call__(self): '' class MyWrongMethod(object): def __call__(self): '' # NOTE: It doesn't matter runtime modifications in the instance, what is really being tested # is the *class* of the object (My) is what is really being tested. m = My() m.m1 = MyWrongMethod() assert IsImplementation(m, _InterfM1) == True m.m1 = MyRightMethod() assert IsImplementation(m, _InterfM1) == True # NOTE: Testing behaviour of private methods here. from ben10.interface._interface import _IsImplementationFullChecking m = My() m.m1 = MyWrongMethod() r = _IsImplementationFullChecking(m, _InterfM1) assert r == False m.m1 = MyRightMethod() r = _IsImplementationFullChecking(m, _InterfM1) assert r == True del m.m1 assert IsImplementation(m, _InterfM1) == True
def testInterfaceCheckRequiresInterface(self): class M3(object): def m3(self, *args, **kwargs): '' with pytest.raises(InterfaceError): AssertImplements(M3(), M3) with pytest.raises(InterfaceError): IsImplementation(M3(), M3)
def testIsImplementationWithSubclasses(self): ''' Checks if the IsImplementation method works with subclasses interfaces. Given that an interface I2 inherits from I1 of a given object declared that it implements I2 then it is implicitly declaring that implements I1. ''' class My2(object): ImplementsInterface(_InterfM2) def m2(self): '' class My3(object): ImplementsInterface(_InterfM3) def m3(self, arg1, arg2): '' class My4(object): ImplementsInterface(_InterfM4) def m3(self, arg1, arg2): '' def m4(self): '' m2 = My2() m3 = My3() m4 = My4() # My2 assert IsImplementation(m2, _InterfM3) == False # My3 assert IsImplementation(m3, _InterfM3) == True assert IsImplementation(m3, _InterfM4) == False # My4 assert IsImplementation(m4, _InterfM4) == True assert IsImplementation(m4, _InterfM3) == True # When wrapped in an m4 interface it should still accept m3 as a declared interface wrapped_intef_m4 = _InterfM4(m4) assert IsImplementation(wrapped_intef_m4, _InterfM4) == True assert IsImplementation(wrapped_intef_m4, _InterfM3) == True
def testDeclareClassImplements(self): class I1(Interface): def M1(self): '' class I2(Interface): def M2(self): '' class C0(object): '' class C1(object): def M1(self): '' class C2(object): def M2(self): '' class C2B(object): ImplementsInterface(I2) def M2(self): '' class C12B(C1, C2B): '' with pytest.raises(AssertionError): DeclareClassImplements(C0, I1) assert IsImplementation(C1, I1) == False with pytest.raises(AssertionError): AssertImplements(C1, I1) assert IsImplementation(C12B, I1) == False # C1 still does not implements I1 DeclareClassImplements(C1, I1) assert IsImplementation(C1, I1) == True AssertImplements(C1, I1) # C1 is parent of C12B, and, above, it was declared that C1 implements I1, so C12B should # automatically implement I1. But this is not automatic, so you must also declare for it! assert IsImplementation(C12B, I1) == False # not automatic assert IsImplementation( C12B, I2) == True # inheritance for Implements still works automatically DeclareClassImplements(C12B, I1) assert IsImplementation(C12B, I1) == True # now it implements assert IsImplementation(C12B, I2) == True DeclareClassImplements(C2, I2) assert IsImplementation(C2, I2) == True AssertImplements(C2, I2) # Exception: if I define a class *after* using DeclareClassImplements in the base, it works: class C12(C1, C2): '' AssertImplements(C12, I1) AssertImplements(C12, I2)
def testIsImplementationWithBuiltInObjects(self): my_number = 10 assert IsImplementation(my_number, _InterfM1) == False
def testAttributes(self): class IZoo(Interface): zoo = Attribute(int) class I(Interface): foo = Attribute(int) bar = Attribute(str) foobar = Attribute(int, None) a_zoo = Attribute(IZoo) class Zoo(object): ImplementsInterface(IZoo) # NOTE: This class 'C' doesn't REALLY implements 'I', although it says so. The problem is # that there's a flaw with attributes *not being checked*. # In fact: Attributes should not be in the (Abstract) properties COULD be in # the interface, but they SHOULD NOT be type-checked (because it involves a # getter call, and this affects runtime behaviour). # This should be reviewed later. class C(object): ImplementsInterface(I) c1 = C() c1.foo = 10 c1.bar = 'hello' c1.foobar = 20 a_zoo = Zoo() a_zoo.zoo = 99 c1.a_zoo = a_zoo c2 = C() assert IsImplementation(C, I) == True assert IsImplementation(c1, I) == True assert IsImplementation(c2, I) == True # NOTE: Testing private methods here # If we do a deprecated "full check", then its behaviour is a little bit more correct. from ben10.interface._interface import _IsImplementationFullChecking assert not _IsImplementationFullChecking( C, I) == True # only works with instances assert _IsImplementationFullChecking(c1, I) == True # OK, has attributes assert not _IsImplementationFullChecking( c2, I) == True # not all the attributes necessary # must not be true if including an object that doesn't implement IZoo interface expected for # a_zoo attribute c1.a_zoo = 'wrong' assert not _IsImplementationFullChecking( c1, I) == True # failed, invalid attr type c1.a_zoo = a_zoo # test if we can set foobar to None c1.foobar = None assert IsImplementation(c1, I) == True # OK c1.foobar = 'hello' assert not _IsImplementationFullChecking( c1, I) == True # failed, invalid attr type