[Zope3-checkins] CVS: Zope3/src/zope/interface/tests - m1.py:1.2 m2.py:1.2 odd.py:1.2 test_declarations.py:1.2 test_odd_declarations.py:1.2

Jim Fulton jim@zope.com
Sat, 3 May 2003 12:38:01 -0400


Update of /cvs-repository/Zope3/src/zope/interface/tests
In directory cvs.zope.org:/tmp/cvs-serv24631/src/zope/interface/tests

Added Files:
	m1.py m2.py odd.py test_declarations.py 
	test_odd_declarations.py 
Log Message:
Added tests for new-style declarations.



=== Zope3/src/zope/interface/tests/m1.py 1.1 => 1.2 ===
--- /dev/null	Sat May  3 12:38:01 2003
+++ Zope3/src/zope/interface/tests/m1.py	Sat May  3 12:38:00 2003
@@ -0,0 +1,9 @@
+"""Test module that declares an interface
+"""
+
+from zope.interface import Interface, moduleProvides
+
+class I1(Interface): pass
+class I2(Interface): pass
+
+moduleProvides(I1, I2)


=== Zope3/src/zope/interface/tests/m2.py 1.1 => 1.2 ===
--- /dev/null	Sat May  3 12:38:01 2003
+++ Zope3/src/zope/interface/tests/m2.py	Sat May  3 12:38:00 2003
@@ -0,0 +1,2 @@
+"""Test module that doesn't declare an interface
+"""


