[Checkins] SVN: plone.z3cform/trunk/ * Split traversal tests for Zope2.10, not all traversal functionality is
Laurence Rowe
l at lrowe.co.uk
Tue May 3 16:13:01 EDT 2011
Log message for revision 121528:
* Split traversal tests for Zope2.10, not all traversal functionality is
supported on Zope 2.10 and different errors are raised.
Changed:
U plone.z3cform/trunk/docs/HISTORY.txt
U plone.z3cform/trunk/plone/z3cform/tests.py
A plone.z3cform/trunk/plone/z3cform/zope210traversal.txt
-=-
Modified: plone.z3cform/trunk/docs/HISTORY.txt
===================================================================
--- plone.z3cform/trunk/docs/HISTORY.txt 2011-05-03 19:37:28 UTC (rev 121527)
+++ plone.z3cform/trunk/docs/HISTORY.txt 2011-05-03 20:13:01 UTC (rev 121528)
@@ -4,6 +4,10 @@
0.7.5 - unreleased
------------------
+* Split traversal tests for Zope2.10, not all traversal functionality is
+ supported on Zope 2.10 and different errors are raised.
+ [elro]
+
* Revert [120798] as it breaks on Zope2.10 / Plone 3.3. We can deal with Zope
2.14 in 0.8.x.
[elro]
Modified: plone.z3cform/trunk/plone/z3cform/tests.py
===================================================================
--- plone.z3cform/trunk/plone/z3cform/tests.py 2011-05-03 19:37:28 UTC (rev 121527)
+++ plone.z3cform/trunk/plone/z3cform/tests.py 2011-05-03 20:13:01 UTC (rev 121528)
@@ -1,4 +1,5 @@
import os
+import sys
import doctest
import unittest
@@ -70,8 +71,14 @@
fieldsets_txt = doctest.DocFileSuite('fieldsets/README.txt')
fieldsets_txt.layer = testing_zcml_layer
- traversal_txt = doctest.DocFileSuite('traversal.txt')
- traversal_txt.layer = testing_zcml_layer
+ if sys.version_info[:2] == (2, 4):
+ # Zope 2.10 raises TraversalError instead of LocationError
+ # and some more advanced functionality breaks.
+ traversal_txt = doctest.DocFileSuite('zope210traversal.txt')
+ traversal_txt.layer = testing_zcml_layer
+ else:
+ traversal_txt = doctest.DocFileSuite('traversal.txt')
+ traversal_txt.layer = testing_zcml_layer
return unittest.TestSuite([
layout_txt, inputs_txt, fieldsets_txt, traversal_txt,
Copied: plone.z3cform/trunk/plone/z3cform/zope210traversal.txt (from rev 120505, plone.z3cform/trunk/plone/z3cform/traversal.txt)
===================================================================
--- plone.z3cform/trunk/plone/z3cform/zope210traversal.txt (rev 0)
+++ plone.z3cform/trunk/plone/z3cform/zope210traversal.txt 2011-05-03 20:13:01 UTC (rev 121528)
@@ -0,0 +1,169 @@
+Traversal
+=========
+
+plone.z3cform allows you to traverse to a widget using the ++widget++
+namespace adapter on a form wrapper view or standalone form view.
+
+Note that widgets may need to mix in Acquisition.Explicit to be truly
+traversable in Zope 2.10. In Zope 2.12, that is not required. However, you
+may get an error if you mix in Explicit in Zope 2.12 and the parent view
+(normally the form or the form layout wrapper) does not, as is likely to be
+the case. To be compatible with both Zope 2.10 and 2.12, you'll need to
+mix in Acquisition.Explicit, but make sure the widget does *not* provide the
+IAcquirer interface. One way to do that is by using implementsOnly(), e.g.::
+
+ class MyWidget(Aquisition.Explicit):
+ implementsOnly(IMyWidget)
+
+ ...
+
+If you are only targeting Zope 2.12 and later, you can avoid mixing in any
+kind of acquisition altogether.
+
+The ++widget++ namespace works both in the case of a layout wrapper view,
+and in the case of a form used directly (in Zope 2.12 or later).
+
+Traversal on a standalone form
+------------------------------
+
+First, we create a simple form and context.
+
+ >>> from zope.interface import alsoProvides
+ >>> from zope.publisher.browser import TestRequest
+ >>> from zope.annotation.interfaces import IAttributeAnnotatable
+ >>> from z3c.form.interfaces import IFormLayer
+
+ >>> def make_request(form={}):
+ ... request = TestRequest()
+ ... request.form.update(form)
+ ... alsoProvides(request, IFormLayer)
+ ... alsoProvides(request, IAttributeAnnotatable)
+ ... return request
+
+ >>> from zope import interface, schema
+ >>> from z3c.form import form, field, button
+
+ >>> class MySchema(interface.Interface):
+ ... age = schema.Int(title=u"Age")
+
+ >>> from z3c.form.interfaces import IFieldsForm
+ >>> from zope.interface import implements
+ >>> class MyForm(form.Form):
+ ... implements(IFieldsForm)
+ ... fields = field.Fields(MySchema)
+ ... ignoreContext = True # don't use context to get widget data
+ ...
+ ... def update(self):
+ ... print "Updating test form"
+ ... super(MyForm, self).update()
+
+ >>> from zope.component import provideAdapter
+ >>> from zope.publisher.interfaces.browser import IBrowserRequest
+ >>> from zope.interface import Interface
+
+ >>> provideAdapter(adapts=(Interface, IBrowserRequest),
+ ... provides=Interface,
+ ... factory=MyForm,
+ ... name=u"test-form")
+
+ >>> from Acquisition import Implicit
+ >>> class Bar(Implicit):
+ ... __allow_access_to_unprotected_subobjects__ = 1
+ ... implements(Interface)
+
+ >>> from zope.component import getMultiAdapter
+ >>> context = Bar()
+ >>> request = make_request()
+
+Now, let's emulate the publisher and look up the namespace traversal
+adapter. For example, let's say we'd traversed to
+../@@test-form/++widget++age. The publisher would then do:
+
+ >>> form = getMultiAdapter((context, request), name=u"test-form")
+
+ >>> from zope.traversing.interfaces import ITraversable
+ >>> traverser = getMultiAdapter((form, request), name=u"widget")
+ >>> traverser.traverse('age', [])
+ Updating test form
+ <TextWidget 'form.widgets.age'>
+
+Please note that this point, the form has been updated, but not rendered.
+
+Traversal on a layout wrapper view
+-----------------------------------
+
+Again, we create a simple form and context.
+
+ >>> from zope.interface import alsoProvides
+ >>> from zope.publisher.browser import TestRequest
+ >>> from zope.annotation.interfaces import IAttributeAnnotatable
+ >>> from z3c.form.interfaces import IFormLayer
+
+ >>> def make_request(form={}):
+ ... request = TestRequest()
+ ... request.form.update(form)
+ ... alsoProvides(request, IFormLayer)
+ ... alsoProvides(request, IAttributeAnnotatable)
+ ... return request
+
+ >>> from zope import interface, schema
+ >>> from z3c.form import form, field, button
+ >>> from plone.z3cform.layout import FormWrapper
+
+ >>> class MySchema(interface.Interface):
+ ... age = schema.Int(title=u"Age")
+
+ >>> from z3c.form.interfaces import IFieldsForm
+ >>> from zope.interface import implements
+ >>> class MyForm(form.Form):
+ ... implements(IFieldsForm)
+ ... fields = field.Fields(MySchema)
+ ... ignoreContext = True # don't use context to get widget data
+ ...
+ ... def update(self):
+ ... print "Updating test form"
+ ... super(MyForm, self).update()
+
+ >>> class MyFormWrapper(FormWrapper):
+ ... form = MyForm
+ ... label = u"Please enter your age"
+
+ >>> from zope.component import provideAdapter
+ >>> from zope.publisher.interfaces.browser import IBrowserRequest
+ >>> from zope.interface import Interface
+
+ >>> provideAdapter(adapts=(Interface, IBrowserRequest),
+ ... provides=Interface,
+ ... factory=MyFormWrapper,
+ ... name=u"test-form")
+
+ >>> from Acquisition import Implicit
+ >>> class Bar(Implicit):
+ ... __allow_access_to_unprotected_subobjects__ = 1
+ ... implements(Interface)
+
+ >>> from zope.component import getMultiAdapter
+ >>> context = Bar()
+ >>> request = make_request()
+
+Now, let's emulate the publisher and look up the namespace traversal
+adapter. For example, let's say we'd traversed to
+../@@test-form/++widget++age. The publisher would then do:
+
+ >>> form = getMultiAdapter((context, request), name=u"test-form")
+
+ >>> from zope.traversing.interfaces import ITraversable
+ >>> traverser = getMultiAdapter((form, request), name=u"widget")
+ >>> traverser.traverse('age', [])
+ Updating test form
+ <TextWidget 'form.widgets.age'>
+
+Please note that this point, the form has been updated, but not rendered.
+
+When a form field does not exist a TraversalError is raised.
+
+ >>> traverser = getMultiAdapter((form, request), name=u"widget")
+ >>> traverser.traverse('missing', [])
+ Traceback (most recent call last):
+ ...
+ TraversalError: 'missing'
More information about the checkins
mailing list