"""Tests for default IOpenProvider (etc.) adapters TODO: - Test Zope interface registrations """ from unittest import TestCase, makeSuite, TestSuite from protocols import * from checks import ProviderChecks, AdaptiveChecks, ClassProvidesChecks from checks import makeClassProvidesTests, makeInstanceTests from checks import makeMetaClassProvidesTests class IA(Interface): pass class IB(IA): pass class IPure(Interface): # We use this for pickle/copy tests because the other protocols # imply various dynamically created interfaces, and so any object # registered with them won't be picklable pass class BasicChecks(AdaptiveChecks, ProviderChecks): """Checks to be done on every object""" IA = IA IB = IB Interface = Interface IPure = IPure def checkCircularRegister(self): P1 = Protocol() P2 = Protocol() declareAdapter(NO_ADAPTER_NEEDED,provides=[P2],forProtocols=[P1]) declareAdapter(NO_ADAPTER_NEEDED,provides=[P1],forProtocols=[P2]) self.declareObImplements([P1]) # implies P1->P2->P1 class ClassChecks(ClassProvidesChecks, BasicChecks): """Checks to be done on classes and types""" class InstanceConformChecks: """Things to check on adapted instances""" def checkBadConform(self): def __conform__(proto): pass self.ob.__conform__ = __conform__ self.assertBadConform(self.ob, [self.IA], __conform__) def assertBadConform(self, ob, protocols, conform): try: adviseObject(ob, provides=protocols) except TypeError,v: assert v.args==( "Incompatible __conform__ on adapted object", ob, conform ), v.args else: raise AssertionError("Should've detected invalid __conform__") class ClassConformChecks(InstanceConformChecks): """Things to check on adapted classes""" def checkInheritedConform(self): class Base(self.ob): def __conform__(self,protocol): pass class Sub(Base): pass self.assertBadConform(Sub, [self.IA], Base.__conform__.im_func) def checkInstanceConform(self): class Base(self.ob): def __conform__(self,protocol): pass b = Base() self.assertBadConform(b, [self.IA], b.__conform__) class AdviseMixinInstance(BasicChecks): def setUp(self): self.ob = ProviderMixin() # Notice that we don't test the *metaclass* of the next three configurations; # it would fail because the metaclass itself can't be adapted to an open # provider, because it has a __conform__ method (from ProviderMixin). For # that to work, there'd have to be *another* metalevel. class AdviseMixinMultiMeta1(BasicChecks): def setUp(self): class Meta(ProviderMixin, type): pass class Test(ProviderMixin,object): __metaclass__ = Meta self.ob = Test() class InstanceTestsBase(BasicChecks, InstanceConformChecks): pass class ClassTestsBase(ClassChecks, ClassConformChecks): pass class Picklable: # Pickling needs classes in top-level namespace pass class NewStyle(object): pass TestClasses = ( AdviseMixinInstance, AdviseMixinMultiMeta1, ) TestClasses += makeMetaClassProvidesTests(ClassChecks) TestClasses += makeClassProvidesTests(ClassTestsBase) TestClasses += makeInstanceTests(InstanceTestsBase,Picklable,NewStyle) def test_suite(): return TestSuite([makeSuite(t,'check') for t in TestClasses])