[Checkins] SVN: zope.interface/branches/tseaver-better_unittests/ Better unit tests, to date.

Tres Seaver tseaver at palladion.com
Wed Apr 28 12:48:14 EDT 2010


Log message for revision 111554:
  Better unit tests, to date.

Changed:
  _U  zope.interface/branches/tseaver-better_unittests/
  U   zope.interface/branches/tseaver-better_unittests/src/zope/interface/index.txt
  U   zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/dummy.py
  A   zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/idummy.py
  D   zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/ifoo.py
  U   zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_document.py
  A   zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_exceptions.py
  U   zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_interface.py
  U   zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_odd_declarations.py
  U   zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_verify.py
  D   zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/unitfixtures.py
  U   zope.interface/branches/tseaver-better_unittests/src/zope/interface/verify.py

-=-

Property changes on: zope.interface/branches/tseaver-better_unittests
___________________________________________________________________
Added: svn:mergeinfo
   + /zope.interface/branches/tseaver-better_unittests:111152-111153,111551
/zope.interface/branches/tseaver-better_unit_tests:111114-111115

Added: svk:merge
   + 62d5b8a3-27da-0310-9561-8e5933582275:/zope.interface/branches/tseaver-better_unittests:111551


Modified: zope.interface/branches/tseaver-better_unittests/src/zope/interface/index.txt
===================================================================
--- zope.interface/branches/tseaver-better_unittests/src/zope/interface/index.txt	2010-04-28 16:41:48 UTC (rev 111553)
+++ zope.interface/branches/tseaver-better_unittests/src/zope/interface/index.txt	2010-04-28 16:48:14 UTC (rev 111554)
@@ -10,6 +10,7 @@
    adapter
    human
    verify
+   tests/foodforthought
 
 По-русски
 =========

Modified: zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/dummy.py
===================================================================
--- zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/dummy.py	2010-04-28 16:41:48 UTC (rev 111553)
+++ zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/dummy.py	2010-04-28 16:48:14 UTC (rev 111554)
@@ -11,14 +11,13 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Dummy Module
-
-$Id$
+""" Dummy Module
 """
 from zope.interface import moduleProvides
-from zope.interface.tests.ifoo import IFoo
+from zope.interface.tests.idummy import IDummyModule
 
-moduleProvides(IFoo)
+moduleProvides(IDummyModule)
 
 def bar(baz):
+    # Note:  no 'self', because the module provides the interface directly.
     pass

Copied: zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/idummy.py (from rev 111553, zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/ifoo.py)
===================================================================
--- zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/idummy.py	                        (rev 0)
+++ zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/idummy.py	2010-04-28 16:48:14 UTC (rev 111554)
@@ -0,0 +1,23 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 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.
+#
+##############################################################################
+""" Interface describing API of zope.interface.tests.dummy test module
+"""
+from zope.interface import Interface
+
+class IDummyModule(Interface):
+    """ Dummy interface for unit tests.
+    """
+    def bar(baz):
+        """ Just a note.
+        """

Deleted: zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/ifoo.py
===================================================================
--- zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/ifoo.py	2010-04-28 16:41:48 UTC (rev 111553)
+++ zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/ifoo.py	2010-04-28 16:48:14 UTC (rev 111554)
@@ -1,28 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 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.
-#
-##############################################################################
-"""IFoo test module
-
-$Id$
-"""
-from zope.interface import Interface
-
-class IFoo(Interface):
-    """
-        Dummy interface for unit tests.
-    """
-
-    def bar(baz):
-        """
-            Just a note.
-        """

Modified: zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_document.py
===================================================================
--- zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_document.py	2010-04-28 16:41:48 UTC (rev 111553)
+++ zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_document.py	2010-04-28 16:48:14 UTC (rev 111554)
@@ -12,60 +12,275 @@
 #
 ##############################################################################
 """Documentation tests.
-
-$Id$
 """
-from unittest import TestCase, main, makeSuite
+import unittest 
 
-from zope.interface import Interface, Attribute
 
-class Test(TestCase):
+class Test_asStructuredText(unittest.TestCase):
 
-    def testBlech(self):
+    def _callFUT(self, iface):
         from zope.interface.document import asStructuredText
+        return asStructuredText(iface)
 
-        self.assertEqual(asStructuredText(I2), '''\
-I2
+    def test_asStructuredText_no_docstring(self):
+        from zope.interface import Interface
+        EXPECTED = '\n\n'.join([
+            "INoDocstring",
+            " Attributes:",
+            " Methods:",
+            ""
+        ])
+        class INoDocstring(Interface):
+            pass
+        self.assertEqual(self._callFUT(INoDocstring), EXPECTED)
 
- I2 doc
+    def test_asStructuredText_empty_with_docstring(self):
+        from zope.interface import Interface
+        EXPECTED = '\n\n'.join([
+            "IEmpty",
+            " This is an empty interface.",
+            " Attributes:",
+            " Methods:",
+            ""
+        ])
+        class IEmpty(Interface):
+            """ This is an empty interface.
+            """
+        self.assertEqual(self._callFUT(IEmpty), EXPECTED)
 
- This interface extends:
+    def test_asStructuredText_empty_with_multiline_docstring(self):
+        from zope.interface import Interface
+        EXPECTED = '\n'.join([
+            "IEmpty",
+            "",
+            " This is an empty interface.",
+            " ",
+            ("             It can be used to annotate any class or object, "
+                             "because it promises"),
+            "             nothing.",
+            "",
+            " Attributes:",
+            "",
+            " Methods:",
+            "",
+            ""
+        ])
+        class IEmpty(Interface):
+            """ This is an empty interface.
 
-  o _I1
+            It can be used to annotate any class or object, because it promises
+            nothing.
+            """
+        self.assertEqual(self._callFUT(IEmpty), EXPECTED)
 
- Attributes:
+    def test_asStructuredText_with_attribute_no_docstring(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+        EXPECTED = '\n\n'.join([
+            "IHasAttribute",
+            " This interface has an attribute.",
+            " Attributes:",
+            "  an_attribute -- no documentation",
+            " Methods:",
+            ""
+        ])
+        class IHasAttribute(Interface):
+            """ This interface has an attribute.
+            """
+            an_attribute = Attribute('an_attribute')
 
-  a1 -- no documentation
+        self.assertEqual(self._callFUT(IHasAttribute), EXPECTED)
 
-  a2 -- a2 doc
+    def test_asStructuredText_with_attribute_with_docstring(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+        EXPECTED = '\n\n'.join([
+            "IHasAttribute",
+            " This interface has an attribute.",
+            " Attributes:",
+            "  an_attribute -- This attribute is documented.",
+            " Methods:",
+            ""
+        ])
+        class IHasAttribute(Interface):
+            """ This interface has an attribute.
+            """
+            an_attribute = Attribute('an_attribute',
+                                     'This attribute is documented.')
 
- Methods:
+        self.assertEqual(self._callFUT(IHasAttribute), EXPECTED)
 
-  f21() -- f21 doc
+    def test_asStructuredText_with_method_no_args_no_docstring(self):
+        from zope.interface import Interface
+        EXPECTED = '\n\n'.join([
+            "IHasMethod",
+            " This interface has a method.",
+            " Attributes:",
+            " Methods:",
+            "  aMethod() -- no documentation",
+            ""
+        ])
+        class IHasMethod(Interface):
+            """ This interface has a method.
+            """
+            def aMethod():
+                pass
 
-  f22() -- no documentation
+        self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
 
-  f23() -- f23 doc
+    def test_asStructuredText_with_method_positional_args_no_docstring(self):
+        from zope.interface import Interface
+        EXPECTED = '\n\n'.join([
+            "IHasMethod",
+            " This interface has a method.",
+            " Attributes:",
+            " Methods:",
+            "  aMethod(first, second) -- no documentation",
+            ""
+        ])
+        class IHasMethod(Interface):
+            """ This interface has a method.
+            """
+            def aMethod(first, second):
+                pass
 
-''')
+        self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
 
+    def test_asStructuredText_with_method_starargs_no_docstring(self):
+        from zope.interface import Interface
+        EXPECTED = '\n\n'.join([
+            "IHasMethod",
+            " This interface has a method.",
+            " Attributes:",
+            " Methods:",
+            "  aMethod(first, second, *rest) -- no documentation",
+            ""
+        ])
+        class IHasMethod(Interface):
+            """ This interface has a method.
+            """
+            def aMethod(first, second, *rest):
+                pass
 
-def test_suite():
-    return makeSuite(Test)
+        self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
 
-class _I1(Interface):
-    def f11(): pass
-    def f12(): pass
+    def test_asStructuredText_with_method_kwargs_no_docstring(self):
+        from zope.interface import Interface
+        EXPECTED = '\n\n'.join([
+            "IHasMethod",
+            " This interface has a method.",
+            " Attributes:",
+            " Methods:",
+            "  aMethod(first, second, **kw) -- no documentation",
+            ""
+        ])
+        class IHasMethod(Interface):
+            """ This interface has a method.
+            """
+            def aMethod(first, second, **kw):
+                pass
 
-class I2(_I1):
-    "I2 doc"
+        self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
 
-    a1 = Attribute('a1')
-    a2 = Attribute('a2', 'a2 doc')
+    def test_asStructuredText_with_method_with_docstring(self):
+        from zope.interface import Interface
+        EXPECTED = '\n\n'.join([
+            "IHasMethod",
+            " This interface has a method.",
+            " Attributes:",
+            " Methods:",
+            "  aMethod() -- This method is documented.",
+            ""
+        ])
+        class IHasMethod(Interface):
+            """ This interface has a method.
+            """
+            def aMethod():
+                """This method is documented.
+                """
 
