Skip to content
This repository has been archived by the owner on Apr 9, 2019. It is now read-only.

Commit

Permalink
cleanup tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jensens committed Oct 8, 2018
1 parent 87b1975 commit 7abce7a
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 79 deletions.
33 changes: 19 additions & 14 deletions src/plone/z3cform/layout.txt → src/plone/z3cform/layout.rst
Expand Up @@ -9,15 +9,15 @@ Layout wrapper views are used for two purposes:
acquisition anyway)
* To avoid separate form templates from layout templates (aka the main
template), to allow a single form to be usable in different contexts,
e.g. as a standalone form or a viwelet.
e.g. as a standalone form or a viewlet.

If you are using Zope 2.12 or later, you don't need to use the wrapper view
if you don't want to, so long as you have loaded the plone.z3cform
configuration.

To use the wrapper, you can call the ``wrap_form`` function defined in the
``layout`` module to create a view that's suitable for registration with a
``browser:page`` directive.
``browser:page`` directive::

>>> from zope.interface import alsoProvides
>>> from zope.publisher.browser import TestRequest
Expand All @@ -31,7 +31,7 @@ To use the wrapper, you can call the ``wrap_form`` function defined in the
... alsoProvides(request, IAttributeAnnotatable)
... return request

Then we create a simple form:
Then we create a simple form::

>>> from zope import interface, schema
>>> from z3c.form import form, field, button
Expand Down Expand Up @@ -67,14 +67,14 @@ Then we create a simple form:

For our context, we define a class that inherits from Acquisition.
This is to satisfy permission checking later on, and it'll allow the
layout view to call ``aq_inner`` on the context:
layout view to call ``aq_inner`` on the context::

>>> from Acquisition import Implicit
>>> @implementer(Interface)
... class Bar(Implicit):
... __allow_access_to_unprotected_subobjects__ = 1

Let's verify that worked:
Let's verify that worked::

>>> from zope.component import getMultiAdapter
>>> context = Bar()
Expand All @@ -84,19 +84,18 @@ Let's verify that worked:
<MyFormWrapper object ...>

We can also use a function called ``wrap_form`` to wrap our form in a
layout. We define a custom layout template first:
layout. We define a custom layout template first::

