123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- ##############################################################################
- #
- # 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
- # pylint:disable=protected-access
- # pylint:disable=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 Interface
- from zope.interface import implementedBy
- from zope.interface import implementer
- from zope.interface import providedBy
- 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 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)
|