-    def f21(): "f21 doc"
-    def f22(): pass
-    def f23(): "f23 doc"
+        self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
 
-if __name__=='__main__':
-    main(defaultTest='test_suite')
+    def test_asStructuredText_derived_ignores_base(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+        EXPECTED = '\n\n'.join([
+            "IDerived",
+            " IDerived doc",
+            " This interface extends:",
+            "  o IBase",
+            " Attributes:",
+            "  attr1 -- no documentation",
+            "  attr2 -- attr2 doc",
+            " Methods:",
+            "  method3() -- method3 doc",
+            "  method4() -- no documentation",
+            "  method5() -- method5 doc",
+            "",
+        ])
+
+        class IBase(Interface):
+            def method1():
+                pass
+            def method2():
+                pass
+
+        class IDerived(IBase):
+            "IDerived doc"
+            attr1 = Attribute('attr1')
+            attr2 = Attribute('attr2', 'attr2 doc')
+
+            def method3():
+                "method3 doc"
+            def method4():
+                pass
+            def method5():
+                "method5 doc"
+
+        self.assertEqual(self._callFUT(IDerived), EXPECTED)
+
+class Test__justify_and_indent(unittest.TestCase):
+
+    def _callFUT(self, text, level, **kw):
+        from zope.interface.document import _justify_and_indent
+        return _justify_and_indent(text, level, **kw)
+
+    def test_simple_level_0(self):
+        LINES = ['Three blind mice', 'See how they run']
+        text = '\n'.join(LINES)
+        self.assertEqual(self._callFUT(text, 0), text)
+
+    def test_simple_level_1(self):
+        LINES = ['Three blind mice', 'See how they run']
+        text = '\n'.join(LINES)
+        self.assertEqual(self._callFUT(text, 1),
+                         '\n'.join([' ' + line for line in LINES]))
+
+    def test_simple_level_2(self):
+        LINES = ['Three blind mice', 'See how they run']
+        text = '\n'.join(LINES)
+        self.assertEqual(self._callFUT(text, 1),
+                         '\n'.join([' ' + line for line in LINES]))
+
+    def test_simple_w_CRLF(self):
+        LINES = ['Three blind mice', 'See how they run']
+        text = '\r\n'.join(LINES)
+        self.assertEqual(self._callFUT(text, 1),
+                         '\n'.join([' ' + line for line in LINES]))
+
+    def test_with_munge(self):
+        TEXT = ("This is a piece of text longer than 15 characters, \n"
+                "and split across multiple lines.")
+        EXPECTED = ("  This is a piece\n"
+                    "  of text longer\n"
+                    "  than 15 characters,\n"
+                    "  and split across\n"
+                    "  multiple lines.\n"
+                    " ")
+        self.assertEqual(self._callFUT(TEXT, 1, munge=1, width=15), EXPECTED)
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(Test_asStructuredText),
+        unittest.makeSuite(Test__justify_and_indent),
+    ))

Copied: zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_exceptions.py (from rev 111551, zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_exceptions.py)
===================================================================
--- zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_exceptions.py	                        (rev 0)
+++ zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_exceptions.py	2010-04-28 16:48:14 UTC (rev 111554)
@@ -0,0 +1,75 @@
+##############################################################################
+#
+# Copyright (c) 2010 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.
+#
+##############################################################################
+""" zope.interface.exceptions unit tests
+"""
+import unittest
+
+def _makeIface():
+    from zope.interface import Interface
+    class IDummy(Interface):
+        pass
+    return IDummy
+
+class DoesNotImplementTests(unittest.TestCase):
+
+    def _getTargetClass(self):
+        from zope.interface.exceptions import DoesNotImplement
+        return DoesNotImplement
+
+    def _makeOne(self, iface=None):
+        if iface is None:
+            iface = _makeIface()
+        return self._getTargetClass()(iface)
+
+    def test___str__(self):
+        dni = self._makeOne()
+        # XXX The trailing newlines and blank spaces are a stupid artifact.
+        self.assertEqual(str(dni),
+            'An object does not implement interface <InterfaceClass '
+               'zope.interface.tests.test_exceptions.IDummy>\n\n        ')
+
+class BrokenImplementationTests(unittest.TestCase):
+
+    def _getTargetClass(self):
+        from zope.interface.exceptions import BrokenImplementation
+        return BrokenImplementation
+
+    def _makeOne(self, iface=None, name='missing'):
+        if iface is None:
+            iface = _makeIface()
+        return self._getTargetClass()(iface, name)
+
+    def test___str__(self):
+        dni = self._makeOne()
+        # XXX The trailing newlines and blank spaces are a stupid artifact.
+        self.assertEqual(str(dni),
+            'An object has failed to implement interface <InterfaceClass '
+               'zope.interface.tests.test_exceptions.IDummy>\n\n'
+               '        The missing attribute was not provided.\n        ')
+
+class BrokenMethodImplementationTests(unittest.TestCase):
+
+    def _getTargetClass(self):
+        from zope.interface.exceptions import BrokenMethodImplementation
+        return BrokenMethodImplementation
+
+    def _makeOne(self, method='aMethod', mess='I said so'):
+        return self._getTargetClass()(method, mess)
+
+    def test___str__(self):
+        dni = self._makeOne()
+        self.assertEqual(str(dni),
+            'The implementation of aMethod violates its contract\n'
+             '        because I said so.\n        ')
+

Modified: zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_interface.py
===================================================================
--- zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_interface.py	2010-04-28 16:41:48 UTC (rev 111553)
+++ zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_interface.py	2010-04-28 16:48:14 UTC (rev 111554)
@@ -13,420 +13,871 @@
 ##############################################################################
 """Test Interface implementation
 """
+import unittest
 import doctest
-import unittest
-import sys
 
 class InterfaceTests(unittest.TestCase):
 
-    def _makeDerivedInterface(self):
+    def test_attributes_link_to_interface(self):
         from zope.interface import Interface
         from zope.interface import Attribute
-        class _I1(Interface):
 
-            a1 = Attribute("This is an attribute")
+        class I1(Interface):
+            attr = Attribute("My attr")
 
-            def f11():
+        self.failUnless(I1['attr'].interface is I1)
+
+    def test_methods_link_to_interface(self):
+        from zope.interface import Interface
+
+        class I1(Interface):
+
+            def method(foo, bar, bingo):
                 pass
-            def f12():
+
+        self.failUnless(I1['method'].interface is I1)
+
+    def test_classImplements_simple(self):
+        from zope.interface import Interface
+        from zope.interface import implementedBy
+        from zope.interface import providedBy
+
+        class ICurrent(Interface):
+            def method1(a, b):
                 pass
-            f12.optional = 1
+            def method2(a, b):
+                pass
 
-        class _I1_(_I1):
+        class IOther(Interface):
             pass
 
-        class _I1__(_I1_):
+        class Current(object):
+            __implemented__ = ICurrent
+            def method1(self, a, b):
+                return 1
+            def method2(self, a, b):
+                return 2
+
+        current = Current()
+
+        self.failUnless(ICurrent.implementedBy(Current))
+        self.failIf(IOther.implementedBy(Current))
+        self.failUnless(ICurrent in implementedBy(Current))
+        self.failIf(IOther in implementedBy(Current))
+        self.failUnless(ICurrent in providedBy(current))
+        self.failIf(IOther in providedBy(current))
+
+    def test_classImplements_base_not_derived(self):
+        from zope.interface import Interface
+        from zope.interface import implementedBy
+        from zope.interface import providedBy
+        class IBase(Interface):
+            def method():
+                pass
+        class IDerived(IBase):
             pass
+        class Current():
+            __implemented__ = IBase
+            def method(self):
+                pass
+        current = Current()
 
-        class _I2(_I1__):
-            def f21():
+        self.failUnless(IBase.implementedBy(Current))
+        self.failIf(IDerived.implementedBy(Current))
+        self.failUnless(IBase in implementedBy(Current))
+        self.failIf(IDerived in implementedBy(Current))
+        self.failUnless(IBase in providedBy(current))
+        self.failIf(IDerived in providedBy(current))
+
+    def test_classImplements_base_and_derived(self):
+        from zope.interface import Interface
+        from zope.interface import implementedBy
+        from zope.interface import providedBy
+
+        class IBase(Interface):
+            def method():
                 pass
-            def f22():
+
+        class IDerived(IBase):
+            pass
+
+        class Current(object):
+            __implemented__ = IDerived
+            def method(self):
                 pass
-            f23 = f22
 
-        return _I2
+        current = Current()
 
-    def testInterfaceSetOnAttributes(self):
-        from zope.interface.tests.unitfixtures import FooInterface
-        self.assertEqual(FooInterface['foobar'].interface,
-                         FooInterface)
-        self.assertEqual(FooInterface['aMethod'].interface,
-                         FooInterface)
+        self.failUnless(IBase.implementedBy(Current))
+        self.failUnless(IDerived.implementedBy(Current))
+        self.failIf(IBase in implementedBy(Current))
+        self.failUnless(IBase in implementedBy(Current).flattened())
+        self.failUnless(IDerived in implementedBy(Current))
+        self.failIf(IBase in providedBy(current))
+        self.failUnless(IBase in providedBy(current).flattened())
+        self.failUnless(IDerived in providedBy(current))
 
