Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

edgify / zope.interface   python

Repository URL to install this package:

Version: 5.1.0 

/ interface / tests / test_declarations.py

##############################################################################
#
# 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 the new API for making and checking interface declarations
"""
import unittest

from zope.interface._compat import _skip_under_py3k
from zope.interface._compat import PYTHON3
from zope.interface.tests import OptimizationTestMixin
from zope.interface.tests import MissingSomeAttrs
from zope.interface.tests.test_interface import NameAndModuleComparisonTestsMixin

# pylint:disable=inherit-non-class,too-many-lines,protected-access
# pylint:disable=blacklisted-name,attribute-defined-outside-init

class _Py3ClassAdvice(object):

    def _run_generated_code(self, code, globs, locs,
                            fails_under_py3k=True,
                           ):
        # pylint:disable=exec-used,no-member
        import warnings
        with warnings.catch_warnings(record=True) as log:
            warnings.resetwarnings()
            if not PYTHON3:
                exec(code, globs, locs)
                self.assertEqual(len(log), 0) # no longer warn
                return True

            try:
                exec(code, globs, locs)
            except TypeError:
                return False
            else:
                if fails_under_py3k:
                    self.fail("Didn't raise TypeError")
            return None


class NamedTests(unittest.TestCase):

    def test_class(self):
        from zope.interface.declarations import named

        @named(u'foo')
        class Foo(object):
            pass

        self.assertEqual(Foo.__component_name__, u'foo') # pylint:disable=no-member

    def test_function(self):
        from zope.interface.declarations import named

        @named(u'foo')
        def doFoo(o):
            raise NotImplementedError()

        self.assertEqual(doFoo.__component_name__, u'foo')

    def test_instance(self):
        from zope.interface.declarations import named

        class Foo(object):
            pass
        foo = Foo()
        named(u'foo')(foo)

        self.assertEqual(foo.__component_name__, u'foo') # pylint:disable=no-member


class EmptyDeclarationTests(unittest.TestCase):
    # Tests that should pass for all objects that are empty
    # declarations. This includes a Declaration explicitly created
    # that way, and the empty ImmutableDeclaration.
    def _getEmpty(self):
        from zope.interface.declarations import Declaration
        return Declaration()

    def test___iter___empty(self):
        decl = self._getEmpty()
        self.assertEqual(list(decl), [])

    def test_flattened_empty(self):
        from zope.interface.interface import Interface
        decl = self._getEmpty()
        self.assertEqual(list(decl.flattened()), [Interface])

    def test___contains___empty(self):
        from zope.interface.interface import Interface
        decl = self._getEmpty()
        self.assertNotIn(Interface, decl)

    def test_extends_empty(self):
        from zope.interface.interface import Interface
        decl = self._getEmpty()
        self.assertTrue(decl.extends(Interface))
        self.assertTrue(decl.extends(Interface, strict=True))

    def test_interfaces_empty(self):
        decl = self._getEmpty()
        l = list(decl.interfaces())
        self.assertEqual(l, [])

    def test___sro___(self):
        from zope.interface.interface import Interface
        decl = self._getEmpty()
        self.assertEqual(decl.__sro__, (decl, Interface,))

    def test___iro___(self):
        from zope.interface.interface import Interface
        decl = self._getEmpty()
        self.assertEqual(decl.__iro__, (Interface,))

    def test_get(self):
        decl = self._getEmpty()
        self.assertIsNone(decl.get('attr'))
        self.assertEqual(decl.get('abc', 'def'), 'def')
        # It's a positive cache only (when it even exists)
        # so this added nothing.
        self.assertFalse(decl._v_attrs)

    def test_changed_w_existing__v_attrs(self):
        decl = self._getEmpty()
        decl._v_attrs = object()
        decl.changed(decl)
        self.assertFalse(decl._v_attrs)


class DeclarationTests(EmptyDeclarationTests):

    def _getTargetClass(self):
        from zope.interface.declarations import Declaration
        return Declaration

    def _makeOne(self, *args, **kw):
        return self._getTargetClass()(*args, **kw)

    def test_ctor_no_bases(self):
        decl = self._makeOne()
        self.assertEqual(list(decl.__bases__), [])

    def test_ctor_w_interface_in_bases(self):
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        decl = self._makeOne(IFoo)
        self.assertEqual(list(decl.__bases__), [IFoo])

    def test_ctor_w_implements_in_bases(self):
        from zope.interface.declarations import Implements
        impl = Implements()
        decl = self._makeOne(impl)
        self.assertEqual(list(decl.__bases__), [impl])

    def test_changed_wo_existing__v_attrs(self):
        decl = self._makeOne()
        decl.changed(decl) # doesn't raise
        self.assertIsNone(decl._v_attrs)

    def test___contains__w_self(self):
        decl = self._makeOne()
        self.assertNotIn(decl, decl)

    def test___contains__w_unrelated_iface(self):
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        decl = self._makeOne()
        self.assertNotIn(IFoo, decl)

    def test___contains__w_base_interface(self):
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        decl = self._makeOne(IFoo)
        self.assertIn(IFoo, decl)

    def test___iter___single_base(self):
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        decl = self._makeOne(IFoo)
        self.assertEqual(list(decl), [IFoo])

    def test___iter___multiple_bases(self):
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        IBar = InterfaceClass('IBar')
        decl = self._makeOne(IFoo, IBar)
        self.assertEqual(list(decl), [IFoo, IBar])

    def test___iter___inheritance(self):
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        IBar = InterfaceClass('IBar', (IFoo,))
        decl = self._makeOne(IBar)
        self.assertEqual(list(decl), [IBar]) #IBar.interfaces() omits bases

    def test___iter___w_nested_sequence_overlap(self):
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        IBar = InterfaceClass('IBar')
        decl = self._makeOne(IBar, (IFoo, IBar))
        self.assertEqual(list(decl), [IBar, IFoo])

    def test_flattened_single_base(self):
        from zope.interface.interface import Interface
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        decl = self._makeOne(IFoo)
        self.assertEqual(list(decl.flattened()), [IFoo, Interface])

    def test_flattened_multiple_bases(self):
        from zope.interface.interface import Interface
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        IBar = InterfaceClass('IBar')
        decl = self._makeOne(IFoo, IBar)
        self.assertEqual(list(decl.flattened()), [IFoo, IBar, Interface])

    def test_flattened_inheritance(self):
        from zope.interface.interface import Interface
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        IBar = InterfaceClass('IBar', (IFoo,))
        decl = self._makeOne(IBar)
        self.assertEqual(list(decl.flattened()), [IBar, IFoo, Interface])

    def test_flattened_w_nested_sequence_overlap(self):
        from zope.interface.interface import Interface
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        IBar = InterfaceClass('IBar')
        # This is the same as calling ``Declaration(IBar, IFoo, IBar)``
        # which doesn't make much sense, but here it is. In older
        # versions of zope.interface, the __iro__ would have been
        # IFoo, IBar, Interface, which especially makes no sense.
        decl = self._makeOne(IBar, (IFoo, IBar))
        # Note that decl.__iro__ has IFoo first.
        self.assertEqual(list(decl.flattened()), [IBar, IFoo, Interface])

    def test___sub___unrelated_interface(self):
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        IBar = InterfaceClass('IBar')
        before = self._makeOne(IFoo)
        after = before - IBar
        self.assertIsInstance(after, self._getTargetClass())
        self.assertEqual(list(after), [IFoo])

    def test___sub___related_interface(self):
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        before = self._makeOne(IFoo)
        after = before - IFoo
        self.assertEqual(list(after), [])

    def test___sub___related_interface_by_inheritance(self):
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        IBar = InterfaceClass('IBar', (IFoo,))
        before = self._makeOne(IBar)
        after = before - IBar
        self.assertEqual(list(after), [])

    def test___add___unrelated_interface(self):
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        IBar = InterfaceClass('IBar')
        before = self._makeOne(IFoo)
        after = before + IBar
        self.assertIsInstance(after, self._getTargetClass())
        self.assertEqual(list(after), [IFoo, IBar])

    def test___add___related_interface(self):
        from zope.interface.interface import InterfaceClass
        IFoo = InterfaceClass('IFoo')
        IBar = InterfaceClass('IBar')
        IBaz = InterfaceClass('IBaz')
        before = self._makeOne(IFoo, IBar)
        other = self._makeOne(IBar, IBaz)
        after = before + other
        self.assertEqual(list(after), [IFoo, IBar, IBaz])


class TestImmutableDeclaration(EmptyDeclarationTests):

    def _getTargetClass(self):
        from zope.interface.declarations import _ImmutableDeclaration
        return _ImmutableDeclaration

    def _getEmpty(self):
        from zope.interface.declarations import _empty
        return _empty

    def test_pickle(self):
        import pickle
        copied = pickle.loads(pickle.dumps(self._getEmpty()))
        self.assertIs(copied, self._getEmpty())

    def test_singleton(self):
        self.assertIs(
            self._getTargetClass()(),
            self._getEmpty()
        )

    def test__bases__(self):
        self.assertEqual(self._getEmpty().__bases__, ())

    def test_change__bases__(self):
        empty = self._getEmpty()
        empty.__bases__ = ()
        self.assertEqual(self._getEmpty().__bases__, ())

        with self.assertRaises(TypeError):
            empty.__bases__ = (1,)

    def test_dependents(self):
        empty = self._getEmpty()
        deps = empty.dependents
        self.assertEqual({}, deps)
        # Doesn't change the return.
        deps[1] = 2
        self.assertEqual({}, empty.dependents)

    def test_changed(self):
        # Does nothing, has no visible side-effects
        self._getEmpty().changed(None)

    def test_extends_always_false(self):
        self.assertFalse(self._getEmpty().extends(self))
        self.assertFalse(self._getEmpty().extends(self, strict=True))
        self.assertFalse(self._getEmpty().extends(self, strict=False))

    def test_get_always_default(self):
        self.assertIsNone(self._getEmpty().get('name'))
        self.assertEqual(self._getEmpty().get('name', 42), 42)
Loading ...