I'm trying to develop a new widget using z3c.forms and I've got to the point when I can do functional testings.
Unfortunately, when I setup tests with forms, when updateWidgets is called ComponentLookupError is raised for IWidgets interface, which should just lookup FieldWidgets form z3c.form.field
I'm guessing I didn't properly registered z3c.form in test setup, but I have no idea how to fix it.
Here's test code:
import unittest2 as unittest
import zope.interface
import zope.schema
from z3c.schema.optchoice import OptionalChoice
from zope.app.testing import setup as ztc_setup
from z3c.form.testing import TestRequest
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
from zope.traversing.adapters import DefaultTraversable
from z3c.form import form, field
from widget import OptChoiceWidget, OptChoiceWidgetCustomTokenFactoryFactory
sample_terms = SimpleVocabulary([
SimpleTerm(value="first", title="First"),
SimpleTerm(value="second", title="Second")
])
class ISchema(zope.interface.Interface):
test_name = OptionalChoice(
title= u"This is a title",
values=sample_terms,
value_type=zope.schema.TextLine(),
)
class SampleForm(form.BaseForm):
widgets = [OptChoiceWidget]
fields = field.Fields(ISchema)
fields['test_name'].widgetFactory = OptChoiceWidgetCustomTokenFactoryFactory(('other', "Other"))
ignoreContext = True
class TestFunctionalForm(unittest.TestCase):
def setUp(self):
#plone.z3cform/tests.py
component.provideAdapter(DefaultTraversable, [None])
self.context = ztc_setup.placefulSetUp(True)
def tearDown(self):
ztc_setup.placefulTearDown()
def test_add_form(self):
sample_form = SampleForm(self.context, TestRequest())
data = sample_form.update()
Error message:
ERROR: test_add_form (z3cwidgetoptchoice.tests.TestFunctionalForm)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/alex/git/z3c.widget.optchoice/z3cwidgetoptchoice/tests.py", line 174, in test_add_form
data = sample_form.update()
File "/home/alex/.virtualenvs/optchoice/lib/python2.6/site-packages/z3c.form-2.9.1-py2.6.egg/z3c/form/form.py", line 150, in update
self.updateWidgets()
File "/home/alex/.virtualenvs/optchoice/lib/python2.6/site-packages/z3c.form-2.9.1-py2.6.egg/z3c/form/form.py", line 127, in updateWidgets
(self, self.request, self.getContent()), interfaces.IWidgets)
File "/home/alex/.virtualenvs/optchoice/lib/python2.6/site-packages/zope.component-4.0.1-py2.6.egg/zope/component/_api.py", line 112, in getMultiAdapter
raise ComponentLookupError(objects, interface, name)
ComponentLookupError: ((<z3cwidgetoptchoice.tests.SampleForm object at 0x462d990>, <z3c.form.testing.TestRequest instance URL=http://127.0.0.1>, <zope.site.folder.Folder object at 0x3f070c8>), <InterfaceClass z3c.form.interfaces.IWidgets>, u'')
Here's I'm poking in stack trace:
test_add_form (z3cwidgetoptchoice.tests.TestFunctionalForm) ... > /home/alex/.virtualenvs/optchoice/lib/python2.6/site-packages/zope.component-4.0.1-py2.6.egg/zope/component/_api.py(112)getMultiAdapter()
-> raise ComponentLookupError(objects, interface, name)
(Pdb) up
> /home/alex/.virtualenvs/optchoice/lib/python2.6/site-packages/z3c.form-2.9.1-py2.6.egg/z3c/form/form.py(127)updateWidgets()
-> (self, self.request, self.getContent()), interfaces.IWidgets)
(Pdb) self
<z3cwidgetoptchoice.tests.SampleForm object at 0x462d990>
(Pdb) self.request
<z3c.form.testing.TestRequest instance URL=http://127.0.0.1>
(Pdb) self.getContent()
<zope.site.folder.Folder object at 0x3f070c8>
(Pdb) list
122 return self.context
123
124 def updateWidgets(self, prefix=None):
125 '''See interfaces.IForm'''
126 self.widgets = zope.component.getMultiAdapter(
127 -> (self, self.request, self.getContent()), interfaces.IWidgets)
128 if prefix is not None:
129 self.widgets.prefix = prefix
130 self.widgets.mode = self.mode
131 self.widgets.ignoreContext = self.ignoreContext
132 self.widgets.ignoreRequest = self.ignoreRequest
(Pdb) c
ERROR
Update:
I also tried explicitly registering the interface just before instantiating Sample form, but that didn't help and ComponentLookupError got raised again.
from z3c.form import form, field, interfaces
zope.interface.classImplementsOnly(field.FieldWidgets,
interfaces.IWidgets)