123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- ##############################################################################
- #
- # Copyright (c) 2003 Zope Foundation and Contributors.
- # All Rights Reserved.
- #
- # This software is subject to the provisions of the Zope Public License,
- # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
- # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
- # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
- # FOR A PARTICULAR PURPOSE.
- #
- ##############################################################################
- """Test interface declarations against ExtensionClass-like classes.
- These tests are to make sure we do something sane in the presence of
- classic ExtensionClass classes and instances.
- """
- import unittest
- from zope.interface import Interface
- from zope.interface import classImplements
- from zope.interface import classImplementsOnly
- from zope.interface import directlyProvidedBy
- from zope.interface import directlyProvides
- from zope.interface import implementedBy
- from zope.interface import implementer
- from zope.interface import providedBy
- from . import odd
- class I1(Interface):
- pass
- class I2(Interface):
- pass
- class I3(Interface):
- pass
- class I31(I3):
- pass
- class I4(Interface):
- pass
- class I5(Interface):
- pass
- class Odd:
- pass
- Odd = odd.MetaClass('Odd', Odd.__bases__, {})
- class B(Odd):
- __implemented__ = I2
- # TODO: We are going to need more magic to make classProvides work with odd
- # classes. This will work in the next iteration. For now, we'll use
- # a different mechanism.
- # from zope.interface import classProvides
- class A(Odd):
- pass
- classImplements(A, I1)
- class C(A, B):
- pass
- classImplements(C, I31)
- class Test(unittest.TestCase):
- def test_ObjectSpecification(self):
- c = C()
- directlyProvides(c, I4)
- self.assertEqual([i.getName() for i in providedBy(c)],
- ['I4', 'I31', 'I1', 'I2']
- )
- self.assertEqual([i.getName() for i in providedBy(c).flattened()],
- ['I4', 'I31', 'I3', 'I1', 'I2', 'Interface']
- )
- self.assertIn(I1, providedBy(c))
- self.assertNotIn(I3, providedBy(c))
- self.assertTrue(providedBy(c).extends(I3))
- self.assertTrue(providedBy(c).extends(I31))
- self.assertFalse(providedBy(c).extends(I5))
- class COnly(A, B):
- pass
- classImplementsOnly(COnly, I31)
- class D(COnly):
- pass
- classImplements(D, I5)
- classImplements(D, I5)
- c = D()
- directlyProvides(c, I4)
- self.assertEqual([i.getName() for i in providedBy(c)],
- ['I4', 'I5', 'I31'])
- self.assertEqual([i.getName() for i in providedBy(c).flattened()],
- ['I4', 'I5', 'I31', 'I3', 'Interface'])
- self.assertNotIn(I1, providedBy(c))
- self.assertNotIn(I3, providedBy(c))
- self.assertTrue(providedBy(c).extends(I3))
- self.assertFalse(providedBy(c).extends(I1))
- self.assertTrue(providedBy(c).extends(I31))
- self.assertTrue(providedBy(c).extends(I5))
- class COnly(A, B):
- __implemented__ = I31
- class D(COnly):
- pass
- classImplements(D, I5)
- classImplements(D, I5)
- c = D()
- directlyProvides(c, I4)
- self.assertEqual([i.getName() for i in providedBy(c)],
- ['I4', 'I5', 'I31'])
- self.assertEqual([i.getName() for i in providedBy(c).flattened()],
- ['I4', 'I5', 'I31', 'I3', 'Interface'])
- self.assertNotIn(I1, providedBy(c))
- self.assertNotIn(I3, providedBy(c))
- self.assertTrue(providedBy(c).extends(I3))
- self.assertFalse(providedBy(c).extends(I1))
- self.assertTrue(providedBy(c).extends(I31))
- self.assertTrue(providedBy(c).extends(I5))
- def test_classImplements(self):
- @implementer(I3)
- class A(Odd):
- pass
- @implementer(I4)
- class B(Odd):
- pass
- class C(A, B):
- pass
- classImplements(C, I1, I2)
- self.assertEqual([i.getName() for i in implementedBy(C)],
- ['I1', 'I2', 'I3', 'I4'])
- classImplements(C, I5)
- self.assertEqual([i.getName() for i in implementedBy(C)],
- ['I1', 'I2', 'I5', 'I3', 'I4'])
- def test_classImplementsOnly(self):
- @implementer(I3)
- class A(Odd):
- pass
- @implementer(I4)
- class B(Odd):
- pass
- class C(A, B):
- pass
- classImplementsOnly(C, I1, I2)
- self.assertEqual([i.__name__ for i in implementedBy(C)],
- ['I1', 'I2'])
- def test_directlyProvides(self):
- class IA1(Interface):
- pass
- class IA2(Interface):
- pass
- class IB(Interface):
- pass
- class IC(Interface):
- pass
- class A(Odd):
- pass
- classImplements(A, IA1, IA2)
- class B(Odd):
- pass
- classImplements(B, IB)
- class C(A, B):
- pass
- classImplements(C, IC)
- ob = C()
- directlyProvides(ob, I1, I2)
- self.assertIn(I1, providedBy(ob))
- self.assertIn(I2, providedBy(ob))
- self.assertIn(IA1, providedBy(ob))
- self.assertIn(IA2, providedBy(ob))
- self.assertIn(IB, providedBy(ob))
- self.assertIn(IC, providedBy(ob))
- directlyProvides(ob, directlyProvidedBy(ob) - I2)
- self.assertIn(I1, providedBy(ob))
- self.assertNotIn(I2, providedBy(ob))
- self.assertNotIn(I2, providedBy(ob))
- directlyProvides(ob, directlyProvidedBy(ob), I2)
- self.assertIn(I2, providedBy(ob))
- # see above
- # def TODO_test_classProvides_fails_for_odd_class(self):
- # try:
- # class A(Odd):
- # classProvides(I1)
- # except TypeError:
- # pass # Success
- # self.assert_(
- # False,
- # "Shouldn't be able to use directlyProvides on odd class."
- # )
- def test_implementedBy(self):
- class I2(I1):
- pass
- class C1(Odd):
- pass
- classImplements(C1, I2)
- class C2(C1):
- pass
- classImplements(C2, I3)
- self.assertEqual([i.getName() for i in implementedBy(C2)],
- ['I3', 'I2'])
- def test_odd_metaclass_that_doesnt_subclass_type(self):
- # This was originally a doctest in odd.py.
- # It verifies that the metaclass the rest of these tests use
- # works as expected.
- # This is used for testing support for ExtensionClass in new
- # interfaces.
- class A:
- a = 1
- A = odd.MetaClass('A', A.__bases__, A.__dict__)
- class B:
- b = 1
- B = odd.MetaClass('B', B.__bases__, B.__dict__)
- class C(A, B):
- pass
- self.assertEqual(C.__bases__, (A, B))
- a = A()
- aa = A()
- self.assertEqual(a.a, 1)
- self.assertEqual(aa.a, 1)
- aa.a = 2
- self.assertEqual(a.a, 1)
- self.assertEqual(aa.a, 2)
- c = C()
- self.assertEqual(c.a, 1)
- self.assertEqual(c.b, 1)
- c.b = 2
- self.assertEqual(c.b, 2)
- C.c = 1
- self.assertEqual(c.c, 1)
- c.c
- self.assertIs(C.__class__.__class__, C.__class__)
|