Back to index

plone3  3.1.7
testInterfaces.py
Go to the documentation of this file.
00001 #
00002 # interface testing suite
00003 #
00004 
00005 from Testing import ZopeTestCase
00006 
00007 import traceback
00008 
00009 from types import TupleType, TypeType, ClassType
00010 from zope.interface.interface import InterfaceClass
00011 from ExtensionClass import ExtensionClass
00012 
00013 from Interface.Implements import getImplementsOfInstances
00014 from Interface.Implements import getImplements, flattenInterfaces
00015 from Interface.Verify import verifyClass, verifyObject
00016 from Interface.Exceptions import BrokenImplementation, DoesNotImplement
00017 from Interface.Exceptions import BrokenMethodImplementation
00018 
00019 ###############################################################################
00020 ###               import classes and interfaces for testing                 ###
00021 ###############################################################################
00022 
00023 from Products.CMFPlone.ActionIconsTool import ActionIconsTool
00024 from Products.CMFPlone.ActionsTool import ActionsTool
00025 from Products.CMFPlone.CalendarTool import CalendarTool
00026 from Products.CMFPlone.CatalogTool import CatalogTool
00027 from Products.CMFPlone.DiscussionTool import DiscussionTool
00028 from Products.CMFPlone.FactoryTool import FactoryTool, TempFolder
00029 from Products.CMFPlone.GroupDataTool import GroupDataTool
00030 from Products.CMFPlone.GroupsTool import GroupsTool
00031 from Products.CMFPlone.InterfaceTool import InterfaceTool
00032 from Products.CMFPlone.MemberDataTool import MemberDataTool
00033 from Products.CMFPlone.MembershipTool import MembershipTool
00034 from Products.CMFPlone.MetadataTool import MetadataTool
00035 from Products.CMFPlone.MigrationTool import MigrationTool
00036 from Products.CMFPlone.PloneControlPanel import PloneControlPanel, PloneConfiglet
00037 from Products.CMFPlone.PloneFolder import OrderedContainer, BasePloneFolder, PloneFolder
00038 from Products.CMFPlone.PloneTool import PloneTool
00039 from Products.CMFPlone.Portal import PloneSite
00040 from Products.CMFPlone.PropertiesTool import PropertiesTool, SimpleItemWithProperties
00041 from Products.CMFPlone.QuickInstallerTool import QuickInstallerTool
00042 from Products.CMFPlone.RegistrationTool import RegistrationTool
00043 from Products.CMFPlone.SkinsTool import SkinsTool
00044 from Products.CMFPlone.SyndicationTool import SyndicationTool
00045 from Products.CMFPlone.TypesTool import TypesTool
00046 from Products.CMFPlone.UndoTool import UndoTool
00047 from Products.CMFPlone.URLTool import URLTool
00048 from Products.CMFPlone.WorkflowTool import WorkflowTool
00049 
00050 def className(klass):
00051     """ get the short class name """
00052     if not isinstance(klass, (TypeType, ClassType,
00053                               ExtensionClass, InterfaceClass)):
00054         # Looks like an instance, get it's class.
00055         if hasattr(klass, '__class__'):
00056             klass = klass.__class__
00057     return klass.__name__
00058 
00059 def dottedName(klass):
00060     return "%s.%s" % (klass.__module__, klass.__name__)
00061 
00062 # list of tests
00063 tests = []
00064 
00065 class InterfaceTest(ZopeTestCase.ZopeTestCase):
00066     """general interface testing class
00067 
00068     klass - the class object to test
00069     forcedImpl - a list of interface class objects that the class klass
00070         *must* implement to fullfil this test
00071 
00072     This test class doesn't implement a test* method so you have to provide
00073     a test method in your implementation. See above for two examples. One
00074     example uses the special magic of setattr::
00075 
00076         setattr(MyClass, MyMethodName, lambda self: self._testStuff())
00077 
00078     """
00079 
00080     _setup_fixture = 0  # No default fixture
00081 
00082     klass = None    # test this class
00083     instance = None # test this instance
00084     forcedImpl = () # class must implement this tuple of interfaces
00085 
00086     def interfaceImplementedByInstanceOf(self, klass, interface):
00087         """ tests if the klass implements the interface in the right way """
00088         from Interface.Verify import verifyClass
00089         from Interface.Exceptions import BrokenImplementation, DoesNotImplement
00090         from Interface.Exceptions import BrokenMethodImplementation
00091 
00092         # is the class really implemented by the given interface?
00093         self.failUnless(interface.isImplementedByInstancesOf(klass),
00094             'The class %s does not implement %s' % (dottedName(klass),
00095                                                     dottedName(interface)))
00096         # verify if the implementation is correct
00097         try:
00098             verifyClass(interface, klass)
00099         except (BrokenImplementation, DoesNotImplement,
00100                 BrokenMethodImplementation), errmsg:
00101             self.fail('The class %s does not implement %s correctly: \n%s'
00102                       % (dottedName(klass), dottedName(interface), errmsg))
00103        except AttributeError, errmsg:
00104            self.fail('There was a problem while checking the implementation of '
00105                      'class %s and interface %s: \nAttributeError %s\n%s'
00106                     % (dottedName(klass), dottedName(interface), errmsg,
00107                          ''.join(traceback.format_tb(sys.exc_traceback))))
00108 
00109     def interfaceImplementedBy(self, instance, interface):
00110         """ tests if the instance implements the interface in the right way """
00111         from Interface.Verify import verifyObject
00112         from Interface.Exceptions import BrokenImplementation, DoesNotImplement
00113         from Interface.Exceptions import BrokenMethodImplementation
00114 
00115         # is the class really implemented by the given interface?
00116         self.failUnless(interface.isImplementedBy(instance),
00117             'The instance of %s does not implement %s' % (dottedName(instance),
00118                                                           dottedName(interface)))
00119         # verify if the implementation is correct
00120         try:
00121             verifyObject(interface, instance)
00122         except (BrokenImplementation, DoesNotImplement,
00123           BrokenMethodImplementation), errmsg:
00124             self.fail('The instance of %s does not implement %s correctly: \n%s'
00125                 % (dottedName(instance), dottedName(interface), errmsg))
00126 
00127     def getImplementsOfInstanceOf(self, klass):
00128         """ returns the interfaces implemented by the klass (flat)"""
00129         from Interface.Implements import getImplementsOfInstances, flattenInterfaces
00130 
00131         impl = getImplementsOfInstances(klass)
00132         if type(impl) is not TupleType:
00133             impl = (impl,)
00134         if impl:
00135             return flattenInterfaces(impl)
00136 
00137     def getImplementsOf(self, instance):
00138         """ returns the interfaces implemented by the instance (flat)"""
00139         from Interface.Implements import getImplements, flattenInterfaces
00140 
00141         impl = getImplements(instance)
00142         if type(impl) is not TupleType:
00143             impl = (impl,)
00144         if impl:
00145             return flattenInterfaces(impl)
00146 
00147     def doesImplementByInstanceOf(self, klass, interfaces):
00148         """ make sure that the klass implements at least these interfaces"""
00149         if type(interfaces) is not TupleType:
00150             interfaces = (interfaces)
00151         impl = self.getImplementsOfInstanceOf(klass)
00152         for interface in interfaces:
00153             self.failUnless(
00154                 interface in impl,
00155                 'The class %s does not implement %s' % (dottedName(klass),
00156                                                         dottedName(interface)))
00157 
00158     def doesImplementBy(self, instance, interfaces):
00159         """ make sure that the klass implements at least these interfaces"""
00160         if type(interfaces) is not TupleType:
00161             interfaces = (interfaces)
00162         impl = self.getImplementsOf(instance)
00163         for interface in interfaces:
00164             self.failUnless(
00165                 interface in impl,
00166                 'The instance of %s does not implement %s' % (dottedName(instance),
00167                                                               dottedName(interface)))
00168 
00169     def _testStuff(self):
00170         """ test self.klass and self.instance """
00171         if self.klass:
00172             if self.forcedImpl:
00173                 self.doesImplementByInstanceOf(self.klass, self.forcedImpl)
00174             for iface in self.getImplementsOfInstanceOf(self.klass):
00175                 self.interfaceImplementedByInstanceOf(self.klass, iface)
00176         if self.instance:
00177             if self.forcedImpl:
00178                 self.doesImplementBy(self.instance, self.forcedImpl)
00179             for iface in self.getImplementsOf(self.instance):
00180                 self.interfaceImplementedBy(self.instance, iface)
00181 
00182 
00183 class zope_interface_test(ZopeTestCase.ZopeTestCase):
00184     """general zope.interface testing class
00185 
00186     klass - the class object to test
00187     forcedImpl - a list of interface class objects that the class klass
00188         *must* implement to fullfil this test
00189 
00190     This test class doesn't implement a test* method so you have to provide
00191     a test method in your implementation. See above for two examples. One
00192     example uses the special magic of setattr::
00193 
00194         setattr(MyClass, MyMethodName, lambda self: self._testStuff())
00195 
00196     """
00197 
00198     _setup_fixture = 0  # No default fixture
00199 
00200     klass = None    # test this class
00201     instance = None # test this instance
00202     forcedImpl = () # class must implement this tuple of interfaces
00203 
00204     def interfaceImplementedBy(self, klass, interface):
00205         """ tests if the klass implements the interface in the right way """
00206 
00207         from zope.interface.verify import verifyClass
00208         from zope.interface.exceptions import BrokenImplementation, DoesNotImplement
00209         from zope.interface.exceptions import BrokenMethodImplementation
00210 
00211         # is the class really implemented by the given interface?
00212         self.failUnless(interface.implementedBy(klass),
00213             'The class %s does not implement %s' % (dottedName(klass),
00214                                                     dottedName(interface)))
00215         # verify if the implementation is correct
00216         try:
00217             verifyClass(interface, klass)
00218         except (BrokenImplementation, DoesNotImplement,
00219                 BrokenMethodImplementation), errmsg:
00220             self.fail('The class %s does not implement %s correctly: \n%s'
00221                       % (dottedName(klass), dottedName(interface), errmsg))
00222        except AttributeError, errmsg:
00223            self.fail('There was a problem while checking the implementation of '
00224                      'class %s and interface %s: \nAttributeError %s\n%s'
00225                     % (dottedName(klass), dottedName(interface), errmsg,
00226                          ''.join(traceback.format_tb(sys.exc_traceback))))
00227 
00228     def interfaceProvidedBy(self, instance, interface):
00229         """ tests if the instance implements the interface in the right way """
00230         from zope.interface.verify import verifyObject
00231         from zope.interface.exceptions import BrokenImplementation, DoesNotImplement
00232         from zope.interface.exceptions import BrokenMethodImplementation
00233 
00234         # is the class really implemented by the given interface?
00235         self.failUnless(interface.providedBy(instance),
00236             'The instance of %s does not provide %s' % (dottedName(instance),
00237                                                         dottedName(interface)))
00238         # verify if the implementation is correct
00239         try:
00240             verifyObject(interface, instance)
00241         except (BrokenImplementation, DoesNotImplement,
00242                 BrokenMethodImplementation), errmsg:
00243             self.fail('The instance of %s does not provide %s correctly: \n%s'
00244                       % (dottedName(instance), dottedName(interface), errmsg))
00245 
00246     def getImplementedBy(self, klass):
00247         """ returns the interfaces implemented by the klass (flat)"""
00248         from zope.interface import implementedBy
00249         return implementedBy(klass)
00250 
00251     def getProvidedBy(self, instance):
00252         """ returns the interfaces implemented by the instance (flat)"""
00253         from zope.interface import providedBy
00254         return providedBy(instance)
00255 
00256     def doesImplementedBy(self, klass, interfaces):
00257         """ make sure that the klass implements at least these interfaces"""
00258         impl = self.getImplementedBy(klass)
00259         for interface in interfaces:
00260             self.failUnless(
00261                 interface in impl,
00262                 'The class %s does not implement %s' % (dottedName(klass),
00263                                                         dottedName(interface)))
00264 
00265     def doesProvidedBy(self, instance, interfaces):
00266         """ make sure that the klass implements at least these interfaces"""
00267         impl = self.getProvidedBy(instance)
00268         for interface in interfaces:
00269             self.failUnless(
00270                 interface in impl,
00271                 'The instance of %s does not provide %s' % (dottedName(instance),
00272                                                             dottedName(interface)))
00273 
00274     def _testStuff(self):
00275         """ test self.klass and self.instance """
00276         if self.klass:
00277             if self.forcedImpl:
00278                 self.doesImplementedBy(self.klass, self.forcedImpl)
00279             for iface in self.getImplementedBy(self.klass):
00280                 self.interfaceImplementedBy(self.klass, iface)
00281         if self.instance:
00282             if self.forcedImpl:
00283                 self.doesProvidedBy(self.instance, self.forcedImpl)
00284             for iface in self.getProvidedBy(self.instance):
00285                 self.interfaceProvidedBy(self.instance, iface)
00286 
00287 
00288 ###############################################################################
00289 ###                         testing starts here                             ###
00290 ###############################################################################
00291 
00292 # format: (class object, (list interface objects))
00293 testClasses = [
00294     (ActionIconsTool, ()),
00295     (ActionsTool, ()),
00296     (CalendarTool, ()),
00297     (CatalogTool, ()),
00298     (DiscussionTool, ()),
00299     (FactoryTool, ()), (TempFolder, ()),
00300     (GroupDataTool, ()),
00301     (GroupsTool, ()),
00302     (InterfaceTool, ()),
00303     (MemberDataTool, ()),
00304     (MembershipTool, ()),
00305     (MetadataTool, ()),
00306     (MigrationTool, ()),
00307     (PloneControlPanel, ()), (PloneConfiglet, ()),
00308     (OrderedContainer, ()), (BasePloneFolder, ()), (PloneFolder, ()),
00309     (PloneTool, ()),
00310     (PloneSite, ()),
00311     (PropertiesTool, ()), (SimpleItemWithProperties, ()),
00312     (QuickInstallerTool, ()),
00313     (RegistrationTool, ()),
00314     (SkinsTool, ()),
00315     (SyndicationTool, ()),
00316     (TypesTool, ()),
00317     (UndoTool, ()),
00318     (URLTool, ()),
00319     (WorkflowTool, ()),
00320 ]
00321 
00322 # format: (instance object, (list interface objects))
00323 # take care: you must provide an instance, not a class!
00324 testInstances = [
00325     # (, ()),
00326 ]
00327 
00328 for testClass in testClasses:
00329     klass, forcedImpl = testClass
00330     name = className(klass)
00331     funcName = 'test%sInterface' % name
00332 
00333     class KlassInterfaceTest(InterfaceTest):
00334         """ implementation for %s """ % name
00335         klass      = klass
00336         forcedImpl = forcedImpl
00337 
00338     # add the testing method to the class to get a nice name
00339     setattr(KlassInterfaceTest, funcName, lambda self: self._testStuff())
00340     tests.append(KlassInterfaceTest)
00341 
00342     class KlassInterfaceTest(zope_interface_test):
00343         """ implementation for %s """ % name
00344         klass      = klass
00345         forcedImpl = forcedImpl
00346 
00347     # add the testing method to the class to get a nice name
00348     setattr(KlassInterfaceTest, funcName, lambda self: self._testStuff())
00349     tests.append(KlassInterfaceTest)
00350 
00351 
00352 for testInstance in testInstances:
00353     instance, forcedImpl = testInstance
00354     name = className(instance)
00355     funcName = 'test%sInterface' % name
00356 
00357     class InstanceInterfaceTest(InterfaceTest):
00358         """ implementation for %s """ % name
00359         instance   = instance
00360         forcedImpl = forcedImpl
00361 
00362     # add the testing method to the class to get a nice name
00363     setattr(InstanceInterfaceTest, funcName, lambda self: self._testStuff())
00364     tests.append(InstanceInterfaceTest)
00365 
00366     class InstanceInterfaceTest(zope_interface_test):
00367         """ implementation for %s """ % name
00368         instance   = instance
00369         forcedImpl = forcedImpl
00370 
00371 import unittest
00372 
00373 def test_suite():
00374     suite = unittest.TestSuite()
00375     for test in tests:
00376         suite.addTest(unittest.makeSuite(test))
00377     return suite
00378 
00379 if __name__ == '__main__':
00380     unittest.main(defaultTest='test_suite')