[Zope3-checkins] SVN: zope.formlib/branches/faassen-zaf/src/zope/formlib/ Move tests into subdirectory so we can receive the widget tests.

Martijn Faassen faassen at startifact.com
Wed Dec 30 15:30:50 EST 2009


Log message for revision 107386:
  Move tests into subdirectory so we can receive the widget tests.
  

Changed:
  U   zope.formlib/branches/faassen-zaf/src/zope/formlib/ftesting.zcml
  A   zope.formlib/branches/faassen-zaf/src/zope/formlib/tests/
  A   zope.formlib/branches/faassen-zaf/src/zope/formlib/tests/__init__.py
  A   zope.formlib/branches/faassen-zaf/src/zope/formlib/tests/test_formlib.py
  D   zope.formlib/branches/faassen-zaf/src/zope/formlib/tests.py

-=-
Modified: zope.formlib/branches/faassen-zaf/src/zope/formlib/ftesting.zcml
===================================================================
--- zope.formlib/branches/faassen-zaf/src/zope/formlib/ftesting.zcml	2009-12-30 20:25:24 UTC (rev 107385)
+++ zope.formlib/branches/faassen-zaf/src/zope/formlib/ftesting.zcml	2009-12-30 20:30:50 UTC (rev 107386)
@@ -7,17 +7,17 @@
   <include package="zope.component" file="meta.zcml" />
   <include package="zope.security" file="meta.zcml" />
 
-  <class class=".tests.Order">
-    <allow interface=".tests.IOrder" />
+  <class class=".tests.test_formlib.Order">
+    <allow interface=".tests.test_formlib.IOrder" />
     <require
-      set_schema=".tests.IOrder"
+      set_schema=".tests.test_formlib.IOrder"
       permission="zope.ManageContent"
       />
   </class>
-  <adapter factory=".tests.Descriptive" />
-  <class class=".tests.Descriptive">
+  <adapter factory=".tests.test_formlib.Descriptive" />
+  <class class=".tests.test_formlib.Descriptive">
     <require
-      interface=".tests.IDescriptive" 
+      interface=".tests.test_formlib.IDescriptive" 
       permission="zope.View"
       />
   </class>