>>> import os
>>> import tempfile
>>> from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
>>> fd, path = tempfile.mkstemp()
>>> f = os.fdopen(fd, 'w')
>>> _ = f.write("""
>>> with os.fdopen(fd, 'w') as fio:
... _ = fio.write("""
... <html>Hello, this is your layout speaking:
... <h1 tal:content="view/label">View Title</h1>
... <div tal:content="structure view/contents"></div>
... </html>""")
>>> f.close()
>>> layout = ViewPageTemplateFile(path, _prefix='')

Note that the ``_prefix`` argument passed to Five's
Expand All @@ -105,22 +104,24 @@ now make the actual call to ``wrap_form`` and register the view class
it returns. Normally, you'd register this view class using ZCML, like
with any other view.

::

>>> from plone.z3cform.layout import wrap_form
>>> view_class = wrap_form(MyForm, index=layout, label=u'My label')
>>> provideAdapter(adapts=(Interface, IBrowserRequest),
... provides=Interface,
... factory=view_class,
... name=u'test-form2')

Let's render this view:
Let's render this view::

>>> view = getMultiAdapter(
... (context, request), name=u'test-form2')
>>> print(view()) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
<html>Hello, this is your layout speaking:...My label...Age...</html>

If we don't pass the label to ``wrap_form``, it'll try to look up the
label from the form instance:
label from the form instance::

>>> class MyLabelledForm(MyForm):
... @property
Expand All @@ -133,7 +134,7 @@ label from the form instance:
<html>Hello, this is your layout speaking:...Another label...Age...</html>


Send bad data to the form:
Send bad data to the form::

>>> request = make_request(form={'form.widgets.age': '12.1'})
>>> from zope.interface import Interface
Expand All @@ -146,7 +147,7 @@ Send bad data to the form:
>>> errors
(<ValueErrorViewSnippet for ValueError>,)

And then send correct data to the form:
And then send correct data to the form::

>>> request = make_request(form={'form.widgets.age': '12'})
>>> from zope.interface import Interface
Expand All @@ -162,10 +163,12 @@ And then send correct data to the form:

We also have the option of defining a default layout template for all forms
that don't specify a particular 'index' template. Here, we use the 'path'
function from plone.z3cform.templates to locate a template file (the default
function from plone.z3cform.views to locate a template file (the default
template, in fact) from the plone.z3cform directory. For your own purposes,
you probably just want to specify a filename relative to your package.

::

>>> new_view_class = wrap_form(MyLabelledForm)
>>> view = new_view_class(context, request)

Expand All @@ -176,6 +179,8 @@ you probably just want to specify a filename relative to your package.
Note that the 'form' parameter here should be the wrapper view class, or an
interface implemented by it, not the form class itself.

::

>>> provideAdapter(layout_factory)
>>> print(view()) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
<html>Hello, this is your layout speaking:...Another label...Age...</html>
Expand Down
95 changes: 46 additions & 49 deletions src/plone/z3cform/templates.py
Expand Up @@ -4,9 +4,15 @@
The default templates draw from a macro page template which you can use by
itself to render parts of it.
"""
from Acquisition import IAcquirer, ImplicitAcquisitionWrapper
from Acquisition import IAcquirer
from Acquisition import ImplicitAcquisitionWrapper
from Products.Five.browser.pagetemplatefile import (
ViewPageTemplateFile as ZopeTwoPageTemplateFile
)
from z3c.form import util
from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile
from zope.pagetemplate.interfaces import IPageTemplate

import os
import plone.z3cform
import plone.z3cform.layout
Expand All @@ -15,21 +21,12 @@
import z3c.form.widget
import zope.publisher.browser

try:
# chameleon-compatible page templates
from five.pt.pagetemplate import ViewPageTemplateFile
from five.pt.pagetemplate import ViewPageTemplateFile as ZopeTwoPageTemplateFile # noqa
except ImportError:
# standard Zope page templates
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile as ZopeTwoPageTemplateFile # noqa
from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile

def path(filename):
return os.path.join(
os.path.dirname(plone.z3cform.__file__), 'pagetemplates', filename
)

path = lambda p: os.path.join(
os.path.dirname(
plone.z3cform.__file__),
'templates',
p)

# Zope 2-compatible form and widget template factory classes.

Expand All @@ -44,17 +41,14 @@ class FormTemplateFactory(z3c.form.form.FormTemplateFactory):
"""

def __init__(
self,
filename,
contentType='text/html',
form=None,
request=None):
self, filename, contentType='text/html', form=None, request=None
):
self.template = ViewPageTemplateFile(
filename,
content_type=contentType)
filename, content_type=contentType
)
zope.component.adapter(
util.getSpecification(form),
util.getSpecification(request))(self)
util.getSpecification(form), util.getSpecification(request)
)(self)
zope.interface.implementer(IPageTemplate)(self)


Expand All @@ -66,25 +60,21 @@ class ZopeTwoFormTemplateFactory(z3c.form.form.FormTemplateFactory):
"""

def __init__(
self,
filename,
contentType='text/html',
form=None,
request=None):
self, filename, contentType='text/html', form=None, request=None
):
self.template = ZopeTwoPageTemplateFile(
filename,
content_type=contentType)
filename, content_type=contentType
)
zope.component.adapter(
util.getSpecification(form),
util.getSpecification(request))(self)
util.getSpecification(form), util.getSpecification(request)
)(self)
zope.interface.implementer(IPageTemplate)(self)

def __call__(self, form, request):
template = self.template
if IAcquirer.providedBy(template):
return ImplicitAcquisitionWrapper(template, form)
else:
return template
return template


