Back to index

plone3  3.1.7
test_utils.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2004 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """ GenericSetup.utils unit tests
00014 
00015 $Id: test_utils.py 84384 2008-03-01 19:14:13Z shh $
00016 """
00017 
00018 import unittest
00019 import Testing
00020 
00021 from xml.dom.minidom import parseString
00022 
00023 from OFS.interfaces import IItem
00024 from OFS.SimpleItem import Item
00025 from Products.Five.utilities.marker import MarkerInterfacesAdapter
00026 from Testing.ZopeTestCase import ZopeTestCase
00027 from Testing.ZopeTestCase import installProduct
00028 from zope.component import provideAdapter
00029 from zope.component.interface import provideInterface
00030 from zope.interface import directlyProvides
00031 from zope.testing.cleanup import cleanUp
00032 
00033 from Products.GenericSetup.testing import DummySetupEnviron
00034 from Products.GenericSetup.testing import IDummyMarker
00035 from Products.GenericSetup.utils import PrettyDocument
00036 
00037 installProduct('GenericSetup')
00038 
00039 
00040 _EMPTY_PROPERTY_EXPORT = """\
00041 <?xml version="1.0"?>
00042 <dummy>
00043  <property name="foo_boolean" type="boolean">False</property>
00044  <property name="foo_date" type="date">1970/01/01</property>
00045  <property name="foo_float" type="float">0.0</property>
00046  <property name="foo_int" type="int">0</property>
00047  <property name="foo_lines" type="lines"/>
00048  <property name="foo_long" type="long">0</property>
00049  <property name="foo_string" type="string"></property>
00050  <property name="foo_text" type="text"></property>
00051  <property name="foo_tokens" type="tokens"/>
00052  <property name="foo_selection" select_variable="foobarbaz"
00053     type="selection"></property>
00054  <property name="foo_mselection" select_variable="foobarbaz"
00055     type="multiple selection"/>
00056  <property name="foo_boolean0" type="boolean">False</property>
00057  <property name="foo_int_nodel">0</property>
00058  <property name="foo_float_nodel">0.0</property>
00059  <property name="foo_boolean_nodel">False</property>
00060 </dummy>
00061 """
00062 
00063 _NORMAL_PROPERTY_EXPORT = """\
00064 <?xml version="1.0"?>
00065 <dummy>
00066  <property name="foo_boolean" type="boolean">True</property>
00067  <property name="foo_date" type="date">2000/01/01</property>
00068  <property name="foo_float" type="float">1.1</property>
00069  <property name="foo_int" type="int">1</property>
00070  <property name="foo_lines" type="lines">
00071   <element value="Foo"/>
00072   <element value="Lines"/>
00073  </property>
00074  <property name="foo_long" type="long">1</property>
00075  <property name="foo_string" type="string">Foo String</property>
00076  <property name="foo_text" type="text">Foo
00077   Text</property>
00078  <property name="foo_tokens" type="tokens">
00079   <element value="Foo"/>
00080   <element value="Tokens"/>
00081  </property>
00082  <property name="foo_selection" select_variable="foobarbaz"
00083     type="selection">Foo</property>
00084  <property name="foo_mselection" select_variable="foobarbaz"
00085     type="multiple selection">
00086   <element value="Foo"/>
00087   <element value="Baz"/>
00088  </property>
00089  <property name="foo_boolean0" type="boolean">False</property>
00090  <property name="foo_int_nodel">1789</property>
00091  <property name="foo_float_nodel">3.1415</property>
00092  <property name="foo_boolean_nodel">True</property>
00093 </dummy>
00094 """
00095 
00096 _FIXED_PROPERTY_EXPORT = """\
00097 <?xml version="1.0"?>
00098 <dummy>
00099  <property name="foo_boolean">True</property>
00100  <property name="foo_date">2000/01/01</property>
00101  <property name="foo_float">1.1</property>
00102  <property name="foo_int">1</property>
00103  <property name="foo_lines">
00104   <element value="Foo"/>
00105   <element value="Lines"/>
00106  </property>
00107  <property name="foo_long">1</property>
00108  <property name="foo_string">Foo String</property>
00109  <property name="foo_text">Foo
00110   Text</property>
00111  <property name="foo_tokens">
00112   <element value="Foo"/>
00113   <element value="Tokens"/></property>
00114  <property name="foo_selection" type="selection"
00115     select_variable="foobarbaz">Foo</property>
00116  <property name="foo_mselection">
00117   <element value="Foo"/>
00118   <element value="Baz"/>
00119  </property>
00120  <property name="foo_boolean0">False</property>
00121  <property name="foo_int_nodel">1789</property>
00122  <property name="foo_float_nodel">3.1415</property>
00123  <property name="foo_boolean_nodel">True</property>
00124 </dummy>
00125 """
00126 
00127 _SPECIAL_IMPORT = """\
00128 <?xml version="1.0"?>
00129 <dummy>
00130  <!-- ignore comment, import 0 as False -->
00131  <property name="foo_boolean0" type="boolean">0</property>
00132 </dummy>
00133 """
00134 
00135 _I18N_IMPORT = """\
00136 <?xml version="1.0"?>
00137 <dummy xmlns:i18n="http://xml.zope.org/namespaces/i18n"
00138    i18n:domain="dummy_domain">
00139  <property name="foo_string" i18n:translate="">Foo String</property>
00140 </dummy>
00141 """
00142 
00143 _NOPURGE_IMPORT = """\
00144 <?xml version="1.0"?>
00145 <dummy>
00146  <property name="lines1">
00147   <element value="Foo"/>
00148   <element value="Bar"/>
00149  </property>
00150  <property name="lines2" purge="True">
00151   <element value="Foo"/>
00152   <element value="Bar"/>
00153  </property>
00154  <property name="lines3" purge="False">
00155   <element value="Foo"/>
00156   <element value="Bar"/>
00157  </property>
00158 </dummy>
00159 """
00160 
00161 _NORMAL_MARKER_EXPORT = """\
00162 <?xml version="1.0"?>
00163 <dummy>
00164  <marker name="Products.GenericSetup.testing.IDummyMarker"/>
00165 </dummy>
00166 """
00167 
00168 _ADD_IMPORT = """\
00169 <?xml version="1.0"?>
00170 <dummy>
00171  <object name="history" meta_type="Generic Setup Tool"/>
00172 </dummy>
00173 """
00174 _REMOVE_IMPORT = """\
00175 <?xml version="1.0"?>
00176 <dummy>
00177  <object name="history" remove="True"/>
00178 </dummy>
00179 """
00180 
00181 
00182 def _testFunc( *args, **kw ):
00183 
00184     """ This is a test.
00185 
00186     This is only a test.
00187     """
00188 
00189 _TEST_FUNC_NAME = 'Products.GenericSetup.tests.test_utils._testFunc'
00190 
00191 class Whatever:
00192     pass
00193 
00194 _WHATEVER_NAME = 'Products.GenericSetup.tests.test_utils.Whatever'
00195 
00196 whatever_inst = Whatever()
00197 whatever_inst.__name__ = 'whatever_inst'
00198 
00199 _WHATEVER_INST_NAME = 'Products.GenericSetup.tests.test_utils.whatever_inst'
00200 
00201 class UtilsTests( unittest.TestCase ):
00202 
00203     def test__getDottedName_simple( self ):
00204 
00205         from Products.GenericSetup.utils import _getDottedName
00206 
00207         self.assertEqual( _getDottedName( _testFunc ), _TEST_FUNC_NAME )
00208 
00209     def test__getDottedName_string( self ):
00210 
00211         from Products.GenericSetup.utils import _getDottedName
00212 
00213         self.assertEqual( _getDottedName( _TEST_FUNC_NAME ), _TEST_FUNC_NAME )
00214 
00215     def test__getDottedName_unicode( self ):
00216 
00217         from Products.GenericSetup.utils import _getDottedName
00218 
00219         dotted = u'%s' % _TEST_FUNC_NAME
00220         self.assertEqual( _getDottedName( dotted ), _TEST_FUNC_NAME )
00221         self.assertEqual( type( _getDottedName( dotted ) ), str )
00222 
00223     def test__getDottedName_class( self ):
00224 
00225         from Products.GenericSetup.utils import _getDottedName
00226 
00227         self.assertEqual( _getDottedName( Whatever ), _WHATEVER_NAME )
00228 
00229     def test__getDottedName_inst( self ):
00230 
00231         from Products.GenericSetup.utils import _getDottedName
00232 
00233         self.assertEqual( _getDottedName( whatever_inst )
00234                         , _WHATEVER_INST_NAME )
00235 
00236     def test__getDottedName_noname( self ):
00237 
00238         from Products.GenericSetup.utils import _getDottedName
00239 
00240         class Doh:
00241             pass
00242 
00243         doh = Doh()
00244         self.assertRaises( ValueError, _getDottedName, doh )
00245 
00246 
00247 class PropertyManagerHelpersTests(unittest.TestCase):
00248 
00249     def _getTargetClass(self):
00250         from Products.GenericSetup.utils import PropertyManagerHelpers
00251 
00252         return PropertyManagerHelpers
00253 
00254     def _makeOne(self, *args, **kw):
00255         from Products.GenericSetup.utils import NodeAdapterBase
00256 
00257         class Foo(self._getTargetClass(), NodeAdapterBase):
00258 
00259             pass
00260 
00261         return Foo(*args, **kw)
00262 
00263     def setUp(self):
00264         from OFS.PropertyManager import PropertyManager
00265 
00266         obj = PropertyManager('obj')
00267         obj.foobarbaz = ('Foo', 'Bar', 'Baz')
00268         obj._properties = ()
00269         obj.manage_addProperty('foo_boolean', '', 'boolean')
00270         obj.manage_addProperty('foo_date', '1970/01/01', 'date')
00271         obj.manage_addProperty('foo_float', '0', 'float')
00272         obj.manage_addProperty('foo_int', '0', 'int')
00273         obj.manage_addProperty('foo_lines', '', 'lines')
00274         obj.manage_addProperty('foo_long', '0', 'long')
00275         obj.manage_addProperty('foo_string', '', 'string')
00276         obj.manage_addProperty('foo_text', '', 'text')
00277         obj.manage_addProperty('foo_tokens', '', 'tokens')
00278         obj.manage_addProperty('foo_selection', 'foobarbaz', 'selection')
00279         obj.manage_addProperty('foo_mselection', 'foobarbaz',
00280                                'multiple selection')
00281         obj.manage_addProperty('foo_boolean0', '', 'boolean')
00282         obj.manage_addProperty('foo_ro', '', 'string')
00283         obj._properties[-1]['mode'] = '' # Read-only, not exported or purged
00284         obj.manage_addProperty('foo_int_nodel', 0, 'int')
00285         obj._properties[-1]['mode'] = 'w' # Not deletable
00286         obj.manage_addProperty('foo_float_nodel', 0, 'float')
00287         obj._properties[-1]['mode'] = 'w' # Not deletable
00288         obj.manage_addProperty('foo_boolean_nodel', '', 'boolean')
00289         obj._properties[-1]['mode'] = 'w' # Not deletable
00290         self.helpers = self._makeOne(obj, DummySetupEnviron())
00291 
00292     def _populate(self, obj):
00293         obj._updateProperty('foo_boolean', 'True')
00294         obj._updateProperty('foo_date', '2000/01/01')
00295         obj._updateProperty('foo_float', '1.1')
00296         obj._updateProperty('foo_int', '1')
00297         obj._updateProperty('foo_lines', 'Foo\nLines')
00298         obj._updateProperty('foo_long', '1')
00299         obj._updateProperty('foo_string', 'Foo String')
00300         obj._updateProperty('foo_text', 'Foo\nText')
00301         obj._updateProperty( 'foo_tokens', ('Foo', 'Tokens') )
00302         obj._updateProperty('foo_selection', 'Foo')
00303         obj._updateProperty( 'foo_mselection', ('Foo', 'Baz') )
00304         obj.foo_boolean0 = 0
00305         obj._updateProperty('foo_ro', 'RO')
00306         obj._updateProperty('foo_int_nodel', '1789')
00307         obj._updateProperty('foo_float_nodel', '3.1415')
00308         obj._updateProperty('foo_boolean_nodel', 'True')
00309 
00310     def test__extractProperties_empty(self):
00311         doc = self.helpers._doc = PrettyDocument()
00312         node = doc.createElement('dummy')
00313         node.appendChild(self.helpers._extractProperties())
00314         doc.appendChild(node)
00315 
00316         self.assertEqual(doc.toprettyxml(' '), _EMPTY_PROPERTY_EXPORT)
00317 
00318     def test__extractProperties_normal(self):
00319         self._populate(self.helpers.context)
00320         doc = self.helpers._doc = PrettyDocument()
00321         node = doc.createElement('dummy')
00322         node.appendChild(self.helpers._extractProperties())
00323         doc.appendChild(node)
00324 
00325         self.assertEqual(doc.toprettyxml(' '), _NORMAL_PROPERTY_EXPORT)
00326 
00327     def test__purgeProperties(self):
00328         obj = self.helpers.context
00329         self._populate(obj)
00330         self.helpers._purgeProperties()
00331 
00332         self.assertEqual(getattr(obj, 'foo_boolean', None), None)
00333         self.assertEqual(getattr(obj, 'foo_date', None), None)
00334         self.assertEqual(getattr(obj, 'foo_float', None), None)
00335         self.assertEqual(getattr(obj, 'foo_int', None), None)
00336         self.assertEqual(getattr(obj, 'foo_lines', None), None)
00337         self.assertEqual(getattr(obj, 'foo_long', None), None)
00338         self.assertEqual(getattr(obj, 'foo_string', None), None)
00339         self.assertEqual(getattr(obj, 'foo_text', None), None)
00340         self.assertEqual(getattr(obj, 'foo_tokens', None), None)
00341         self.assertEqual(getattr(obj, 'foo_selection', None), None)
00342         self.assertEqual(getattr(obj, 'foo_mselection', None), None)
00343         self.assertEqual(getattr(obj, 'foo_boolean0', None), None)
00344         self.assertEqual(getattr(obj, 'foo_ro', None), 'RO')
00345 
00346     def test__initProperties_normal(self):
00347         node = parseString(_NORMAL_PROPERTY_EXPORT).documentElement
00348         self.helpers._initProperties(node)
00349         self.assertEqual(type(self.helpers.context.foo_int), int)
00350         self.assertEqual(type(self.helpers.context.foo_string), str)
00351         self.assertEqual(type(self.helpers.context.foo_tokens), tuple)
00352         self.assertEqual(type(self.helpers.context.foo_tokens[0]), str)
00353 
00354         doc = self.helpers._doc = PrettyDocument()
00355         node = doc.createElement('dummy')
00356         node.appendChild(self.helpers._extractProperties())
00357         doc.appendChild(node)
00358 
00359         self.assertEqual(doc.toprettyxml(' '), _NORMAL_PROPERTY_EXPORT)
00360 
00361     def test__initProperties_fixed(self):
00362         node = parseString(_FIXED_PROPERTY_EXPORT).documentElement
00363         self.helpers._initProperties(node)
00364 
00365         doc = self.helpers._doc = PrettyDocument()
00366         node = doc.createElement('dummy')
00367         node.appendChild(self.helpers._extractProperties())
00368         doc.appendChild(node)
00369 
00370         self.assertEqual(doc.toprettyxml(' '), _NORMAL_PROPERTY_EXPORT)
00371 
00372     def test__initProperties_special(self):
00373         node = parseString(_SPECIAL_IMPORT).documentElement
00374         self.helpers._initProperties(node)
00375 
00376         doc = self.helpers._doc = PrettyDocument()
00377         node = doc.createElement('dummy')
00378         node.appendChild(self.helpers._extractProperties())
00379         doc.appendChild(node)
00380 
00381         self.assertEqual(doc.toprettyxml(' '), _EMPTY_PROPERTY_EXPORT)
00382 
00383     def test__initProperties_i18n(self):
00384         self.helpers.context.manage_addProperty('i18n_domain', '', 'string')
00385         node = parseString(_I18N_IMPORT).documentElement
00386         self.helpers._initProperties(node)
00387 
00388         self.assertEqual(self.helpers.context.i18n_domain, 'dummy_domain')
00389 
00390     def test__initProperties_nopurge_base(self):
00391         node = parseString(_NOPURGE_IMPORT).documentElement
00392         self.helpers.environ._should_purge = True # base profile
00393         obj = self.helpers.context
00394         obj._properties = ()
00395         obj.manage_addProperty('lines1', ('Foo', 'Gee'), 'lines')
00396         obj.manage_addProperty('lines2', ('Foo', 'Gee'), 'lines')
00397         obj.manage_addProperty('lines3', ('Foo', 'Gee'), 'lines')
00398         self.helpers._initProperties(node)
00399 
00400         self.assertEquals(obj.lines1, ('Foo', 'Bar'))
00401         self.assertEquals(obj.lines2, ('Foo', 'Bar'))
00402         self.assertEquals(obj.lines3, ('Gee', 'Foo', 'Bar'))
00403 
00404     def test__initProperties_nopurge_extension(self):
00405         node = parseString(_NOPURGE_IMPORT).documentElement
00406         self.helpers.environ._should_purge = False # extension profile
00407         obj = self.helpers.context
00408         obj._properties = ()
00409         obj.manage_addProperty('lines1', ('Foo', 'Gee'), 'lines')
00410         obj.manage_addProperty('lines2', ('Foo', 'Gee'), 'lines')
00411         obj.manage_addProperty('lines3', ('Foo', 'Gee'), 'lines')
00412         self.helpers._initProperties(node)
00413 
00414         self.assertEquals(obj.lines1, ('Foo', 'Bar'))
00415         self.assertEquals(obj.lines2, ('Foo', 'Bar'))
00416         self.assertEquals(obj.lines3, ('Gee', 'Foo', 'Bar'))
00417 
00418 
00419 class MarkerInterfaceHelpersTests(unittest.TestCase):
00420 
00421     def _getTargetClass(self):
00422         from Products.GenericSetup.utils import MarkerInterfaceHelpers
00423 
00424         return MarkerInterfaceHelpers
00425 
00426     def _makeOne(self, *args, **kw):
00427         from Products.GenericSetup.utils import NodeAdapterBase
00428 
00429         class Foo(self._getTargetClass(), NodeAdapterBase):
00430 
00431             pass
00432 
00433         return Foo(*args, **kw)
00434 
00435     def _populate(self, obj):
00436         directlyProvides(obj, IDummyMarker)
00437 
00438     def setUp(self):
00439         obj = Item('obj')
00440         self.helpers = self._makeOne(obj, DummySetupEnviron())
00441         provideAdapter(MarkerInterfacesAdapter, (IItem,))
00442         provideInterface('', IDummyMarker)
00443 
00444     def tearDown(self):
00445         cleanUp()
00446 
00447     def test__extractMarkers(self):
00448         self._populate(self.helpers.context)
00449         doc = self.helpers._doc = PrettyDocument()
00450         node = doc.createElement('dummy')
00451         node.appendChild(self.helpers._extractMarkers())
00452         doc.appendChild(node)
00453 
00454         self.assertEqual(doc.toprettyxml(' '), _NORMAL_MARKER_EXPORT)
00455 
00456     def test__purgeMarkers(self):
00457         obj = self.helpers.context
00458         self._populate(obj)
00459         self.failUnless(IDummyMarker.providedBy(obj))
00460 
00461         self.helpers._purgeMarkers()
00462         self.failIf(IDummyMarker.providedBy(obj))
00463 
00464     def test__initMarkers(self):
00465         node = parseString(_NORMAL_MARKER_EXPORT).documentElement
00466         self.helpers._initMarkers(node)
00467         self.failUnless(IDummyMarker.providedBy(self.helpers.context))
00468 
00469         doc = self.helpers._doc = PrettyDocument()
00470         node = doc.createElement('dummy')
00471         node.appendChild(self.helpers._extractMarkers())
00472         doc.appendChild(node)
00473 
00474         self.assertEqual(doc.toprettyxml(' '), _NORMAL_MARKER_EXPORT)
00475 
00476 
00477 class ObjectManagerHelpersTests(ZopeTestCase):
00478 
00479     def _getTargetClass(self):
00480         from Products.GenericSetup.utils import ObjectManagerHelpers
00481 
00482         return ObjectManagerHelpers
00483 
00484     def _makeOne(self, *args, **kw):
00485         from Products.GenericSetup.utils import NodeAdapterBase
00486 
00487         class Foo(self._getTargetClass(), NodeAdapterBase):
00488 
00489             pass
00490 
00491         return Foo(*args, **kw)
00492 
00493     def setUp(self):
00494         from OFS.ObjectManager import ObjectManager
00495 
00496         obj = ObjectManager('obj')
00497         self.helpers = self._makeOne(obj, DummySetupEnviron())
00498 
00499     def test__initObjects(self):
00500         obj = self.helpers.context
00501         self.failIf('history' in obj.objectIds())
00502 
00503         # Add object
00504         node = parseString(_ADD_IMPORT).documentElement
00505         self.helpers._initObjects(node)
00506         self.failUnless('history' in obj.objectIds())
00507 
00508         # Remove it again
00509         node = parseString(_REMOVE_IMPORT).documentElement
00510         self.helpers._initObjects(node)
00511         self.failIf('history' in obj.objectIds())
00512         
00513         # Removing it a second time should not throw an
00514         # AttributeError.
00515         node = parseString(_REMOVE_IMPORT).documentElement
00516         self.helpers._initObjects(node)
00517         self.failIf('history' in obj.objectIds())
00518         
00519 
00520 class PrettyDocumentTests(unittest.TestCase):
00521 
00522     def test_attr_quoting(self):
00523         original = 'baz &nbsp;<bar>&"\''
00524         expected = ('<?xml version="1.0"?>\n'
00525                     '<doc foo="baz &amp;nbsp;&lt;bar&gt;&amp;&quot;\'"/>\n')
00526 
00527         doc = PrettyDocument()
00528         node = doc.createElement('doc')
00529         node.setAttribute('foo', original)
00530         doc.appendChild(node)
00531         self.assertEqual(doc.toprettyxml(' '), expected)
00532         # Reparse
00533         e = parseString(expected).documentElement
00534         self.assertEqual(e.getAttribute('foo'), original)
00535 
00536     def test_text_quoting(self):
00537         original = 'goo &nbsp;<hmm>&"\''
00538         expected = ('<?xml version="1.0"?>\n'
00539                     '<doc>goo &amp;nbsp;&lt;hmm&gt;&amp;"\'</doc>\n')
00540 
00541         doc = PrettyDocument()
00542         node = doc.createElement('doc')
00543         child = doc.createTextNode(original)
00544         node.appendChild(child)
00545         doc.appendChild(node)
00546         self.assertEqual(doc.toprettyxml(' '), expected)
00547         # Reparse
00548         e = parseString(expected).documentElement
00549         self.assertEqual(e.childNodes[0].nodeValue, original)
00550 
00551 
00552 def test_suite():
00553     # reimport to make sure tests are run from Products
00554     from Products.GenericSetup.tests.test_utils import UtilsTests
00555 
00556     return unittest.TestSuite((
00557         unittest.makeSuite(UtilsTests),
00558         unittest.makeSuite(PropertyManagerHelpersTests),
00559         unittest.makeSuite(MarkerInterfaceHelpersTests),
00560         unittest.makeSuite(ObjectManagerHelpersTests),
00561         unittest.makeSuite(PrettyDocumentTests),
00562         ))
00563 
00564 if __name__ == '__main__':
00565     unittest.main(defaultTest='test_suite')