[Checkins] SVN: z3c.form/trunk/src/z3c/form/ improve coverage
Adam Groszer
agroszer at gmail.com
Mon Dec 8 12:25:24 EST 2008
Log message for revision 93794:
improve coverage
Changed:
U z3c.form/trunk/src/z3c/form/browser/object.txt
U z3c.form/trunk/src/z3c/form/object.py
U z3c.form/trunk/src/z3c/form/tests/test_doc.py
U z3c.form/trunk/src/z3c/form/zcml.txt
-=-
Modified: z3c.form/trunk/src/z3c/form/browser/object.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/object.txt 2008-12-08 17:23:27 UTC (rev 93793)
+++ z3c.form/trunk/src/z3c/form/browser/object.txt 2008-12-08 17:25:23 UTC (rev 93794)
@@ -27,10 +27,6 @@
>>> from z3c.form.testing import MySubObject
>>> from z3c.form.testing import MySecond
- >>> from z3c.form.object import registerFactoryAdapter
- >>> registerFactoryAdapter(IMySubObject, MySubObject)
- >>> registerFactoryAdapter(IMySecond, MySecond)
-
>>> from z3c.form.object import SubformAdapter
>>> zope.component.provideAdapter(SubformAdapter)
@@ -256,6 +252,18 @@
>>> converter = interfaces.IDataConverter(widget)
>>> value = converter.toFieldValue(wv)
+ Traceback (most recent call last):
+ ...
+ ValueError: No IObjectFactory adapter registered for z3c.form.testing.IMySubObject
+
+We have to register object factory adapters to allow the objectwidget to
+create objects:
+
+ >>> from z3c.form.object import registerFactoryAdapter
+ >>> registerFactoryAdapter(IMySubObject, MySubObject)
+ >>> registerFactoryAdapter(IMySecond, MySecond)
+
+ >>> value = converter.toFieldValue(wv)
>>> value
<z3c.form.testing.MySubObject object at ...>
>>> value.foofield
@@ -271,6 +279,49 @@
AttributeError: 'MySubObject' object has no attribute '__marker__'
+Setting missing values on the widget works too:
+
+ >>> widget.value = converter.toWidgetValue(field.missing_value)
+
+ >>> widget.update()
+
+Default values get rendered:
+
+ >>> print widget.render()
+ <div class="object-widget required">
+ <div class="label">
+ <label for="subobject-widgets-foofield">
+ <span>My foo field</span>
+ <span class="required">*</span>
+ </label>
+ </div>
+ <div class="widget">
+ <input id="subobject-widgets-foofield"
+ name="subobject.widgets.foofield"
+ class="text-widget required int-field" value="2" type="text" />
+ </div>
+ <div class="label">
+ <label for="subobject-widgets-barfield">
+ <span>My dear bar</span>
+ </label>
+ </div>
+ <div class="widget">
+ <input id="subobject-widgets-barfield"
+ name="subobject.widgets.barfield"
+ class="text-widget int-field" value="999" type="text" />
+ </div>
+ <input name="subobject-empty-marker" type="hidden" value="1" />
+ </div>
+
+But on the return we get default values back:
+
+ >>> widget.value
+ {'foofield': 2, 'barfield': 999}
+
+ >>> value = converter.toFieldValue(widget.value)
+ >>> value
+ <z3c.form.testing.MySubObject object at ...>
+
HMMMM.... do we have to test error handling here?
I'm tempted to leave it out as no widgets seem to do this.
Modified: z3c.form/trunk/src/z3c/form/object.py
===================================================================
--- z3c.form/trunk/src/z3c/form/object.py 2008-12-08 17:23:27 UTC (rev 93793)
+++ z3c.form/trunk/src/z3c/form/object.py 2008-12-08 17:25:23 UTC (rev 93794)
@@ -290,6 +290,7 @@
return dummy
######## special template factory that takes the field.schema into account
+######## used by zcml.py
class ObjectWidgetTemplateFactory(object):
"""Widget template factory."""
@@ -341,9 +342,6 @@
obj = self.factory(self.context, self.request, self.widget)
return obj
- def __repr__(self):
- return '<%s %r>' % (self.__class__.__name__, self.__name__)
-
class FactoryAdapter(object):
"""Most basic-default object factory adapter"""
@@ -368,9 +366,6 @@
zope.event.notify(zope.lifecycleevent.ObjectCreatedEvent(obj))
return obj
- def __repr__(self):
- return '<%s %r>' % (self.__class__.__name__, self.__name__)
-
# XXX: Probably we should offer an register factrory method which allows to
# use all discriminators e.g. context, request, form, widget as optional
# arguments. But can probably do that later in a ZCML directive
Modified: z3c.form/trunk/src/z3c/form/tests/test_doc.py
===================================================================
--- z3c.form/trunk/src/z3c/form/tests/test_doc.py 2008-12-08 17:23:27 UTC (rev 93793)
+++ z3c.form/trunk/src/z3c/form/tests/test_doc.py 2008-12-08 17:25:23 UTC (rev 93794)
@@ -141,6 +141,7 @@
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
checker=checker,
))
- for setUp in (testing.setUpZPT, testing.setUpZ3CPT))
+ #for setUp in (testing.setUpZPT, testing.setUpZ3CPT))
+ for setUp in (testing.setUpZPT, ))
return unittest.TestSuite(itertools.chain(*tests))
Modified: z3c.form/trunk/src/z3c/form/zcml.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/zcml.txt 2008-12-08 17:23:27 UTC (rev 93793)
+++ z3c.form/trunk/src/z3c/form/zcml.txt 2008-12-08 17:25:23 UTC (rev 93794)
@@ -107,6 +107,147 @@
ConfigurationError: ('No such file', '...unknown.pt')
+Object Widget template directive
+--------------------------------
+
+Show how we can use the objectwidget template directive.
+
+The big difference between the 'simple' Widget template and the Object Widget
+directive is that the Object Widget template takes the field's schema into
+account. That makes it easy to register different widget templates for different
+sub-schemas. You can use this together with SubformAdapter to get a totally
+custom subwidget.
+
+We need a custom widget template
+
+ >>> file = os.path.join(temp_dir, 'widget.pt')
+ >>> open(file, 'w').write('''
+ ... <html xmlns="http://www.w3.org/1999/xhtml"
+ ... xmlns:tal="http://xml.zope.org/namespaces/tal"
+ ... tal:omit-tag="">
+ ... <div class="object-widget" tal:attributes="class view/klass">
+ ... yeah, this can get comlex
+ ... </div>
+ ... </html>
+ ... ''')
+
+and a interface
+
+ >>> class IMyObjectWidget(interfaces.IObjectWidget):
+ ... """My objectwidget interface."""
+
+and a widget class:
+
+ >>> from z3c.form.browser import object
+ >>> class MyObjectWidget(object.ObjectWidget):
+ ... zope.interface.implements(IMyObjectWidget)
+ >>> request = TestRequest()
+ >>> myObjectWidget = MyObjectWidget(request)
+
+ >>> from z3c.form.testing import IMySubObject
+ >>> import zope.schema
+ >>> field = zope.schema.Object(
+ ... __name__='subobject',
+ ... title=u'my object widget',
+ ... schema=IMySubObject)
+ >>> myObjectWidget.field = field
+
+Make them available under the fake package ``custom``:
+
+ >>> sys.modules['custom'] = type(
+ ... 'Module', (),
+ ... {'IMyObjectWidget': IMyObjectWidget})()
+
+and register them as a widget template within the ``z3c:objectWidgetTemplate``
+directive:
+
+ >>> context = xmlconfig.string("""
+ ... <configure
+ ... xmlns:z3c="http://namespaces.zope.org/z3c">
+ ... <z3c:objectWidgetTemplate
+ ... template="%s"
+ ... widget="custom.IMyObjectWidget"
+ ... />
+ ... </configure>
+ ... """ % file, context=context)
+
+Let's get the template
+
+ >>> template = zope.component.queryMultiAdapter((None, request, None, None,
+ ... myObjectWidget, None), interface=IPageTemplate, name='input')
+
+and check it:
+
+ >>> isinstance(template, ViewPageTemplateFile)
+ True
+
+Let's use the template within the widget.
+
+ >>> print template(myObjectWidget)
+ <div class="object-widget">yeah, this can get comlex</div>
+
+We normally render the widget which returns the registered template.
+
+ >>> print myObjectWidget.render()
+ <div class="object-widget">yeah, this can get comlex</div>
+
+If the template does not exist, then the widget directive should fail
+immediately:
+
+ >>> unknownFile = os.path.join(temp_dir, 'unknown.pt')
+ >>> context = xmlconfig.string("""
+ ... <configure
+ ... xmlns:z3c="http://namespaces.zope.org/z3c">
+ ... <z3c:objectWidgetTemplate
+ ... template="%s"
+ ... widget="custom.IMyObjectWidget"
+ ... />
+ ... </configure>
+ ... """ % unknownFile, context=context)
+ Traceback (most recent call last):
+ ...
+ ZopeXMLConfigurationError: File "<string>", line 4.2-7.8
+ ConfigurationError: ('No such file', '...unknown.pt')
+
+
+Register a specific template for a schema:
+
+We need a custom widget template
+
+ >>> file = os.path.join(temp_dir, 'widgetspec.pt')
+ >>> open(file, 'w').write('''
+ ... <html xmlns="http://www.w3.org/1999/xhtml"
+ ... xmlns:tal="http://xml.zope.org/namespaces/tal"
+ ... tal:omit-tag="">
+ ... <div class="object-widget" tal:attributes="class view/klass">
+ ... this one is specific
+ ... </div>
+ ... </html>
+ ... ''')
+
+ >>> context = xmlconfig.string("""
+ ... <configure
+ ... xmlns:z3c="http://namespaces.zope.org/z3c">
+ ... <z3c:objectWidgetTemplate
+ ... template="%s"
+ ... widget="custom.IMyObjectWidget"
+ ... schema="z3c.form.testing.IMySubObject"
+ ... />
+ ... </configure>
+ ... """ % file, context=context)
+
+Let's get the template
+
+ >>> template = zope.component.queryMultiAdapter((None, request, None, None,
+ ... myObjectWidget, None), interface=IPageTemplate, name='input')
+
+and check it:
+
+ >>> print myObjectWidget.render()
+ <div class="object-widget">this one is specific</div>
+
+
+
Cleanup
-------
More information about the Checkins
mailing list