z3c.forms を使用して新しいウィジェットを開発しようとしていますが、機能テストを行うことができるようになりました。
残念ながら、フォームを使用してテストをセットアップすると、updateWidgets が呼び出されると、IWidgets インターフェイスに対して ComponentLookupError が発生し、z3c.form.field から FieldWidgets を検索する必要があります。
テストセットアップで z3c.form を適切に登録していないと推測していますが、修正方法がわかりません。
テストコードは次のとおりです。
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: 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'')
ここに私がスタックトレースを突っ込んでいます:
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
アップデート:
また、サンプル フォームをインスタンス化する直前にインターフェイスを明示的に登録しようとしましたが、それは役に立たず、ComponentLookupError が再び発生しました。
from z3c.form import form, field, interfaces
zope.interface.classImplementsOnly(field.FieldWidgets,
interfaces.IWidgets)