[Zope3-checkins] CVS: Zope3/src/zope/app/form/tests - test_utility.py:1.20 test_widget.py:1.6 test_widget_geddon_deprecations.py:NONE

Garrett Smith garrett at mojave-corp.com
Fri Mar 5 23:17:55 EST 2004


Update of /cvs-repository/Zope3/src/zope/app/form/tests
In directory cvs.zope.org:/tmp/cvs-serv15646/src/zope/app/form/tests

Modified Files:
	test_utility.py test_widget.py 
Removed Files:
	test_widget_geddon_deprecations.py 
Log Message:
Merged changes from garrett-widgets2-branch:

- Changed the way widgets are looked up to use interfaces instead of 
  names.
  
- Refactor of zope/app/form/utility.py -- see 

    http://dev.zope.org/Zope3/WidgetsAndMultiwayAdapters
    
  for details.
  
- Moved configuration of vocab widgets to its own zcml file
  (zope/app/browser/form/vocabularywidget.zcml).

- Removed 'propertyNames' and 'getValue' from widgets. This  is replaced
  by accessing the widget attributes directly.
  
- Deleted depreated methods from widget interface: haveData and getData.


=== Zope3/src/zope/app/form/tests/test_utility.py 1.19 => 1.20 ===
--- Zope3/src/zope/app/form/tests/test_utility.py:1.19	Tue Dec  2 16:30:21 2003
+++ Zope3/src/zope/app/form/tests/test_utility.py	Fri Mar  5 23:17:24 2004
@@ -17,565 +17,895 @@
 
 $Id$
 """
+import doctest
+
+from zope.interface import Interface, implements
 
-from unittest import TestCase, TestSuite, main, makeSuite
 from zope.app.tests import ztapi
-from zope.app.tests.placelesssetup import PlacelessSetup
+
+from zope.component.interfaces import IViewFactory
+from zope.component.exceptions import ComponentLookupError
+
 from zope.publisher.browser import BrowserView
 from zope.publisher.browser import TestRequest
-from zope.interface import Interface, directlyProvides, implements
-from zope.schema import Text, accessors
-from zope.app.browser.form.widget import TextWidget
-from zope.schema.interfaces import IText
-from zope.app.interfaces.form import WidgetsError
-from zope.app.form.utility import setUpWidget, setUpWidgets, setUpEditWidgets
-from zope.app.form.utility import getWidgetsData, getWidgetsDataForContent
-from zope.app.form.utility import viewHasInput
-from zope.schema.interfaces import ValidationError
-from zope.component.interfaces import IViewFactory
 
+from zope.schema import Field
+from zope.schema.interfaces import IField
 
-class I(Interface):
-    title = Text(title=u"Title", required = False)
-    description = Text(title=u"Description",
-                       default = u'No description', required = False)
-    def foo():
-        """Does foo things"""
-
-class I2(Interface):
-    title = Text(title = u"Title", required = True)
-    description = Text(title = u"Description", required = True)
-
-class I3(Interface):
-    title = Text(title = u"Title", required = True)
-    description = Text(title=u"Description", required = False)
-
-class C:
-    implements(I)
-
-class C2:
-    implements(I2)
-
-
-class Ia(Interface):
-    getTitle, setTitle = accessors(Text(title=u"Title", required = False))
-    getDescription, setDescription = accessors(Text(
-        title=u"Description",
-        default = u'No description', required = False)
-                                               )
-
-class Ca:
-    implements(Ia)
-
-    def getTitle(self): return self._t
-    def setTitle(self, v): self._t = v
-    def getDescription(self): return self._d
-    def setDescription(self, v): self._d = v
-
-class ViewWithCustomTitleWidgetFactory(BrowserView):
-
-    def title_widget(self, context, request):
-        w = W(context, request)
-        w.custom = 1
-        return w
-
-    directlyProvides(title_widget, IViewFactory)
-
-def kw(**kw):
-    return kw
-
-class W(TextWidget):
-
-    def setRenderedValue(self, v):
-        self.context.validate(v)
-        self._data = v
-
-    def setPrefix(self, prefix):
-        self.prefix = prefix
-
-    def __call__(self):
-        name = self.name
-        v = self._showData()
-        return unicode(self.context.__name__) + u': ' + (v or '')
-
-    def getInputValue(self):
-        v = self.request.get(self.name, self)
-        if v is self:
-            if self.context.required:
-                raise ValidationError("%s required" % self.name)
-            v = self.context.default
-        return v
-
-    def hasInput(self):
-        if self.name in self.request and self.request[self.name]:
-            return True
-        return False
+from zope.app.form.widget import Widget
 
-class Test(PlacelessSetup, TestCase):
+from zope.app.interfaces.form import IWidget
+from zope.app.interfaces.form import IInputWidget
+from zope.app.interfaces.form import IDisplayWidget
+from zope.app.interfaces.form import WidgetsError
 
-    def setUp(self):
-        super(Test, self).setUp()
-        ztapi.setDefaultViewName(IText, 'edit')
-        ztapi.browserView(IText, 'edit', W)
-
-
-    def test_setUpWidget(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        setUpWidget(view, 'title', I['title'])
-        self.assertEqual(view.title_widget(), u'title: ')
-        self.assertEqual(view.title_widget.getInputValue(), None)
-
-
-    def test_setUpWidget_w_request_data(self):
-        c = C()
-        request = TestRequest()
-        request.form['field.title'] = u'xxx'
-        view = BrowserView(c, request)
-        setUpWidget(view, 'title', I['title'])
-        self.assertEqual(view.title_widget(), u'title: xxx')
-        self.assertEqual(view.title_widget.getInputValue(), u'xxx')
-
-    def test_setUpWidget_w_request_data_and_initial_data(self):
-        c = C()
-        request = TestRequest()
-        request.form['field.title'] = u'xxx'
-        view = BrowserView(c, request)
-        setUpWidget(view, 'title', I['title'], u'yyy')
-        self.assertEqual(view.title_widget(), u'title: xxx')
-        self.assertEqual(view.title_widget.getInputValue(), u'xxx')
-
-    def test_setUpWidget_w_request_data_and_initial_data_force(self):
-        c = C()
-        request = TestRequest()
-        request.form['field.title'] = u'xxx'
-        view = BrowserView(c, request)
-        setUpWidget(view, 'title', I['title'], u'yyy', force=1)
-        self.assertEqual(view.title_widget(), u'title: yyy')
-        self.assertEqual(view.title_widget.getInputValue(), u'xxx')
-
-    def test_setUpWidget_w_initial_data(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        setUpWidget(view, 'title', I['title'], u'yyy')
-        self.assertEqual(view.title_widget(), u'title: yyy')
-        self.assertEqual(view.title_widget.getInputValue(), None)
-
-    def test_setUpWidget_w_bad_initial_data(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        self.assertRaises(ValidationError,
-                          setUpWidget, view, 'title', I['title'], 'yyy')
-
-    def test_setUpWidget_w_custom_widget(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        view.title_widget = w = W(I['title'], request)
-        setUpWidget(view, 'title', I['title'], u'yyy')
-        self.assertEqual(view.title_widget(), u'title: yyy')
-        self.assertEqual(view.title_widget.getInputValue(), None)
-        self.assertEqual(view.title_widget, w)
-
-    def test_setUpWidget_w_Custom_widget(self):
-        c = C()
-        request = TestRequest()
-        view = ViewWithCustomTitleWidgetFactory(c, request)
-        setUpWidget(view, 'title', I['title'], u'yyy')
-        self.assertEqual(view.title_widget(), u'title: yyy')
-        self.assertEqual(view.title_widget.getInputValue(), None)
-        self.assertEqual(view.title_widget.custom, 1)
-
-    def test_setupWidgets(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        setUpWidgets(view, I)
-        self.assertEqual(view.title_widget(), u'title: ')
-        self.assertEqual(view.description_widget(),
-                         u'description: No description')
-
-    def test_setupWidgets_via_names(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        setUpWidgets(view, I, names=['title'])
-        self.assertEqual(view.title_widget(), u'title: ')
-        self.failIf(hasattr(view, 'description'))
-
-    def test_setupWidgets_bad_field_name(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        self.assertRaises(KeyError, setUpWidgets, view, I, names=['bar'])
-        #This AttributeError occurs when setUpWidget tries to call
-        #bind on the non-Field (Method) object.  The point is that
-        #that *some* error should occur, not necessarily this specific one.
-        self.assertRaises(AttributeError, setUpWidgets, view, I, names=['foo'])
-
-    def test_setupWidgets_w_prefix(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        setUpWidgets(view, I, prefix='spam')
-        self.assertEqual(view.title_widget.prefix, 'spam')
-        self.assertEqual(view.description_widget.prefix, 'spam')
-
-    def test_setupWidgets_w_initial_data_and_custom_widget(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        view.title_widget = w = W(I['title'], request)
-        setUpWidgets(view, I, initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(view.title_widget(), u'title: ttt')
-        self.assertEqual(view.description_widget(), u'description: ddd')
-        self.assertEqual(view.title_widget, w)
-
-    def test_setupWidgets_w_initial_data_and_request_data(self):
-        c = C()
-        request = TestRequest()
-        request.form['field.title'] = u'yyy'
-        view = BrowserView(c, request)
-        setUpWidgets(view, I, initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(view.title_widget(), u'title: yyy')
-
-    def test_setupWidgets_w_initial_data_forced_and_request_data(self):
-        c = C()
-        request = TestRequest()
-        request.form['field.title'] = u'yyy'
-        view = BrowserView(c, request)
-        setUpWidgets(view, I, force=1,
-                     initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(view.title_widget(), u'title: ttt')
-
-    def test_setupEditWidgets_w_custom_widget(self):
-        c = C()
-        c.title = u'ct'
-        c.description = u'cd'
-        request = TestRequest()
-        view = BrowserView(c, request)
-        view.title_widget = w = W(I['title'], request)
-        setUpEditWidgets(view, I)
-        self.assertEqual(view.title_widget(), u'title: ct')
-        self.assertEqual(view.description_widget(), u'description: cd')
-        self.assertEqual(view.title_widget, w)
-
-    def test_setupEditWidgets_w_form_data(self):
-        c = C()
-        c.title = u'ct'
-        c.description = u'cd'
-        request = TestRequest()
-        request.form['field.title'] = u'ft'
-        request.form['field.description'] = u'fd'
-        view = BrowserView(c, request)
-        setUpEditWidgets(view, I)
-        self.assertEqual(view.title_widget(), u'title: ft')
-        self.assertEqual(view.description_widget(), u'description: fd')
-
-    def test_setupEditWidgets_via_names(self):
-        c = C()
-        c.title = u'ct'
-        request = TestRequest()
-        request.form['field.title'] = u'ft'
-        view = BrowserView(c, request)
-        setUpEditWidgets(view, I, names=['title'])
-        self.assertEqual(view.title_widget(), u'title: ft')
-        self.failIf(hasattr(view, 'description'))
-
-    def test_setupEditWidgets_and_accessors(self):
-        c = Ca()
-        c.setTitle(u'ct')
-        c.setDescription(u'cd')
-        request = TestRequest()
-        view = BrowserView(c, request)
-        setUpEditWidgets(view, Ia)
-        self.assertEqual(view.getTitle_widget(), u'getTitle: ct')
-        self.assertEqual(view.getDescription_widget(), u'getDescription: cd')
-
-    def test_setupWidgets_bad_field_name(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        self.assertRaises(KeyError, setUpEditWidgets, view, I, names=['bar'])
-        #This AttributeError occurs when setUpEditWidget tries to call
-        #bind on the non-Field (Method) object.  The point is that
-        #that *some* error should occur, not necessarily this specific one.
-        self.assertRaises(AttributeError, setUpEditWidgets, view,
-                          I, names=['foo'])
-
-    def test_setupEditWidgets_w_form_data_force(self):
-        c = C()
-        c.title = u'ct'
-        c.description = u'cd'
-        request = TestRequest()
-        request.form['field.title'] = u'ft'
-        request.form['field.description'] = u'ft'
-        view = BrowserView(c, request)
-        setUpEditWidgets(view, I, force=1)
-        self.assertEqual(view.title_widget(), u'title: ct')
-        self.assertEqual(view.description_widget(), u'description: cd')
-
-    def test_setupEditWidgets_w_custom_widget_and_prefix(self):
-        c = C()
-        c.title = u'ct'
-        c.description = u'cd'
-        request = TestRequest()
-        view = BrowserView(c, request)
-        view.title_widget = w = W(I['title'], request)
-        setUpEditWidgets(view, I, prefix='eggs')
-        self.assertEqual(view.title_widget.prefix, 'eggs')
-        self.assertEqual(view.description_widget.prefix, 'eggs')
-        self.assertEqual(view.title_widget, w)
-
-    def test_setupEditWidgets_w_other_data(self):
-        c = C()
-        c2 = C()
-        c2.title = u'ct'
-        c2.description = u'cd'
-        request = TestRequest()
-        view = BrowserView(c, request)
-        setUpEditWidgets(view, I)
-        self.assertEqual(view.title_widget(), u'title: ')
-        self.assertEqual(view.description_widget(),
-                         u'description: No description')
-        setUpEditWidgets(view, I, c2)
-        self.assertEqual(view.title_widget(), u'title: ct')
-        self.assertEqual(view.description_widget(), u'description: cd')
-
-        view = BrowserView(c2, request)
-        setUpEditWidgets(view, I)
-        self.assertEqual(view.title_widget(), u'title: ct')
-        self.assertEqual(view.description_widget(), u'description: cd')
-
-    def test_setupEditWidgets_w_bad_data(self):
-        class Forbidden(AttributeError): pass
-
-        class C(object):
-            title = u'foo'
-
-            def d(self):
-                raise Forbidden()
-
-            description = property(d)
-
-        c = C()
-
-        request = TestRequest()
-        view = BrowserView(c, request)
-        self.assertRaises(Forbidden, setUpEditWidgets, view, I)
-
-    def test_getSetupWidgets_w_form_data(self):
-        c = C()
-        request = TestRequest()
-        request.form['field.title'] = u'ft'
-        view = BrowserView(c, request)
-        setUpWidgets(view, I, initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(view.title_widget(), u'title: ft')
-        self.assertEqual(view.description_widget(), u'description: ddd')
-
-
-    def test_getWidgetsData(self):
-        c = C()
-        request = TestRequest()
-        request.form['field.title'] = u'ft'
-        request.form['field.description'] = u'fd'
-        view = BrowserView(c, request)
-        setUpWidgets(view, I, initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(getWidgetsData(view, I),
-                         {'title': u'ft',
-                          'description': u'fd'})
-
-
-        setUpWidgets(view, I3, initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(getWidgetsData(view, I3),
-                         {'title': u'ft',
-                          'description': u'fd'})
-
-        request.form['field.description'] = ''
-        setUpWidgets(view, I3, initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(getWidgetsData(view, I3),
-                         {'title': u'ft',
-                          'description': None})
-
-        request.form['field.description'] = u''
-        setUpWidgets(view, I, initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(getWidgetsData(view, I),
-                         {'title': u'ft',
-                          'description': None})
-
-    def test_getWidgetsData_w_names(self):
-        c = C()
-        request = TestRequest()
-        request.form['field.title'] = u'ft'
-        request.form['field.description'] = u'fd'
-        view = BrowserView(c, request)
-        setUpWidgets(view, I, initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(getWidgetsData(view, I, names=['title']),
-                         {'title': u'ft'})
-        self.assertRaises(KeyError, getWidgetsData, view, I, names=['bar'])
-        self.assertRaises(AttributeError, getWidgetsData, view, I,
-                          names=['foo'])
-
-    def test_getWidgetsData_w_readonly_fields(self):
-        class ITest(I):
-            name = Text(title=u"Title", readonly=True)
-
-        c = C()
-        request = TestRequest()
-        request.form['field.name'] = u'foo'
-        request.form['field.title'] = u'ft'
-        request.form['field.description'] = u'fd'
-        view = BrowserView(c, request)
-        setUpWidgets(view, ITest, initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(getWidgetsData(view, ITest, names=['name', 'title']),
-                         {'title': u'ft', 'name': 'foo'})
-
-    def test_getWidgetsData_w_readonly_fields_but_exclude_anyway(self):
-        class ITest(I):
-            name = Text(title=u"Title", readonly=True)
-
-        c = C()
-        request = TestRequest()
-        request.form['field.name'] = u'foo'
-        request.form['field.title'] = u'ft'
-        request.form['field.description'] = u'fd'
-        view = BrowserView(c, request)
-        setUpWidgets(view, ITest, initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(
-            getWidgetsData(view, ITest, names=['name', 'title'],
-                           exclude_readonly=True),
-            {'title': u'ft'})
+from zope.app.form.utility import no_value
+from zope.app.form.utility import setUpWidget
+from zope.app.form.utility import setUpWidgets
+from zope.app.form.utility import setUpEditWidgets
+from zope.app.form.utility import setUpDisplayWidgets
+from zope.app.form.utility import getWidgetsData
+from zope.app.form.utility import viewHasInput
+from zope.app.form.utility import applyWidgetsChanges
 
-    def test_viewHasInput(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        setUpWidgets(view, I, initial=kw(title=u"ttt", description=u"ddd"))
-        self.failIf(viewHasInput(view, I))
-
-        request.form['field.description'] = u'fd'
-        self.failUnless(viewHasInput(view, I))
-
-    def test_viewHasInput_w_names(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        setUpWidgets(view, I, initial=kw(title=u"ttt", description=u"ddd"))
-        self.failIf(viewHasInput(view, I))
-
-        request.form['field.description'] = u'fd'
-        self.failUnless(viewHasInput(view, I))
-        self.failIf(viewHasInput(view, I, names=['title']))
-        self.assertRaises(KeyError, viewHasInput, view, I, names=['bar'])
-        self.assertRaises(AttributeError, viewHasInput, view, I,
-                          names=['foo'])
-
-    def test_getWidgetsData_w_default(self):
-        c = C()
-        request = TestRequest()
-        view = BrowserView(c, request)
-        setUpWidgets(view, I, initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(
-            getWidgetsData(view, I, strict=False, set_missing=False),
-            {})
-
-        self.assertEqual(
-            getWidgetsData(view, I, strict=False, set_missing=True),
-            {'description': None,  'title': None})
-
-        # XXX check that the WidgetsError contains a MissingInputError
-        self.assertRaises(WidgetsError,
-                          getWidgetsData, view, I2, strict=True)
-
-        self.assertEqual(getWidgetsData(view, I),
-                         {'description': None, 'title': None})
-
-        request.form['field.description'] = u'fd'
-        self.assertEqual(getWidgetsData(view, I2, strict=False,
-                                        set_missing=False),
-                         {'description': u'fd'})
-
-        self.assertEqual(getWidgetsData(view, I2, strict=False,
-                                        set_missing=True),
-                         {'description': u'fd', 'title': None})
-
-        # XXX check that the WidgetsError contains a MissingInputError
-        self.assertRaises(WidgetsError, getWidgetsData, view, I2)
-        self.assertEqual(getWidgetsData(view, I), {'description': u'fd',
-                                                   'title': None})
-
-    def test_getWidgetsDataForContent(self):
-        c = C()
-        request = TestRequest()
-        request.form['field.title'] = u'ft'
-        request.form['field.description'] = u'fd'
-        view = BrowserView(c, request)
-        setUpWidgets(view, I, initial=kw(title=u"ttt", description=u"ddd"))
-        getWidgetsDataForContent(view, I)
-
-        self.assertEqual(c.title, u'ft')
-        self.assertEqual(c.description, u'fd')
-
-        c2 = C()
-        request.form['field.title'] = u'ftt'
-        request.form['field.description'] = u'fdd'
-        getWidgetsDataForContent(view, I, c2)
-
-        self.assertEqual(c.title, u'ft')
-        self.assertEqual(c.description, u'fd')
-
-        self.assertEqual(c2.title, u'ftt')
-        self.assertEqual(c2.description, u'fdd')
-
-    def test_getWidgetsDataForContent_accessors(self):
-        c = Ca()
-        request = TestRequest()
-        request.form['field.getTitle'] = u'ft'
-        request.form['field.getDescription'] = u'fd'
-        view = BrowserView(c, request)
-        setUpWidgets(view, Ia, initial=kw(title=u"ttt", description=u"ddd"))
-        getWidgetsDataForContent(view, Ia)
-
-        self.assertEqual(c.getTitle(), u'ft')
-        self.assertEqual(c.getDescription(), u'fd')
-
-        c2 = Ca()
-        request.form['field.getTitle'] = u'ftt'
-        request.form['field.getDescription'] = u'fdd'
-        getWidgetsDataForContent(view, Ia, c2)
-
-        self.assertEqual(c.getTitle(), u'ft')
-        self.assertEqual(c.getDescription(), u'fd')
-
-        self.assertEqual(c2.getTitle(), u'ftt')
-        self.assertEqual(c2.getDescription(), u'fdd')
-
-    def testErrors(self):
-        c = C2()
-        c.title = u'old title'
-        c.description = u'old description'
-        request = TestRequest()
-        request.form['field.title'] = u'ft'
-        view = BrowserView(c, request)
-        setUpWidgets(view, I2, initial=kw(title=u"ttt", description=u"ddd"))
-        getWidgetsDataForContent(view, I2, names=("title",))
-        self.assertEqual(c.title, u'ft')
-        self.assertEqual(c.description, u'old description')
-
-        request = TestRequest()
-        c.title = u'old title'
-        view = BrowserView(c, request)
-        setUpWidgets(view, I2, initial=kw(title=u"ttt", description=u"ddd"))
-        self.assertEqual(c.title, u'old title')
-        self.assertEqual(c.description, u'old description')
+from zope.app.tests import placelesssetup
 
+request = TestRequest()
+
+class IFoo(IField):
+    pass
+    
+class Foo(Field):
+    implements(IFoo)
+    
+class IBar(IField):
+    pass
+    
+class Bar(Field):
+    implements(IBar)
+    
+class IContent(Interface):
+    foo = Foo()
+    bar = Bar()
+    
+class Content:
+    implements(IContent)
+    foo = 'Foo'
+    
+class IFooWidget(IWidget):
+    pass
+    
+class IBarWidget(IWidget):
+    pass
+
+class FooWidget(Widget):
+    implements(IFooWidget)
+    def getPrefix(self): return self._prefix  # exposes _prefix for testing
+    def getRenderedValue(self): return self._data # exposes _data for testing
+    def renderedValueSet(self): return self._renderedValueSet() # for testing
+    
+class BarWidget(Widget):
+    implements(IBarWidget)
+    def getRenderedValue(self): return self._data # exposes _data for testing
+    def renderedValueSet(self): return self._renderedValueSet() # for testing
+        
+def setUp():
+    """Setup for tests."""
+    placelesssetup.setUp()
+    ztapi.browserView(IFoo, '', FooWidget, providing=IFooWidget)
+    ztapi.browserView(IBar, '', BarWidget, providing=IBarWidget)
+    
+def tearDown():
+    placelesssetup.tearDown()
+    
+def assertRaises(exceptionType, callable, *args):
+    try:
+        callable(*args)
+        return False
+    except Exception, e:
+        return isinstance(e, exceptionType)
+       
+class TestSetUpWidget:
+    
+    def test_typical(self):
+        """Documents and tests the typical uses of setUpWidget.
+        
+        >>> setUp()
+          
+        setUpWidget ensures that the appropriate widget exists as an
+        attribute of a view. There are four required arguments to the
+        function:
+        
+            >>> view = BrowserView(Content(), request)
+            >>> name = 'foo'
+            >>> field = IContent['foo']
+            >>> typeView = IFooWidget
+            
+        setUpWidget will add the appropriate widget as attribute to view
+        named 'foo_widget'.
+        
+            >>> hasattr(view, 'foo_widget')
+            False
+            >>> setUpWidget(view, name, field, typeView)
+            >>> hasattr(view, 'foo_widget')
+            True
+            >>> IFooWidget.providedBy(view.foo_widget)
+            True
+            
+        If the view already has an attribute with that name, it attempts to
+        use the existing value to create a widget. Two types are supported:
+           
+            - IViewFactory
+            - IWidget
+           
+        If the existing attribute value implements IViewFactory, it is used
+        to create a widget:
+           
+            >>> widget = FooWidget(IContent['foo'], request)
+            >>> class Factory:
+            ...     implements(IViewFactory)
+            ...     def __call__(self, request, context):
+            ...         return widget
+            >>> setattr(view, 'foo_widget', Factory())
+            >>> view.foo_widget is widget
+            False
+            >>> setUpWidget(view, name, field, typeView)
+            >>> view.foo_widget is widget
+            True
+            
+        If the existing attribute value implements IWidget, it is used without
+        modification:
+           
+            >>> setattr(view, 'foo_widget', widget)
+            >>> IWidget.providedBy(widget)
+            True
+            >>> setUpWidget(view, name, field, typeView)
+            >>> view.foo_widget is widget
+            True
+
+        >>> tearDown()
+        """
+        
+    def test_validation(self):
+        """Documents and tests validation performed by setUpWidget.
+        
+        >>> setUp()
+            
+        setUpWidget ensures that the the view has an attribute that implements
+        IWidget. If setUpWidget cannot configure a widget, it raises a
+        TypeError. 
+        
+        E.g., if a view already has a widget attribute of the name 
+        <field_name> + '_widget' that does not implement IViewFactory or
+        IWidget, setUpWidget raises a TypeError: 
+        
+            >>> view = BrowserView(Content(), request)
+            >>> setattr(view, 'foo_widget', 'not a widget')
+            >>> assertRaises(TypeError, setUpWidget,
+            ...              view, 'foo', IContent['foo'], IFooWidget)
+            True
+            
+        Similarly, if a view has a widget attribute that implements 
+        IViewFactory, the object created by the factory must implement IWidget.
+        
+            >>> class Factory:
+            ...     implements(IViewFactory)
+            ...     def __call__(self, request, context):
+            ...         return 'not a widget'
+            >>> setattr(view, 'foo_widget', Factory())
+            >>> assertRaises(TypeError, setUpWidget,
+            ...              view, 'foo', IContent['foo'], IFooWidget)
+            True
+            
+        >>> tearDown()
+        """
+        
+    def test_context(self):
+        """Documents and tests the role of context in setUpWidget.
+        
+        >>> setUp()
+        
+        setUpWidget configures a widget by associating it to a bound field,
+        which is a copy of a schema field that is bound to an object. The
+        object the field is bound to can be explicitly specified in the
+        setUpWidget 'context' argument.
+        
+        By default, the context used by setUpWidget is the view context:
+            
+            >>> context = Content()
+            >>> view = BrowserView(context, request)
+            >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget)
+            >>> view.foo_widget.context.context is context
+            True
+            
+        Alternatively, you can specify a context explicitly:
+            
+            >>> view = BrowserView(context, request)
+            >>> altContext = Content()
+            >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget,
+            ...             context=altContext)
+            >>> view.foo_widget.context.context is context
+            False
+            >>> view.foo_widget.context.context is altContext
+            True
+                    
+        >>> tearDown()
+        """
+        
+    def test_widgetLookup(self):
+        """Documents and tests how widgets are looked up by type.
+        
+        >>> setUp()
+        
+        If the view does not already have a widget configured for the
+        specified field name, setUpWidget will look up a widget using
+        an interface specified for the widgetType argument.
+        
+        Widgets are typically looked up for IInputWidget and IDisplayWidget
+        types. To illustrate this, we'll create two widgets, one for editing
+        and another for displaying IFoo attributes. Each widget is registered
+        as a view providing the appropriate widget type.
+        
+            >>> class EditFooWidget(Widget):
+            ...     implements(IInputWidget)
+            ...     def hasInput(self):
+            ...         return False
+            >>> ztapi.browserViewProviding(IFoo, EditFooWidget, IInputWidget)
+            >>> class DisplayFooWidget(Widget):
+            ...     implements(IDisplayWidget)            
+            >>> ztapi.browserViewProviding(IFoo, DisplayFooWidget, 
+            ...                            IDisplayWidget)
+            
+        A call to setUpWidget will lookup the widgets based on the specified 
+        type.
+            
+            >>> view = BrowserView(Content(), request)
+            >>> setUpWidget(view, 'foo', IContent['foo'], IInputWidget)
+            >>> IInputWidget.providedBy(view.foo_widget)
+            True
+            >>> delattr(view, 'foo_widget')
+            >>> setUpWidget(view, 'foo', IContent['foo'], IDisplayWidget)
+            >>> IDisplayWidget.providedBy(view.foo_widget)
+            True
+            
+        A ComponentError is raised if a widget is not registered for the
+        specified type:
+            
+            >>> class IUnregisteredWidget(IWidget):
+            ...     pass
+            >>> delattr(view, 'foo_widget')
+            >>> assertRaises(ComponentLookupError, setUpWidget,
+            ...              view, 'foo', IContent['foo'], IUnregisteredWidget)
+            True
+
+        >>> tearDown()
+        """
+        
+    def test_prefix(self):
+        """Documents and tests the specification of widget prefixes.
+        
+        >>> setUp()
+        
+        Widgets support a prefix that can be used to group related widgets
+        on a view. To specify the prefix for a widget, specify in the call to
+        setUpWidget:
+            
+            >>> view = BrowserView(Content(), request)
+            >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget,
+            ...             prefix='mygroup')
+            >>> view.foo_widget.getPrefix()
+            'mygroup.'
+        
+        >>> tearDown()
+        """
+        
+    def test_value(self):
+        """Documents and tests values and setUpWidget.
+        
+        >>> setUp()
+        
+        setUpWidget configures the widget with the value specified in the
+        'value' argument:
+            
+            >>> view = BrowserView(Content(), request)
+            >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget, 
+            ...             value='Explicit Widget Value')
+            >>> view.foo_widget.renderedValueSet()
+            True
+            >>> view.foo_widget.getRenderedValue()
+            'Explicit Widget Value'
+            
+        The utility module provides a marker object 'no_value' that can be
+        used as setUpWidget's 'value' argument to indicate that a value 
+        doesn't exist for the bound field. This may seem a bit unusual since
+        None is typically used for this purpose. However, None is a valid
+        value for many fields and does not indicate 'no value'.
+        
+        When no_value is specified in a call to setUpWidget, the effected
+        widget is not configured with a value:
+        
+            >>> delattr(view, 'foo_widget')
+            >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget,
+            ...             value=no_value)
+            >>> view.foo_widget.renderedValueSet()
+            False
+            
+        This is the also default behavior when the value argument is omitted:
+            
+            >>> delattr(view, 'foo_widget')
+            >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget)
+            >>> view.foo_widget.renderedValueSet()
+            False
+            
+        Note that when None is specified for 'value', the widget is configured
+        with None:
+            
+            >>> delattr(view, 'foo_widget')
+            >>> setUpWidget(view, 'foo', IContent['foo'], IFooWidget,
+            ...             value=None)
+            >>> view.foo_widget.renderedValueSet()
+            True
+            >>> view.foo_widget.getRenderedValue() is None
+            True
+            
+        >>> tearDown()
+        """
+        
+    def test_stickyValues(self):
+        """Documents and tests setUpWidget's handling of sticky values.
+        
+        >>> setUp()
+        
+        setUpWidget supports the concept of 'sticky values'. A sticky value
+        is a value displayed by a widget that should persist across multiple
+        across multiple object edit sessions. Sticky values ensure that invalid
+        user is available for the user to modify rather than being replaced 
+        by some other value.
+        
+        setUpWidget inferst that a widget has a sticky value if:
+            
+            - The widget implements IInputWidget
+            - The widget returns True for its hasInput method
+            
+        To illustrate, we'll create and register an edit widget for foo that 
+        has input:
+            
+            >>> class EditFooWidget(Widget):
+            ...     implements(IInputWidget)
+            ...     _data = "Original Value"
+            ...     def hasInput(self): return True
+            ...     def getRenderedValue(self): return self._data
+            >>> ztapi.browserView(IFoo, '', EditFooWidget, 
+            ...                   providing=IInputWidget)
+            
+        Specifying a value to setUpWidget would typically cause that value
+        to be set for the widget:
+        
+            >>> view = BrowserView(Content(), request)
+            >>> setUpWidget(view, 'foo', IContent['foo'], IInputWidget,
+            ...     value="A New Value")
+            
+        However, because EditFooWidget has input (i.e. has a 'sticky' value), 
+        setUpWidget will not overwrite its value:
+            
+            >>> view.foo_widget._data
+            'Original Value'
+            
+        You can use setUpWidget's 'ignoreStickyValues' argument to override
+        this behavior and force the widget's value to be overwritten with
+        the 'value' argument:
+            
+            >>> delattr(view, 'foo_widget')
+            >>> setUpWidget(view, 'foo', IContent['foo'], IInputWidget,
+            ...             value="A New Value", ignoreStickyValues=True)
+            >>> view.foo_widget.getRenderedValue()
+            'A New Value'
+        
+        >>> tearDown()
+        """
+
+class TestSetUpWidgets:
+    
+    def test_typical(self):
+        """Tests the typical use of setUpWidgets.
+        
+        >>> setUp()
+        
+        The simplest use of setUpWidget configures a view with widgets of a
+        particular type for a schema:
+        
+            >>> view = BrowserView(Content(), request)
+            >>> setUpWidgets(view, IContent, IWidget)
+            
+        The view now has two widgets, one for each field in the specified
+        schema:
+            
+            >>> IWidget.providedBy(view.foo_widget)
+            True
+            >>> IWidget.providedBy(view.bar_widget)
+            True
+            
+        Because we did not provide initial values, the widget values are not
+        configured:
+            
+            >>> view.foo_widget.renderedValueSet()
+            False
+            >>> view.bar_widget.renderedValueSet()
+            False
+            
+        To specify initial values for the widgets, we can use the 'initial'
+        argument:
+            
+            >>> view = BrowserView(Content(), request)
+            >>> initial = {'foo': 'Value of Foo', 'bar': 'Value of Bar'}
+            >>> setUpWidgets(view, IContent, IWidget, initial=initial)
+            >>> view.foo_widget.getRenderedValue()
+            'Value of Foo'
+            >>> view.bar_widget.getRenderedValue()
+            'Value of Bar'
+        
+        >>> tearDown()
+        """        
+        
+    def test_names(self):
+        """Documents and tests the use of names in setUpWidgets.
+        
+        >>> setUp()
+        
+        The names argument can be used to configure a specific set of widgets
+        for a view:
+            
+            >>> view = BrowserView(Content(), request)
+            >>> IContent.names()
+            ['foo', 'bar']
+            >>> setUpWidgets(view, IContent, IWidget, names=('bar',))
+            >>> hasattr(view, 'foo_widget')
+            False
+            >>> hasattr(view, 'bar_widget')
+            True
+        
+        >>> tearDown()
+        """
+        
+    def test_delegation(self):
+        """Tests setUpWidgets' use of setUpWidget.
+        
+        >>> setUp()
+        
+        setUpWidgets delegates several of its arguments to multiple calls to
+        setUpWidget - one call for each widget being configured. The arguments
+        passed directly through to calls to setUpWidget are:
+            
+            view
+            viewType
+            prefix
+            ignoreStickyValues
+            context
+
+        To illustrate this, we'll replace setUpWidget in the utility module 
+        and capture arguments passed to it when setUpWidgets is called.
+        
+            >>> def setUpWidget(view, name, field, viewType, value=None, 
+            ...                 prefix=None, ignoreStickyValues=False, 
+            ...                 context=None):
+            ...     print "view: %s" % view.__class__
+            ...     print "name: %s" % name
+            ...     print "field: %s" % field.__class__
+            ...     print "viewType: %s" % viewType.__class__
+            ...     if value is no_value:
+            ...         print "value: not specified"
+            ...     else:
+            ...         print "value: %s" % value
+            ...     print "prefix %s" % prefix
+            ...     print "ignoreStickyValues: %s" % ignoreStickyValues
+            ...     print "context: %s" % context
+            ...     print '---'
+            >>> import zope.app.form.utility
+            >>> setUpWidgetsSave = zope.app.form.utility.setUpWidget
+            >>> zope.app.form.utility.setUpWidget = setUpWidget
+            
+        When we call setUpWidgets, we should see that setUpWidget is called 
+        for each field in the specified schema:
+            
+            >>> view = BrowserView(Content(), request)
+            >>> setUpWidgets(view, IContent, IWidget, 'prefix', True,
+            ...              initial={ "bar":"Bar" },
+            ...              context="Alt Context")
+            view: <class 'zope.publisher.browser.BrowserView'>
+            name: foo
+            field: <class 'zope.app.form.tests.test_utility.Foo'>
+            viewType: <class 'zope.interface.interface.InterfaceClass'>
+            value: not specified
+            prefix prefix
+            ignoreStickyValues: True
+            context: Alt Context
+            ---
+            view: <class 'zope.publisher.browser.BrowserView'>
+            name: bar
+            field: <class 'zope.app.form.tests.test_utility.Bar'>
+            viewType: <class 'zope.interface.interface.InterfaceClass'>
+            value: Bar
+            prefix prefix
+            ignoreStickyValues: True
+            context: Alt Context
+            ---
+            >>> zope.app.form.utility.setUpWidget = setUpWidgetsSave
+     
+        >>> tearDown()
+        """
+        
+class TestFormSetUp:
+    
+    def test_setUpEditWidgets(self):
+        """Documents and tests setUpEditWidgets.
+        
+        >>> setUp()
+        
+        setUpEditWidgets configures a view to collect field values from a
+        user. The function looks up widgets of type IInputWidget for the 
+        specified schema.
+        
+        We'll first create and register widgets for the schema fields for
+        which we want input:
+            
+            >>> class InputWidget(Widget):
+            ...     implements(IInputWidget)
+            ...     def hasInput(self):
+            ...         return False
+            ...     def getRenderedValue(self): return self._data
+            >>> ztapi.browserViewProviding(IFoo, InputWidget, IInputWidget)
+            >>> ztapi.browserViewProviding(IBar, InputWidget, IInputWidget)
+
+        Next we'll configure a view with a context object:
+            
+            >>> context = Content()
+            >>> context.foo = 'abc'
+            >>> context.bar = 'def'
+            >>> view = BrowserView(context, request)
+            
+        A call to setUpEditWidgets with the view:
+            
+            >>> setUpEditWidgets(view, IContent)
+            
+        configures the view with widgets that accept input for the context 
+        field values:
+            
+            >>> isinstance(view.foo_widget, InputWidget)
+            True
+            >>> view.foo_widget.getRenderedValue()
+            'abc'
+            >>> isinstance(view.bar_widget, InputWidget)
+            True
+            >>> view.bar_widget.getRenderedValue()
+            'def'
+            
+        setUpEditWidgets provides a 'source' argument that provides an
+        alternate source of values to be edited:
+            
+            >>> view = BrowserView(context, request)
+            >>> source = Content()
+            >>> source.foo = 'abc2'
+            >>> source.bar = 'def2'
+            >>> setUpEditWidgets(view, IContent, source=source)
+            >>> view.foo_widget.getRenderedValue()
+            'abc2'
+            >>> view.bar_widget.getRenderedValue()
+            'def2'
+            
+        If a field is read only, setUpEditWidgets will use a display widget
+        (IDisplayWidget) intead of an input widget to display the field value.
+        
+            >>> class DisplayWidget(Widget):
+            ...     implements(IDisplayWidget)
+            >>> ztapi.browserViewProviding(IFoo, DisplayWidget, IDisplayWidget)
+            >>> save = IContent['foo'].readonly  # save readonly value
+            >>> IContent['foo'].readonly = True
+            >>> delattr(view, 'foo_widget')
+            >>> setUpEditWidgets(view, IContent)
+            >>> isinstance(view.foo_widget, DisplayWidget)
+            True
+            >>> IContent['foo'].readonly = save  # restore readonly value
+        
+        >>> tearDown()
+        """
+        
+    def test_setUpDisplayWidgets(self):
+        """Documents and tests setUpDisplayWidgets.
+        
+        >>> setUp()
+        
+        setUpDisplayWidgets configures a view for use as a display only form.
+        The function looks up widgets of type IDisplayWidget for the specified
+        schema.
+        
+        We'll first create and register widgets for the schame fields
+        we want to edit:
+            
+            >>> class DisplayWidget(Widget):
+            ...     implements(IDisplayWidget)
+            ...     def getRenderedValue(self): return self._data
+            >>> ztapi.browserViewProviding(IFoo, DisplayWidget, IDisplayWidget)
+            >>> ztapi.browserViewProviding(IBar, DisplayWidget, IDisplayWidget)
+
+        Next we'll configure a view with a context object:
+            
+            >>> context = Content()
+            >>> context.foo = 'abc'
+            >>> context.bar = 'def'
+            >>> view = BrowserView(context, request)
+            
+        A call to setUpEditWidgets with the view:
+            
+            >>> setUpDisplayWidgets(view, IContent)
+            
+        configures the view with widgets that display the context fields:
+            
+            >>> isinstance(view.foo_widget, DisplayWidget)
+            True
+            >>> view.foo_widget.getRenderedValue()
+            'abc'
+            >>> isinstance(view.bar_widget, DisplayWidget)
+            True
+            >>> view.bar_widget.getRenderedValue()
+            'def'
+            
+        Like setUpEditWidgets, setUpDisplayWidgets accepts a 'source'
+        argument that provides an alternate source of values to be edited:
+            
+            >>> view = BrowserView(context, request)
+            >>> source = Content()
+            >>> source.foo = 'abc2'
+            >>> source.bar = 'def2'
+            >>> setUpDisplayWidgets(view, IContent, source=source)
+            >>> view.foo_widget.getRenderedValue()
+            'abc2'
+            >>> view.bar_widget.getRenderedValue()
+            'def2'
+        
+        >>> tearDown()
+        """
+        
+class TestForms:
+    
+    def test_viewHasInput(self):
+        """Tests viewHasInput.
+        
+        >>> setUp()
+        
+        viewHasInput returns True if any of the widgets for a set of fields
+        have user input.
+        
+        This method is typically invoked on a view that has been configured
+        with one setUpEditWidgets.
+        
+            >>> class InputWidget(Widget):
+            ...     implements(IInputWidget)
+            ...     input = None
+            ...     def hasInput(self):
+            ...         return self.input is not None
+            >>> ztapi.browserViewProviding(IFoo, InputWidget, IInputWidget)
+            >>> ztapi.browserViewProviding(IBar, InputWidget, IInputWidget)
+            >>> view = BrowserView(Content(), request)
+            >>> setUpEditWidgets(view, IContent)
+            
+        Because InputWidget is configured to not have input by default, the
+        view does not have input:
+            
+            >>> viewHasInput(view, IContent)
+            False
+            
+        But if we specify input for at least one widget:
+            
+            >>> view.foo_widget.input = 'Some Value'
+            >>> viewHasInput(view, IContent)
+            True
+            
+        >>> tearDown()
+        """
+        
+    def test_applyWidgetsChanges(self):
+        """Documents and tests applyWidgetsChanges.
+        
+        >>> setUp()
+        
+        applyWidgetsChanges updates the view context, or an optional alternate
+        context, with widget values. This is typically called when a form
+        is submitted.
+        
+        We'll first create a simple edit widget that can be used to update
+        an object:
+        
+            >>> class InputWidget(Widget):
+            ...     implements(IInputWidget)           
+            ...     input = None
+            ...     def hasInput(self):
+            ...         return input is not None
+            ...     def applyChanges(self, object):
+            ...         field = self.context
+            ...         field.set(object, self.input)
+            ...         return True
+            >>> ztapi.browserViewProviding(IFoo, InputWidget, IInputWidget)
+            
+        Before calling applyWidgetsUpdate, we need to configure a context and
+        a view with edit widgets:
+            
+            >>> context = Content()
+            >>> view = BrowserView(context, request)
+            >>> setUpEditWidgets(view, IContent, names=('foo',))
+            
+        We now specify new widget input and apply the changes: 
+
+            >>> view.foo_widget.input = 'The quick brown fox...'
+            >>> context.foo
+            'Foo'
+            >>> applyWidgetsChanges(view, IContent, names=('foo',))
+            True
+            >>> context.foo
+            'The quick brown fox...'
+            
+        By default, applyWidgetsChanges applies the new widget values to the
+        view context. Alternatively, we can provide a 'target' argument to
+        be updated:
+            
+            >>> target = Content()
+            >>> target.foo
+            'Foo'
+            >>> applyWidgetsChanges(view, IContent, target=target, 
+            ...                     names=('foo',))
+            True
+            >>> target.foo
+            'The quick brown fox...'
+            
+        applyWidgetsChanges is typically used in conjunction with one of the
+        setUp utility functions. If applyWidgetsChanges is called using a
+        view that was not previously configured with a setUp function, or
+        was not otherwise configured with widgets for each of the applicable
+        fields, an AttributeError will be raised:
+            
+            >>> view = BrowserView(context, request)
+            >>> applyWidgetsChanges(view, IContent, names=('foo',))
+            Traceback (most recent call last):
+            AttributeError: 'BrowserView' object has no attribute 'foo_widget'
+
+        >>> tearDown()
+        """
+        
+class TestGetWidgetsData:
+    
+    def test_typical(self):
+        """Documents and tests the typical use of getWidgetsData.
+        
+        >>> setUp()
+        
+        getWidgetsData retrieves the current values from widgets on a view.
+        For this test, we'll create a simple edit widget and register it
+        for the schema field types:
+            
+            >>> class InputWidget(Widget):
+            ...     implements(IInputWidget)
+            ...     input = None
+            ...     def hasInput(self):
+            ...         return self.input is not None
+            ...     def getInputValue(self):
+            ...         return self.input
+            >>> ztapi.browserViewProviding(IFoo, InputWidget, IInputWidget)
+            >>> ztapi.browserViewProviding(IBar, InputWidget, IInputWidget)
+
+        We use setUpEditWidgets to configure a view with widgets for the
+        IContent schema:
+        
+            >>> view = BrowserView(Content(), request)
+            >>> setUpEditWidgets(view, IContent)
+            
+        The simplest form of getWidgetsData requires a view and a schema:
+            
+            >>> try:
+            ...     result = getWidgetsData(view, IContent)
+            ... except Exception, e:
+            ...     print 'getWidgetsData failed'
+            ...     e
+            getWidgetsData failed
+            MissingInputError: ('foo', u'', 'the field is required')
+            MissingInputError: ('bar', u'', 'the field is required')
+            
+        We see that getWidgetsData raises a MissingInputError if a required
+        field does not have input from a widget.:
+            
+            >>> view.foo_widget.input = 'Input for foo'
+            >>> view.bar_widget.input = 'Input for bar'
+            >>> result = getWidgetsData(view, IContent)
+            
+        The result of getWidgetsData is a map of field names to widget values.
+        
+            >>> keys = result.keys(); keys.sort(); keys
+            ['bar', 'foo']
+            >>> result['foo']
+            'Input for foo'
+            >>> result['bar']
+            'Input for bar'
+            
+        If a field is not required, however:
+            
+            >>> IContent['foo'].required = False
+            
+        we can omit input for its widget:
+            
+            >>> view.foo_widget.input = None
+            >>> result = getWidgetsData(view, IContent)
+            >>> 'foo' in result
+            False
+            
+        Note that when a widget indicates that is does not have input, its
+        results are omitted from getWidgetsData's return value. Users of
+        getWidgetsData should explicitly check for field values before
+        accessing them:
+            
+            >>> for name in IContent:
+            ...     if name in result:
+            ...         print (name, result[name])
+            ('bar', 'Input for bar')
+            
+        You can also specify an optional 'names' argument (a tuple) to 
+        request a subset of the schema fields:
+            
+            >>> result = getWidgetsData(view, IContent, names=('bar',))
+            >>> result.keys()
+            ['bar']
+            
+        >>> tearDown()
+        """
+        
+    def test_widgetsErrorException(self):
+        """Documents and tests WidgetsError.
+        
+        XXX Move this test into zope.app.interfaces.tests.test_form when
+        that module is created.
+        
+        WidgetsError wraps one or more errors, which are specified as a
+        sequence in the 'errors' argument:
+        
+            >>> error = WidgetsError(('foo',))
+            >>> error
+            str: foo
+            
+        WidgetsError also provides a 'widgetsData' attribute, which is a
+        map of valid field values, keyed by field name, that were obtained
+        in the same read operation that generated the errors:
+            
+            >>> error = WidgetsError(('foo',), widgetsData={'bar': 'Bar'})
+            >>> error.widgetsData
+            {'bar': 'Bar'}
+            
+        The most typical use of this error is when reading a set of widget
+        values -- the read operation can generate more than one error, as well
+        as a set of successfully read values:
+            
+            >>> values = {'foo': 'Foo'}
+            >>> errors = []
+            >>> widgetsData = {}
+            >>> for name in ('foo', 'bar'):  # some list of values to read
+            ...     try:
+            ...         widgetsData[name] = values[name]  # read operation
+            ...     except Exception, e:
+            ...         errors.append(e)    # capture all errors
+            >>> if errors:
+            ...     widgetsError = WidgetsError(errors, widgetsData)
+            ...     raise widgetsError
+            Traceback (most recent call last):
+            WidgetsError: KeyError: 'bar'
+            
+        The handler of error can access all of the widget error as well as
+        the widget values read:
+            
+            >>> for error in widgetsError:
+            ...     error.__class__.__name__
+            'KeyError'
+            >>> widgetsError.widgetsData
+            {'foo': 'Foo'}
+        """
+            
 def test_suite():
-    return TestSuite((
-        makeSuite(Test),
-        ))
+    return doctest.DocTestSuite()
 
 if __name__=='__main__':
     main(defaultTest='test_suite')


=== Zope3/src/zope/app/form/tests/test_widget.py 1.5 => 1.6 ===
--- Zope3/src/zope/app/form/tests/test_widget.py:1.5	Fri Jan 16 08:09:07 2004
+++ Zope3/src/zope/app/form/tests/test_widget.py	Fri Mar  5 23:17:24 2004
@@ -18,70 +18,83 @@
 $Id$
 """
 
