[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()