[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