=== Zope3/src/zope/interface/tests/odd.py 1.1 => 1.2 ===
--- /dev/null	Sat May  3 12:38:01 2003
+++ Zope3/src/zope/interface/tests/odd.py	Sat May  3 12:38:00 2003
@@ -0,0 +1,129 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""Odd meta class that doesn't subclass type.
+
+This is used for testing support for ExtensionClass in new interfaces.
+
+  >>> class A:
+  ...     __metaclass__ = MetaClass
+  ...     a = 1
+  ...
+  >>> A.__name__
+  'A'
+  >>> A.__bases__
+  ()
+  >>> class B:
+  ...     __metaclass__ = MetaClass
+  ...     b = 1
+  ...
+  >>> class C(A, B): pass
+  ...
+  >>> C.__name__
+  'C'
+  >>> int(C.__bases__ == (A, B))
+  1
+  >>> a = A()
+  >>> aa = A()
+  >>> a.a
+  1
+  >>> aa.a
+  1
+  >>> aa.a = 2
+  >>> a.a
+  1
+  >>> aa.a
+  2
+  >>> c = C()
+  >>> c.a
+  1
+  >>> c.b
+  1
+  >>> c.b = 2
+  >>> c.b
+  2
+  >>> C.c = 1
+  >>> c.c
+  1
+  >>> from types import ClassType
+  >>> int(isinstance(C, (type, ClassType)))
+  0
+  >>> int(C.__class__.__class__ is C.__class__)
+  1
+
+$Id$
+"""
+
+# class OddClass is an odd meta class
+
+class MetaMetaClass(type):
+
+    def __getattribute__(self, name):
+        if name == '__class__':
+            return self
+        return type.__getattribute__(self, name)
+    
+
+class MetaClass(object):
+    """Odd classes
+    """
+    __metaclass__ = MetaMetaClass
+
+    def __init__(self, name, bases, dict):
+        self.__name__ = name
+        self.__bases__ = bases
+        self.__dict__.update(dict)
+
+    def __call__(self):
+        return OddInstance(self)
+
+    def __getattr__(self, name):
+        for b in self.__bases__:
+            v = getattr(b, name, self)
+            if v is not self:
+                return v
+        raise AttributeError, name
+
+    def __repr__(self):
+        return "<odd class %s at %s>" % (self.__name__, hex(id(self)))
+
+class OddInstance(object):
+
+    def __init__(self, cls):
+        self.__dict__['__class__'] = cls
+
+    def __getattribute__(self, name):
+        dict = object.__getattribute__(self, '__dict__')
+        if name == '__dict__':
+            return dict
+        v = dict.get(name, self)
+        if v is not self:
+            return v
+        return getattr(dict['__class__'], name)
+
+    def __setattr__(self, name, v):
+        self.__dict__[name] = v
+
+    def __delattr__(self, name):
+        del self.__dict__[name]
+
+    def __repr__(self):
+        return "<odd %s instance at %s>" % (
+            self.__class__.__name__, hex(id(self)))
+        
+
+
+# DocTest:
+if __name__ == "__main__":
+    import doctest, __main__
+    doctest.testmod(__main__, isprivate=lambda *a: False)


=== Zope3/src/zope/interface/tests/test_declarations.py 1.1 => 1.2 ===
--- /dev/null	Sat May  3 12:38:01 2003
+++ Zope3/src/zope/interface/tests/test_declarations.py	Sat May  3 12:38:00 2003
@@ -0,0 +1,167 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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 the new API for making and checking interface declarations
+
+
+$Id$
+"""
+
+import unittest
+from zope.interface import *
+from zope.testing.doc import doctest
+from zope.interface import Interface
+
+class I1(Interface): pass
+class I2(Interface): pass
+class I3(Interface): pass
+class I4(Interface): pass
+class I5(Interface): pass
+
+class A:
+    implements(I1)
+class B:
+    implements(I2)
+class C(A, B):
+    implements(I3)
+
+class COnly(A, B):
+    implementsOnly(I3)
+
+class COnly_old(A, B):
+    __implements__ = I3
+    
+class D(COnly):
+    implements(I5)
+    
+
+class Test(unittest.TestCase):
+
+    # Note that most of the tests are in the doc strings of the
+    # declarations module.
+
+    def test_doctest(self):
+        doctest(self, declarations)
+
+    def test_ObjectSpecification_Simple(self):
+        c = C()
+        directlyProvides(c, I4)
+        spec = providedBy(c)
+        sig = spec.__signature__
+        expect = (c.__provides__.__signature__,
+                  C.__dict__['__implements__'].__signature__,
+                  A.__dict__['__implements__'].__signature__,
+                  B.__dict__['__implements__'].__signature__,
+                  )
+        self.assertEqual(sig, expect)
+
+    def test_ObjectSpecification_Simple_w_only(self):
+        c = COnly()
+        directlyProvides(c, I4)
+        spec = providedBy(c)
+        sig = spec.__signature__
+        expect = (c.__provides__.__signature__,
+                  COnly.__dict__['__implements__'].__signature__,
+                  A.__dict__['__implements__'].__signature__,
+                  B.__dict__['__implements__'].__signature__,
+                  )
+        self.assertEqual(sig, expect)
+
+    def test_ObjectSpecification_Simple_old_style(self):
+        c = COnly_old()
+        directlyProvides(c, I4)
+        spec = providedBy(c)
+        sig = spec.__signature__
+        expect = (c.__provides__.__signature__,
+                  COnly_old.__dict__['__implements__'].__signature__,
+                  A.__dict__['__implements__'].__signature__,
+                  B.__dict__['__implements__'].__signature__,
+                  )
+        self.assertEqual(sig, expect)
+
+    def test_backward_compat(self):
+
+        class C1: __implements__ = I1
+        class C2(C1): __implements__ = I2, I5
+        class C3(C2): __implements__ = I3, C2.__implements__
+
+        self.assert_(C3.__implements__.__class__ is tuple)
+
+        self.assertEqual(
+            [i.__name__ for i in providedBy(C3())],
+            ['I3', 'I2', 'I5'],
+            )
+
+        class C4(C3):
+            implements(I4)
+
+        self.assertEqual(
+            [i.__name__ for i in providedBy(C4())],
+            ['I4', 'I3', 'I2', 'I5'],
+            )
+
+        self.assertEqual(
+            [i.__name__ for i in C4.__implements__],
+            ['I4', 'I3', 'I2', 'I5'],
+            )
+
+        # Note that C3.__implements__ should now be a sequence of interfaces
+        self.assertEqual(
+            [i.__name__ for i in C3.__implements__],
+            ['I3', 'I2', 'I5'],
+            )
+        self.failIf(C3.__implements__.__class__ is tuple)
+
+    def test_module(self):
+        import zope.interface.tests.m1
+        import zope.interface.tests.m2
+        directlyProvides(zope.interface.tests.m2,
+                         zope.interface.tests.m1.I1,
+                         zope.interface.tests.m1.I2,
+                         )
+        self.assertEqual(list(providedBy(zope.interface.tests.m1)),
+                         list(providedBy(zope.interface.tests.m2)),
+                         )
+
+    def test_builtins(self):
+        classImplements(int, I1)
+        class myint(int):
+            implements(I2)
+
+        x = 42
+        self.assertEqual([i.__name__ for i in providedBy(x)],
+                         ['I1'])
+
+        x = myint(42)
+        directlyProvides(x, I3)
+        self.assertEqual([i.__name__ for i in providedBy(x)],
+                         ['I3', 'I2', 'I1'])
+
+        # cleanup
+        from zope.interface.declarations import _implements_reg
+        _implements_reg.clear()
+
+        x = 42
+        self.assertEqual([i.__name__ for i in providedBy(x)],
+                         [])
+        
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(Test))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main()