-    def testClassImplements(self):
-        from zope.interface.tests.unitfixtures import A
-        from zope.interface.tests.unitfixtures import B
-        from zope.interface.tests.unitfixtures import C
-        from zope.interface.tests.unitfixtures import D
-        from zope.interface.tests.unitfixtures import E
-        from zope.interface.tests.unitfixtures import I1
-        from zope.interface.tests.unitfixtures import I2
-        from zope.interface.tests.unitfixtures import IC
-        self.assert_(IC.implementedBy(C))
+    def test_classImplements_multiple(self):
+        from zope.interface import Interface
+        from zope.interface import implementedBy
+        from zope.interface import providedBy
 
-        self.assert_(I1.implementedBy(A))
-        self.assert_(I1.implementedBy(B))
-        self.assert_(not I1.implementedBy(C))
-        self.assert_(I1.implementedBy(D))
-        self.assert_(I1.implementedBy(E))
+        class ILeft(Interface):
+            def method():
+                pass
 
-        self.assert_(not I2.implementedBy(A))
-        self.assert_(I2.implementedBy(B))
-        self.assert_(not I2.implementedBy(C))
+        class IRight(ILeft):
+            pass
 
-        # No longer after interfacegeddon
-        # self.assert_(not I2.implementedBy(D))
+        class Left(object):
+            __implemented__ = ILeft
 
-        self.assert_(not I2.implementedBy(E))
+            def method(self):
+                pass
 
-    def testUtil(self):
+        class Right(object):
+            __implemented__ = IRight
+
+        class Ambi(Left, Right):
+            pass
+
+        ambi = Ambi()
+
+        self.failUnless(ILeft.implementedBy(Ambi))
+        self.failUnless(IRight.implementedBy(Ambi))
+        self.failUnless(ILeft in implementedBy(Ambi))
+        self.failUnless(IRight in implementedBy(Ambi))
+        self.failUnless(ILeft in providedBy(ambi))
+        self.failUnless(IRight in providedBy(ambi))
+
+    def test_classImplements_multiple_w_explict_implements(self):
+        from zope.interface import Interface
         from zope.interface import implementedBy
         from zope.interface import providedBy
-        from zope.interface.tests.unitfixtures import A
-        from zope.interface.tests.unitfixtures import B
-        from zope.interface.tests.unitfixtures import C
-        from zope.interface.tests.unitfixtures import I1
-        from zope.interface.tests.unitfixtures import I2
-        from zope.interface.tests.unitfixtures import IC
-        self.assert_(IC in implementedBy(C))
-        self.assert_(I1 in implementedBy(A))
-        self.assert_(not I1 in implementedBy(C))
-        self.assert_(I2 in implementedBy(B))
-        self.assert_(not I2 in implementedBy(C))
 
-        self.assert_(IC in providedBy(C()))
-        self.assert_(I1 in providedBy(A()))
-        self.assert_(not I1 in providedBy(C()))
-        self.assert_(I2 in providedBy(B()))
-        self.assert_(not I2 in providedBy(C()))
+        class ILeft(Interface):
 
+            def method():
+                pass
 
-    def testObjectImplements(self):
-        from zope.interface.tests.unitfixtures import A
-        from zope.interface.tests.unitfixtures import B
-        from zope.interface.tests.unitfixtures import C
-        from zope.interface.tests.unitfixtures import D
-        from zope.interface.tests.unitfixtures import E
-        from zope.interface.tests.unitfixtures import I1
-        from zope.interface.tests.unitfixtures import I2
-        from zope.interface.tests.unitfixtures import IC
-        self.assert_(IC.providedBy(C()))
+        class IRight(ILeft):
+            pass
 
-        self.assert_(I1.providedBy(A()))
-        self.assert_(I1.providedBy(B()))
-        self.assert_(not I1.providedBy(C()))
-        self.assert_(I1.providedBy(D()))
-        self.assert_(I1.providedBy(E()))
+        class IOther(Interface):
+            pass
 
-        self.assert_(not I2.providedBy(A()))
-        self.assert_(I2.providedBy(B()))
-        self.assert_(not I2.providedBy(C()))
+        class Left():
+            __implemented__ = ILeft
 
-        # Not after interface geddon
-        # self.assert_(not I2.providedBy(D()))
+            def method(self):
+                pass
 
-        self.assert_(not I2.providedBy(E()))
+        class Right(object):
+            __implemented__ = IRight
 
-    def testDeferredClass(self):
-        from zope.interface.tests.unitfixtures import A
+        class Other(object):
+            __implemented__ = IOther
+
+        class Mixed(Left, Right):
+            __implemented__ = Left.__implemented__, Other.__implemented__
+
+        mixed = Mixed()
+
+        self.failUnless(ILeft.implementedBy(Mixed))
+        self.failIf(IRight.implementedBy(Mixed))
+        self.failUnless(IOther.implementedBy(Mixed))
+        self.failUnless(ILeft in implementedBy(Mixed))
+        self.failIf(IRight in implementedBy(Mixed))
+        self.failUnless(IOther in implementedBy(Mixed))
+        self.failUnless(ILeft in providedBy(mixed))
+        self.failIf(IRight in providedBy(mixed))
+        self.failUnless(IOther in providedBy(mixed))
+
+    def test_interface_deferred_class_method_broken(self):
+        from zope.interface import Interface
         from zope.interface.exceptions import BrokenImplementation
-        a = A()
-        self.assertRaises(BrokenImplementation, a.ma)
 
+        class IDeferring(Interface):
+            def method():
+                pass
 
+        class Deferring(IDeferring.deferred()):
+            __implemented__ = IDeferring
+
+        deferring = Deferring()
+
+        self.assertRaises(BrokenImplementation, deferring.method)
+
     def testInterfaceExtendsInterface(self):
-        from zope.interface.tests.unitfixtures import BazInterface
-        from zope.interface.tests.unitfixtures import BarInterface
-        from zope.interface.tests.unitfixtures import BobInterface
-        from zope.interface.tests.unitfixtures import FunInterface
-        self.assert_(BazInterface.extends(BobInterface))
-        self.assert_(BazInterface.extends(BarInterface))
-        self.assert_(BazInterface.extends(FunInterface))
-        self.assert_(not BobInterface.extends(FunInterface))
-        self.assert_(not BobInterface.extends(BarInterface))
-        self.assert_(BarInterface.extends(FunInterface))
-        self.assert_(not BarInterface.extends(BazInterface))
+        from zope.interface import Interface
 
