diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/zope/interface/index.txt | 1 | ||||
| -rw-r--r-- | src/zope/interface/tests/dummy.py | 9 | ||||
| -rw-r--r-- | src/zope/interface/tests/idummy.py (renamed from src/zope/interface/tests/ifoo.py) | 13 | ||||
| -rw-r--r-- | src/zope/interface/tests/test_document.py | 281 | ||||
| -rw-r--r-- | src/zope/interface/tests/test_exceptions.py | 75 | ||||
| -rw-r--r-- | src/zope/interface/tests/test_interface.py | 1121 | ||||
| -rw-r--r-- | src/zope/interface/tests/test_odd_declarations.py | 18 | ||||
| -rw-r--r-- | src/zope/interface/tests/test_verify.py | 538 | ||||
| -rw-r--r-- | src/zope/interface/tests/unitfixtures.py | 142 | ||||
| -rw-r--r-- | src/zope/interface/verify.py | 3 |
10 files changed, 1558 insertions, 643 deletions
diff --git a/src/zope/interface/index.txt b/src/zope/interface/index.txt index 3c499b5..603f53e 100644 --- a/src/zope/interface/index.txt +++ b/src/zope/interface/index.txt @@ -10,6 +10,7 @@ Contents: adapter human verify + tests/foodforthought По-русски ========= diff --git a/src/zope/interface/tests/dummy.py b/src/zope/interface/tests/dummy.py index 74bc65e..9057d73 100644 --- a/src/zope/interface/tests/dummy.py +++ b/src/zope/interface/tests/dummy.py @@ -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 diff --git a/src/zope/interface/tests/ifoo.py b/src/zope/interface/tests/idummy.py index 3e38b69..1e34fe0 100644 --- a/src/zope/interface/tests/ifoo.py +++ b/src/zope/interface/tests/idummy.py @@ -11,18 +11,13 @@ # FOR A PARTICULAR PURPOSE. # ############################################################################## -"""IFoo test module - -$Id$ +""" Interface describing API of zope.interface.tests.dummy test module """ from zope.interface import Interface -class IFoo(Interface): - """ - Dummy interface for unit tests. +class IDummyModule(Interface): + """ Dummy interface for unit tests. """ - def bar(baz): - """ - Just a note. + """ Just a note. """ diff --git a/src/zope/interface/tests/test_document.py b/src/zope/interface/tests/test_document.py index 66f7e27..6a1b0b2 100644 --- a/src/zope/interface/tests/test_document.py +++ b/src/zope/interface/tests/test_document.py @@ -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) + + 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 + + self.assertEqual(self._callFUT(IHasMethod), EXPECTED) + + 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. + """ + + self.assertEqual(self._callFUT(IHasMethod), EXPECTED) + + 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 _I1(Interface): - def f11(): pass - def f12(): pass + class IDerived(IBase): + "IDerived doc" + attr1 = Attribute('attr1') + attr2 = Attribute('attr2', 'attr2 doc') -class I2(_I1): - "I2 doc" + def method3(): + "method3 doc" + def method4(): + pass + def method5(): + "method5 doc" - a1 = Attribute('a1') - a2 = Attribute('a2', 'a2 doc') + self.assertEqual(self._callFUT(IDerived), EXPECTED) - def f21(): "f21 doc" - def f22(): pass - def f23(): "f23 doc" +class Test__justify_and_indent(unittest.TestCase): -if __name__=='__main__': - main(defaultTest='test_suite') + 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), + )) diff --git a/src/zope/interface/tests/test_exceptions.py b/src/zope/interface/tests/test_exceptions.py new file mode 100644 index 0000000..94009f6 --- /dev/null +++ b/src/zope/interface/tests/test_exceptions.py @@ -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 ') + diff --git a/src/zope/interface/tests/test_interface.py b/src/zope/interface/tests/test_interface.py index b2dbb33..868c351 100644 --- a/src/zope/interface/tests/test_interface.py +++ b/src/zope/interface/tests/test_interface.py @@ -13,420 +13,871 @@ ############################################################################## """Test Interface implementation """ -import doctest import unittest -import sys +import doctest 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") + + self.failUnless(I1['attr'].interface is I1) + + def test_methods_link_to_interface(self): + from zope.interface import Interface + + class I1(Interface): - def f11(): + 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 + def method2(a, b): pass - f12.optional = 1 - class _I1_(_I1): + class IOther(Interface): + pass + + 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() + + 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 _I1__(_I1_): + class IBase(Interface): + def method(): + pass + + class IDerived(IBase): pass - class _I2(_I1__): - def f21(): + class Current(object): + __implemented__ = IDerived + def method(self): + pass + + current = Current() + + 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 test_classImplements_multiple(self): + from zope.interface import Interface + from zope.interface import implementedBy + from zope.interface import providedBy + + class ILeft(Interface): + def method(): pass - def f22(): + + class IRight(ILeft): + pass + + class Left(object): + __implemented__ = ILeft + + def method(self): pass - f23 = f22 - - return _I2 - - def testInterfaceSetOnAttributes(self): - from zope.interface.tests.unitfixtures import FooInterface - self.assertEqual(FooInterface['foobar'].interface, - FooInterface) - self.assertEqual(FooInterface['aMethod'].interface, - FooInterface) - - 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)) - - 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)) - - self.assert_(not I2.implementedBy(A)) - self.assert_(I2.implementedBy(B)) - self.assert_(not I2.implementedBy(C)) - - # No longer after interfacegeddon - # self.assert_(not I2.implementedBy(D)) - - self.assert_(not I2.implementedBy(E)) - - 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())) - - - 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())) - - 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())) - - self.assert_(not I2.providedBy(A())) - self.assert_(I2.providedBy(B())) - self.assert_(not I2.providedBy(C())) - - # Not after interface geddon - # self.assert_(not I2.providedBy(D())) - - self.assert_(not I2.providedBy(E())) - - def testDeferredClass(self): - from zope.interface.tests.unitfixtures import A + + class ILeft(Interface): + + def method(): + pass + + class IRight(ILeft): + pass + + class IOther(Interface): + pass + + class Left(): + __implemented__ = ILeft + + def method(self): + pass + + class Right(object): + __implemented__ = IRight + + 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)) - - def testVerifyImplementation(self): + from zope.interface import Interface + + 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.verify import verifyObject + + class ICheckMe(Interface): + attr = Attribute(u'My attr') + + def method(): + pass + + class CheckMe(object): + __implemented__ = ICheckMe + attr = 'value' + + def method(self): + pass + + check_me = CheckMe() + + self.failUnless(verifyObject(ICheckMe, check_me)) + + def test_interface_object_provides_Interface(self): + from zope.interface import Interface + + class AnInterface(Interface): + pass + + self.assert_(Interface.providedBy(AnInterface)) + + def test_names_simple(self): + from zope.interface import Attribute + from zope.interface import 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 - 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)) - - 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']) - - 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']) - - for name, d in iface.namesAndDescriptions(1): - self.assertEqual(name, d.__name__) - - 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 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') - - def test___contains__(self): - iface = self._makeDerivedInterface() - self.failUnless('f11' in iface) - self.failIf('f33' in iface) - - def test___iter__(self): - iface = self._makeDerivedInterface() - names = list(iter(iface)) - names.sort() - self.assertEqual(names, ['a1', 'f11', 'f12', 'f21', 'f22', 'f23']) - - def testAttr(self): - iface = self._makeDerivedInterface() - description = iface.getDescriptionFor('a1') - self.assertEqual(description.__name__, 'a1') - self.assertEqual(description.__doc__, 'This is an attribute') - - def testFunctionAttributes(self): - # Make sure function attributes become tagged values. - from zope.interface import Interface - class ITest(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) - - 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__']) + has_invariant.foo = 1 + has_invariant.bar = 2 + self.assertEquals(IInvariant.validateInvariants(has_invariant), None) def testIssue228(self): - from zope.interface import Interface # Test for http://collector.zope.org/Zope3-dev/228 - 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) - - - -if sys.version_info >= (2, 4): + import sys + if sys.version[0] < '3': + # No old style classes in Python 3, so the test becomes moot. + from zope.interface import Interface - def test_invariant_as_decorator(): - """Invaiants can be deined in line + class I(Interface): + "xxx" - >>> 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 OldStyle: + __providedBy__ = None + self.assertRaises(AttributeError, I.providedBy, OldStyle) - >>> class Range(object): - ... implements(IRange) - ... - ... def __init__(self, min, max): - ... self.min, self.max = min, max + 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 - >>> IRange.validateInvariants(Range(1,2)) - >>> IRange.validateInvariants(Range(1,1)) - >>> try: - ... IRange.validateInvariants(Range(2,1)) - ... except Invalid, e: - ... str(e) - '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) + + def __init__(self, min, max): + self.min, self.max = min, max + + 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 + class I3(I2): + pass -def test_description_cache_management(): - """ See https://bugs.launchpad.net/zope.interface/+bug/185974 + self.failUnless(I3.get('a') is I1.get('a')) -There was a bug where the cache used by Specification.get() was not -cleared when the bases were changed. + I2.__bases__ = (Interface,) + self.failUnless(I3.get('a') is None) - >>> from zope.interface import Interface - >>> from zope.interface import Attribute - >>> class I1(Interface): - ... a = Attribute('a') +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 I2(I1): - ... 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!') - >>> class I3(I2): - ... pass - >>> 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 diff --git a/src/zope/interface/tests/test_odd_declarations.py b/src/zope/interface/tests/test_odd_declarations.py index 973bd5e..849ff35 100644 --- a/src/zope/interface/tests/test_odd_declarations.py +++ b/src/zope/interface/tests/test_odd_declarations.py @@ -180,15 +180,15 @@ class Test(unittest.TestCase): 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 diff --git a/src/zope/interface/tests/test_verify.py b/src/zope/interface/tests/test_verify.py index 6ae9915..e516ca8 100644 --- a/src/zope/interface/tests/test_verify.py +++ b/src/zope/interface/tests/test_verify.py @@ -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 _callFUT(self, iface, klass): + from zope.interface.verify import verifyClass + return verifyClass(iface, klass) - def testNotImplemented(self): + def test_class_doesnt_implement(self): + from zope.interface import Interface + from zope.interface.exceptions import DoesNotImplement - class C(object): pass + class ICurrent(Interface): + pass + + class Current(object): + pass - class I(Interface): pass + self.assertRaises(DoesNotImplement, self._callFUT, ICurrent, Current) - self.assertRaises(DoesNotImplement, verifyClass, I, C) + def test_class_doesnt_implement_but_classImplements_later(self): + from zope.interface import Interface + from zope.interface import classImplements + + class ICurrent(Interface): + pass + + class Current(object): + pass - classImplements(C, I) + classImplements(Current, ICurrent) - verifyClass(I, C) + self._callFUT(ICurrent, Current) - def testMissingAttr(self): + 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 - class I(Interface): - def f(): pass + class ICurrent(Interface): + def method(): pass - class C(object): - implements(I) + class Current(object): + implements(ICurrent) - self.assertRaises(BrokenImplementation, verifyClass, I, C) + self.assertRaises(BrokenImplementation, + self._callFUT, ICurrent, Current) - C.f=lambda self: None + def test_class_has_required_method_simple(self): + from zope.interface import Interface + from zope.interface import implements - 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(): + 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 + + class ICurrent(Interface): - C.f=lambda self, a: None + def method(a): + pass - verifyClass(I, C) + class Current(object): + implements(ICurrent) - C.f=lambda self, **kw: None + def method(self, b): + pass - self.assertRaises(BrokenMethodImplementation, verifyClass, I, C) + self._callFUT(ICurrent, Current) - C.f=lambda self, a, *args: None + def test_method_takes_not_enough_args(self): + from zope.interface import Interface + from zope.interface import implements + from zope.interface.exceptions import BrokenMethodImplementation - verifyClass(I, C) + class ICurrent(Interface): - C.f=lambda self, a, *args, **kw: None + def method(a): + pass - verifyClass(I, C) + class Current(object): + implements(ICurrent) - C.f=lambda self, *args: None + def method(self): + pass - verifyClass(I, C) + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) - def testExtraArgs(self): + 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 I(Interface): - def f(a): pass + class ICurrent(Interface): - class C(object): - def f(self, a, b): pass + def method(*args): + pass - implements(I) + class Current(object): + implements(ICurrent) - self.assertRaises(BrokenMethodImplementation, verifyClass, I, C) + def method(self): + pass - C.f=lambda self, a: None + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) - verifyClass(I, C) + 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 - C.f=lambda self, a, b=None: None + class ICurrent(Interface): - verifyClass(I, C) + def method(**kw): + pass - def testNoVar(self): + class Current(object): + implements(ICurrent) - class I(Interface): - def f(a, *args): pass + def method(self): + pass - class C(object): - def f(self, a): pass + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) - implements(I) + def test_method_takes_extra_arg(self): + from zope.interface import Interface + from zope.interface import implements + from zope.interface.exceptions import BrokenMethodImplementation - 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 testNoKW(self): + def method(self, a, b): + pass - class I(Interface): - def f(a, **args): pass + self.assertRaises(BrokenMethodImplementation, + self._callFUT, ICurrent, Current) - class C(object): - def f(self, a): pass + def test_method_takes_extra_arg_with_default(self): + from zope.interface import Interface + from zope.interface import implements - implements(I) + class ICurrent(Interface): - self.assertRaises(BrokenMethodImplementation, verifyClass, I, C) + def method(a): + pass - C.f=lambda self, a, **foo: None + class Current(object): + implements(ICurrent) - verifyClass(I, C) + def method(self, a, b=None): + pass - def testModule(self): + self._callFUT(ICurrent, Current) - from zope.interface.tests.ifoo import IFoo - from zope.interface.tests import dummy + def test_method_takes_only_positional_args(self): + from zope.interface import Interface + from zope.interface import implements + + class ICurrent(Interface): + + def method(a): + pass + + class Current(object): + implements(ICurrent) - verifyObject(IFoo, dummy) + def method(self, *args): + pass + + self._callFUT(ICurrent, Current) + + def test_method_takes_only_kwargs(self): + from zope.interface import Interface + from zope.interface import implements + from zope.interface.exceptions import BrokenMethodImplementation + + class ICurrent(Interface): + + def method(a): + pass + + class Current(object): + implements(ICurrent) + + 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 - def testMethodForAttr(self): - - class IFoo(Interface): - foo = Attribute("The foo Attribute") + self._callFUT(ICurrent, Current) + def test_method_takes_extra_starargs_and_kwargs(self): + from zope.interface import Interface + from zope.interface import implements - class Foo: - implements(IFoo) + class ICurrent(Interface): - def foo(self): - pass + def method(a): + pass + + class Current(object): + implements(ICurrent) + + def method(self, a, *args, **kw): + pass + + self._callFUT(ICurrent, Current) - verifyClass(IFoo, Foo) + 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 - def testNonMethodForMethod(self): + class ICurrent(Interface): - class IBar(Interface): - def foo(): - pass + 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 - class Bar: - implements(IBar) + 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 - foo = 1 + self.assertRaises(DoesNotImplement, + self._callFUT, IDummyModule, dummy) - self.assertRaises(BrokenMethodImplementation, verifyClass, IBar, Bar) - +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), + )) diff --git a/src/zope/interface/tests/unitfixtures.py b/src/zope/interface/tests/unitfixtures.py deleted file mode 100644 index 28f3ff3..0000000 --- a/src/zope/interface/tests/unitfixtures.py +++ /dev/null @@ -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 diff --git a/src/zope/interface/verify.py b/src/zope/interface/verify.py index 7393534..49c8972 100644 --- a/src/zope/interface/verify.py +++ b/src/zope/interface/verify.py @@ -70,7 +70,8 @@ def _verify(iface, candidate, tentative=0, vtype=None): 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) |