=== Zope3/src/zope/interface/tests/test_odd_declarations.py 1.1 => 1.2 ===
--- /dev/null	Sat May  3 12:38:01 2003
+++ Zope3/src/zope/interface/tests/test_odd_declarations.py	Sat May  3 12:38:00 2003
@@ -0,0 +1,211 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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 presense of
+classic ExtensionClass classes and instances.
+
+$Id$
+"""
+
+import unittest, odd
+from zope.interface import Interface
+from zope.interface import directlyProvides, providedBy, directlyProvidedBy
+from zope.interface import classImplements, classImplementsOnly, implementedBy
+
+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: __metaclass__ = odd.MetaClass
+
+class B(Odd): __implements__ = I2
+
+
+# XXX We are going to need more magic to make implements work with odd
+#     classes. This will work in the next iteration. For now, we'll use
+#     a different mechanism.
+
+# from zope.interface import implements, classProvides
+
+class A(Odd):
+    # implements(I1)
+    __implements__ = I1
+
+class C(A, B):
+    pass
+    #implements(I31)
+classImplements(C, I31)
+
+
+
+class Test(unittest.TestCase):
+
+    def test_ObjectSpecification(self):        
+        c = C()
+        directlyProvides(c, I4)
+        self.assertEqual([i.__name__ for i in providedBy(c)],
+                         ['I4', 'I31', 'I1', 'I2']
+                         )
+        self.assertEqual([i.__name__ for i in providedBy(c).flattened()],
+                         ['I4', 'I31', 'I3', 'I1', 'I2', 'Interface']
+                         )
+        self.assert_(I1 in providedBy(c))
+        self.failIf(I3 in providedBy(c))        
+        self.assert_(providedBy(c).extends(I3))
+        self.assert_(providedBy(c).extends(I31))
+        self.failIf(providedBy(c).extends(I5))
+
+        class COnly(A, B):
+            # XXX implementsOnly(I31)
+            __implements__ = I31
+        class D(COnly):
+            # XXX implements(I5)
+            pass
+        classImplements(D, I5)
+        
+        c = D()
+        directlyProvides(c, I4)
+        self.assertEqual([i.__name__ for i in providedBy(c)],
+                         ['I4', 'I5', 'I31'])
+        self.assertEqual([i.__name__ for i in providedBy(c).flattened()],
+                         ['I4', 'I5', 'I31', 'I3', 'Interface'])
+        self.failIf(I1 in providedBy(c))
+        self.failIf(I3 in providedBy(c))
+        self.assert_(providedBy(c).extends(I3))
+        self.failIf(providedBy(c).extends(I1))
+        self.assert_(providedBy(c).extends(I31))
+        self.assert_(providedBy(c).extends(I5))
+
+        class COnly(A, B): __implements__ = I31        
+        class D(COnly):
+            # XXX implements(I5)
+            pass
+        classImplements(D, I5)
+        c = D()
+        directlyProvides(c, I4)
+        self.assertEqual([i.__name__ for i in providedBy(c)],
+                         ['I4', 'I5', 'I31'])
+        self.assertEqual([i.__name__ for i in providedBy(c).flattened()],
+                         ['I4', 'I5', 'I31', 'I3', 'Interface'])
+        self.failIf(I1 in providedBy(c))
+        self.failIf(I3 in providedBy(c))
+        self.assert_(providedBy(c).extends(I3))
+        self.failIf(providedBy(c).extends(I1))
+        self.assert_(providedBy(c).extends(I31))
+        self.assert_(providedBy(c).extends(I5))
+        
+    def test_classImplements(self):
+        class A(Odd):
+          # XXX implements(I3)
+          __implements__ = I3
+        class B(Odd):
+          # XXX implements(I4)
+          __implements__ = I4
+        class C(A, B):
+          pass
+        classImplements(C, I1, I2)
+        self.assertEqual([i.__name__ for i in implementedBy(C)],
+                         ['I1', 'I2', 'I3', 'I4'])
+        classImplements(C, I5)
+        self.assertEqual([i.__name__ for i in implementedBy(C)],
+                         ['I1', 'I2', 'I5', 'I3', 'I4'])
+        
+    def test_classImplementsOnly(self):
+        class A(Odd):
+            # XXX implements(I3)
+          __implements__ = I3
+        class B(Odd):
+            # XXX implements(I4)
+          __implements__ = I4
+        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):
+            # XXX implements(IA1, IA2)
+            __implements__ = IA1, IA2
+        class B(Odd):
+            # XXX implements(IB)
+            __implements__ = IB
+        class C(A, B):
+            # XXX implements(IC)
+            pass
+        classImplements(C, IC)
+
+        ob = C()
+        directlyProvides(ob, I1, I2)
+        self.assert_(I1 in providedBy(ob))
+        self.assert_(I2 in providedBy(ob))
+        self.assert_(IA1 in providedBy(ob))
+        self.assert_(IA2 in providedBy(ob))
+        self.assert_(IB in providedBy(ob))
+        self.assert_(IC in providedBy(ob))
+        
+        directlyProvides(ob, directlyProvidedBy(ob)-I2)
+        self.assert_(I1 in providedBy(ob))
+        self.failIf(I2 in providedBy(ob))
+        self.failIf(I2 in providedBy(ob))
+        directlyProvides(ob, directlyProvidedBy(ob), I2)
+        self.assert_(I2 in providedBy(ob))
+
+    def test_directlyProvides_fails_for_odd_class(self):
+        self.assertRaises(TypeError, directlyProvides, C, I5)
+
+    # XXX see above
+    def XXX_test_classProvides_fails_for_odd_class(self):
+        try:
+            class A(Odd):
+                classProvides(I1)
+        except TypeError:
+            pass # Sucess
+        self.assert_(False,
+                     "Shouldn't be able to use directlyProvides on odd class."
+                     )
+
+    def test_implementedBy(self):
+        class I2(I1): pass
+        
+        class C1(Odd):
+          # XXX implements(I2)
+          __implements__ = I2
+        class C2(C1):
+          # XXX implements(I3)
+          pass
+        classImplements(C2, I3)
+        self.assertEqual([i.__name__ for i in implementedBy(C2)],
+                         ['I3', 'I2'])
+
+    
+        
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(Test))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main()