-    def testVerifyImplementation(self):
+        new = Interface.__class__
+        FunInterface = new('FunInterface')
+        BarInterface = new('BarInterface', [FunInterface])
+        BobInterface = new('BobInterface')
+        BazInterface = new('BazInterface', [BobInterface, BarInterface])
+
+        self.failUnless(BazInterface.extends(BobInterface))
+        self.failUnless(BazInterface.extends(BarInterface))
+        self.failUnless(BazInterface.extends(FunInterface))
+        self.failIf(BobInterface.extends(FunInterface))
+        self.failIf(BobInterface.extends(BarInterface))
+        self.failUnless(BarInterface.extends(FunInterface))
+        self.failIf(BarInterface.extends(BazInterface))
+
+    def test_verifyClass(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
         from zope.interface.verify import verifyClass
+
+        class ICheckMe(Interface):
+            attr = Attribute(u'My attr')
+
+            def method():
+                pass
+
+        class CheckMe(object):
+            __implemented__ = ICheckMe
+            attr = 'value'
+
+            def method(self):
+                pass
+
+        self.failUnless(verifyClass(ICheckMe, CheckMe))
+
+    def test_verifyObject(self):
+        from zope.interface import Attribute
         from zope.interface import Interface
-        from zope.interface.tests.unitfixtures import Foo
-        from zope.interface.tests.unitfixtures import FooInterface
-        from zope.interface.tests.unitfixtures import I1
-        self.assert_(verifyClass(FooInterface, Foo))
-        self.assert_(Interface.providedBy(I1))
+        from zope.interface.verify import verifyObject
 
-    def test_names(self):
-        iface = self._makeDerivedInterface()
-        names = list(iface.names())
-        names.sort()
-        self.assertEqual(names, ['f21', 'f22', 'f23'])
-        all = list(iface.names(all=True))
-        all.sort()
-        self.assertEqual(all, ['a1', 'f11', 'f12', 'f21', 'f22', 'f23'])
+        class ICheckMe(Interface):
+            attr = Attribute(u'My attr')
 
-    def test_namesAndDescriptions(self):
-        iface = self._makeDerivedInterface()
-        names = [nd[0] for nd in iface.namesAndDescriptions()]
-        names.sort()
-        self.assertEqual(names, ['f21', 'f22', 'f23'])
-        names = [nd[0] for nd in iface.namesAndDescriptions(1)]
-        names.sort()
-        self.assertEqual(names, ['a1', 'f11', 'f12', 'f21', 'f22', 'f23'])
+            def method():
+                pass
 
-        for name, d in iface.namesAndDescriptions(1):
-            self.assertEqual(name, d.__name__)
+        class CheckMe(object):
+            __implemented__ = ICheckMe
+            attr = 'value'
 
-    def test_getDescriptionFor(self):
-        iface = self._makeDerivedInterface()
-        self.assertEqual(iface.getDescriptionFor('f11').__name__, 'f11')
-        self.assertEqual(iface.getDescriptionFor('f22').__name__, 'f22')
-        self.assertEqual(iface.queryDescriptionFor('f33', self), self)
-        self.assertRaises(KeyError, iface.getDescriptionFor, 'f33')
+            def method(self):
+                pass
 
-    def test___getitem__(self):
-        iface = self._makeDerivedInterface()
-        self.assertEqual(iface['f11'].__name__, 'f11')
-        self.assertEqual(iface['f22'].__name__, 'f22')
-        self.assertEqual(iface.get('f33', self), self)
-        self.assertRaises(KeyError, iface.__getitem__, 'f33')
+        check_me = CheckMe()
 
-    def test___contains__(self):
-        iface = self._makeDerivedInterface()
-        self.failUnless('f11' in iface)
-        self.failIf('f33' in iface)
+        self.failUnless(verifyObject(ICheckMe, check_me))
 
-    def test___iter__(self):
-        iface = self._makeDerivedInterface()
-        names = list(iter(iface))
-        names.sort()
-        self.assertEqual(names, ['a1', 'f11', 'f12', 'f21', 'f22', 'f23'])
+    def test_interface_object_provides_Interface(self):
+        from zope.interface import Interface
 
-    def testAttr(self):
-        iface = self._makeDerivedInterface()
-        description = iface.getDescriptionFor('a1')
-        self.assertEqual(description.__name__, 'a1')
-        self.assertEqual(description.__doc__, 'This is an attribute')
+        class AnInterface(Interface):
+            pass
 
-    def testFunctionAttributes(self):
-        # Make sure function attributes become tagged values.
+        self.assert_(Interface.providedBy(AnInterface))
+
+    def test_names_simple(self):
+        from zope.interface import Attribute
         from zope.interface import Interface
-        class ITest(Interface):
+
+        class ISimple(Interface):
+            attr = Attribute(u'My attr')
+
             def method():
                 pass
+
+        self.assertEqual(sorted(ISimple.names()), ['attr', 'method'])
+
+    def test_names_derived(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+
+        class IBase(Interface):
+            attr = Attribute(u'My attr')
+
+            def method():
+                pass
+
+        class IDerived(IBase):
+            attr2 = Attribute(u'My attr')
+
+            def method():
+                pass
+
+            def method2():
+                pass
+
+        self.assertEqual(sorted(IDerived.names()),
+                         ['attr2', 'method', 'method2'])
+        self.assertEqual(sorted(IDerived.names(all=True)),
+                         ['attr', 'attr2', 'method', 'method2'])
+
+    def test_namesAndDescriptions_simple(self):
+        from zope.interface import Attribute
+        from zope.interface.interface import Method
+        from zope.interface import Interface
+
+        class ISimple(Interface):
+            attr = Attribute(u'My attr')
+
+            def method():
+                "My method"
+
+        name_values = sorted(ISimple.namesAndDescriptions())
+
+        self.assertEqual(len(name_values), 2)
+        self.assertEqual(name_values[0][0], 'attr')
+        self.failUnless(isinstance(name_values[0][1], Attribute))
+        self.assertEqual(name_values[0][1].__name__, 'attr')
+        self.assertEqual(name_values[0][1].__doc__, 'My attr')
+        self.assertEqual(name_values[1][0], 'method')
+        self.failUnless(isinstance(name_values[1][1], Method))
+        self.assertEqual(name_values[1][1].__name__, 'method')
+        self.assertEqual(name_values[1][1].__doc__, 'My method')
+
+    def test_namesAndDescriptions_derived(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+        from zope.interface.interface import Method
+
+        class IBase(Interface):
+            attr = Attribute(u'My attr')
+
+            def method():
+                "My method"
+
+        class IDerived(IBase):
+            attr2 = Attribute(u'My attr2')
+
+            def method():
+                "My method, overridden"
+
+            def method2():
+                "My method2"
+
+        name_values = sorted(IDerived.namesAndDescriptions())
+
+        self.assertEqual(len(name_values), 3)
+        self.assertEqual(name_values[0][0], 'attr2')
+        self.failUnless(isinstance(name_values[0][1], Attribute))
+        self.assertEqual(name_values[0][1].__name__, 'attr2')
+        self.assertEqual(name_values[0][1].__doc__, 'My attr2')
+        self.assertEqual(name_values[1][0], 'method')
+        self.failUnless(isinstance(name_values[1][1], Method))
+        self.assertEqual(name_values[1][1].__name__, 'method')
+        self.assertEqual(name_values[1][1].__doc__, 'My method, overridden')
+        self.assertEqual(name_values[2][0], 'method2')
+        self.failUnless(isinstance(name_values[2][1], Method))
+        self.assertEqual(name_values[2][1].__name__, 'method2')
+        self.assertEqual(name_values[2][1].__doc__, 'My method2')
+
+        name_values = sorted(IDerived.namesAndDescriptions(all=True))
+
+        self.assertEqual(len(name_values), 4)
+        self.assertEqual(name_values[0][0], 'attr')
+        self.failUnless(isinstance(name_values[0][1], Attribute))
+        self.assertEqual(name_values[0][1].__name__, 'attr')
+        self.assertEqual(name_values[0][1].__doc__, 'My attr')
+        self.assertEqual(name_values[1][0], 'attr2')
+        self.failUnless(isinstance(name_values[1][1], Attribute))
+        self.assertEqual(name_values[1][1].__name__, 'attr2')
+        self.assertEqual(name_values[1][1].__doc__, 'My attr2')
+        self.assertEqual(name_values[2][0], 'method')
+        self.failUnless(isinstance(name_values[2][1], Method))
+        self.assertEqual(name_values[2][1].__name__, 'method')
+        self.assertEqual(name_values[2][1].__doc__, 'My method, overridden')
+        self.assertEqual(name_values[3][0], 'method2')
+        self.failUnless(isinstance(name_values[3][1], Method))
+        self.assertEqual(name_values[3][1].__name__, 'method2')
+        self.assertEqual(name_values[3][1].__doc__, 'My method2')
+
+    def test_getDescriptionFor_nonesuch_no_default(self):
+        from zope.interface import Interface
+
+        class IEmpty(Interface):
+            pass
+
+        self.assertRaises(KeyError, IEmpty.getDescriptionFor, 'nonesuch')
+
+    def test_getDescriptionFor_simple(self):
+        from zope.interface import Attribute
+        from zope.interface.interface import Method
+        from zope.interface import Interface
+
+        class ISimple(Interface):
+            attr = Attribute(u'My attr')
+
+            def method():
+                "My method"
+
+        a_desc = ISimple.getDescriptionFor('attr')
+        self.failUnless(isinstance(a_desc, Attribute))
+        self.assertEqual(a_desc.__name__, 'attr')
+        self.assertEqual(a_desc.__doc__, 'My attr')
+
+        m_desc = ISimple.getDescriptionFor('method')
+        self.failUnless(isinstance(m_desc, Method))
+        self.assertEqual(m_desc.__name__, 'method')
+        self.assertEqual(m_desc.__doc__, 'My method')
+
+    def test_getDescriptionFor_derived(self):
+        from zope.interface import Attribute
+        from zope.interface.interface import Method
+        from zope.interface import Interface
+
+        class IBase(Interface):
+            attr = Attribute(u'My attr')
+
+            def method():
+                "My method"
+
+        class IDerived(IBase):
+            attr2 = Attribute(u'My attr2')
+
+            def method():
+                "My method, overridden"
+
+            def method2():
+                "My method2"
+
+        a_desc = IDerived.getDescriptionFor('attr')
+        self.failUnless(isinstance(a_desc, Attribute))
+        self.assertEqual(a_desc.__name__, 'attr')
+        self.assertEqual(a_desc.__doc__, 'My attr')
+
+        m_desc = IDerived.getDescriptionFor('method')
+        self.failUnless(isinstance(m_desc, Method))
+        self.assertEqual(m_desc.__name__, 'method')
+        self.assertEqual(m_desc.__doc__, 'My method, overridden')
+
+        a2_desc = IDerived.getDescriptionFor('attr2')
+        self.failUnless(isinstance(a2_desc, Attribute))
+        self.assertEqual(a2_desc.__name__, 'attr2')
+        self.assertEqual(a2_desc.__doc__, 'My attr2')
+
+        m2_desc = IDerived.getDescriptionFor('method2')
+        self.failUnless(isinstance(m2_desc, Method))
+        self.assertEqual(m2_desc.__name__, 'method2')
+        self.assertEqual(m2_desc.__doc__, 'My method2')
+
+    def test___getitem__nonesuch(self):
+        from zope.interface import Interface
+
+        class IEmpty(Interface):
+            pass
+
+        self.assertRaises(KeyError, IEmpty.__getitem__, 'nonesuch')
+
+    def test___getitem__simple(self):
+        from zope.interface import Attribute
+        from zope.interface.interface import Method
+        from zope.interface import Interface
+
+        class ISimple(Interface):
+            attr = Attribute(u'My attr')
+
+            def method():
+                "My method"
+
+        a_desc = ISimple['attr']
+        self.failUnless(isinstance(a_desc, Attribute))
+        self.assertEqual(a_desc.__name__, 'attr')
+        self.assertEqual(a_desc.__doc__, 'My attr')
+
+        m_desc = ISimple['method']
+        self.failUnless(isinstance(m_desc, Method))
+        self.assertEqual(m_desc.__name__, 'method')
+        self.assertEqual(m_desc.__doc__, 'My method')
+
+    def test___getitem___derived(self):
+        from zope.interface import Attribute
+        from zope.interface.interface import Method
+        from zope.interface import Interface
+
+        class IBase(Interface):
+            attr = Attribute(u'My attr')
+
+            def method():
+                "My method"
+
+        class IDerived(IBase):
+            attr2 = Attribute(u'My attr2')
+
+            def method():
+                "My method, overridden"
+
+            def method2():
+                "My method2"
+
+        a_desc = IDerived['attr']
+        self.failUnless(isinstance(a_desc, Attribute))
+        self.assertEqual(a_desc.__name__, 'attr')
+        self.assertEqual(a_desc.__doc__, 'My attr')
+
+        m_desc = IDerived['method']
+        self.failUnless(isinstance(m_desc, Method))
+        self.assertEqual(m_desc.__name__, 'method')
+        self.assertEqual(m_desc.__doc__, 'My method, overridden')
+
+        a2_desc = IDerived['attr2']
+        self.failUnless(isinstance(a2_desc, Attribute))
+        self.assertEqual(a2_desc.__name__, 'attr2')
+        self.assertEqual(a2_desc.__doc__, 'My attr2')
+
+        m2_desc = IDerived['method2']
+        self.failUnless(isinstance(m2_desc, Method))
+        self.assertEqual(m2_desc.__name__, 'method2')
+        self.assertEqual(m2_desc.__doc__, 'My method2')
+
+    def test___contains__nonesuch(self):
+        from zope.interface import Interface
+
+        class IEmpty(Interface):
+            pass
+
+        self.failIf('nonesuch' in IEmpty)
+
+    def test___contains__simple(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+
+        class ISimple(Interface):
+            attr = Attribute(u'My attr')
+
+            def method():
+                "My method"
+
+        self.failUnless('attr' in ISimple)
+        self.failUnless('method' in ISimple)
+
+    def test___contains__derived(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+
+        class IBase(Interface):
+            attr = Attribute(u'My attr')
+
+            def method():
+                "My method"
+
+        class IDerived(IBase):
+            attr2 = Attribute(u'My attr2')
+
+            def method():
+                "My method, overridden"
+
+            def method2():
+                "My method2"
+
+        self.failUnless('attr' in IDerived)
+        self.failUnless('method' in IDerived)
+        self.failUnless('attr2' in IDerived)
+        self.failUnless('method2' in IDerived)
+
+    def test___iter__empty(self):
+        from zope.interface import Interface
+
+        class IEmpty(Interface):
+            pass
+
+        self.assertEqual(list(IEmpty), [])
+
+    def test___iter__simple(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+
+        class ISimple(Interface):
+            attr = Attribute(u'My attr')
+
+            def method():
+                "My method"
+
+        self.assertEqual(sorted(list(ISimple)), ['attr', 'method'])
+
+    def test___iter__derived(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+
+        class IBase(Interface):
+            attr = Attribute(u'My attr')
+
+            def method():
+                "My method"
+
+        class IDerived(IBase):
+            attr2 = Attribute(u'My attr2')
+
+            def method():
+                "My method, overridden"
+
+            def method2():
+                "My method2"
+
+        self.assertEqual(sorted(list(IDerived)),
+                         ['attr', 'attr2', 'method', 'method2'])
+
+    def test_function_attributes_become_tagged_values(self):
+        from zope.interface import Interface
+
+        class ITagMe(Interface):
+            def method():
+                pass
             method.optional = 1
 
-        method = ITest['method']
+        method = ITagMe['method']
         self.assertEqual(method.getTaggedValue('optional'), 1)
 
-    def testInvariant(self):
+    def test___doc___non_element(self):
+        from zope.interface import Interface
+
+        class IHaveADocString(Interface):
+            "xxx"
+
+        self.assertEqual(IHaveADocString.__doc__, "xxx")
+        self.assertEqual(list(IHaveADocString), [])
+
+    def test___doc___as_element(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+
+        class IHaveADocString(Interface):
+            "xxx"
+            __doc__ = Attribute('the doc')
+
+        self.assertEqual(IHaveADocString.__doc__, "")
+        self.assertEqual(list(IHaveADocString), ['__doc__'])
+
+    def _errorsEqual(self, has_invariant, error_len, error_msgs, iface):
         from zope.interface.exceptions import Invalid
+        self.assertRaises(Invalid, iface.validateInvariants, has_invariant)
+        e = []
+        try:
+            iface.validateInvariants(has_invariant, e)
+        except Invalid, error:
+            self.assertEquals(error.args[0], e)
+        else:
+            self._assert(0) # validateInvariants should always raise
+            # Invalid
+        self.assertEquals(len(e), error_len)
+        msgs = [error.args[0] for error in e]
+        msgs.sort()
+        for msg in msgs:
+            self.assertEquals(msg, error_msgs.pop(0))
+
+    def test_invariant_simple(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
         from zope.interface import directlyProvides
-        from zope.interface.tests.unitfixtures import BarGreaterThanFoo
-        from zope.interface.tests.unitfixtures import ifFooThenBar
-        from zope.interface.tests.unitfixtures import IInvariant
-        from zope.interface.tests.unitfixtures import InvariantC
-        from zope.interface.tests.unitfixtures import ISubInvariant
+        from zope.interface import invariant
+
+        class IInvariant(Interface):
+            foo = Attribute('foo')
+            bar = Attribute('bar; must eval to Boolean True if foo does')
+            invariant(_ifFooThenBar)
+
+        class HasInvariant(object):
+            pass
+
         # set up
-        o = InvariantC()
-        directlyProvides(o, IInvariant)
-        # a helper
-        def errorsEqual(self, o, error_len, error_msgs, iface=None):
-            if iface is None:
-                iface = IInvariant
-            self.assertRaises(Invalid, iface.validateInvariants, o)
-            e = []
-            try:
-                iface.validateInvariants(o, e)
-            except Invalid, error:
-                self.assertEquals(error.args[0], e)
-            else:
-                self._assert(0) # validateInvariants should always raise
-                # Invalid
-            self.assertEquals(len(e), error_len)
-            msgs = [error.args[0] for error in e]
-            msgs.sort()
-            for msg in msgs:
-                self.assertEquals(msg, error_msgs.pop(0))
+        has_invariant = HasInvariant()
+        directlyProvides(has_invariant, IInvariant)
         # the tests
         self.assertEquals(IInvariant.getTaggedValue('invariants'),
-                          [ifFooThenBar])
-        self.assertEquals(IInvariant.validateInvariants(o), None)
-        o.bar = 27
-        self.assertEquals(IInvariant.validateInvariants(o), None)
-        o.foo = 42
-        self.assertEquals(IInvariant.validateInvariants(o), None)
-        del o.bar
-        errorsEqual(self, o, 1, ['If Foo, then Bar!'])
+                          [_ifFooThenBar])
+        self.assertEquals(IInvariant.validateInvariants(has_invariant), None)
+        has_invariant.bar = 27
+        self.assertEquals(IInvariant.validateInvariants(has_invariant), None)
+        has_invariant.foo = 42
+        self.assertEquals(IInvariant.validateInvariants(has_invariant), None)
+        del has_invariant.bar
+        self._errorsEqual(has_invariant, 1, ['If Foo, then Bar!'],
+                          IInvariant)
+
+    def test_invariant_nested(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+        from zope.interface import directlyProvides
+        from zope.interface import invariant
+
+        class IInvariant(Interface):
+            foo = Attribute('foo')
+            bar = Attribute('bar; must eval to Boolean True if foo does')
+            invariant(_ifFooThenBar)
+
+        class ISubInvariant(IInvariant):
+            invariant(_barGreaterThanFoo)
+
+        class HasInvariant(object):
+            pass
+
         # nested interfaces with invariants:
         self.assertEquals(ISubInvariant.getTaggedValue('invariants'),
-                          [BarGreaterThanFoo])
-        o = InvariantC()
-        directlyProvides(o, ISubInvariant)
-        o.foo = 42
+                          [_barGreaterThanFoo])
+        has_invariant = HasInvariant()
+        directlyProvides(has_invariant, ISubInvariant)
+        has_invariant.foo = 42
         # even though the interface has changed, we should still only have one
         # error.
-        errorsEqual(self, o, 1, ['If Foo, then Bar!'], ISubInvariant)
+        self._errorsEqual(has_invariant, 1, ['If Foo, then Bar!'],
+                          ISubInvariant)
         # however, if we set foo to 0 (Boolean False) and bar to a negative
         # number then we'll get the new error
-        o.foo = 2
-        o.bar = 1
-        errorsEqual(self, o, 1, ['Please, Boo MUST be greater than Foo!'],
-                    ISubInvariant)
+        has_invariant.foo = 2
+        has_invariant.bar = 1
+        self._errorsEqual(has_invariant, 1,
+                          ['Please, Boo MUST be greater than Foo!'],
+                          ISubInvariant)
         # and if we set foo to a positive number and boo to 0, we'll
         # get both errors!
-        o.foo = 1
-        o.bar = 0
-        errorsEqual(self, o, 2, ['If Foo, then Bar!',
-                                 'Please, Boo MUST be greater than Foo!'],
-                    ISubInvariant)
+        has_invariant.foo = 1
+        has_invariant.bar = 0
+        self._errorsEqual(has_invariant, 2,
+                          ['If Foo, then Bar!',
+                           'Please, Boo MUST be greater than Foo!'],
+                          ISubInvariant)
         # for a happy ending, we'll make the invariants happy
-        o.foo = 1
-        o.bar = 2
-        self.assertEquals(IInvariant.validateInvariants(o), None) # woohoo
+        has_invariant.foo = 1
+        has_invariant.bar = 2
+        self.assertEquals(IInvariant.validateInvariants(has_invariant), None)
+
+    def test_invariant_mutandis(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+        from zope.interface import directlyProvides
+        from zope.interface import invariant
+
+        class IInvariant(Interface):
+            foo = Attribute('foo')
+            bar = Attribute('bar; must eval to Boolean True if foo does')
+            invariant(_ifFooThenBar)
+
+        class HasInvariant(object):
+            pass
+
         # now we'll do two invariants on the same interface,
         # just to make sure that a small
         # multi-invariant interface is at least minimally tested.
-        o = InvariantC()
-        directlyProvides(o, IInvariant)
-        o.foo = 42
+        has_invariant = HasInvariant()
+        directlyProvides(has_invariant, IInvariant)
+        has_invariant.foo = 42
+
+        # if you really need to mutate, then this would be the way to do it.
+        # Probably a bad idea, though. :-)
         old_invariants = IInvariant.getTaggedValue('invariants')
         invariants = old_invariants[:]
-        invariants.append(BarGreaterThanFoo) # if you really need to mutate,
-        # then this would be the way to do it.  Probably a bad idea, though. :-)
+        invariants.append(_barGreaterThanFoo)
         IInvariant.setTaggedValue('invariants', invariants)
-        #
+
         # even though the interface has changed, we should still only have one
         # error.
-        errorsEqual(self, o, 1, ['If Foo, then Bar!'])
+        self._errorsEqual(has_invariant, 1, ['If Foo, then Bar!'],
+                          IInvariant)
         # however, if we set foo to 0 (Boolean False) and bar to a negative
         # number then we'll get the new error
-        o.foo = 2
-        o.bar = 1
-        errorsEqual(self, o, 1, ['Please, Boo MUST be greater than Foo!'])
+        has_invariant.foo = 2
+        has_invariant.bar = 1
+        self._errorsEqual(has_invariant, 1,
+                         ['Please, Boo MUST be greater than Foo!'], IInvariant)
         # and if we set foo to a positive number and boo to 0, we'll
         # get both errors!
-        o.foo = 1
-        o.bar = 0
-        errorsEqual(self, o, 2, ['If Foo, then Bar!',
-                                 'Please, Boo MUST be greater than Foo!'])
+        has_invariant.foo = 1
+        has_invariant.bar = 0
+        self._errorsEqual(has_invariant, 2,
+                          ['If Foo, then Bar!',
+                           'Please, Boo MUST be greater than Foo!'],
+                          IInvariant)
         # for another happy ending, we'll make the invariants happy again
-        o.foo = 1
-        o.bar = 2
-        self.assertEquals(IInvariant.validateInvariants(o), None) # bliss
-        # clean up
-        IInvariant.setTaggedValue('invariants', old_invariants)
+        has_invariant.foo = 1
+        has_invariant.bar = 2
+        self.assertEquals(IInvariant.validateInvariants(has_invariant), None)
 
-    def test___doc___element(self):
-        from zope.interface import Interface
-        from zope.interface import Attribute
-        class I(Interface):
-            "xxx"
-
-        self.assertEqual(I.__doc__, "xxx")
-        self.assertEqual(list(I), [])
-
-        class I(Interface):
-            "xxx"
-
-            __doc__ = Attribute('the doc')
-
-        self.assertEqual(I.__doc__, "")
-        self.assertEqual(list(I), ['__doc__'])
-
     def testIssue228(self):
-        from zope.interface import Interface
         # Test for http://collector.zope.org/Zope3-dev/228
-        if sys.version[0] == '3':
+        # Old style classes don't have a '__class__' attribute
+        import sys
+        if sys.version[0] < '3':
             # No old style classes in Python 3, so the test becomes moot.
-            return
-        class I(Interface):
-            "xxx"
-        class Bad:
-            __providedBy__ = None
-        # Old style classes don't have a '__class__' attribute
-        self.failUnlessRaises(AttributeError, I.providedBy, Bad)
+            from zope.interface import Interface
 
+            class I(Interface):
+                "xxx"
 
+            class OldStyle:
+                __providedBy__ = None
 
-if sys.version_info >= (2, 4):
+            self.assertRaises(AttributeError, I.providedBy, OldStyle)
 
-    def test_invariant_as_decorator():
-        """Invaiants can be deined in line
+    def test_invariant_as_decorator(self):
+        from zope.interface import Interface
+        from zope.interface import Attribute
+        from zope.interface import implements
+        from zope.interface import invariant
+        from zope.interface.exceptions import Invalid
 
-          >>> from zope.interface.exceptions import Invalid
-          >>> from zope.interface import Interface
-          >>> from zope.interface import Attribute
-          >>> from zope.interface import implements
-          >>> from zope.interface import invariant
-          >>> class IRange(Interface):
-          ...     min = Attribute("Lower bound")
-          ...     max = Attribute("Upper bound")
-          ...
-          ...     @invariant
-          ...     def range_invariant(ob):
-          ...         if ob.max < ob.min:
-          ...             raise Invalid('max < min')
+        class IRange(Interface):
+            min = Attribute("Lower bound")
+            max = Attribute("Upper bound")
+            
+            @invariant
+            def range_invariant(ob):
+                if ob.max < ob.min:
+                    raise Invalid('max < min')
 
+        class Range(object):
+            implements(IRange)
 
-          >>> class Range(object):
-          ...     implements(IRange)
-          ...
-          ...     def __init__(self, min, max):
-          ...         self.min, self.max = min, max
+            def __init__(self, min, max):
+                self.min, self.max = min, max
 
-          >>> from zope.interface.exceptions import Invalid
-          >>> IRange.validateInvariants(Range(1,2))
-          >>> IRange.validateInvariants(Range(1,1))
-          >>> try:
-          ...     IRange.validateInvariants(Range(2,1))
-          ... except Invalid, e:
-          ...     str(e)
-          'max < min'
+        IRange.validateInvariants(Range(1,2))
+        IRange.validateInvariants(Range(1,1))
+        try:
+            IRange.validateInvariants(Range(2,1))
+        except Invalid, e:
+            self.assertEqual(str(e), 'max < min')
 
+    def test_description_cache_management(self):
+        # See https://bugs.launchpad.net/zope.interface/+bug/185974
+        # There was a bug where the cache used by Specification.get() was not
+        # cleared when the bases were changed.
+        from zope.interface import Interface
+        from zope.interface import Attribute
 
-        """
+        class I1(Interface):
+            a = Attribute('a')
 
+        class I2(I1):
+            pass
 
-def test_description_cache_management():
-    """ See https://bugs.launchpad.net/zope.interface/+bug/185974
+        class I3(I2):
+            pass
 
-There was a bug where the cache used by Specification.get() was not
-cleared when the bases were changed.
+        self.failUnless(I3.get('a') is I1.get('a'))
 
-    >>> from zope.interface import Interface
-    >>> from zope.interface import Attribute
-    >>> class I1(Interface):
-    ...     a = Attribute('a')
+        I2.__bases__ = (Interface,)
+        self.failUnless(I3.get('a') is None)
 
-    >>> class I2(I1):
-    ...     pass
+def _barGreaterThanFoo(obj):
+    from zope.interface.exceptions import Invalid
+    foo = getattr(obj, 'foo', None)
+    bar = getattr(obj, 'bar', None)
+    if foo is not None and isinstance(foo, type(bar)):
+        # type checking should be handled elsewhere (like, say, 
+        # schema); these invariants should be intra-interface 
+        # constraints.  This is a hacky way to do it, maybe, but you
+        # get the idea
+        if not bar > foo:
+            raise Invalid('Please, Boo MUST be greater than Foo!')
 
-    >>> class I3(I2):
-    ...     pass
+def _ifFooThenBar(obj):
+    from zope.interface.exceptions import Invalid
+    if getattr(obj, 'foo', None) and not getattr(obj, 'bar', None):
+        raise Invalid('If Foo, then Bar!')
 
-    >>> I3.get('a') is I1.get('a')
-    True
-    >>> I2.__bases__ = (Interface,)
-    >>> I3.get('a') is None
-    True
-    """
 
 
+
 def test_suite():
     suite = unittest.makeSuite(InterfaceTests)
+    suite.addTest(doctest.DocTestSuite())
     suite.addTest(doctest.DocTestSuite("zope.interface.interface"))
-    if sys.version_info >= (2, 4):
-        suite.addTest(doctest.DocTestSuite())
-    suite.addTest(doctest.DocFileSuite(
-        '../README.txt',
-        globs={'__name__': '__main__'},
-        optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
-        ))
-    suite.addTest(doctest.DocFileSuite(
-        '../README.ru.txt',
-        globs={'__name__': '__main__'},
-        optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
-        ))
     return suite

Modified: zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_odd_declarations.py
===================================================================
--- zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_odd_declarations.py	2010-04-28 16:41:48 UTC (rev 111553)
+++ zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_odd_declarations.py	2010-04-28 16:48:14 UTC (rev 111554)
@@ -180,15 +180,15 @@
         self.assertRaises(TypeError, directlyProvides, C, I5)
 
     # see above
-    def TODO_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 TODO_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

Modified: zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_verify.py
===================================================================
--- zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_verify.py	2010-04-28 16:41:48 UTC (rev 111553)
+++ zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/test_verify.py	2010-04-28 16:48:14 UTC (rev 111554)
@@ -11,192 +11,512 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Interface Verify tests
-
-$Id$
+""" zope.interface.verify unit tests
 """
-import doctest
 import unittest
 
-from zope.interface import Interface, implements, classImplements, Attribute
-from zope.interface.verify import verifyClass, verifyObject
-from zope.interface.exceptions import DoesNotImplement, BrokenImplementation
-from zope.interface.exceptions import BrokenMethodImplementation
 
-class Test(unittest.TestCase):
+class Test_verifyClass(unittest.TestCase):
 
-    def testNotImplemented(self):
+    def _callFUT(self, iface, klass):
+        from zope.interface.verify import verifyClass
+        return verifyClass(iface, klass)
 
-        class C(object): pass
+    def test_class_doesnt_implement(self):
+        from zope.interface import Interface
+        from zope.interface.exceptions import DoesNotImplement
 
-        class I(Interface): pass
+        class ICurrent(Interface):
+            pass
 
-        self.assertRaises(DoesNotImplement, verifyClass, I, C)
+        class Current(object):
+            pass
 
-        classImplements(C, I)
+        self.assertRaises(DoesNotImplement, self._callFUT, ICurrent, Current)
 
-        verifyClass(I, C)
+    def test_class_doesnt_implement_but_classImplements_later(self):
+        from zope.interface import Interface
+        from zope.interface import classImplements
 
-    def testMissingAttr(self):
+        class ICurrent(Interface):
+            pass
 
-        class I(Interface):
-            def f(): pass
+        class Current(object):
+            pass
 
-        class C(object):
-            implements(I)
+        classImplements(Current, ICurrent)
 
-        self.assertRaises(BrokenImplementation, verifyClass, I, C)
+        self._callFUT(ICurrent, Current)
 
-        C.f=lambda self: None
+    def test_class_doesnt_have_required_method_simple(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+        from zope.interface.exceptions import BrokenImplementation
 
-        verifyClass(I, C)
+        class ICurrent(Interface):
+            def method(): pass
 
-    def testMissingAttr_with_Extended_Interface(self):
+        class Current(object):
+            implements(ICurrent)
 
-        class II(Interface):
-            def f():
+        self.assertRaises(BrokenImplementation,
+                          self._callFUT, ICurrent, Current)
+
+    def test_class_has_required_method_simple(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+
+        class ICurrent(Interface):
+            def method(): pass
+
+        class Current(object):
+            implements(ICurrent)
+
+            def method(self):
                 pass
 
-        class I(II):
+        self._callFUT(ICurrent, Current)
+
+    def test_class_doesnt_have_required_method_derived(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+        from zope.interface.exceptions import BrokenImplementation
+
+        class IBase(Interface):
+            def method():
+                pass
+
+        class IDerived(IBase):
             pass
 
-        class C(object):
-            implements(I)
+        class Current(object):
+            implements(IDerived)
 
-        self.assertRaises(BrokenImplementation, verifyClass, I, C)
+        self.assertRaises(BrokenImplementation,
+                          self._callFUT, IDerived, Current)
 
-        C.f=lambda self: None
+    def test_class_has_required_method_derived(self):
+        from zope.interface import Interface
+        from zope.interface import implements
 
-        verifyClass(I, C)
+        class IBase(Interface):
+            def method():
+                pass
 
-    def testWrongArgs(self):
+        class IDerived(IBase):
+            pass
 
-        class I(Interface):
-            def f(a): pass
+        class Current(object):
+            implements(IDerived)
 
-        class C(object):
-            def f(self, b): pass
+            def method(self):
+                pass
 
-            implements(I)
+        self._callFUT(IDerived, Current)
 
+    def test_method_takes_wrong_arg_names_but_OK(self):
         # We no longer require names to match.
-        #self.assertRaises(BrokenMethodImplementation, verifyClass, I, C)
+        from zope.interface import Interface
+        from zope.interface import implements
 
-        C.f=lambda self, a: None
+        class ICurrent(Interface):
 
-        verifyClass(I, C)
+            def method(a):
+                pass
 
-        C.f=lambda self, **kw: None
+        class Current(object):
+            implements(ICurrent)
 
-        self.assertRaises(BrokenMethodImplementation, verifyClass, I, C)
+            def method(self, b):
+                pass
 
-        C.f=lambda self, a, *args: None
+        self._callFUT(ICurrent, Current)
 
-        verifyClass(I, C)
+    def test_method_takes_not_enough_args(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+        from zope.interface.exceptions import BrokenMethodImplementation
 
-        C.f=lambda self, a, *args, **kw: None
+        class ICurrent(Interface):
 
-        verifyClass(I, C)
+            def method(a):
+                pass
 
-        C.f=lambda self, *args: None
+        class Current(object):
+            implements(ICurrent)
 
-        verifyClass(I, C)
+            def method(self):
+                pass
 
-    def testExtraArgs(self):
+        self.assertRaises(BrokenMethodImplementation,
+                          self._callFUT, ICurrent, Current)
 
-        class I(Interface):
-            def f(a): pass
+    def test_method_doesnt_take_required_starargs(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+        from zope.interface.exceptions import BrokenMethodImplementation
 
-        class C(object):
-            def f(self, a, b): pass
+        class ICurrent(Interface):
 
-            implements(I)
+            def method(*args):
+                pass
 
-        self.assertRaises(BrokenMethodImplementation, verifyClass, I, C)
+        class Current(object):
+            implements(ICurrent)
 
-        C.f=lambda self, a: None
+            def method(self):
+                pass
 
-        verifyClass(I, C)
+        self.assertRaises(BrokenMethodImplementation,
+                          self._callFUT, ICurrent, Current)
 
-        C.f=lambda self, a, b=None: None
+    def test_method_doesnt_take_required_only_kwargs(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+        from zope.interface.exceptions import BrokenMethodImplementation
 
-        verifyClass(I, C)
+        class ICurrent(Interface):
 
-    def testNoVar(self):
+            def method(**kw):
+                pass
 
-        class I(Interface):
-            def f(a, *args): pass
+        class Current(object):
+            implements(ICurrent)
 
-        class C(object):
-            def f(self, a): pass
+            def method(self):
+                pass
 
-            implements(I)
+        self.assertRaises(BrokenMethodImplementation,
+                          self._callFUT, ICurrent, Current)
 
-        self.assertRaises(BrokenMethodImplementation, verifyClass, I, C)
+    def test_method_takes_extra_arg(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+        from zope.interface.exceptions import BrokenMethodImplementation
 
-        C.f=lambda self, a, *foo: None
+        class ICurrent(Interface):
 
-        verifyClass(I, C)
+            def method(a):
+                pass
 
-    def testNoKW(self):
+        class Current(object):
+            implements(ICurrent)
 
-        class I(Interface):
-            def f(a, **args): pass
+            def method(self, a, b):
+                pass
 
-        class C(object):
-            def f(self, a): pass
+        self.assertRaises(BrokenMethodImplementation,
+                          self._callFUT, ICurrent, Current)
 
-            implements(I)
+    def test_method_takes_extra_arg_with_default(self):
+        from zope.interface import Interface
+        from zope.interface import implements
 
-        self.assertRaises(BrokenMethodImplementation, verifyClass, I, C)
+        class ICurrent(Interface):
 
-        C.f=lambda self, a, **foo: None
+            def method(a):
+                pass
 
-        verifyClass(I, C)
+        class Current(object):
+            implements(ICurrent)
 
-    def testModule(self):
+            def method(self, a, b=None):
+                pass
 
-        from zope.interface.tests.ifoo import IFoo
-        from zope.interface.tests import dummy
+        self._callFUT(ICurrent, Current)
 
-        verifyObject(IFoo, dummy)
+    def test_method_takes_only_positional_args(self):
+        from zope.interface import Interface
+        from zope.interface import implements
 
-    def testMethodForAttr(self):
-        
-        class IFoo(Interface):
-             foo = Attribute("The foo Attribute")
+        class ICurrent(Interface):
 
+            def method(a):
+                pass
 
-        class Foo:
-             implements(IFoo)
+        class Current(object):
+            implements(ICurrent)
 
-             def foo(self):
-                 pass
+            def method(self, *args):
+                pass
 
-        verifyClass(IFoo, Foo)
+        self._callFUT(ICurrent, Current)
 
-    def testNonMethodForMethod(self):
+    def test_method_takes_only_kwargs(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+        from zope.interface.exceptions import BrokenMethodImplementation
 
-        class IBar(Interface):
-             def foo():
-                 pass
+        class ICurrent(Interface):
 
-        class Bar:
-            implements(IBar)
+            def method(a):
+                pass
 
-            foo = 1
+        class Current(object):
+            implements(ICurrent)
 
-        self.assertRaises(BrokenMethodImplementation, verifyClass, IBar, Bar)
-        
+            def method(self, **kw):
+                pass
 
+        self.assertRaises(BrokenMethodImplementation,
+                          self._callFUT, ICurrent, Current)
+
+    def test_method_takes_extra_starargs(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+
+        class ICurrent(Interface):
+
+            def method(a):
+                pass
+
+        class Current(object):
+            implements(ICurrent)
+
+            def method(self, a, *args):
+                pass
+
+        self._callFUT(ICurrent, Current)
+
+    def test_method_takes_extra_starargs_and_kwargs(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+
+        class ICurrent(Interface):
+
+            def method(a):
+                pass
+
+        class Current(object):
+            implements(ICurrent)
+
+            def method(self, a, *args, **kw):
+                pass
+
+        self._callFUT(ICurrent, Current)
+
+    def test_method_doesnt_take_required_positional_and_starargs(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+        from zope.interface.exceptions import BrokenMethodImplementation
+
+        class ICurrent(Interface):
+
+            def method(a, *args):
+                pass
+
+        class Current(object):
+            implements(ICurrent)
+
+            def method(self, a):
+                pass
+
+        self.assertRaises(BrokenMethodImplementation,
+                          self._callFUT, ICurrent, Current)
+
+    def test_method_takes_required_positional_and_starargs(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+
+        class ICurrent(Interface):
+
+            def method(a, *args):
+                pass
+
+        class Current(object):
+            implements(ICurrent)
+
+            def method(self, a, *args):
+                pass
+
+        self._callFUT(ICurrent, Current)
+
+    def test_method_takes_only_starargs(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+
+        class ICurrent(Interface):
+
+            def method(a, *args):
+                pass
+
+        class Current(object):
+            implements(ICurrent)
+
+            def method(self, *args):
+                pass
+
+        self._callFUT(ICurrent, Current)
+
+    def test_method_takes_required_kwargs(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+
+        class ICurrent(Interface):
+
+            def method(**kwargs):
+                pass
+
+        class Current(object):
+            implements(ICurrent)
+
+            def method(self, **kw):
+                pass
+
+        self._callFUT(ICurrent, Current)
+
+    def test_method_takes_positional_plus_required_starargs(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+        from zope.interface.exceptions import BrokenMethodImplementation
+
+        class ICurrent(Interface):
+
+            def method(*args):
+                pass
+
+        class Current(object):
+            implements(ICurrent)
+
+            def method(self, a, *args):
+                pass
+
+        self.assertRaises(BrokenMethodImplementation,
+                          self._callFUT, ICurrent, Current)
+
+
+    def test_method_doesnt_take_required_kwargs(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+        from zope.interface.exceptions import BrokenMethodImplementation
+
+        class ICurrent(Interface):
+
+            def method(**kwargs):
+                pass
+
+        class Current(object):
+            implements(ICurrent)
+
+            def method(self, a):
+                pass
+
+        self.assertRaises(BrokenMethodImplementation,
+                          self._callFUT, ICurrent, Current)
+
+
+    def test_class_has_method_for_iface_attr(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+        from zope.interface import implements
+
+        class ICurrent(Interface):
+            attr = Attribute("The foo Attribute")
+
+        class Current:
+            implements(ICurrent)
+
+            def attr(self):
+                pass
+
+        self._callFUT(ICurrent, Current)
+
+    def test_class_has_nonmethod_for_method(self):
+        from zope.interface import Interface
+        from zope.interface import implements
+        from zope.interface.exceptions import BrokenMethodImplementation
+
+        class ICurrent(Interface):
+            def method():
+                pass
+
+        class Current:
+            implements(ICurrent)
+            method = 1
+
+        self.assertRaises(BrokenMethodImplementation,
+                          self._callFUT, ICurrent, Current)
+
+    def test_class_has_attribute_for_attribute(self):
+        from zope.interface import Attribute
+        from zope.interface import Interface
+        from zope.interface import implements
+
+        class ICurrent(Interface):
+            attr = Attribute("The foo Attribute")
+
+        class Current:
+            implements(ICurrent)
+
+            attr = 1
+
+        self._callFUT(ICurrent, Current)
+
+    def test_class_misses_attribute_for_attribute(self):
+        # This check *passes* for verifyClass
+        from zope.interface import Attribute
+        from zope.interface import Interface
+        from zope.interface import implements
+
+        class ICurrent(Interface):
+            attr = Attribute("The foo Attribute")
+
+        class Current:
+            implements(ICurrent)
+
+        self._callFUT(ICurrent, Current)
+
+class Test_verifyObject(Test_verifyClass):
+
+    def _callFUT(self, iface, target):
+        from zope.interface.verify import verifyObject
+        if isinstance(target, (type, type(OldSkool))):
+            target = target()
+        return verifyObject(iface, target)
+
+    def test_class_misses_attribute_for_attribute(self):
+        # This check *fails* for verifyObject
+        from zope.interface import Attribute
+        from zope.interface import Interface
+        from zope.interface import implements
+        from zope.interface.exceptions import BrokenImplementation
+
+        class ICurrent(Interface):
+            attr = Attribute("The foo Attribute")
+
+        class Current:
+            implements(ICurrent)
+
+        self.assertRaises(BrokenImplementation,
+                          self._callFUT, ICurrent, Current)
+
+    def test_module_hit(self):
+        from zope.interface.tests.idummy import IDummyModule
+        from zope.interface.tests import dummy
+
+        self._callFUT(IDummyModule, dummy)
+
+    def test_module_miss(self):
+        from zope.interface import Interface
+        from zope.interface.tests import dummy
+        from zope.interface.exceptions import DoesNotImplement
+
+        # same name, different object
+        class IDummyModule(Interface):
+            pass
+
+        self.assertRaises(DoesNotImplement,
+                          self._callFUT, IDummyModule, dummy)
+
+class OldSkool:
+    pass
+
 def test_suite():
-    loader=unittest.TestLoader()
+    #import doctest
     return unittest.TestSuite((
-        doctest.DocFileSuite(
-            '../verify.txt',
-            optionflags=doctest.NORMALIZE_WHITESPACE),
-        loader.loadTestsFromTestCase(Test),
-        ))
-
-if __name__=='__main__':
-    unittest.TextTestRunner().run(test_suite())
+        unittest.makeSuite(Test_verifyClass),
+        unittest.makeSuite(Test_verifyObject),
+    #   This one needs to turn into just docs.
+    #doctest.DocFileSuite('../verify.txt',
+    #                     optionflags=doctest.NORMALIZE_WHITESPACE),
+    ))

Deleted: zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/unitfixtures.py
===================================================================
--- zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/unitfixtures.py	2010-04-28 16:41:48 UTC (rev 111553)
+++ zope.interface/branches/tseaver-better_unittests/src/zope/interface/tests/unitfixtures.py	2010-04-28 16:48:14 UTC (rev 111554)
@@ -1,142 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 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.
-#
-##############################################################################
-"""Unit Test Fixtures
-
-$Id$
-"""
-from zope.interface import Interface, invariant
-from zope.interface.interface import Attribute
-from zope.interface.exceptions import Invalid
-
-class mytest(Interface):
-    pass
-
-class C(object):
-    def m1(self, a, b):
-        "return 1"
-        return 1
-
-    def m2(self, a, b):
-        "return 2"
-        return 2
-
-# testInstancesOfClassImplements
-
-#  YAGNI IC=Interface.impliedInterface(C)
-class IC(Interface):
-    def m1(a, b):
-        "return 1"
-
-    def m2(a, b):
-        "return 2"
-
-
-
-C.__implemented__=IC
-
-class I1(Interface):
-    def ma():
-        "blah"
-
-class I2(I1): pass
-
-class I3(Interface): pass
-
-class I4(Interface): pass
-
-class A(I1.deferred()):
-    __implemented__=I1
-
-class B(object):
-    __implemented__=I2, I3
-
-class D(A, B): pass
-
-class E(A, B):
-    __implemented__ = A.__implemented__, C.__implemented__
-
-
-class FooInterface(Interface):
-    """ This is an Abstract Base Class """
-
-    foobar = Attribute("fuzzed over beyond all recognition")
-
-    def aMethod(foo, bar, bingo):
-        """ This is aMethod """
-
-    def anotherMethod(foo=6, bar="where you get sloshed", bingo=(1,3,)):
-        """ This is anotherMethod """
-
-    def wammy(zip, *argues):
-        """ yadda yadda """
-
-    def useless(**keywords):
-        """ useless code is fun! """
-
-class Foo(object):
-    """ A concrete class """
-
-    __implemented__ = FooInterface,
-
-    foobar = "yeah"
-
-    def aMethod(self, foo, bar, bingo):
-        """ This is aMethod """
-        return "barf!"
-
-    def anotherMethod(self, foo=6, bar="where you get sloshed", bingo=(1,3,)):
-        """ This is anotherMethod """
-        return "barf!"
-
-    def wammy(self, zip, *argues):
-        """ yadda yadda """
-        return "barf!"
-
-    def useless(self, **keywords):
-        """ useless code is fun! """
-        return "barf!"
-
-foo_instance = Foo()
-
-class Blah(object):
-    pass
-
-new = Interface.__class__
-FunInterface = new('FunInterface')
-BarInterface = new('BarInterface', [FunInterface])
-BobInterface = new('BobInterface')
-BazInterface = new('BazInterface', [BobInterface, BarInterface])
-
-# fixtures for invariant tests
-def ifFooThenBar(obj):
-    if getattr(obj, 'foo', None) and not getattr(obj, 'bar', None):
-        raise Invalid('If Foo, then Bar!')
-class IInvariant(Interface):
-    foo = Attribute('foo')
-    bar = Attribute('bar; must eval to Boolean True if foo does')
-    invariant(ifFooThenBar)
-def BarGreaterThanFoo(obj):
-    foo = getattr(obj, 'foo', None)
-    bar = getattr(obj, 'bar', None)
-    if foo is not None and isinstance(foo, type(bar)):
-        # type checking should be handled elsewhere (like, say, 
-        # schema); these invariants should be intra-interface 
-        # constraints.  This is a hacky way to do it, maybe, but you
-        # get the idea
-        if not bar > foo:
-            raise Invalid('Please, Boo MUST be greater than Foo!')
-class ISubInvariant(IInvariant):
-    invariant(BarGreaterThanFoo)
-class InvariantC(object):
-    pass

Modified: zope.interface/branches/tseaver-better_unittests/src/zope/interface/verify.py
===================================================================
--- zope.interface/branches/tseaver-better_unittests/src/zope/interface/verify.py	2010-04-28 16:41:48 UTC (rev 111553)
+++ zope.interface/branches/tseaver-better_unittests/src/zope/interface/verify.py	2010-04-28 16:48:14 UTC (rev 111554)
@@ -70,7 +70,8 @@
         if isinstance(attr, FunctionType):
             if sys.version[0] == '3' and isinstance(candidate, type):
                 # This is an "unbound method" in Python 3.
-                meth = fromFunction(attr, iface, name=name, imlevel=1)
+                meth = fromFunction(attr, iface, name=name,
+                                    imlevel=1) #pragma NO COVERAGE
             else:
                 # Nope, just a normal function
                 meth = fromFunction(attr, iface, name=name)



More information about the checkins mailing list