class ZopeTwoWidgetTemplateFactory(z3c.form.widget.WidgetTemplateFactory):
Expand All @@ -93,48 +83,55 @@ class ZopeTwoWidgetTemplateFactory(z3c.form.widget.WidgetTemplateFactory):
extra Zope 2-isms of Five's ViewPageTemplateFile.
"""

def __init__(self, filename, contentType='text/html', context=None,
request=None, view=None, field=None, widget=None
):
def __init__(
self,
filename,
contentType='text/html',
context=None,
request=None,
view=None,
field=None,
widget=None,
):
self.template = ViewPageTemplateFile(
filename,
content_type=contentType)
filename, content_type=contentType
)
zope.component.adapter(
util.getSpecification(context),
util.getSpecification(request),
util.getSpecification(view),
util.getSpecification(field),
util.getSpecification(widget))(self)
util.getSpecification(widget),
)(self)
zope.interface.implementer(IPageTemplate)(self)


# View containing common macros


class Macros(zope.publisher.browser.BrowserView):

def __getitem__(self, key):
return self.index.macros[key]


# Default templates for the wrapped layout view use case

layout_factory = ZopeTwoFormTemplateFactory(
path('layout.pt'),
form=plone.z3cform.interfaces.IFormWrapper)
path('layout.pt'), form=plone.z3cform.interfaces.IFormWrapper
)

wrapped_form_factory = FormTemplateFactory(
path('wrappedform.pt'),
form=plone.z3cform.interfaces.IWrappedForm,
path('wrappedform.pt'), form=plone.z3cform.interfaces.IWrappedForm
)

# Default templates for the standalone form use case

standalone_form_factory = ZopeTwoFormTemplateFactory(
path('form.pt'),
form=z3c.form.interfaces.IForm)
path('form.pt'), form=z3c.form.interfaces.IForm
)

# Default templates for subforms

subform_factory = FormTemplateFactory(
path('subform.pt'),
form=z3c.form.interfaces.ISubForm
path('subform.pt'), form=z3c.form.interfaces.ISubForm
)
2 changes: 1 addition & 1 deletion src/plone/z3cform/templates.zcml
Expand Up @@ -13,7 +13,7 @@
name="ploneform-macros"
for="*"
class=".templates.Macros"
template="templates/macros.pt"
template="pagetemplates/macros.pt"
allowed_interface="zope.interface.common.mapping.IItemMapping"
permission="zope.Public"
/>
Expand Down
2 changes: 0 additions & 2 deletions src/plone/z3cform/testing.zcml
Expand Up @@ -8,8 +8,6 @@
<include file="configure.zcml" package="Products.Five"/>
<include file="meta.zcml" package="z3c.form"/>
<include file="configure.zcml" package="z3c.form"/>

<includeOverrides file="overrides.zcml" package="plone.z3cform"/>
<include file="configure.zcml" package="plone.z3cform"/>

</configure>
33 changes: 20 additions & 13 deletions src/plone/z3cform/tests.py
Expand Up @@ -181,7 +181,7 @@ def check_output(self, want, got, optionflags):

def test_suite():
layout_txt = layered(
doctest.DocFileSuite('layout.txt', checker=Py23DocChecker()),
doctest.DocFileSuite('layout.rst', checker=Py23DocChecker()),
layer=FUNCTIONAL_TESTING,
)
inputs_txt = layered(
Expand All @@ -193,6 +193,23 @@ def test_suite():
layer=FUNCTIONAL_TESTING,
)

traversal_txt = layered(
doctest.DocFileSuite('traversal.txt', checker=Py23DocChecker()),
layer=FUNCTIONAL_TESTING,
)
crud_readme_txt = layered(
doctest.DocFileSuite('crud/README.txt', checker=Py23DocChecker()),
layer=zca.UNIT_TESTING,
)
crud_py = layered(
doctest.DocTestSuite(
'plone.z3cform.crud.crud',
setUp=testing.setUp,
tearDown=testing.tearDown,
checker=Py23DocChecker(),
),
layer=zca.UNIT_TESTING,
)
traversal_txt = layered(
doctest.DocFileSuite('traversal.txt', checker=Py23DocChecker()),
layer=FUNCTIONAL_TESTING,
Expand All @@ -204,17 +221,7 @@ def test_suite():
inputs_txt,
fieldsets_txt,
traversal_txt,
doctest.DocFileSuite(
'crud/README.txt',
setUp=testing.setUp,
tearDown=testing.tearDown,
checker=Py23DocChecker(),
),
doctest.DocTestSuite(
'plone.z3cform.crud.crud',
setUp=testing.setUp,
tearDown=testing.tearDown,
checker=Py23DocChecker(),
),
crud_readme_txt,
crud_py,
]
)

0 comments on commit 7abce7a

Please sign in to comment.