Copied: zope.formlib/branches/faassen-zaf/src/zope/formlib/tests/test_formlib.py (from rev 107383, zope.formlib/branches/faassen-zaf/src/zope/formlib/tests.py)
===================================================================
--- zope.formlib/branches/faassen-zaf/src/zope/formlib/tests/test_formlib.py	                        (rev 0)
+++ zope.formlib/branches/faassen-zaf/src/zope/formlib/tests/test_formlib.py	2009-12-30 20:30:50 UTC (rev 107386)
@@ -0,0 +1,573 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+import unittest
+import re
+import pytz
+
+from zope.component.testing import setUp, tearDown
+from zope.component import adapter
+from zope.component import adapts
+from zope.component import provideAdapter, provideUtility
+
+from zope.i18n.testing import setUp as i18nSetUp
+import zope.interface.common.idatetime
+import zope.publisher.interfaces
+import zope.publisher.interfaces.browser
+import zope.schema.interfaces
+import zope.testing.renormalizing
+import zope.traversing.adapters
+
+from zope.formlib.widgets import (
+    TextWidget, FloatWidget, UnicodeDisplayWidget, IntWidget,
+    DatetimeDisplayWidget, DatetimeWidget)
+
+from zope.formlib import exception
+from zope.formlib.interfaces import IWidgetInputErrorView
+
+import zope.formlib
+import zope.formlib.form
+import zope.formlib.interfaces
+from zope.browserpage.namedtemplate import NamedTemplateImplementation
+
+from zope.configuration.xmlconfig import XMLConfig
+
+ at zope.interface.implementer(zope.interface.common.idatetime.ITZInfo)
+ at adapter(zope.publisher.interfaces.IRequest)
+def requestToTZInfo(request):
+    return pytz.timezone('US/Hawaii')
+
+def pageSetUp(test):
+    setUp(test)
+    provideAdapter(
+        zope.traversing.adapters.DefaultTraversable,
+        [None],
+        )
+
+ at adapter(zope.formlib.interfaces.IForm)
+ at NamedTemplateImplementation
+def TestTemplate(self):
+    status = self.status
+    if status:
+        status = zope.i18n.translate(status,
+                                     context=self.request,
+                                     default=self.status)
+        if getattr(status, 'mapping', 0):
+            status = zope.i18n.interpolate(status, status.mapping)
+        print status
+
+    result = []
+
+    if self.errors:
+        for error in self.errors:
+            result.append("%s: %s" % (error.__class__.__name__, error))
+
+    for w in self.widgets:
+        result.append(w())
+        error = w.error()
+        if error:
+            result.append(str(error))
+
+    for action in self.availableActions():
+        result.append(action.render())
+
+    return '\n'.join(result)
+
+def formSetUp(test):
+    setUp(test)
+    i18nSetUp(test)
+    provideAdapter(
+        TextWidget,
+        [zope.schema.interfaces.ITextLine,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        zope.formlib.interfaces.IInputWidget,
+        )
+    provideAdapter(
+        FloatWidget,
+        [zope.schema.interfaces.IFloat,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        zope.formlib.interfaces.IInputWidget,
+        )
+    provideAdapter(
+        UnicodeDisplayWidget,
+        [zope.schema.interfaces.IInt,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        zope.formlib.interfaces.IDisplayWidget,
+        )
+    provideAdapter(
+        IntWidget,
+        [zope.schema.interfaces.IInt,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        zope.formlib.interfaces.IInputWidget,
+        )
+    provideAdapter(
+        UnicodeDisplayWidget,
+        [zope.schema.interfaces.IFloat,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        zope.formlib.interfaces.IDisplayWidget,
+        )
+    provideAdapter(
+        UnicodeDisplayWidget,
+        [zope.schema.interfaces.ITextLine,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        zope.formlib.interfaces.IDisplayWidget,
+        )
+    provideAdapter(
+        DatetimeDisplayWidget,
+        [zope.schema.interfaces.IDatetime,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        zope.formlib.interfaces.IDisplayWidget,
+        )
+    provideAdapter(
+        DatetimeWidget,
+        [zope.schema.interfaces.IDatetime,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        zope.formlib.interfaces.IInputWidget,
+        )
+    provideAdapter(
+        exception.WidgetInputErrorView,
+        [zope.formlib.interfaces.IWidgetInputError,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        IWidgetInputErrorView,
+        )
+    provideAdapter(
+        zope.formlib.errors.InvalidErrorView,
+        [zope.interface.Invalid,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        IWidgetInputErrorView,
+        )
+    provideAdapter(TestTemplate, name='default')
+    provideAdapter(requestToTZInfo)
+    provideAdapter(
+        zope.formlib.form.render_submit_button, name='render')
+
+    XMLConfig('ftesting.zcml', zope.formlib)
+
+# Classes used in tests
+
+class IOrder(zope.interface.Interface):
+    identifier = zope.schema.Int(title=u"Identifier", readonly=True)
+    name = zope.schema.TextLine(title=u"Name")
+    min_size = zope.schema.Float(title=u"Minimum size")
+    max_size = zope.schema.Float(title=u"Maximum size")
+    now = zope.schema.Datetime(title=u"Now", readonly=True)
+
+class IDescriptive(zope.interface.Interface):
+    title = zope.schema.TextLine(title=u"Title")
+    description = zope.schema.TextLine(title=u"Description")
+
+
+class Order:
+    zope.interface.implements(IOrder)
+    identifier = 1
+    name = 'unknown'
+    min_size = 1.0
+    max_size = 10.0
+
+
+class Descriptive(object):
+    adapts(IOrder)
+    zope.interface.implements(IDescriptive)
+    def __init__(self, context):
+        self.context = context
+
+    def title():
+        def get(self):
+            try:
+                return self.context.__title
+            except AttributeError:
+                return ''
+        def set(self, v):
+            self.context.__title = v
+        return property(get, set)
+    title = title()
+
+    def description():
+        def get(self):
+            try:
+                return self.context.__description
+            except AttributeError:
+                return ''
+        def set(self, v):
+            self.context.__description = v
+        return property(get, set)
+    description = description()
+
+
+def makeSureRenderCanBeCalledWithoutCallingUpdate():
+    """\
+
+    >>> class MyForm(zope.formlib.form.EditForm):
+    ...     form_fields = zope.formlib.form.fields(
+    ...         IOrder, keep_readonly=['identifier'])
+
+    >>> from zope.publisher.browser import TestRequest
+    >>> myform = MyForm(Order(), TestRequest())
+    >>> print myform.render() # doctest: +NORMALIZE_WHITESPACE
+    1
+    <input class="textType" id="form.name" name="form.name"
+           size="20" type="text" value="unknown"  />
+    <input class="textType" id="form.min_size" name="form.min_size"
+           size="10" type="text" value="1.0"  />
+    <input class="textType" id="form.max_size" name="form.max_size"
+           size="10" type="text" value="10.0"  />
+    <input type="submit" id="form.actions.apply" name="form.actions.apply"
+           value="Apply" class="button" />
+
+"""
+
+def make_sure_i18n_is_called_correctly_for_actions():
+    """\
+
+We want to make sure that i18n is called correctly.  This is in
+response to a bug that occurred because actions called i18n.translate
+with incorrect positional arguments.
+
+We'll start by setting up an action:
+
+    >>> import zope.i18nmessageid
+    >>> _ = zope.i18nmessageid.MessageFactory('my.domain')
+    >>> action = zope.formlib.form.Action(_("MyAction"))
+
+Actions get bound to forms.  We'll set up a test request, create a
+form for it and bind the action to the form:
+
+    >>> myform = zope.formlib.form.FormBase(None, 42)
+    >>> action = action.__get__(myform)
+
+Button labels are rendered by form.render_submit_button, passing the
+bound action.  Before we call this however, we need to set up a dummy
+translation domain.  We'll create one for our needs:
+
+    >>> import zope.i18n.interfaces
+    >>> class MyDomain:
+    ...     zope.interface.implements(zope.i18n.interfaces.ITranslationDomain)
+    ...
+    ...     def translate(self, msgid, mapping=None, context=None,
+    ...                   target_language=None, default=None):
+    ...         print msgid
+    ...         print mapping
+    ...         print context
+    ...         print target_language
+    ...         print default
+    ...         return msgid
+
+    >>> provideUtility(MyDomain(), name='my.domain')
+
+Now, if we call render_submit_button, we should be able to verify the
+data passed to translate:
+
+    >>> zope.formlib.form.render_submit_button(action)() # doctest: +NORMALIZE_WHITESPACE
+    MyAction
+    None
+    42
+    None
+    MyAction
+    u'<input type="submit" id="form.actions.myaction"
+       name="form.actions.myaction" value="MyAction" class="button" />'
+
+
+"""
+
+def test_error_handling():
+    """\
+
+Let's test the getWidgetsData method which is responsible for handling widget
+erros raised by the widgets getInputValue method.
+
+    >>> import zope.formlib.interfaces
+    >>> class Widget(object):
+    ...     zope.interface.implements(zope.formlib.interfaces.IInputWidget)
+    ...     def __init__(self):
+    ...         self.name = 'form.summary'
+    ...         self.label = 'Summary'
+    ...     def hasInput(self):
+    ...         return True
+    ...     def getInputValue(self):
+    ...         raise zope.formlib.interfaces.WidgetInputError(
+    ...         field_name='summary',
+    ...         widget_title=u'Summary')
+    >>> widget = Widget()
+    >>> inputs = [(True, widget)]
+    >>> widgets = zope.formlib.form.Widgets(inputs, 5)
+    >>> errors = zope.formlib.form.getWidgetsData(widgets, 'form', {'summary':'value'})
+    >>> errors #doctest: +ELLIPSIS
+    [<zope.formlib.interfaces.WidgetInputError instance at ...>]
+
+Let's see what happens if a widget doesn't convert a ValidationError
+raised by a field to a WidgetInputError. This should not happen if a widget
+converts ValidationErrors to WidgetInputErrors. But since I just fixed
+yesterday the sequence input widget, I decided to catch ValidationError also
+in the formlib as a fallback if some widget doen't handle errors correct. (ri)
+
+    >>> class Widget(object):
+    ...     zope.interface.implements(zope.formlib.interfaces.IInputWidget)
+    ...     def __init__(self):
+    ...         self.name = 'form.summary'
+    ...         self.label = 'summary'
+    ...     def hasInput(self):
+    ...         return True
+    ...     def getInputValue(self):
+    ...         raise zope.schema.interfaces.ValidationError('A error message')
+    >>> widget = Widget()
+    >>> inputs = [(True, widget)]
+    >>> widgets = zope.formlib.form.Widgets(inputs, 5)
+    >>> errors = zope.formlib.form.getWidgetsData(widgets, 'form', {'summary':'value'})
+    >>> errors #doctest: +ELLIPSIS
+    [<zope.formlib.interfaces.WidgetInputError instance at ...>]
+
+"""
+
+def test_form_template_i18n():
+    """\
+Let's try to check that the formlib templates handle i18n correctly.
+We'll define a simple form:
+
+    >>> from zope.browserpage import ViewPageTemplateFile
+    >>> import zope.i18nmessageid
+    >>> _ = zope.i18nmessageid.MessageFactory('my.domain')
+
+    >>> class MyForm(zope.formlib.form.Form):
+    ...     label = _('The label')
+    ...     status = _('Success!')
+    ...     form_fields = zope.formlib.form.Fields(
+    ...         zope.schema.TextLine(__name__='name',
+    ...                              title=_("Name"),
+    ...                              description=_("Enter your name"),
+    ...                             ),
+    ...         )
+    ...     @zope.formlib.form.action(_('Ok'))
+    ...     def ok(self, action, data):
+    ...         pass
+    ...     page = ViewPageTemplateFile("../pageform.pt")
+    ...     subpage = ViewPageTemplateFile("../subpageform.pt")
+
+Now, we should be able to create a form instance:
+
+    >>> from zope.publisher.browser import TestRequest
+    >>> request = TestRequest()
+    >>> form = MyForm(object(), request)
+
+Unfortunately, the "page" template uses a page macro. We need to
+provide a template that it can get one from.  Here, we'll set up a
+view that provides the necessary macros:
+
+    >>> from zope.pagetemplate.pagetemplate import PageTemplate
+    >>> macro_template = PageTemplate()
+    >>> macro_template.write('''\
+    ... <html metal:define-macro="view">
+    ... <body metal:define-slot="body" />
+    ... </html>
+    ... ''')
+
+We also need to provide a traversal adapter for the view namespace
+that lets us look up the macros.
+
+    >>> import zope.traversing.interfaces
+    >>> class view:
+    ...     adapts(None, None)
+    ...     zope.interface.implements(zope.traversing.interfaces.ITraversable)
+    ...     def __init__(self, ob, r=None):
+    ...         pass
+    ...     def traverse(*args):
+    ...         return macro_template.macros
+
+    >>> provideAdapter(view, name='view')
+
+And we have to register the default traversable adapter (I wish we had
+push templates):
+
+    >>> from zope.traversing.adapters import DefaultTraversable
+    >>> provideAdapter(DefaultTraversable, [None])
+
+We need to set up the translation framework. We'll just provide a
+negotiator that always decides to use the test language:
+
+    >>> import zope.i18n.interfaces
+    >>> class Negotiator:
+    ...     zope.interface.implements(zope.i18n.interfaces.INegotiator)
+    ...     def getLanguage(*ignored):
+    ...         return 'test'
+
+    >>> provideUtility(Negotiator())
+
+And we'll set up the fallback-domain factory, which provides the test
+language for all domains:
+
+    >>> from zope.i18n.testmessagecatalog import TestMessageFallbackDomain
+    >>> provideUtility(TestMessageFallbackDomain)
+
+OK, so let's see what the page form looks like. First, we'll compute
+the page:
+
+    >>> form.update()
+    >>> page = form.page()
+
+We want to make sure that the page has the translations we expect and
+that it doesn't double translate anything.  We'll write a generator
+that extracts the translations, complaining if any are nested:
+
+    >>> def find_translations(text):
+    ...     l = 0
+    ...     while 1:
+    ...         lopen = text.find('[[', l)
+    ...         lclose = text.find(']]', l)
+    ...         if lclose >= 0 and lclose < lopen:
+    ...             raise ValueError(lopen, lclose, text)
+    ...         if lopen < 0:
+    ...             break
+    ...         l = lopen + 2
+    ...         lopen = text.find('[[', l)
+    ...         lclose = text.find(']]', l)
+    ...         if lopen >= 0 and lopen < lclose:
+    ...             raise ValueError(lopen, lclose, text)
+    ...         if lclose < 0:
+    ...             raise ValueError(l, text)
+    ...         yield text[l-2:lclose+2]
+    ...         l = lclose + 2
+
+    >>> for t in find_translations(page):
+    ...     print t
+    [[my.domain][The label]]
+    [[my.domain][Success!]]
+    [[my.domain][Name]]
+    [[my.domain][Enter your name]]
+    [[my.domain][Ok]]
+
+Now, let's try the same thing with the sub-page form:
+
+    >>> for t in find_translations(form.subpage()):
+    ...     print t
+    [[my.domain][The label]]
+    [[my.domain][Success!]]
+    [[my.domain][Name]]
+    [[my.domain][Enter your name]]
+    [[my.domain][Ok]]
+
+"""
+
+
+def test_setUpWidgets_prefix():
+    """This is a regression test for field prefix handling in setUp*Widgets.
+
+    Let's set up fields with some interface and a prefix on fields:
+
+        >>> from zope.formlib import form
+        >>> from zope import interface, schema
+
+        >>> class ITrivial(interface.Interface):
+        ...     name = schema.TextLine(title=u"Name")
+
+        >>> form_fields = form.Fields(ITrivial, prefix='one')
+        >>> form_fields += form.Fields(ITrivial, prefix='two')
+        >>> form_fields += form.Fields(ITrivial, prefix='three')
+
+    Let's call setUpDataWidgets and see their names:
+
+        >>> class Trivial(object):
+        ...     interface.implements(ITrivial)
+        ...     name = 'foo'
+        >>> context = Trivial()
+
+        >>> from zope.publisher.browser import TestRequest
+        >>> request = TestRequest()
+
+        >>> widgets = form.setUpDataWidgets(form_fields, 'form', context,
+        ...                                 request, {})
+        >>> [w.name for w in widgets]
+        ['form.one.name', 'form.two.name', 'form.three.name']
+
+    Let's try the same with setUpEditWidgets:
+
+        >>> widgets = form.setUpEditWidgets(form_fields, 'form', context,
+        ...                                  request)
+        >>> [w.name for w in widgets]
+        ['form.one.name', 'form.two.name', 'form.three.name']
+
+    And setUpInputWidgets:
+
+        >>> widgets = form.setUpInputWidgets(form_fields, 'form', context,
+        ...                                  request)
+        >>> [w.name for w in widgets]
+        ['form.one.name', 'form.two.name', 'form.three.name']
+
+    And setUpWidgets:
+
+        >>> widgets = form.setUpWidgets(form_fields, 'form', context, request)
+        >>> [w.name for w in widgets]
+        ['form.one.name', 'form.two.name', 'form.three.name']
+
+    """
+
+def test_Action_interface():
+    """
+    >>> action = zope.formlib.form.Action('foo')
+    >>> import zope.interface.verify
+    >>> zope.interface.verify.verifyObject(zope.formlib.interfaces.IAction,
+    ...                                    action)
+    True
+    """
+
+
+def test_suite():
+    from zope.testing import doctest
+    checker = zope.testing.renormalizing.RENormalizing([
+      (re.compile(r"\[WidgetInputError\('form.summary', 'summary', ValidationError\('A error message'\)\)\]"),
+                  r"[<zope.formlib.interfaces.WidgetInputError instance at ...>]"),
+      (re.compile(r"\[WidgetInputError\('summary', u'Summary', None\)\]"),
+                  r"[<zope.formlib.interfaces.WidgetInputError instance at ...>]"),
+      (re.compile(r" ValueError\('invalid literal for float\(\): (bob'|10,0'),\)"),
+                  r"\n <exceptions.ValueError instance at ...>"),
+    ])
+    return unittest.TestSuite((
+        doctest.DocFileSuite(
+            '../errors.txt',
+            setUp=formSetUp, tearDown=tearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            ),
+        # The following test needs some zope.security test setup
+        #doctest.DocFileSuite(
+        #     'bugs.txt',
+        #     setUp=formSetUp, tearDown=tearDown,
+        #     optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+        #     ),
+        doctest.DocFileSuite(
+            '../form.txt',
+            setUp=formSetUp, tearDown=tearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            checker=checker
+            ),
+        doctest.DocTestSuite(
+            setUp=formSetUp, tearDown=tearDown,
+            checker=checker
+            ),
+        doctest.DocTestSuite(
+            'zope.formlib.errors'),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')
+

Deleted: zope.formlib/branches/faassen-zaf/src/zope/formlib/tests.py
===================================================================
--- zope.formlib/branches/faassen-zaf/src/zope/formlib/tests.py	2009-12-30 20:25:24 UTC (rev 107385)
+++ zope.formlib/branches/faassen-zaf/src/zope/formlib/tests.py	2009-12-30 20:30:50 UTC (rev 107386)
@@ -1,573 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-import unittest
-import re
-import pytz
-
-from zope.component.testing import setUp, tearDown
-from zope.component import adapter
-from zope.component import adapts
-from zope.component import provideAdapter, provideUtility
-
-from zope.i18n.testing import setUp as i18nSetUp
-import zope.interface.common.idatetime
-import zope.publisher.interfaces
-import zope.publisher.interfaces.browser
-import zope.schema.interfaces
-import zope.testing.renormalizing
-import zope.traversing.adapters
-
-from zope.formlib.widgets import (
-    TextWidget, FloatWidget, UnicodeDisplayWidget, IntWidget,
-    DatetimeDisplayWidget, DatetimeWidget)
-
-from zope.formlib import exception
-from zope.formlib.interfaces import IWidgetInputErrorView
-
-import zope.formlib
-import zope.formlib.form
-import zope.formlib.interfaces
-from zope.browserpage.namedtemplate import NamedTemplateImplementation
-
-from zope.configuration.xmlconfig import XMLConfig
-
- at zope.interface.implementer(zope.interface.common.idatetime.ITZInfo)
- at adapter(zope.publisher.interfaces.IRequest)
-def requestToTZInfo(request):
-    return pytz.timezone('US/Hawaii')
-
-def pageSetUp(test):
-    setUp(test)
-    provideAdapter(
-        zope.traversing.adapters.DefaultTraversable,
-        [None],
-        )
-
- at adapter(zope.formlib.interfaces.IForm)
- at NamedTemplateImplementation
-def TestTemplate(self):
-    status = self.status
-    if status:
-        status = zope.i18n.translate(status,
-                                     context=self.request,
-                                     default=self.status)
-        if getattr(status, 'mapping', 0):
-            status = zope.i18n.interpolate(status, status.mapping)
-        print status
-
-    result = []
-
-    if self.errors:
-        for error in self.errors:
-            result.append("%s: %s" % (error.__class__.__name__, error))
-
-    for w in self.widgets:
-        result.append(w())
-        error = w.error()
-        if error:
-            result.append(str(error))
-
-    for action in self.availableActions():
-        result.append(action.render())
-
-    return '\n'.join(result)
-
-def formSetUp(test):
-    setUp(test)
-    i18nSetUp(test)
-    provideAdapter(
-        TextWidget,
-        [zope.schema.interfaces.ITextLine,
-         zope.publisher.interfaces.browser.IBrowserRequest,
-         ],
-        zope.formlib.interfaces.IInputWidget,
-        )
-    provideAdapter(
-        FloatWidget,
-        [zope.schema.interfaces.IFloat,
-         zope.publisher.interfaces.browser.IBrowserRequest,
-         ],
-        zope.formlib.interfaces.IInputWidget,
-        )
-    provideAdapter(
-        UnicodeDisplayWidget,
-        [zope.schema.interfaces.IInt,
-         zope.publisher.interfaces.browser.IBrowserRequest,
-         ],
-        zope.formlib.interfaces.IDisplayWidget,
-        )
-    provideAdapter(
-        IntWidget,
-        [zope.schema.interfaces.IInt,
-         zope.publisher.interfaces.browser.IBrowserRequest,
-         ],
-        zope.formlib.interfaces.IInputWidget,
-        )
-    provideAdapter(
-        UnicodeDisplayWidget,
-        [zope.schema.interfaces.IFloat,
-         zope.publisher.interfaces.browser.IBrowserRequest,
-         ],
-        zope.formlib.interfaces.IDisplayWidget,
-        )
-    provideAdapter(
-        UnicodeDisplayWidget,
-        [zope.schema.interfaces.ITextLine,
-         zope.publisher.interfaces.browser.IBrowserRequest,
-         ],
-        zope.formlib.interfaces.IDisplayWidget,
-        )
-    provideAdapter(
-        DatetimeDisplayWidget,
-        [zope.schema.interfaces.IDatetime,
-         zope.publisher.interfaces.browser.IBrowserRequest,
-         ],
-        zope.formlib.interfaces.IDisplayWidget,
-        )
-    provideAdapter(
-        DatetimeWidget,
-        [zope.schema.interfaces.IDatetime,
-         zope.publisher.interfaces.browser.IBrowserRequest,
-         ],
-        zope.formlib.interfaces.IInputWidget,
-        )
-    provideAdapter(
-        exception.WidgetInputErrorView,
-        [zope.formlib.interfaces.IWidgetInputError,
-         zope.publisher.interfaces.browser.IBrowserRequest,
-         ],
-        IWidgetInputErrorView,
-        )
-    provideAdapter(
-        zope.formlib.errors.InvalidErrorView,
-        [zope.interface.Invalid,
-         zope.publisher.interfaces.browser.IBrowserRequest,
-         ],
-        IWidgetInputErrorView,
-        )
-    provideAdapter(TestTemplate, name='default')
-    provideAdapter(requestToTZInfo)
-    provideAdapter(
-        zope.formlib.form.render_submit_button, name='render')
-
-    XMLConfig('ftesting.zcml', zope.formlib)
-
-# Classes used in tests
-
-class IOrder(zope.interface.Interface):
-    identifier = zope.schema.Int(title=u"Identifier", readonly=True)
-    name = zope.schema.TextLine(title=u"Name")
-    min_size = zope.schema.Float(title=u"Minimum size")
-    max_size = zope.schema.Float(title=u"Maximum size")
-    now = zope.schema.Datetime(title=u"Now", readonly=True)
-
-class IDescriptive(zope.interface.Interface):
-    title = zope.schema.TextLine(title=u"Title")
-    description = zope.schema.TextLine(title=u"Description")
-
-
-class Order:
-    zope.interface.implements(IOrder)
-    identifier = 1
-    name = 'unknown'
-    min_size = 1.0
-    max_size = 10.0
-
-
-class Descriptive(object):
-    adapts(IOrder)
-    zope.interface.implements(IDescriptive)
-    def __init__(self, context):
-        self.context = context
-
-    def title():
-        def get(self):
-            try:
-                return self.context.__title
-            except AttributeError:
-                return ''
-        def set(self, v):
-            self.context.__title = v
-        return property(get, set)
-    title = title()
-
-    def description():
-        def get(self):
-            try:
-                return self.context.__description
-            except AttributeError:
-                return ''
-        def set(self, v):
-            self.context.__description = v
-        return property(get, set)
-    description = description()
-
-
-def makeSureRenderCanBeCalledWithoutCallingUpdate():
-    """\
-
-    >>> class MyForm(zope.formlib.form.EditForm):
-    ...     form_fields = zope.formlib.form.fields(
-    ...         IOrder, keep_readonly=['identifier'])
-
-    >>> from zope.publisher.browser import TestRequest
-    >>> myform = MyForm(Order(), TestRequest())
-    >>> print myform.render() # doctest: +NORMALIZE_WHITESPACE
-    1
-    <input class="textType" id="form.name" name="form.name"
-           size="20" type="text" value="unknown"  />
-    <input class="textType" id="form.min_size" name="form.min_size"
-           size="10" type="text" value="1.0"  />
-    <input class="textType" id="form.max_size" name="form.max_size"
-           size="10" type="text" value="10.0"  />
-    <input type="submit" id="form.actions.apply" name="form.actions.apply"
-           value="Apply" class="button" />
-
-"""
-
-def make_sure_i18n_is_called_correctly_for_actions():
-    """\
-
-We want to make sure that i18n is called correctly.  This is in
-response to a bug that occurred because actions called i18n.translate
-with incorrect positional arguments.
-
-We'll start by setting up an action:
-
-    >>> import zope.i18nmessageid
-    >>> _ = zope.i18nmessageid.MessageFactory('my.domain')
-    >>> action = zope.formlib.form.Action(_("MyAction"))
-
-Actions get bound to forms.  We'll set up a test request, create a
-form for it and bind the action to the form:
-
-    >>> myform = zope.formlib.form.FormBase(None, 42)
-    >>> action = action.__get__(myform)
-
-Button labels are rendered by form.render_submit_button, passing the
-bound action.  Before we call this however, we need to set up a dummy
-translation domain.  We'll create one for our needs:
-
-    >>> import zope.i18n.interfaces
-    >>> class MyDomain:
-    ...     zope.interface.implements(zope.i18n.interfaces.ITranslationDomain)
-    ...
-    ...     def translate(self, msgid, mapping=None, context=None,
-    ...                   target_language=None, default=None):
-    ...         print msgid
-    ...         print mapping
-    ...         print context
-    ...         print target_language
-    ...         print default
-    ...         return msgid
-
-    >>> provideUtility(MyDomain(), name='my.domain')
-
-Now, if we call render_submit_button, we should be able to verify the
-data passed to translate:
-
-    >>> zope.formlib.form.render_submit_button(action)() # doctest: +NORMALIZE_WHITESPACE
-    MyAction
-    None
-    42
-    None
-    MyAction
-    u'<input type="submit" id="form.actions.myaction"
-       name="form.actions.myaction" value="MyAction" class="button" />'
-
-
-"""
-
-def test_error_handling():
-    """\
-
-Let's test the getWidgetsData method which is responsible for handling widget
-erros raised by the widgets getInputValue method.
-
-    >>> import zope.formlib.interfaces
-    >>> class Widget(object):
-    ...     zope.interface.implements(zope.formlib.interfaces.IInputWidget)
-    ...     def __init__(self):
-    ...         self.name = 'form.summary'
-    ...         self.label = 'Summary'
-    ...     def hasInput(self):
-    ...         return True
-    ...     def getInputValue(self):
-    ...         raise zope.formlib.interfaces.WidgetInputError(
-    ...         field_name='summary',
-    ...         widget_title=u'Summary')
-    >>> widget = Widget()
-    >>> inputs = [(True, widget)]
-    >>> widgets = zope.formlib.form.Widgets(inputs, 5)
-    >>> errors = zope.formlib.form.getWidgetsData(widgets, 'form', {'summary':'value'})
-    >>> errors #doctest: +ELLIPSIS
-    [<zope.formlib.interfaces.WidgetInputError instance at ...>]
-
-Let's see what happens if a widget doesn't convert a ValidationError
-raised by a field to a WidgetInputError. This should not happen if a widget
-converts ValidationErrors to WidgetInputErrors. But since I just fixed
-yesterday the sequence input widget, I decided to catch ValidationError also
-in the formlib as a fallback if some widget doen't handle errors correct. (ri)
-
-    >>> class Widget(object):
-    ...     zope.interface.implements(zope.formlib.interfaces.IInputWidget)
-    ...     def __init__(self):
-    ...         self.name = 'form.summary'
-    ...         self.label = 'summary'
-    ...     def hasInput(self):
-    ...         return True
-    ...     def getInputValue(self):
-    ...         raise zope.schema.interfaces.ValidationError('A error message')
-    >>> widget = Widget()
-    >>> inputs = [(True, widget)]
-    >>> widgets = zope.formlib.form.Widgets(inputs, 5)
-    >>> errors = zope.formlib.form.getWidgetsData(widgets, 'form', {'summary':'value'})
-    >>> errors #doctest: +ELLIPSIS
-    [<zope.formlib.interfaces.WidgetInputError instance at ...>]
-
-"""
-
-def test_form_template_i18n():
-    """\
-Let's try to check that the formlib templates handle i18n correctly.
-We'll define a simple form:
-
-    >>> from zope.browserpage import ViewPageTemplateFile
-    >>> import zope.i18nmessageid
-    >>> _ = zope.i18nmessageid.MessageFactory('my.domain')
-
-    >>> class MyForm(zope.formlib.form.Form):
-    ...     label = _('The label')
-    ...     status = _('Success!')
-    ...     form_fields = zope.formlib.form.Fields(
-    ...         zope.schema.TextLine(__name__='name',
-    ...                              title=_("Name"),
-    ...                              description=_("Enter your name"),
-    ...                             ),
-    ...         )
-    ...     @zope.formlib.form.action(_('Ok'))
-    ...     def ok(self, action, data):
-    ...         pass
-    ...     page = ViewPageTemplateFile("pageform.pt")
-    ...     subpage = ViewPageTemplateFile("subpageform.pt")
-
-Now, we should be able to create a form instance:
-
-    >>> from zope.publisher.browser import TestRequest
-    >>> request = TestRequest()
-    >>> form = MyForm(object(), request)
-
-Unfortunately, the "page" template uses a page macro. We need to
-provide a template that it can get one from.  Here, we'll set up a
-view that provides the necessary macros:
-
-    >>> from zope.pagetemplate.pagetemplate import PageTemplate
-    >>> macro_template = PageTemplate()
-    >>> macro_template.write('''\
-    ... <html metal:define-macro="view">
-    ... <body metal:define-slot="body" />
-    ... </html>
-    ... ''')
-
-We also need to provide a traversal adapter for the view namespace
-that lets us look up the macros.
-
-    >>> import zope.traversing.interfaces
-    >>> class view:
-    ...     adapts(None, None)
-    ...     zope.interface.implements(zope.traversing.interfaces.ITraversable)
-    ...     def __init__(self, ob, r=None):
-    ...         pass
-    ...     def traverse(*args):
-    ...         return macro_template.macros
-
-    >>> provideAdapter(view, name='view')
-
-And we have to register the default traversable adapter (I wish we had
-push templates):
-
-    >>> from zope.traversing.adapters import DefaultTraversable
-    >>> provideAdapter(DefaultTraversable, [None])
-
-We need to set up the translation framework. We'll just provide a
-negotiator that always decides to use the test language:
-
-    >>> import zope.i18n.interfaces
-    >>> class Negotiator:
-    ...     zope.interface.implements(zope.i18n.interfaces.INegotiator)
-    ...     def getLanguage(*ignored):
-    ...         return 'test'
-
-    >>> provideUtility(Negotiator())
-
-And we'll set up the fallback-domain factory, which provides the test
-language for all domains:
-
-    >>> from zope.i18n.testmessagecatalog import TestMessageFallbackDomain
-    >>> provideUtility(TestMessageFallbackDomain)
-
-OK, so let's see what the page form looks like. First, we'll compute
-the page:
-
-    >>> form.update()
-    >>> page = form.page()
-
-We want to make sure that the page has the translations we expect and
-that it doesn't double translate anything.  We'll write a generator
-that extracts the translations, complaining if any are nested:
-
-    >>> def find_translations(text):
-    ...     l = 0
-    ...     while 1:
-    ...         lopen = text.find('[[', l)
-    ...         lclose = text.find(']]', l)
-    ...         if lclose >= 0 and lclose < lopen:
-    ...             raise ValueError(lopen, lclose, text)
-    ...         if lopen < 0:
-    ...             break
-    ...         l = lopen + 2
-    ...         lopen = text.find('[[', l)
-    ...         lclose = text.find(']]', l)
-    ...         if lopen >= 0 and lopen < lclose:
-    ...             raise ValueError(lopen, lclose, text)
-    ...         if lclose < 0:
-    ...             raise ValueError(l, text)
-    ...         yield text[l-2:lclose+2]
-    ...         l = lclose + 2
-
-    >>> for t in find_translations(page):
-    ...     print t
-    [[my.domain][The label]]
-    [[my.domain][Success!]]
-    [[my.domain][Name]]
-    [[my.domain][Enter your name]]
-    [[my.domain][Ok]]
-
-Now, let's try the same thing with the sub-page form:
-
-    >>> for t in find_translations(form.subpage()):
-    ...     print t
-    [[my.domain][The label]]
-    [[my.domain][Success!]]
-    [[my.domain][Name]]
-    [[my.domain][Enter your name]]
-    [[my.domain][Ok]]
-
-"""
-
-
-def test_setUpWidgets_prefix():
-    """This is a regression test for field prefix handling in setUp*Widgets.
-
-    Let's set up fields with some interface and a prefix on fields:
-
-        >>> from zope.formlib import form
-        >>> from zope import interface, schema
-
-        >>> class ITrivial(interface.Interface):
-        ...     name = schema.TextLine(title=u"Name")
-
-        >>> form_fields = form.Fields(ITrivial, prefix='one')
-        >>> form_fields += form.Fields(ITrivial, prefix='two')
-        >>> form_fields += form.Fields(ITrivial, prefix='three')
-
-    Let's call setUpDataWidgets and see their names:
-
-        >>> class Trivial(object):
-        ...     interface.implements(ITrivial)
-        ...     name = 'foo'
-        >>> context = Trivial()
-
-        >>> from zope.publisher.browser import TestRequest
-        >>> request = TestRequest()
-
-        >>> widgets = form.setUpDataWidgets(form_fields, 'form', context,
-        ...                                 request, {})
-        >>> [w.name for w in widgets]
-        ['form.one.name', 'form.two.name', 'form.three.name']
-
-    Let's try the same with setUpEditWidgets:
-
-        >>> widgets = form.setUpEditWidgets(form_fields, 'form', context,
-        ...                                  request)
-        >>> [w.name for w in widgets]
-        ['form.one.name', 'form.two.name', 'form.three.name']
-
-    And setUpInputWidgets:
-
-        >>> widgets = form.setUpInputWidgets(form_fields, 'form', context,
-        ...                                  request)
-        >>> [w.name for w in widgets]
-        ['form.one.name', 'form.two.name', 'form.three.name']
-
-    And setUpWidgets:
-
-        >>> widgets = form.setUpWidgets(form_fields, 'form', context, request)
-        >>> [w.name for w in widgets]
-        ['form.one.name', 'form.two.name', 'form.three.name']
-
-    """
-
-def test_Action_interface():
-    """
-    >>> action = zope.formlib.form.Action('foo')
-    >>> import zope.interface.verify
-    >>> zope.interface.verify.verifyObject(zope.formlib.interfaces.IAction,
-    ...                                    action)
-    True
-    """
-
-
-def test_suite():
-    from zope.testing import doctest
-    checker = zope.testing.renormalizing.RENormalizing([
-      (re.compile(r"\[WidgetInputError\('form.summary', 'summary', ValidationError\('A error message'\)\)\]"),
-                  r"[<zope.formlib.interfaces.WidgetInputError instance at ...>]"),
-      (re.compile(r"\[WidgetInputError\('summary', u'Summary', None\)\]"),
-                  r"[<zope.formlib.interfaces.WidgetInputError instance at ...>]"),
-      (re.compile(r" ValueError\('invalid literal for float\(\): (bob'|10,0'),\)"),
-                  r"\n <exceptions.ValueError instance at ...>"),
-    ])
-    return unittest.TestSuite((
-        doctest.DocFileSuite(
-            'errors.txt',
-            setUp=formSetUp, tearDown=tearDown,
-            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
-            ),
-        # The following test needs some zope.security test setup
-        #doctest.DocFileSuite(
-        #     'bugs.txt',
-        #     setUp=formSetUp, tearDown=tearDown,
-        #     optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
-        #     ),
-        doctest.DocFileSuite(
-            'form.txt',
-            setUp=formSetUp, tearDown=tearDown,
-            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
-            checker=checker
-            ),
-        doctest.DocTestSuite(
-            setUp=formSetUp, tearDown=tearDown,
-            checker=checker
-            ),
-        doctest.DocTestSuite(
-            'zope.formlib.errors'),
-        ))
-
-if __name__ == '__main__':
-    unittest.main(defaultTest='test_suite')
-



More information about the Zope3-Checkins mailing list