-from unittest import TestCase, TestSuite, main, makeSuite
+import doctest
+from unittest import TestSuite, main, makeSuite
 from zope.app.form.widget import Widget, CustomWidgetFactory
 from zope.app.interfaces.form import IWidget
-from zope.interface.verify import verifyObject
+from zope.interface.verify import verifyClass, verifyObject
 from zope.schema import Text
 from zope.publisher.browser import TestRequest
 from zope.component.interfaces import IViewFactory
 
-class TestWidget(TestCase):
-
-    def test_name(self):
-        w = Widget(Text(__name__='foo', title=u'Foo title'), TestRequest())
-        self.assertEqual(w.name, 'field.foo')
-
-    def test_setPrefix(self):
-        w = Widget(Text(__name__='foo', title=u'Foo title'), TestRequest())
-        w.setPrefix('test')
-        self.assertEqual(w.name, 'test.foo')
-
-    def test_title(self):
-        from zope.app.tests.placelesssetup import setUp, tearDown
-        setUp()
-        w = Widget(Text(__name__='foo', title=u'Foo title'), TestRequest())
-        self.assertEqual(w.title, 'Foo title')
-        tearDown()
-
-    def test_description(self):
-        from zope.app.tests.placelesssetup import setUp, tearDown
-        setUp()
-        w = Widget(Text(__name__='foo', description=u'Foo desc'),
-                   TestRequest())
-        self.assertEqual(w.description, 'Foo desc')
-        tearDown()
-
-    def test_IWidget(self):
-        from zope.app.tests.placelesssetup import setUp, tearDown
-        setUp()
-        w = Widget(Text(__name__='foo', title=u'Foo title'), TestRequest())
-        verifyObject(IWidget, w)
-        tearDown()
-
-    # XXX Don't test getValue. It's silly and will go away.
-
-class TestCustomWidgetFactory(TestCase):
-
-    # XXX this test should be rewritten once we've refactored widget properties
-
-    def test(self):
-        from zope.app.tests.placelesssetup import setUp, tearDown
-        setUp()
-        cw = CustomWidgetFactory(Widget, width=60)
-        verifyObject(IViewFactory, cw)
-        w = cw(Text(__name__='foo', title=u'Foo title'), TestRequest())
-        self.assertEqual(w.name, 'field.foo')
-        self.assertEqual(w.width, 60)
-        verifyObject(IWidget, w)
-        tearDown()
-
-
+class TestContext:
+    __name__ = 'Test'
+    title = 'My Test Context'
+    description = 'A test context.'
+
+class FooWidget(Widget):
+    pass
+    
+context = TestContext()
+request = TestRequest()
+
+class TestWidget:
+    """Tests basic widget characteristics.
+    
+    Widget implements IWidget:
+
+        >>> verifyClass(IWidget, Widget)
+        True
+        >>> widget = Widget(context, request)
+        >>> verifyObject(IWidget, widget)
+        True
+        
+    The default values for widget are:
+        
+        >>> widget.name
+        'field.Test'
+        >>> widget.title
+        'My Test Context'
+        >>> widget.description
+        'A test context.'
+        >>> widget.visible
+        True
+        
+    In the last example, the widget name consists of a prefix, a dot, and the
+    field name. You can change the prefix used by the widget as follows:
+        
+        >>> widget.setPrefix('newprefix')
+        >>> widget.name
+        'newprefix.Test'
+        
+    To configure a widget, call setRenderedValue with a value that the
+    widget should display:
+        
+        >>> widget.setRenderedValue('Render Me')
+        
+    The way a widget renders a value depends on the type of widget. E.g. a
+    browser widget will render the specified value in HTML.
+    """
+
+class TestCustomWidgetFactory:
+    """Tests the custom widget factory.
+    
+    Custom widgets can be created using a custom widget factory. Factories
+    are used to assign attribute values to widgets they create:
+        
+        >>> factory = CustomWidgetFactory(FooWidget, bar='baz')
+        >>> widget = factory(context, request)
+        >>> isinstance(widget, FooWidget)
+        True
+        >>> widget.bar
+        'baz'
+    """
 
 def test_suite():
     return TestSuite((
         makeSuite(TestWidget),
         makeSuite(TestCustomWidgetFactory),
+        doctest.DocTestSuite(),
         ))
 
 if __name__=='__main__':

=== Removed File Zope3/src/zope/app/form/tests/test_widget_geddon_deprecations.py ===




More information about the Zope3-Checkins mailing list