Primer commit
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
from zope.interface._compat import _should_attempt_c_optimizations
|
||||
|
||||
|
||||
class OptimizationTestMixin:
|
||||
"""
|
||||
Helper for testing that C optimizations are used
|
||||
when appropriate.
|
||||
"""
|
||||
|
||||
def _getTargetClass(self):
|
||||
"""
|
||||
Define this to return the implementation in use,
|
||||
without the 'Py' or 'Fallback' suffix.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def _getFallbackClass(self):
|
||||
"""
|
||||
Define this to return the fallback Python implementation.
|
||||
"""
|
||||
# Is there an algorithmic way to do this? The C
|
||||
# objects all come from the same module so I don't see how we can
|
||||
# get the Python object from that.
|
||||
raise NotImplementedError
|
||||
|
||||
def test_optimizations(self):
|
||||
used = self._getTargetClass()
|
||||
fallback = self._getFallbackClass()
|
||||
|
||||
if _should_attempt_c_optimizations():
|
||||
self.assertIsNot(used, fallback)
|
||||
else:
|
||||
self.assertIs(used, fallback)
|
||||
|
||||
|
||||
class MissingSomeAttrs:
|
||||
"""
|
||||
Helper for tests that raises a specific exception
|
||||
for attributes that are missing. This is usually not
|
||||
an AttributeError, and this object is used to test that
|
||||
those errors are not improperly caught and treated like
|
||||
an AttributeError.
|
||||
"""
|
||||
|
||||
def __init__(self, exc_kind, **other_attrs):
|
||||
self.__exc_kind = exc_kind
|
||||
d = object.__getattribute__(self, '__dict__')
|
||||
d.update(other_attrs)
|
||||
|
||||
def __getattribute__(self, name):
|
||||
# Note that we ignore objects found in the class dictionary.
|
||||
d = object.__getattribute__(self, '__dict__')
|
||||
try:
|
||||
return d[name]
|
||||
except KeyError:
|
||||
raise d['_MissingSomeAttrs__exc_kind'](name)
|
||||
|
||||
EXCEPTION_CLASSES = (
|
||||
TypeError,
|
||||
RuntimeError,
|
||||
BaseException,
|
||||
ValueError,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def test_raises(cls, unittest, test_func, expected_missing, **other_attrs):
|
||||
"""
|
||||
Loop through various exceptions, calling *test_func* inside a ``assertRaises`` block.
|
||||
|
||||
:param test_func: A callable of one argument, the instance of this
|
||||
class.
|
||||
:param str expected_missing: The attribute that should fail with the exception.
|
||||
This is used to ensure that we're testing the path we think we are.
|
||||
:param other_attrs: Attributes that should be provided on the test object.
|
||||
Must not contain *expected_missing*.
|
||||
"""
|
||||
assert isinstance(expected_missing, str)
|
||||
assert expected_missing not in other_attrs
|
||||
for exc in cls.EXCEPTION_CLASSES:
|
||||
ob = cls(exc, **other_attrs)
|
||||
with unittest.assertRaises(exc) as ex:
|
||||
test_func(ob)
|
||||
|
||||
unittest.assertEqual(ex.exception.args[0], expected_missing)
|
||||
|
||||
# Now test that the AttributeError for that expected_missing is *not* raised.
|
||||
ob = cls(AttributeError, **other_attrs)
|
||||
try:
|
||||
test_func(ob)
|
||||
except AttributeError as e:
|
||||
unittest.assertNotIn(expected_missing, str(e))
|
||||
except Exception: # pylint:disable=broad-except
|
||||
pass
|
||||
|
||||
# Be sure cleanup functionality is available; classes that use the adapter hook
|
||||
# need to be sure to subclass ``CleanUp``.
|
||||
#
|
||||
# If zope.component is installed and imported when we run our tests
|
||||
# (import chain:
|
||||
# zope.testrunner->zope.security->zope.location->zope.component.api)
|
||||
# it adds an adapter hook that uses its global site manager. That can cause
|
||||
# leakage from one test to another unless its cleanup hooks are run. The symptoms can
|
||||
# be odd, especially if one test used C objects and the next used the Python
|
||||
# implementation. (For example, you can get strange TypeErrors or find inexplicable
|
||||
# comparisons being done.)
|
||||
try:
|
||||
from zope.testing import cleanup
|
||||
except ImportError:
|
||||
class CleanUp:
|
||||
def cleanUp(self):
|
||||
pass
|
||||
|
||||
setUp = tearDown = cleanUp
|
||||
else:
|
||||
CleanUp = cleanup.CleanUp
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2003 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
import sys
|
||||
|
||||
from zope.interface.advice import getFrameInfo
|
||||
|
||||
my_globals = globals()
|
||||
|
||||
ClassicClass = None
|
||||
|
||||
class NewStyleClass:
|
||||
__metaclass__ = type
|
||||
classLevelFrameInfo = getFrameInfo(sys._getframe())
|
||||
|
||||
moduleLevelFrameInfo = getFrameInfo(sys._getframe())
|
||||
@@ -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.
|
||||
#
|
||||
##############################################################################
|
||||
""" Dummy Module
|
||||
"""
|
||||
from zope.interface import moduleProvides
|
||||
from zope.interface.tests.idummy import IDummyModule
|
||||
|
||||
moduleProvides(IDummyModule)
|
||||
|
||||
def bar(baz):
|
||||
# Note: no 'self', because the module provides the interface directly.
|
||||
raise NotImplementedError()
|
||||
@@ -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.
|
||||
"""
|
||||
21
venv/lib/python3.11/site-packages/zope/interface/tests/m1.py
Normal file
21
venv/lib/python3.11/site-packages/zope/interface/tests/m1.py
Normal file
@@ -0,0 +1,21 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Test module that declares an interface
|
||||
"""
|
||||
from zope.interface import Interface, moduleProvides
|
||||
|
||||
class I1(Interface): pass
|
||||
class I2(Interface): pass
|
||||
|
||||
moduleProvides(I1, I2)
|
||||
124
venv/lib/python3.11/site-packages/zope/interface/tests/odd.py
Normal file
124
venv/lib/python3.11/site-packages/zope/interface/tests/odd.py
Normal file
@@ -0,0 +1,124 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2003 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Odd meta class that doesn't subclass type.
|
||||
|
||||
This is used for testing support for ExtensionClass in new interfaces.
|
||||
|
||||
>>> class A(object):
|
||||
... __metaclass__ = MetaClass
|
||||
... a = 1
|
||||
...
|
||||
>>> A.__name__
|
||||
'A'
|
||||
>>> A.__bases__ == (object,)
|
||||
True
|
||||
>>> class B(object):
|
||||
... __metaclass__ = MetaClass
|
||||
... b = 1
|
||||
...
|
||||
>>> class C(A, B): pass
|
||||
...
|
||||
>>> C.__name__
|
||||
'C'
|
||||
>>> int(C.__bases__ == (A, B))
|
||||
1
|
||||
>>> a = A()
|
||||
>>> aa = A()
|
||||
>>> a.a
|
||||
1
|
||||
>>> aa.a
|
||||
1
|
||||
>>> aa.a = 2
|
||||
>>> a.a
|
||||
1
|
||||
>>> aa.a
|
||||
2
|
||||
>>> c = C()
|
||||
>>> c.a
|
||||
1
|
||||
>>> c.b
|
||||
1
|
||||
>>> c.b = 2
|
||||
>>> c.b
|
||||
2
|
||||
>>> C.c = 1
|
||||
>>> c.c
|
||||
1
|
||||
|
||||
>>> int(C.__class__.__class__ is C.__class__)
|
||||
1
|
||||
"""
|
||||
|
||||
# class OddClass is an odd meta class
|
||||
|
||||
class MetaMetaClass(type):
|
||||
|
||||
def __getattribute__(cls, name):
|
||||
if name == '__class__':
|
||||
return cls
|
||||
# Under Python 3.6, __prepare__ gets requested
|
||||
return type.__getattribute__(cls, name)
|
||||
|
||||
|
||||
class MetaClass:
|
||||
"""Odd classes
|
||||
"""
|
||||
|
||||
def __init__(self, name, bases, dict):
|
||||
self.__name__ = name
|
||||
self.__bases__ = bases
|
||||
self.__dict__.update(dict)
|
||||
|
||||
def __call__(self):
|
||||
return OddInstance(self)
|
||||
|
||||
def __getattr__(self, name):
|
||||
for b in self.__bases__:
|
||||
v = getattr(b, name, self)
|
||||
if v is not self:
|
||||
return v
|
||||
raise AttributeError(name)
|
||||
|
||||
def __repr__(self): # pragma: no cover
|
||||
return "<odd class {} at {}>".format(self.__name__, hex(id(self)))
|
||||
|
||||
|
||||
MetaClass = MetaMetaClass('MetaClass',
|
||||
MetaClass.__bases__,
|
||||
{k: v for k, v in MetaClass.__dict__.items()
|
||||
if k not in ('__dict__',)})
|
||||
|
||||
class OddInstance:
|
||||
|
||||
def __init__(self, cls):
|
||||
self.__dict__['__class__'] = cls
|
||||
|
||||
def __getattribute__(self, name):
|
||||
dict = object.__getattribute__(self, '__dict__')
|
||||
if name == '__dict__':
|
||||
return dict
|
||||
v = dict.get(name, self)
|
||||
if v is not self:
|
||||
return v
|
||||
return getattr(dict['__class__'], name)
|
||||
|
||||
def __setattr__(self, name, v):
|
||||
self.__dict__[name] = v
|
||||
|
||||
def __delattr__(self, name):
|
||||
raise NotImplementedError()
|
||||
|
||||
def __repr__(self): # pragma: no cover
|
||||
return "<odd {} instance at {}>".format(
|
||||
self.__class__.__name__, hex(id(self)))
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,191 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2003 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Tests for advice
|
||||
|
||||
This module was adapted from 'protocols.tests.advice', part of the Python
|
||||
Enterprise Application Kit (PEAK). Please notify the PEAK authors
|
||||
(pje@telecommunity.com and tsarna@sarna.org) if bugs are found or
|
||||
Zope-specific changes are required, so that the PEAK version of this module
|
||||
can be kept in sync.
|
||||
|
||||
PEAK is a Python application framework that interoperates with (but does
|
||||
not require) Zope 3 and Twisted. It provides tools for manipulating UML
|
||||
models, object-relational persistence, aspect-oriented programming, and more.
|
||||
Visit the PEAK home page at http://peak.telecommunity.com for more information.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
|
||||
class FrameInfoTest(unittest.TestCase):
|
||||
|
||||
def test_w_module(self):
|
||||
from zope.interface.tests import advisory_testing
|
||||
(kind, module,
|
||||
f_locals, f_globals) = advisory_testing.moduleLevelFrameInfo
|
||||
self.assertEqual(kind, "module")
|
||||
for d in module.__dict__, f_locals, f_globals:
|
||||
self.assertTrue(d is advisory_testing.my_globals)
|
||||
|
||||
def test_w_class(self):
|
||||
from zope.interface.tests import advisory_testing
|
||||
(kind,
|
||||
module,
|
||||
f_locals,
|
||||
f_globals) = advisory_testing.NewStyleClass.classLevelFrameInfo
|
||||
self.assertEqual(kind, "class")
|
||||
|
||||
for d in module.__dict__, f_globals:
|
||||
self.assertTrue(d is advisory_testing.my_globals)
|
||||
|
||||
def test_inside_function_call(self):
|
||||
from zope.interface.advice import getFrameInfo
|
||||
kind, module, f_locals, f_globals = getFrameInfo(sys._getframe())
|
||||
self.assertEqual(kind, "function call")
|
||||
self.assertTrue(f_locals is locals()) # ???
|
||||
for d in module.__dict__, f_globals:
|
||||
self.assertTrue(d is globals())
|
||||
|
||||
def test_inside_exec(self):
|
||||
from zope.interface.advice import getFrameInfo
|
||||
_globals = {'getFrameInfo': getFrameInfo}
|
||||
_locals = {}
|
||||
exec(_FUNKY_EXEC, _globals, _locals)
|
||||
self.assertEqual(_locals['kind'], "exec")
|
||||
self.assertTrue(_locals['f_locals'] is _locals)
|
||||
self.assertTrue(_locals['module'] is None)
|
||||
self.assertTrue(_locals['f_globals'] is _globals)
|
||||
|
||||
|
||||
_FUNKY_EXEC = """\
|
||||
import sys
|
||||
kind, module, f_locals, f_globals = getFrameInfo(sys._getframe())
|
||||
"""
|
||||
|
||||
class Test_isClassAdvisor(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, *args, **kw):
|
||||
from zope.interface.advice import isClassAdvisor
|
||||
return isClassAdvisor(*args, **kw)
|
||||
|
||||
def test_w_non_function(self):
|
||||
self.assertEqual(self._callFUT(self), False)
|
||||
|
||||
def test_w_normal_function(self):
|
||||
def foo():
|
||||
raise NotImplementedError()
|
||||
self.assertEqual(self._callFUT(foo), False)
|
||||
|
||||
def test_w_advisor_function(self):
|
||||
def bar():
|
||||
raise NotImplementedError()
|
||||
bar.previousMetaclass = object()
|
||||
self.assertEqual(self._callFUT(bar), True)
|
||||
|
||||
|
||||
class Test_determineMetaclass(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, *args, **kw):
|
||||
from zope.interface.advice import determineMetaclass
|
||||
return determineMetaclass(*args, **kw)
|
||||
|
||||
def test_empty_w_explicit_metatype(self):
|
||||
class Meta(type):
|
||||
pass
|
||||
self.assertEqual(self._callFUT((), Meta), Meta)
|
||||
|
||||
def test_single(self):
|
||||
class Meta(type):
|
||||
pass
|
||||
self.assertEqual(self._callFUT((Meta,)), type)
|
||||
|
||||
def test_meta_of_class(self):
|
||||
class Metameta(type):
|
||||
pass
|
||||
class Meta(type, metaclass=Metameta):
|
||||
pass
|
||||
|
||||
self.assertEqual(self._callFUT((Meta, type)), Metameta)
|
||||
|
||||
def test_multiple_in_hierarchy_py3k(self):
|
||||
class Meta_A(type):
|
||||
pass
|
||||
|
||||
class Meta_B(Meta_A):
|
||||
pass
|
||||
|
||||
class A(type, metaclass=Meta_A):
|
||||
pass
|
||||
|
||||
class B(type, metaclass=Meta_B):
|
||||
pass
|
||||
|
||||
self.assertEqual(self._callFUT((A, B)), Meta_B)
|
||||
|
||||
|
||||
def test_multiple_not_in_hierarchy_py3k(self):
|
||||
class Meta_A(type):
|
||||
pass
|
||||
|
||||
class Meta_B(type):
|
||||
pass
|
||||
|
||||
class A(type, metaclass=Meta_A):
|
||||
pass
|
||||
|
||||
class B(type, metaclass=Meta_B):
|
||||
pass
|
||||
|
||||
self.assertRaises(TypeError, self._callFUT, (A, B))
|
||||
|
||||
|
||||
class Test_minimalBases(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, klasses):
|
||||
from zope.interface.advice import minimalBases
|
||||
return minimalBases(klasses)
|
||||
|
||||
def test_empty(self):
|
||||
self.assertEqual(self._callFUT([]), [])
|
||||
|
||||
def test_w_newstyle_meta(self):
|
||||
self.assertEqual(self._callFUT([type]), [type])
|
||||
|
||||
def test_w_newstyle_class(self):
|
||||
class C:
|
||||
pass
|
||||
self.assertEqual(self._callFUT([C]), [C])
|
||||
|
||||
def test_simple_hierarchy_skips_implied(self):
|
||||
class A:
|
||||
pass
|
||||
class B(A):
|
||||
pass
|
||||
class C(B):
|
||||
pass
|
||||
class D:
|
||||
pass
|
||||
self.assertEqual(self._callFUT([A, B, C]), [C])
|
||||
self.assertEqual(self._callFUT([A, C]), [C])
|
||||
self.assertEqual(self._callFUT([B, C]), [C])
|
||||
self.assertEqual(self._callFUT([A, B]), [B])
|
||||
self.assertEqual(self._callFUT([D, B, D]), [B, D])
|
||||
|
||||
def test_repeats_kicked_to_end_of_queue(self):
|
||||
class A:
|
||||
pass
|
||||
class B:
|
||||
pass
|
||||
self.assertEqual(self._callFUT([A, B, A]), [B, A])
|
||||
@@ -0,0 +1,29 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2022 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
|
||||
#
|
||||
##############################################################################
|
||||
import struct
|
||||
import unittest
|
||||
|
||||
import zope.interface # noqa: try to load a C module for side effects
|
||||
|
||||
|
||||
class TestFloatingPoint(unittest.TestCase):
|
||||
|
||||
def test_no_fast_math_optimization(self):
|
||||
# Building with -Ofast enables -ffast-math, which sets certain FPU
|
||||
# flags that can cause breakage elsewhere. A library such as BTrees
|
||||
# has no business changing global FPU flags for the entire process.
|
||||
zero_bits = struct.unpack("!Q", struct.pack("!d", 0.0))[0]
|
||||
next_up = zero_bits + 1
|
||||
smallest_subnormal = struct.unpack("!d", struct.pack("!Q", next_up))[0]
|
||||
self.assertNotEqual(smallest_subnormal, 0.0)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,505 @@
|
||||
##############################################################################
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
##############################################################################
|
||||
"""Documentation tests.
|
||||
"""
|
||||
import unittest
|
||||
|
||||
|
||||
class Test_asStructuredText(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, iface):
|
||||
from zope.interface.document import asStructuredText
|
||||
return asStructuredText(iface)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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.
|
||||
|
||||
It can be used to annotate any class or object, because it promises
|
||||
nothing.
|
||||
"""
|
||||
self.assertEqual(self._callFUT(IEmpty), EXPECTED)
|
||||
|
||||
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')
|
||||
|
||||
self.assertEqual(self._callFUT(IHasAttribute), EXPECTED)
|
||||
|
||||
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.')
|
||||
|
||||
self.assertEqual(self._callFUT(IHasAttribute), EXPECTED)
|
||||
|
||||
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 # pragma: no cover
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
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 # pragma: no cover
|
||||
|
||||
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 # pragma: no cover
|
||||
|
||||
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 # pragma: no cover
|
||||
|
||||
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():
|
||||
"""docstring"""
|
||||
def method2():
|
||||
"""docstring"""
|
||||
|
||||
class IDerived(IBase):
|
||||
"IDerived doc"
|
||||
attr1 = Attribute('attr1')
|
||||
attr2 = Attribute('attr2', 'attr2 doc')
|
||||
|
||||
def method3():
|
||||
"method3 doc"
|
||||
def method4():
|
||||
pass # pragma: no cover
|
||||
def method5():
|
||||
"method5 doc"
|
||||
|
||||
self.assertEqual(self._callFUT(IDerived), EXPECTED)
|
||||
|
||||
|
||||
class Test_asReStructuredText(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, iface):
|
||||
from zope.interface.document import asReStructuredText
|
||||
return asReStructuredText(iface)
|
||||
|
||||
def test_asReStructuredText_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)
|
||||
|
||||
def test_asReStructuredText_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)
|
||||
|
||||
def test_asReStructuredText_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.
|
||||
|
||||
It can be used to annotate any class or object, because it promises
|
||||
nothing.
|
||||
"""
|
||||
self.assertEqual(self._callFUT(IEmpty), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_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')
|
||||
|
||||
self.assertEqual(self._callFUT(IHasAttribute), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_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.')
|
||||
|
||||
self.assertEqual(self._callFUT(IHasAttribute), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_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 # pragma: no cover
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_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 # pragma: no cover
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_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 # pragma: no cover
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_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 # pragma: no cover
|
||||
|
||||
self.assertEqual(self._callFUT(IHasMethod), EXPECTED)
|
||||
|
||||
def test_asReStructuredText_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_asReStructuredText_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 # pragma: no cover
|
||||
def method2():
|
||||
pass # pragma: no cover
|
||||
|
||||
class IDerived(IBase):
|
||||
"IDerived doc"
|
||||
attr1 = Attribute('attr1')
|
||||
attr2 = Attribute('attr2', 'attr2 doc')
|
||||
|
||||
def method3():
|
||||
"method3 doc"
|
||||
def method4():
|
||||
pass # pragma: no cover
|
||||
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)
|
||||
@@ -0,0 +1,31 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2003 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Test Element meta-class.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from zope.interface.interface import Element
|
||||
|
||||
class TestElement(unittest.TestCase):
|
||||
|
||||
def test_taggedValues(self):
|
||||
"""Test that we can update tagged values of more than one element
|
||||
"""
|
||||
|
||||
e1 = Element("foo")
|
||||
e2 = Element("bar")
|
||||
e1.setTaggedValue("x", 1)
|
||||
e2.setTaggedValue("x", 2)
|
||||
self.assertEqual(e1.getTaggedValue("x"), 1)
|
||||
self.assertEqual(e2.getTaggedValue("x"), 2)
|
||||
@@ -0,0 +1,184 @@
|
||||
##############################################################################
|
||||
#
|
||||
# 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, *args):
|
||||
iface = _makeIface()
|
||||
return self._getTargetClass()(iface, *args)
|
||||
|
||||
def test___str__(self):
|
||||
dni = self._makeOne()
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"An object has failed to implement interface "
|
||||
"zope.interface.tests.test_exceptions.IDummy: "
|
||||
"Does not declaratively implement the interface."
|
||||
)
|
||||
|
||||
def test___str__w_candidate(self):
|
||||
dni = self._makeOne('candidate')
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"The object 'candidate' has failed to implement interface "
|
||||
"zope.interface.tests.test_exceptions.IDummy: "
|
||||
"Does not declaratively implement the interface."
|
||||
)
|
||||
|
||||
|
||||
class BrokenImplementationTests(unittest.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.exceptions import BrokenImplementation
|
||||
return BrokenImplementation
|
||||
|
||||
def _makeOne(self, *args):
|
||||
iface = _makeIface()
|
||||
return self._getTargetClass()(iface, 'missing', *args)
|
||||
|
||||
def test___str__(self):
|
||||
dni = self._makeOne()
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
'An object has failed to implement interface '
|
||||
'zope.interface.tests.test_exceptions.IDummy: '
|
||||
"The 'missing' attribute was not provided.")
|
||||
|
||||
def test___str__w_candidate(self):
|
||||
dni = self._makeOne('candidate')
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
'The object \'candidate\' has failed to implement interface '
|
||||
'zope.interface.tests.test_exceptions.IDummy: '
|
||||
"The 'missing' attribute was not provided.")
|
||||
|
||||
|
||||
def broken_function():
|
||||
"""
|
||||
This is a global function with a simple argument list.
|
||||
|
||||
It exists to be able to report the same information when
|
||||
formatting signatures.
|
||||
"""
|
||||
|
||||
|
||||
class BrokenMethodImplementationTests(unittest.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
return BrokenMethodImplementation
|
||||
|
||||
message = 'I said so'
|
||||
|
||||
def _makeOne(self, *args):
|
||||
return self._getTargetClass()('aMethod', self.message, *args)
|
||||
|
||||
def test___str__(self):
|
||||
dni = self._makeOne()
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"An object has failed to implement interface <Unknown>: "
|
||||
"The contract of 'aMethod' is violated because I said so."
|
||||
)
|
||||
|
||||
def test___str__w_candidate_no_implementation(self):
|
||||
dni = self._makeOne('some_function', '<IFoo>', 'candidate')
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"The object 'candidate' has failed to implement interface <IFoo>: "
|
||||
"The contract of 'aMethod' is violated because I said so."
|
||||
)
|
||||
|
||||
def test___str__w_candidate_w_implementation(self):
|
||||
self.message = 'implementation is wonky'
|
||||
dni = self._makeOne(broken_function, '<IFoo>', 'candidate')
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"The object 'candidate' has failed to implement interface <IFoo>: "
|
||||
"The contract of 'aMethod' is violated because "
|
||||
"'broken_function()' is wonky."
|
||||
)
|
||||
|
||||
def test___str__w_candidate_w_implementation_not_callable(self):
|
||||
self.message = 'implementation is not callable'
|
||||
dni = self._makeOne(42, '<IFoo>', 'candidate')
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"The object 'candidate' has failed to implement interface <IFoo>: "
|
||||
"The contract of 'aMethod' is violated because "
|
||||
"'42' is not callable."
|
||||
)
|
||||
|
||||
def test___repr__w_candidate(self):
|
||||
dni = self._makeOne(None, 'candidate')
|
||||
self.assertEqual(
|
||||
repr(dni),
|
||||
"BrokenMethodImplementation('aMethod', 'I said so', None, 'candidate')"
|
||||
)
|
||||
|
||||
|
||||
class MultipleInvalidTests(unittest.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.exceptions import MultipleInvalid
|
||||
return MultipleInvalid
|
||||
|
||||
def _makeOne(self, excs):
|
||||
iface = _makeIface()
|
||||
return self._getTargetClass()(iface, 'target', excs)
|
||||
|
||||
def test__str__(self):
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
excs = [
|
||||
BrokenMethodImplementation('aMethod', 'I said so'),
|
||||
Exception("Regular exception")
|
||||
]
|
||||
dni = self._makeOne(excs)
|
||||
self.assertEqual(
|
||||
str(dni),
|
||||
"The object 'target' has failed to implement interface "
|
||||
"zope.interface.tests.test_exceptions.IDummy:\n"
|
||||
" The contract of 'aMethod' is violated because I said so\n"
|
||||
" Regular exception"
|
||||
)
|
||||
|
||||
def test__repr__(self):
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
excs = [
|
||||
BrokenMethodImplementation('aMethod', 'I said so'),
|
||||
# Use multiple arguments to normalize repr; versions of Python
|
||||
# prior to 3.7 add a trailing comma if there's just one.
|
||||
Exception("Regular", "exception")
|
||||
]
|
||||
dni = self._makeOne(excs)
|
||||
self.assertEqual(
|
||||
repr(dni),
|
||||
"MultipleInvalid(<InterfaceClass zope.interface.tests.test_exceptions.IDummy>,"
|
||||
" 'target',"
|
||||
" (BrokenMethodImplementation('aMethod', 'I said so'),"
|
||||
" Exception('Regular', 'exception')))"
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,128 @@
|
||||
import unittest
|
||||
|
||||
|
||||
class _ConformsToIObjectEvent:
|
||||
|
||||
def _makeOne(self, target=None):
|
||||
if target is None:
|
||||
target = object()
|
||||
return self._getTargetClass()(target)
|
||||
|
||||
def test_class_conforms_to_IObjectEvent(self):
|
||||
from zope.interface.interfaces import IObjectEvent
|
||||
from zope.interface.verify import verifyClass
|
||||
verifyClass(IObjectEvent, self._getTargetClass())
|
||||
|
||||
def test_instance_conforms_to_IObjectEvent(self):
|
||||
from zope.interface.interfaces import IObjectEvent
|
||||
from zope.interface.verify import verifyObject
|
||||
verifyObject(IObjectEvent, self._makeOne())
|
||||
|
||||
|
||||
class _ConformsToIRegistrationEvent(_ConformsToIObjectEvent):
|
||||
|
||||
def test_class_conforms_to_IRegistrationEvent(self):
|
||||
from zope.interface.interfaces import IRegistrationEvent
|
||||
from zope.interface.verify import verifyClass
|
||||
verifyClass(IRegistrationEvent, self._getTargetClass())
|
||||
|
||||
def test_instance_conforms_to_IRegistrationEvent(self):
|
||||
from zope.interface.interfaces import IRegistrationEvent
|
||||
from zope.interface.verify import verifyObject
|
||||
verifyObject(IRegistrationEvent, self._makeOne())
|
||||
|
||||
|
||||
class ObjectEventTests(unittest.TestCase, _ConformsToIObjectEvent):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.interfaces import ObjectEvent
|
||||
return ObjectEvent
|
||||
|
||||
def test_ctor(self):
|
||||
target = object()
|
||||
event = self._makeOne(target)
|
||||
self.assertTrue(event.object is target)
|
||||
|
||||
|
||||
class RegistrationEventTests(unittest.TestCase,
|
||||
_ConformsToIRegistrationEvent):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.interfaces import RegistrationEvent
|
||||
return RegistrationEvent
|
||||
|
||||
def test___repr__(self):
|
||||
target = object()
|
||||
event = self._makeOne(target)
|
||||
r = repr(event)
|
||||
self.assertEqual(r.splitlines(),
|
||||
['RegistrationEvent event:', repr(target)])
|
||||
|
||||
|
||||
class RegisteredTests(unittest.TestCase,
|
||||
_ConformsToIRegistrationEvent):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.interfaces import Registered
|
||||
return Registered
|
||||
|
||||
def test_class_conforms_to_IRegistered(self):
|
||||
from zope.interface.interfaces import IRegistered
|
||||
from zope.interface.verify import verifyClass
|
||||
verifyClass(IRegistered, self._getTargetClass())
|
||||
|
||||
def test_instance_conforms_to_IRegistered(self):
|
||||
from zope.interface.interfaces import IRegistered
|
||||
from zope.interface.verify import verifyObject
|
||||
verifyObject(IRegistered, self._makeOne())
|
||||
|
||||
|
||||
class UnregisteredTests(unittest.TestCase,
|
||||
_ConformsToIRegistrationEvent):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.interfaces import Unregistered
|
||||
return Unregistered
|
||||
|
||||
def test_class_conforms_to_IUnregistered(self):
|
||||
from zope.interface.interfaces import IUnregistered
|
||||
from zope.interface.verify import verifyClass
|
||||
verifyClass(IUnregistered, self._getTargetClass())
|
||||
|
||||
def test_instance_conforms_to_IUnregistered(self):
|
||||
from zope.interface.interfaces import IUnregistered
|
||||
from zope.interface.verify import verifyObject
|
||||
verifyObject(IUnregistered, self._makeOne())
|
||||
|
||||
|
||||
class InterfaceClassTests(unittest.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from zope.interface.interface import InterfaceClass
|
||||
return InterfaceClass
|
||||
|
||||
def _getTargetInterface(self):
|
||||
from zope.interface.interfaces import IInterface
|
||||
return IInterface
|
||||
|
||||
def _makeOne(self):
|
||||
from zope.interface.interface import Interface
|
||||
return Interface
|
||||
|
||||
def test_class_conforms(self):
|
||||
from zope.interface.verify import verifyClass
|
||||
verifyClass(self._getTargetInterface(), self._getTargetClass())
|
||||
|
||||
def test_instance_conforms(self):
|
||||
from zope.interface.verify import verifyObject
|
||||
verifyObject(self._getTargetInterface(), self._makeOne())
|
||||
|
||||
def test_instance_consistent__iro__(self):
|
||||
from zope.interface import ro
|
||||
self.assertTrue(ro.is_consistent(self._getTargetInterface()))
|
||||
|
||||
def test_class_consistent__iro__(self):
|
||||
from zope.interface import ro
|
||||
from zope.interface import implementedBy
|
||||
|
||||
self.assertTrue(ro.is_consistent(implementedBy(self._getTargetClass())))
|
||||
@@ -0,0 +1,255 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2003 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""Test interface declarations against ExtensionClass-like classes.
|
||||
|
||||
These tests are to make sure we do something sane in the presence of
|
||||
classic ExtensionClass classes and instances.
|
||||
"""
|
||||
import unittest
|
||||
|
||||
from zope.interface.tests import odd
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface import directlyProvides
|
||||
from zope.interface import providedBy
|
||||
from zope.interface import directlyProvidedBy
|
||||
from zope.interface import classImplements
|
||||
from zope.interface import classImplementsOnly
|
||||
from zope.interface import implementedBy
|
||||
|
||||
class I1(Interface): pass
|
||||
class I2(Interface): pass
|
||||
class I3(Interface): pass
|
||||
class I31(I3): pass
|
||||
class I4(Interface): pass
|
||||
class I5(Interface): pass
|
||||
|
||||
class Odd:
|
||||
pass
|
||||
Odd = odd.MetaClass('Odd', Odd.__bases__, {})
|
||||
|
||||
|
||||
class B(Odd): __implemented__ = I2
|
||||
|
||||
|
||||
# TODO: We are going to need more magic to make classProvides work with odd
|
||||
# classes. This will work in the next iteration. For now, we'll use
|
||||
# a different mechanism.
|
||||
|
||||
# from zope.interface import classProvides
|
||||
class A(Odd):
|
||||
pass
|
||||
classImplements(A, I1)
|
||||
|
||||
class C(A, B):
|
||||
pass
|
||||
classImplements(C, I31)
|
||||
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_ObjectSpecification(self):
|
||||
c = C()
|
||||
directlyProvides(c, I4)
|
||||
self.assertEqual([i.getName() for i in providedBy(c)],
|
||||
['I4', 'I31', 'I1', 'I2']
|
||||
)
|
||||
self.assertEqual([i.getName() for i in providedBy(c).flattened()],
|
||||
['I4', 'I31', 'I3', 'I1', 'I2', 'Interface']
|
||||
)
|
||||
self.assertTrue(I1 in providedBy(c))
|
||||
self.assertFalse(I3 in providedBy(c))
|
||||
self.assertTrue(providedBy(c).extends(I3))
|
||||
self.assertTrue(providedBy(c).extends(I31))
|
||||
self.assertFalse(providedBy(c).extends(I5))
|
||||
|
||||
class COnly(A, B):
|
||||
pass
|
||||
classImplementsOnly(COnly, I31)
|
||||
|
||||
class D(COnly):
|
||||
pass
|
||||
classImplements(D, I5)
|
||||
|
||||
classImplements(D, I5)
|
||||
|
||||
c = D()
|
||||
directlyProvides(c, I4)
|
||||
self.assertEqual([i.getName() for i in providedBy(c)],
|
||||
['I4', 'I5', 'I31'])
|
||||
self.assertEqual([i.getName() for i in providedBy(c).flattened()],
|
||||
['I4', 'I5', 'I31', 'I3', 'Interface'])
|
||||
self.assertFalse(I1 in providedBy(c))
|
||||
self.assertFalse(I3 in providedBy(c))
|
||||
self.assertTrue(providedBy(c).extends(I3))
|
||||
self.assertFalse(providedBy(c).extends(I1))
|
||||
self.assertTrue(providedBy(c).extends(I31))
|
||||
self.assertTrue(providedBy(c).extends(I5))
|
||||
|
||||
class COnly(A, B): __implemented__ = I31
|
||||
class D(COnly):
|
||||
pass
|
||||
classImplements(D, I5)
|
||||
|
||||
classImplements(D, I5)
|
||||
c = D()
|
||||
directlyProvides(c, I4)
|
||||
self.assertEqual([i.getName() for i in providedBy(c)],
|
||||
['I4', 'I5', 'I31'])
|
||||
self.assertEqual([i.getName() for i in providedBy(c).flattened()],
|
||||
['I4', 'I5', 'I31', 'I3', 'Interface'])
|
||||
self.assertFalse(I1 in providedBy(c))
|
||||
self.assertFalse(I3 in providedBy(c))
|
||||
self.assertTrue(providedBy(c).extends(I3))
|
||||
self.assertFalse(providedBy(c).extends(I1))
|
||||
self.assertTrue(providedBy(c).extends(I31))
|
||||
self.assertTrue(providedBy(c).extends(I5))
|
||||
|
||||
def test_classImplements(self):
|
||||
|
||||
@implementer(I3)
|
||||
class A(Odd):
|
||||
pass
|
||||
|
||||
@implementer(I4)
|
||||
class B(Odd):
|
||||
pass
|
||||
|
||||
class C(A, B):
|
||||
pass
|
||||
classImplements(C, I1, I2)
|
||||
self.assertEqual([i.getName() for i in implementedBy(C)],
|
||||
['I1', 'I2', 'I3', 'I4'])
|
||||
classImplements(C, I5)
|
||||
self.assertEqual([i.getName() for i in implementedBy(C)],
|
||||
['I1', 'I2', 'I5', 'I3', 'I4'])
|
||||
|
||||
def test_classImplementsOnly(self):
|
||||
@implementer(I3)
|
||||
class A(Odd):
|
||||
pass
|
||||
|
||||
@implementer(I4)
|
||||
class B(Odd):
|
||||
pass
|
||||
|
||||
class C(A, B):
|
||||
pass
|
||||
classImplementsOnly(C, I1, I2)
|
||||
self.assertEqual([i.__name__ for i in implementedBy(C)],
|
||||
['I1', 'I2'])
|
||||
|
||||
|
||||
def test_directlyProvides(self):
|
||||
class IA1(Interface): pass
|
||||
class IA2(Interface): pass
|
||||
class IB(Interface): pass
|
||||
class IC(Interface): pass
|
||||
class A(Odd):
|
||||
pass
|
||||
classImplements(A, IA1, IA2)
|
||||
|
||||
class B(Odd):
|
||||
pass
|
||||
classImplements(B, IB)
|
||||
|
||||
class C(A, B):
|
||||
pass
|
||||
classImplements(C, IC)
|
||||
|
||||
|
||||
ob = C()
|
||||
directlyProvides(ob, I1, I2)
|
||||
self.assertTrue(I1 in providedBy(ob))
|
||||
self.assertTrue(I2 in providedBy(ob))
|
||||
self.assertTrue(IA1 in providedBy(ob))
|
||||
self.assertTrue(IA2 in providedBy(ob))
|
||||
self.assertTrue(IB in providedBy(ob))
|
||||
self.assertTrue(IC in providedBy(ob))
|
||||
|
||||
directlyProvides(ob, directlyProvidedBy(ob)-I2)
|
||||
self.assertTrue(I1 in providedBy(ob))
|
||||
self.assertFalse(I2 in providedBy(ob))
|
||||
self.assertFalse(I2 in providedBy(ob))
|
||||
directlyProvides(ob, directlyProvidedBy(ob), I2)
|
||||
self.assertTrue(I2 in providedBy(ob))
|
||||
|
||||
# see above
|
||||
#def TODO_test_classProvides_fails_for_odd_class(self):
|
||||
# try:
|
||||
# class A(Odd):
|
||||
# classProvides(I1)
|
||||
# except TypeError:
|
||||
# pass # Success
|
||||
# self.assert_(False,
|
||||
# "Shouldn't be able to use directlyProvides on odd class."
|
||||
# )
|
||||
|
||||
def test_implementedBy(self):
|
||||
class I2(I1): pass
|
||||
|
||||
class C1(Odd):
|
||||
pass
|
||||
classImplements(C1, I2)
|
||||
|
||||
class C2(C1):
|
||||
pass
|
||||
classImplements(C2, I3)
|
||||
|
||||
self.assertEqual([i.getName() for i in implementedBy(C2)],
|
||||
['I3', 'I2'])
|
||||
|
||||
def test_odd_metaclass_that_doesnt_subclass_type(self):
|
||||
# This was originally a doctest in odd.py.
|
||||
# It verifies that the metaclass the rest of these tests use
|
||||
# works as expected.
|
||||
|
||||
# This is used for testing support for ExtensionClass in new interfaces.
|
||||
|
||||
class A:
|
||||
a = 1
|
||||
|
||||
A = odd.MetaClass('A', A.__bases__, A.__dict__)
|
||||
|
||||
class B:
|
||||
b = 1
|
||||
|
||||
B = odd.MetaClass('B', B.__bases__, B.__dict__)
|
||||
|
||||
class C(A, B):
|
||||
pass
|
||||
|
||||
self.assertEqual(C.__bases__, (A, B))
|
||||
|
||||
a = A()
|
||||
aa = A()
|
||||
self.assertEqual(a.a, 1)
|
||||
self.assertEqual(aa.a, 1)
|
||||
|
||||
aa.a = 2
|
||||
self.assertEqual(a.a, 1)
|
||||
self.assertEqual(aa.a, 2)
|
||||
|
||||
c = C()
|
||||
self.assertEqual(c.a, 1)
|
||||
self.assertEqual(c.b, 1)
|
||||
|
||||
c.b = 2
|
||||
self.assertEqual(c.b, 2)
|
||||
|
||||
C.c = 1
|
||||
self.assertEqual(c.c, 1)
|
||||
c.c
|
||||
|
||||
self.assertIs(C.__class__.__class__, C.__class__)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,426 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2014 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.
|
||||
#
|
||||
##############################################################################
|
||||
"""Resolution ordering utility tests"""
|
||||
import unittest
|
||||
|
||||
# pylint:disable=blacklisted-name,protected-access,attribute-defined-outside-init
|
||||
|
||||
class Test__mergeOrderings(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, orderings):
|
||||
from zope.interface.ro import _legacy_mergeOrderings
|
||||
return _legacy_mergeOrderings(orderings)
|
||||
|
||||
def test_empty(self):
|
||||
self.assertEqual(self._callFUT([]), [])
|
||||
|
||||
def test_single(self):
|
||||
self.assertEqual(self._callFUT(['a', 'b', 'c']), ['a', 'b', 'c'])
|
||||
|
||||
def test_w_duplicates(self):
|
||||
self.assertEqual(self._callFUT([['a'], ['b', 'a']]), ['b', 'a'])
|
||||
|
||||
def test_suffix_across_multiple_duplicates(self):
|
||||
O1 = ['x', 'y', 'z']
|
||||
O2 = ['q', 'z']
|
||||
O3 = [1, 3, 5]
|
||||
O4 = ['z']
|
||||
self.assertEqual(self._callFUT([O1, O2, O3, O4]),
|
||||
['x', 'y', 'q', 1, 3, 5, 'z'])
|
||||
|
||||
|
||||
class Test__flatten(unittest.TestCase):
|
||||
|
||||
def _callFUT(self, ob):
|
||||
from zope.interface.ro import _legacy_flatten
|
||||
return _legacy_flatten(ob)
|
||||
|
||||
def test_w_empty_bases(self):
|
||||
class Foo:
|
||||
pass
|
||||
foo = Foo()
|
||||
foo.__bases__ = ()
|
||||
self.assertEqual(self._callFUT(foo), [foo])
|
||||
|
||||
def test_w_single_base(self):
|
||||
class Foo:
|
||||
pass
|
||||
self.assertEqual(self._callFUT(Foo), [Foo, object])
|
||||
|
||||
def test_w_bases(self):
|
||||
class Foo:
|
||||
pass
|
||||
class Bar(Foo):
|
||||
pass
|
||||
self.assertEqual(self._callFUT(Bar), [Bar, Foo, object])
|
||||
|
||||
def test_w_diamond(self):
|
||||
class Foo:
|
||||
pass
|
||||
class Bar(Foo):
|
||||
pass
|
||||
class Baz(Foo):
|
||||
pass
|
||||
class Qux(Bar, Baz):
|
||||
pass
|
||||
self.assertEqual(self._callFUT(Qux),
|
||||
[Qux, Bar, Foo, object, Baz, Foo, object])
|
||||
|
||||
|
||||
class Test_ro(unittest.TestCase):
|
||||
maxDiff = None
|
||||
def _callFUT(self, ob, **kwargs):
|
||||
from zope.interface.ro import _legacy_ro
|
||||
return _legacy_ro(ob, **kwargs)
|
||||
|
||||
def test_w_empty_bases(self):
|
||||
class Foo:
|
||||
pass
|
||||
foo = Foo()
|
||||
foo.__bases__ = ()
|
||||
self.assertEqual(self._callFUT(foo), [foo])
|
||||
|
||||
def test_w_single_base(self):
|
||||
class Foo:
|
||||
pass
|
||||
self.assertEqual(self._callFUT(Foo), [Foo, object])
|
||||
|
||||
def test_w_bases(self):
|
||||
class Foo:
|
||||
pass
|
||||
class Bar(Foo):
|
||||
pass
|
||||
self.assertEqual(self._callFUT(Bar), [Bar, Foo, object])
|
||||
|
||||
def test_w_diamond(self):
|
||||
class Foo:
|
||||
pass
|
||||
class Bar(Foo):
|
||||
pass
|
||||
class Baz(Foo):
|
||||
pass
|
||||
class Qux(Bar, Baz):
|
||||
pass
|
||||
self.assertEqual(self._callFUT(Qux),
|
||||
[Qux, Bar, Baz, Foo, object])
|
||||
|
||||
def _make_IOErr(self):
|
||||
# This can't be done in the standard C3 ordering.
|
||||
class Foo:
|
||||
def __init__(self, name, *bases):
|
||||
self.__name__ = name
|
||||
self.__bases__ = bases
|
||||
def __repr__(self): # pragma: no cover
|
||||
return self.__name__
|
||||
|
||||
# Mimic what classImplements(IOError, IIOError)
|
||||
# does.
|
||||
IEx = Foo('IEx')
|
||||
IStdErr = Foo('IStdErr', IEx)
|
||||
IEnvErr = Foo('IEnvErr', IStdErr)
|
||||
IIOErr = Foo('IIOErr', IEnvErr)
|
||||
IOSErr = Foo('IOSErr', IEnvErr)
|
||||
|
||||
IOErr = Foo('IOErr', IEnvErr, IIOErr, IOSErr)
|
||||
return IOErr, [IOErr, IIOErr, IOSErr, IEnvErr, IStdErr, IEx]
|
||||
|
||||
def test_non_orderable(self):
|
||||
IOErr, bases = self._make_IOErr()
|
||||
|
||||
self.assertEqual(self._callFUT(IOErr), bases)
|
||||
|
||||
def test_mixed_inheritance_and_implementation(self):
|
||||
# https://github.com/zopefoundation/zope.interface/issues/8
|
||||
# This test should fail, but doesn't, as described in that issue.
|
||||
# pylint:disable=inherit-non-class
|
||||
from zope.interface import implementer
|
||||
from zope.interface import Interface
|
||||
from zope.interface import providedBy
|
||||
from zope.interface import implementedBy
|
||||
|
||||
class IFoo(Interface):
|
||||
pass
|
||||
|
||||
@implementer(IFoo)
|
||||
class ImplementsFoo:
|
||||
pass
|
||||
|
||||
class ExtendsFoo(ImplementsFoo):
|
||||
pass
|
||||
|
||||
class ImplementsNothing:
|
||||
pass
|
||||
|
||||
class ExtendsFooImplementsNothing(ExtendsFoo, ImplementsNothing):
|
||||
pass
|
||||
|
||||
self.assertEqual(
|
||||
self._callFUT(providedBy(ExtendsFooImplementsNothing())),
|
||||
[implementedBy(ExtendsFooImplementsNothing),
|
||||
implementedBy(ExtendsFoo),
|
||||
implementedBy(ImplementsFoo),
|
||||
IFoo,
|
||||
Interface,
|
||||
implementedBy(ImplementsNothing),
|
||||
implementedBy(object)])
|
||||
|
||||
|
||||
class C3Setting:
|
||||
|
||||
def __init__(self, setting, value):
|
||||
self._setting = setting
|
||||
self._value = value
|
||||
|
||||
def __enter__(self):
|
||||
from zope.interface import ro
|
||||
setattr(ro.C3, self._setting.__name__, self._value)
|
||||
|
||||
def __exit__(self, t, v, tb):
|
||||
from zope.interface import ro
|
||||
setattr(ro.C3, self._setting.__name__, self._setting)
|
||||
|
||||
class Test_c3_ro(Test_ro):
|
||||
|
||||
def setUp(self):
|
||||
Test_ro.setUp(self)
|
||||
from zope.testing.loggingsupport import InstalledHandler
|
||||
self.log_handler = handler = InstalledHandler('zope.interface.ro')
|
||||
self.addCleanup(handler.uninstall)
|
||||
|
||||
def _callFUT(self, ob, **kwargs):
|
||||
from zope.interface.ro import ro
|
||||
return ro(ob, **kwargs)
|
||||
|
||||
def _make_complex_diamond(self, base):
|
||||
# https://github.com/zopefoundation/zope.interface/issues/21
|
||||
O = base
|
||||
class F(O):
|
||||
pass
|
||||
class E(O):
|
||||
pass
|
||||
class D(O):
|
||||
pass
|
||||
class C(D, F):
|
||||
pass
|
||||
class B(D, E):
|
||||
pass
|
||||
class A(B, C):
|
||||
pass
|
||||
|
||||
if hasattr(A, 'mro'):
|
||||
self.assertEqual(A.mro(), self._callFUT(A))
|
||||
|
||||
return A
|
||||
|
||||
def test_complex_diamond_object(self):
|
||||
self._make_complex_diamond(object)
|
||||
|
||||
def test_complex_diamond_interface(self):
|
||||
from zope.interface import Interface
|
||||
|
||||
IA = self._make_complex_diamond(Interface)
|
||||
|
||||
self.assertEqual(
|
||||
[x.__name__ for x in IA.__iro__],
|
||||
['A', 'B', 'C', 'D', 'E', 'F', 'Interface']
|
||||
)
|
||||
|
||||
def test_complex_diamond_use_legacy_argument(self):
|
||||
from zope.interface import Interface
|
||||
|
||||
A = self._make_complex_diamond(Interface)
|
||||
legacy_A_iro = self._callFUT(A, use_legacy_ro=True)
|
||||
self.assertNotEqual(A.__iro__, legacy_A_iro)
|
||||
|
||||
# And logging happened as a side-effect.
|
||||
self._check_handler_complex_diamond()
|
||||
|
||||
def test_complex_diamond_compare_legacy_argument(self):
|
||||
from zope.interface import Interface
|
||||
|
||||
A = self._make_complex_diamond(Interface)
|
||||
computed_A_iro = self._callFUT(A, log_changed_ro=True)
|
||||
# It matches, of course, but we did log a warning.
|
||||
self.assertEqual(tuple(computed_A_iro), A.__iro__)
|
||||
self._check_handler_complex_diamond()
|
||||
|
||||
def _check_handler_complex_diamond(self):
|
||||
handler = self.log_handler
|
||||
self.assertEqual(1, len(handler.records))
|
||||
record = handler.records[0]
|
||||
|
||||
self.assertEqual('\n'.join(l.rstrip() for l in record.getMessage().splitlines()), """\
|
||||
Object <InterfaceClass zope.interface.tests.test_ro.A> has different legacy and C3 MROs:
|
||||
Legacy RO (len=7) C3 RO (len=7; inconsistent=no)
|
||||
==================================================================
|
||||
zope.interface.tests.test_ro.A zope.interface.tests.test_ro.A
|
||||
zope.interface.tests.test_ro.B zope.interface.tests.test_ro.B
|
||||
- zope.interface.tests.test_ro.E
|
||||
zope.interface.tests.test_ro.C zope.interface.tests.test_ro.C
|
||||
zope.interface.tests.test_ro.D zope.interface.tests.test_ro.D
|
||||
+ zope.interface.tests.test_ro.E
|
||||
zope.interface.tests.test_ro.F zope.interface.tests.test_ro.F
|
||||
zope.interface.Interface zope.interface.Interface""")
|
||||
|
||||
def test_ExtendedPathIndex_implement_thing_implementedby_super(self):
|
||||
# See https://github.com/zopefoundation/zope.interface/pull/182#issuecomment-598754056
|
||||
from zope.interface import ro
|
||||
# pylint:disable=inherit-non-class
|
||||
class _Based:
|
||||
__bases__ = ()
|
||||
|
||||
def __init__(self, name, bases=(), attrs=None):
|
||||
self.__name__ = name
|
||||
self.__bases__ = bases
|
||||
|
||||
def __repr__(self):
|
||||
return self.__name__
|
||||
|
||||
Interface = _Based('Interface', (), {})
|
||||
|
||||
class IPluggableIndex(Interface):
|
||||
pass
|
||||
|
||||
class ILimitedResultIndex(IPluggableIndex):
|
||||
pass
|
||||
|
||||
class IQueryIndex(IPluggableIndex):
|
||||
pass
|
||||
|
||||
class IPathIndex(Interface):
|
||||
pass
|
||||
|
||||
# A parent class who implements two distinct interfaces whose
|
||||
# only common ancestor is Interface. An easy case.
|
||||
# @implementer(IPathIndex, IQueryIndex)
|
||||
# class PathIndex(object):
|
||||
# pass
|
||||
obj = _Based('object')
|
||||
PathIndex = _Based('PathIndex', (IPathIndex, IQueryIndex, obj))
|
||||
|
||||
# Child class that tries to put an interface the parent declares
|
||||
# later ahead of the parent.
|
||||
# @implementer(ILimitedResultIndex, IQueryIndex)
|
||||
# class ExtendedPathIndex(PathIndex):
|
||||
# pass
|
||||
ExtendedPathIndex = _Based('ExtendedPathIndex',
|
||||
(ILimitedResultIndex, IQueryIndex, PathIndex))
|
||||
|
||||
# We were able to resolve it, and in exactly the same way as
|
||||
# the legacy RO did, even though it is inconsistent.
|
||||
result = self._callFUT(ExtendedPathIndex, log_changed_ro=True, strict=False)
|
||||
self.assertEqual(result, [
|
||||
ExtendedPathIndex,
|
||||
ILimitedResultIndex,
|
||||
PathIndex,
|
||||
IPathIndex,
|
||||
IQueryIndex,
|
||||
IPluggableIndex,
|
||||
Interface,
|
||||
obj])
|
||||
|
||||
record, = self.log_handler.records
|
||||
self.assertIn('used the legacy', record.getMessage())
|
||||
|
||||
with self.assertRaises(ro.InconsistentResolutionOrderError):
|
||||
self._callFUT(ExtendedPathIndex, strict=True)
|
||||
|
||||
def test_OSError_IOError(self):
|
||||
from zope.interface.common import interfaces
|
||||
from zope.interface import providedBy
|
||||
|
||||
self.assertEqual(
|
||||
list(providedBy(OSError()).flattened()),
|
||||
[
|
||||
interfaces.IOSError,
|
||||
interfaces.IIOError,
|
||||
interfaces.IEnvironmentError,
|
||||
interfaces.IStandardError,
|
||||
interfaces.IException,
|
||||
interfaces.Interface,
|
||||
])
|
||||
|
||||
def test_non_orderable(self):
|
||||
import warnings
|
||||
from zope.interface import ro
|
||||
try:
|
||||
# If we've already warned, we must reset that state.
|
||||
del ro.__warningregistry__
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('error')
|
||||
with C3Setting(ro.C3.WARN_BAD_IRO, True), C3Setting(ro.C3.STRICT_IRO, False):
|
||||
with self.assertRaises(ro.InconsistentResolutionOrderWarning):
|
||||
super().test_non_orderable()
|
||||
|
||||
IOErr, _ = self._make_IOErr()
|
||||
with self.assertRaises(ro.InconsistentResolutionOrderError):
|
||||
self._callFUT(IOErr, strict=True)
|
||||
|
||||
with C3Setting(ro.C3.TRACK_BAD_IRO, True), C3Setting(ro.C3.STRICT_IRO, False):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore')
|
||||
self._callFUT(IOErr)
|
||||
self.assertIn(IOErr, ro.C3.BAD_IROS)
|
||||
|
||||
iro = self._callFUT(IOErr, strict=False)
|
||||
legacy_iro = self._callFUT(IOErr, use_legacy_ro=True, strict=False)
|
||||
self.assertEqual(iro, legacy_iro)
|
||||
|
||||
|
||||
class TestC3(unittest.TestCase):
|
||||
def _makeOne(self, C, strict=False, base_mros=None):
|
||||
from zope.interface.ro import C3
|
||||
return C3.resolver(C, strict, base_mros)
|
||||
|
||||
def test_base_mros_given(self):
|
||||
c3 = self._makeOne(type(self), base_mros={unittest.TestCase: unittest.TestCase.__mro__})
|
||||
memo = c3.memo
|
||||
self.assertIn(unittest.TestCase, memo)
|
||||
# We used the StaticMRO class
|
||||
self.assertIsNone(memo[unittest.TestCase].had_inconsistency)
|
||||
|
||||
def test_one_base_optimization(self):
|
||||
c3 = self._makeOne(type(self))
|
||||
# Even though we didn't call .mro() yet, the MRO has been
|
||||
# computed.
|
||||
self.assertIsNotNone(c3._C3__mro) # pylint:disable=no-member
|
||||
c3._merge = None
|
||||
self.assertEqual(c3.mro(), list(type(self).__mro__))
|
||||
|
||||
|
||||
class Test_ROComparison(unittest.TestCase):
|
||||
|
||||
class MockC3:
|
||||
direct_inconsistency = False
|
||||
bases_had_inconsistency = False
|
||||
|
||||
def _makeOne(self, c3=None, c3_ro=(), legacy_ro=()):
|
||||
from zope.interface.ro import _ROComparison
|
||||
return _ROComparison(c3 or self.MockC3(), c3_ro, legacy_ro)
|
||||
|
||||
def test_inconsistent_label(self):
|
||||
comp = self._makeOne()
|
||||
self.assertEqual('no', comp._inconsistent_label)
|
||||
|
||||
comp.c3.direct_inconsistency = True
|
||||
self.assertEqual("direct", comp._inconsistent_label)
|
||||
|
||||
comp.c3.bases_had_inconsistency = True
|
||||
self.assertEqual("direct+bases", comp._inconsistent_label)
|
||||
|
||||
comp.c3.direct_inconsistency = False
|
||||
self.assertEqual('bases', comp._inconsistent_label)
|
||||
@@ -0,0 +1,64 @@
|
||||
##############################################################################
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
##############################################################################
|
||||
"""Test interface sorting
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from zope.interface import Interface
|
||||
|
||||
class I1(Interface): pass
|
||||
class I2(I1): pass
|
||||
class I3(I1): pass
|
||||
class I4(Interface): pass
|
||||
class I5(I4): pass
|
||||
class I6(I2): pass
|
||||
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test(self):
|
||||
l = [I1, I3, I5, I6, I4, I2]
|
||||
l.sort()
|
||||
self.assertEqual(l, [I1, I2, I3, I4, I5, I6])
|
||||
|
||||
def test_w_None(self):
|
||||
l = [I1, None, I3, I5, I6, I4, I2]
|
||||
l.sort()
|
||||
self.assertEqual(l, [I1, I2, I3, I4, I5, I6, None])
|
||||
|
||||
def test_w_equal_names(self):
|
||||
# interfaces with equal names but different modules should sort by
|
||||
# module name
|
||||
from zope.interface.tests.m1 import I1 as m1_I1
|
||||
l = [I1, m1_I1]
|
||||
l.sort()
|
||||
self.assertEqual(l, [m1_I1, I1])
|
||||
|
||||
def test_I1_I2(self):
|
||||
self.assertLess(I1.__name__, I2.__name__)
|
||||
self.assertEqual(I1.__module__, I2.__module__)
|
||||
self.assertEqual(I1.__module__, __name__)
|
||||
self.assertLess(I1, I2)
|
||||
|
||||
def _makeI1(self):
|
||||
class I1(Interface):
|
||||
pass
|
||||
return I1
|
||||
|
||||
def test_nested(self):
|
||||
nested_I1 = self._makeI1()
|
||||
self.assertEqual(I1, nested_I1)
|
||||
self.assertEqual(nested_I1, I1)
|
||||
self.assertEqual(hash(I1), hash(nested_I1))
|
||||
@@ -0,0 +1,656 @@
|
||||
##############################################################################
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
##############################################################################
|
||||
""" zope.interface.verify unit tests
|
||||
"""
|
||||
import unittest
|
||||
|
||||
# pylint:disable=inherit-non-class,no-method-argument,no-self-argument
|
||||
|
||||
class Test_verifyClass(unittest.TestCase):
|
||||
|
||||
verifier = None
|
||||
|
||||
def setUp(self):
|
||||
self.verifier = self._get_FUT()
|
||||
|
||||
@classmethod
|
||||
def _get_FUT(cls):
|
||||
from zope.interface.verify import verifyClass
|
||||
return verifyClass
|
||||
|
||||
_adjust_object_before_verify = lambda self, x: x
|
||||
|
||||
def _callFUT(self, iface, klass, **kwargs):
|
||||
return self.verifier(iface,
|
||||
self._adjust_object_before_verify(klass),
|
||||
**kwargs)
|
||||
|
||||
def test_class_doesnt_implement(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface.exceptions import DoesNotImplement
|
||||
|
||||
class ICurrent(Interface):
|
||||
pass
|
||||
|
||||
class Current:
|
||||
pass
|
||||
|
||||
self.assertRaises(DoesNotImplement, self._callFUT, ICurrent, Current)
|
||||
|
||||
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:
|
||||
pass
|
||||
|
||||
classImplements(Current, ICurrent)
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_class_doesnt_have_required_method_simple(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
def method():
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
pass
|
||||
|
||||
self.assertRaises(BrokenImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_class_has_required_method_simple(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
def method():
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_class_doesnt_have_required_method_derived(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenImplementation
|
||||
|
||||
class IBase(Interface):
|
||||
def method():
|
||||
"""docstring"""
|
||||
|
||||
class IDerived(IBase):
|
||||
pass
|
||||
|
||||
@implementer(IDerived)
|
||||
class Current:
|
||||
pass
|
||||
|
||||
self.assertRaises(BrokenImplementation,
|
||||
self._callFUT, IDerived, Current)
|
||||
|
||||
def test_class_has_required_method_derived(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class IBase(Interface):
|
||||
def method():
|
||||
"""docstring"""
|
||||
|
||||
class IDerived(IBase):
|
||||
pass
|
||||
|
||||
@implementer(IDerived)
|
||||
class Current:
|
||||
|
||||
def method(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(IDerived, Current)
|
||||
|
||||
def test_method_takes_wrong_arg_names_but_OK(self):
|
||||
# We no longer require names to match.
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, b):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_not_enough_args(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_method_doesnt_take_required_starargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(*args):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_method_doesnt_take_required_only_kwargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(**kw):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_method_takes_extra_arg(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, a, b):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_method_takes_extra_arg_with_default(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, a, b=None):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_only_positional_args(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, *args):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_only_kwargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, **kw):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
def test_method_takes_extra_starargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, a, *args):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_extra_starargs_and_kwargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, a, *args, **kw):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_doesnt_take_required_positional_and_starargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a, *args):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, a):
|
||||
raise NotImplementedError()
|
||||
|
||||
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 implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a, *args):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, a, *args):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_only_starargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a, *args):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, *args):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_required_kwargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(**kwargs):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, **kw):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_method_takes_positional_plus_required_starargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(*args):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, a, *args):
|
||||
raise NotImplementedError()
|
||||
|
||||
self.assertRaises(BrokenMethodImplementation,
|
||||
self._callFUT, ICurrent, Current)
|
||||
|
||||
|
||||
def test_method_doesnt_take_required_kwargs(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(**kwargs):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def method(self, a):
|
||||
raise NotImplementedError()
|
||||
|
||||
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 implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
attr = Attribute("The foo Attribute")
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
def attr(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_class_has_nonmethod_for_method(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
from zope.interface.exceptions import BrokenMethodImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
def method():
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
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 implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
attr = Attribute("The foo Attribute")
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
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 implementer
|
||||
|
||||
class ICurrent(Interface):
|
||||
attr = Attribute("The foo Attribute")
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
pass
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_w_callable_non_func_method(self):
|
||||
from zope.interface.interface import Method
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
class QuasiMethod(Method):
|
||||
def __call__(self, *args, **kw):
|
||||
raise NotImplementedError()
|
||||
|
||||
class QuasiCallable:
|
||||
def __call__(self, *args, **kw):
|
||||
raise NotImplementedError()
|
||||
|
||||
class ICurrent(Interface):
|
||||
attr = QuasiMethod('This is callable')
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
attr = QuasiCallable()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
|
||||
def test_w_decorated_method(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import implementer
|
||||
|
||||
def decorator(func):
|
||||
# this is, in fact, zope.proxy.non_overridable
|
||||
return property(lambda self: func.__get__(self))
|
||||
|
||||
class ICurrent(Interface):
|
||||
|
||||
def method(a):
|
||||
"""docstring"""
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
|
||||
@decorator
|
||||
def method(self, a):
|
||||
raise NotImplementedError()
|
||||
|
||||
self._callFUT(ICurrent, Current)
|
||||
|
||||
def test_dict_IFullMapping(self):
|
||||
# A dict should be an IFullMapping, but this exposes two
|
||||
# issues. First, on CPython, methods of builtin types are
|
||||
# "method_descriptor" objects, and are harder to introspect.
|
||||
# Second, on PyPy, the signatures can be just plain wrong,
|
||||
# specifying as required arguments that are actually optional.
|
||||
# See https://github.com/zopefoundation/zope.interface/issues/118
|
||||
from zope.interface.common.mapping import IFullMapping
|
||||
self._callFUT(IFullMapping, dict, tentative=True)
|
||||
|
||||
def test_list_ISequence(self):
|
||||
# As for test_dict_IFullMapping
|
||||
from zope.interface.common.sequence import ISequence
|
||||
self._callFUT(ISequence, list, tentative=True)
|
||||
|
||||
def test_tuple_IReadSequence(self):
|
||||
# As for test_dict_IFullMapping
|
||||
from zope.interface.common.sequence import IReadSequence
|
||||
self._callFUT(IReadSequence, tuple, tentative=True)
|
||||
|
||||
|
||||
def test_multiple_invalid(self):
|
||||
from zope.interface.exceptions import MultipleInvalid
|
||||
from zope.interface.exceptions import DoesNotImplement
|
||||
from zope.interface.exceptions import BrokenImplementation
|
||||
from zope.interface import Interface
|
||||
from zope.interface import classImplements
|
||||
|
||||
class ISeveralMethods(Interface):
|
||||
def meth1(arg1):
|
||||
"Method 1"
|
||||
def meth2(arg1):
|
||||
"Method 2"
|
||||
|
||||
class SeveralMethods:
|
||||
pass
|
||||
|
||||
with self.assertRaises(MultipleInvalid) as exc:
|
||||
self._callFUT(ISeveralMethods, SeveralMethods)
|
||||
|
||||
ex = exc.exception
|
||||
self.assertEqual(3, len(ex.exceptions))
|
||||
self.assertIsInstance(ex.exceptions[0], DoesNotImplement)
|
||||
self.assertIsInstance(ex.exceptions[1], BrokenImplementation)
|
||||
self.assertIsInstance(ex.exceptions[2], BrokenImplementation)
|
||||
|
||||
# If everything else is correct, only the single error is raised without
|
||||
# the wrapper.
|
||||
classImplements(SeveralMethods, ISeveralMethods)
|
||||
SeveralMethods.meth1 = lambda self, arg1: "Hi"
|
||||
|
||||
with self.assertRaises(BrokenImplementation):
|
||||
self._callFUT(ISeveralMethods, SeveralMethods)
|
||||
|
||||
class Test_verifyObject(Test_verifyClass):
|
||||
|
||||
@classmethod
|
||||
def _get_FUT(cls):
|
||||
from zope.interface.verify import verifyObject
|
||||
return verifyObject
|
||||
|
||||
def _adjust_object_before_verify(self, target):
|
||||
if isinstance(target, (type, type(OldSkool))):
|
||||
target = target()
|
||||
return 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 implementer
|
||||
from zope.interface.exceptions import BrokenImplementation
|
||||
|
||||
class ICurrent(Interface):
|
||||
attr = Attribute("The foo Attribute")
|
||||
|
||||
@implementer(ICurrent)
|
||||
class Current:
|
||||
pass
|
||||
|
||||
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)
|
||||
|
||||
def test_staticmethod_hit_on_class(self):
|
||||
from zope.interface import Interface
|
||||
from zope.interface import provider
|
||||
from zope.interface.verify import verifyObject
|
||||
|
||||
class IFoo(Interface):
|
||||
|
||||
def bar(a, b):
|
||||
"The bar method"
|
||||
|
||||
@provider(IFoo)
|
||||
class Foo:
|
||||
|
||||
@staticmethod
|
||||
def bar(a, b):
|
||||
raise AssertionError("We're never actually called")
|
||||
|
||||
# Don't use self._callFUT, we don't want to instantiate the
|
||||
# class.
|
||||
verifyObject(IFoo, Foo)
|
||||
|
||||
class OldSkool:
|
||||
pass
|
||||
Reference in New Issue
Block a user