[Zope3-checkins] CVS: Zope3/src/zope/app/browser/form/tests - test_add.py:1.11 test_editview.py:1.8

Jim Fulton jim@zope.com
Mon, 14 Apr 2003 04:27:46 -0400


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

Modified Files:
	test_add.py test_editview.py 
Log Message:
Updated the form-genmeration software to support accessors. Mainly
this involved changing the software to use field ``get``, ``query``,
and ``set`` methods rather than attribute access.  Also modified the
tests to test accessor usage.

Fixed adapter support. Now edit views store the adapted context
separately from the context. Also, edit and add views use getApter
rather than queryAdapter to get adapters. The previous uses of
queryAdapter were hiding some logic errors.  Added unit tests!
In the course of adding unit tests, I discovered an issue relating to
event generation. Normally, we generate an ObjectModification event
when we edit something, however, it's not so clear what we should do
in the presense of an adapter. I finally decided that we should not
generate an event if the object was adapted. In that case, the adapter
should generate any necessary events.


=== Zope3/src/zope/app/browser/form/tests/test_add.py 1.10 => 1.11 ===
--- Zope3/src/zope/app/browser/form/tests/test_add.py:1.10	Tue Apr  8 17:34:22 2003
+++ Zope3/src/zope/app/browser/form/tests/test_add.py	Mon Apr 14 04:27:15 2003
@@ -21,7 +21,7 @@
 
 from zope.app.browser.form.add import add, AddViewFactory, AddView
 from zope.interface import Interface
-from zope.schema import TextLine
+from zope.schema import TextLine, accessors
 from zope.app.interfaces.container import IAdding
 from zope.publisher.interfaces.browser import IBrowserPresentation
 from zope.app.form.widget import CustomWidget
@@ -29,7 +29,10 @@
 from zope.publisher.browser import TestRequest
 from zope.app.tests.placelesssetup import PlacelessSetup
 from zope.component import getView
+from zope.component.adapter import provideAdapter
 from zope.app.browser.form.submit import Update
+from zope.app.browser.form.tests.test_editview import IFoo, IBar, Foo
+from zope.app.browser.form.tests.test_editview import FooBarAdapter
 
 class Context:
 
@@ -50,7 +53,7 @@
     last = TextLine()
     email = TextLine()
     address = TextLine()
-    foo = TextLine()
+    getfoo, setfoo = accessors(TextLine())
     extra1 = TextLine()
     extra2 = TextLine()
 
@@ -62,16 +65,22 @@
         self.args = args
         self.kw = kw
 
+    def getfoo(self): return self._foo
+    def setfoo(self, v): self._foo = v
+
 class V:
     name_ = CustomWidget(Text)
     first = CustomWidget(Text)
     last = CustomWidget(Text)
     email = CustomWidget(Text)
     address = CustomWidget(Text)
-    foo = CustomWidget(Text)
+    getfoo = CustomWidget(Text)
     extra1 = CustomWidget(Text)
     extra2 = CustomWidget(Text)
 
+class FooV:
+    bar = CustomWidget(Text)
+
 
 class SampleData:
 
@@ -80,16 +89,20 @@
     last = u"baz"
     email = u"baz@dot.com"
     address = u"aa"
-    foo = u"foo"
+    getfoo = u"foo"
     extra1 = u"extra1"
     extra2 = u"extra2"
 
 class Test(PlacelessSetup, unittest.TestCase):
 
+    def setUp(self):
+        PlacelessSetup.setUp(self)
+        provideAdapter(IFoo, IBar, FooBarAdapter)
+
     def _invoke_add(self, schema="I", name="addthis", permission="zope.Public",
                     label="Add this", content_factory="C", class_="V",
                     arguments="first last", keyword_arguments="email",
-                    set_before_add="foo", set_after_add="extra1",
+                    set_before_add="getfoo", set_after_add="extra1",
                     fields=None):
         """ Call the 'add' factory to process arguments into 'args'."""
         return add(Context(),
@@ -110,7 +123,7 @@
 
         result1 = self._invoke_add()
         result2 = self._invoke_add(
-            fields="name_ first last email address foo extra1 extra2",
+            fields="name_ first last email address getfoo extra1 extra2",
             )
 
         self.assertEqual(result1, result2)
@@ -139,14 +152,14 @@
         self.assertEqual(bases, (V, AddView, ))
         self.assertEqual(for_, IAdding)
         self.assertEqual(" ".join(fields),
-                         "name_ first last email address foo extra1 extra2")
+                         "name_ first last email address getfoo extra1 extra2")
         self.assertEqual(content_factory, C)
         self.assertEqual(" ".join(arguments),
                          "first last")
         self.assertEqual(" ".join(keyword_arguments),
                          "email")
         self.assertEqual(" ".join(set_before_add),
-                         "foo")
+                         "getfoo")
         self.assertEqual(" ".join(set_after_add),
                          "extra1 name_ address extra2")
         self.failIf(kw)
@@ -168,7 +181,7 @@
                     ob.__dict__,
                     {'args': ("bar", "baz"),
                      'kw': {'email': 'baz@dot.com'},
-                     'foo': 'foo',
+                     '_foo': 'foo',
                     })
                 return ob
             def nextURL(self):
@@ -200,7 +213,7 @@
                     ob.__dict__,
                     {'args': ("bar", "baz"),
                      'kw': {'email': 'baz@dot.com'},
-                     'foo': 'foo',
+                     '_foo': 'foo',
                     })
                 return ob
             def nextURL(self):
@@ -211,6 +224,7 @@
         factory = AddViewFactory(*args)
         request = TestRequest()
         view = getView(adding, 'addthis', request)
+
         view.createAndAdd(SampleData.__dict__)
 
         self.assertEqual(adding.ob.extra1, "extra1")
@@ -218,6 +232,35 @@
         self.assertEqual(adding.ob.name_, "foo")
         self.assertEqual(adding.ob.address, "aa")
 
+    def test_createAndAdd_w_adapter(self):
+
+        class Adding:
+
+            __implements__ = IAdding
+
+            def __init__(self, test):
+                self.test = test
+
+            def add(self, ob):
+                self.ob = ob
+                self.test.assertEqual(ob.__dict__, {'foo': 'bar'})
+                return ob
+            def nextURL(self):
+                return "."
+
+        adding = Adding(self)
+        [(descriminator, callable, args, kw)] = self._invoke_add(
+            schema="IBar", name="addthis", permission="zope.Public",
+            label="Add this", content_factory="Foo", class_="FooV",
+            arguments="", keyword_arguments="",
+            set_before_add="bar", set_after_add="",
+            fields=None)
+        factory = AddViewFactory(*args)
+        request = TestRequest()
+        view = getView(adding, 'addthis', request)
+
+        view.createAndAdd({'bar': 'bar'})
+
     def test_hooks(self):
 
         class Adding:
@@ -246,7 +289,7 @@
                 ob.__dict__,
                 {'args': ("bar", "baz"),
                  'kw': {'email': 'baz@dot.com'},
-                 'foo': 'foo',
+                 '_foo': 'foo',
                  })
             return ob
 


=== Zope3/src/zope/app/browser/form/tests/test_editview.py 1.7 => 1.8 ===
--- Zope3/src/zope/app/browser/form/tests/test_editview.py:1.7	Tue Apr  8 17:34:22 2003
+++ Zope3/src/zope/app/browser/form/tests/test_editview.py	Mon Apr 14 04:27:15 2003
@@ -18,21 +18,23 @@
 from zope.app.tests.placelesssetup import PlacelessSetup
 from zope.app.event.tests.placelesssetup import getEvents
 from zope.interface import Interface
-from zope.schema import TextLine
+from zope.schema import TextLine, accessors
 from zope.schema.interfaces import ITextLine
 from zope.publisher.browser import TestRequest
 from zope.publisher.interfaces.browser import IBrowserPresentation
 from zope.app.browser.form.editview import EditView
 from zope.component.view import provideView, setDefaultViewName
+from zope.component.adapter import provideAdapter
 from zope.app.browser.form.widget import TextWidget
 from zope.app.browser.form.submit import Update
+from zope.component.exceptions import ComponentLookupError
 
 class I(Interface):
     foo = TextLine(title=u"Foo")
     bar = TextLine(title=u"Bar")
     a   = TextLine(title=u"A")
     b   = TextLine(title=u"B")
-    baz = TextLine(title=u"Baz")
+    getbaz, setbaz = accessors(TextLine(title=u"Baz"))
 
 class EV(EditView):
     schema = I
@@ -43,10 +45,36 @@
     bar = u"c bar"
     a   = u"c a"
     b   = u"c b"
-    baz = u"c baz"
+    
+    _baz = u"c baz"
+    def getbaz(self): return self._baz
+    def setbaz(self, v): self._baz = v
 
-class NonConforming(C):
-    __implements__ = ()
+
+class IFoo(Interface):
+    foo = TextLine(title=u"Foo")
+    
+class IBar(Interface):
+    bar = TextLine(title=u"Bar")
+
+class Foo:
+    __implements__ = IFoo
+
+    foo = 'Foo foo'
+
+class FooBarAdapter(object):
+
+    def __init__(self, context):
+        self.context = context
+
+    def setbar(self, v):
+        self.context.foo = v
+
+    bar = property(lambda self: self.context.foo,
+                   setbar)
+
+class BarV(EditView):
+    schema = IBar
 
 class Test(PlacelessSetup, unittest.TestCase):
 
@@ -54,13 +82,14 @@
         PlacelessSetup.setUp(self)
         provideView(ITextLine, 'edit', IBrowserPresentation, TextWidget)
         setDefaultViewName(ITextLine, IBrowserPresentation, "edit")
+        provideAdapter(IFoo, IBar, FooBarAdapter)
 
     def test_setPrefix_and_widgets(self):
         v = EV(C(), TestRequest())
         v.setPrefix("test")
         self.assertEqual(
             [w.name for w in v.widgets()],
-            ['test.foo', 'test.bar', 'test.a', 'test.b', 'test.baz']
+            ['test.foo', 'test.bar', 'test.a', 'test.b', 'test.getbaz']
             )
 
     def test_apply_update_no_data(self):
@@ -70,13 +99,13 @@
         d = {}
         d['foo'] = u'c foo'
         d['bar'] = u'c bar'
-        d['baz'] = u'c baz'
+        d['getbaz'] = u'c baz'
         self.failUnless(v.apply_update(d))
         self.assertEqual(c.foo, u'c foo')
         self.assertEqual(c.bar, u'c bar')
         self.assertEqual(c.a  , u'c a')
         self.assertEqual(c.b  , u'c b')
-        self.assertEqual(c.baz, u'c baz')
+        self.assertEqual(c.getbaz(), u'c baz')
         self.failIf(getEvents())
 
     def test_apply_update(self):
@@ -86,32 +115,32 @@
         d = {}
         d['foo'] = u'd foo'
         d['bar'] = u'd bar'
-        d['baz'] = u'd baz'
+        d['getbaz'] = u'd baz'
         self.failIf(v.apply_update(d))
         self.assertEqual(c.foo, u'd foo')
         self.assertEqual(c.bar, u'd bar')
         self.assertEqual(c.a  , u'c a')
         self.assertEqual(c.b  , u'c b')
-        self.assertEqual(c.baz, u'd baz')
+        self.assertEqual(c.getbaz(), u'd baz')
         self.failUnless(getEvents(filter=lambda event: event.object == c))
 
-    def test_apply_update_w_non_conforming_context(self):
-        # XXX   This feels bogus:  why should we be used to edit a context
-        #       which doesn't implement our schema?
-        c = NonConforming()
+    def test_apply_update_w_adapter(self):
+        c = Foo()
         request = TestRequest()
-        v = EV(c, request)
+        v = BarV(c, request)
         d = {}
-        d['foo'] = u'd foo'
         d['bar'] = u'd bar'
-        d['baz'] = u'd baz'
         self.failIf(v.apply_update(d))
-        self.assertEqual(c.foo, u'd foo')
-        self.assertEqual(c.bar, u'd bar')
-        self.assertEqual(c.a  , u'c a')
-        self.assertEqual(c.b  , u'c b')
-        self.assertEqual(c.baz, u'd baz')
-        self.failUnless(getEvents(filter=lambda event: event.object == c))
+        self.assertEqual(c.foo, u'd bar')
+
+        # We should not get events whan an adapter is used. That's the
+        # adapter's job.
+        self.failIf(getEvents())
+
+    def test_fail_wo_adapter(self):
+        c = Foo()
+        request = TestRequest()
+        self.assertRaises(ComponentLookupError, EV, c, request)
 
     def test_update_no_update(self):
         c = C()
@@ -122,18 +151,18 @@
         self.assertEqual(c.bar, u'c bar')
         self.assertEqual(c.a  , u'c a')
         self.assertEqual(c.b  , u'c b')
-        self.assertEqual(c.baz, u'c baz')
+        self.assertEqual(c.getbaz(), u'c baz')
         request.form['field.foo'] = u'r foo'
         request.form['field.bar'] = u'r bar'
         request.form['field.a']   = u'r a'
         request.form['field.b']   = u'r b'
-        request.form['field.baz'] = u'r baz'
+        request.form['field.getbaz'] = u'r baz'
         self.assertEqual(v.update(), '')
         self.assertEqual(c.foo, u'c foo')
         self.assertEqual(c.bar, u'c bar')
         self.assertEqual(c.a  , u'c a')
         self.assertEqual(c.b  , u'c b')
-        self.assertEqual(c.baz, u'c baz')
+        self.assertEqual(c.getbaz(), u'c baz')
         self.failIf(getEvents())
 
     def test_update(self):
@@ -143,7 +172,7 @@
         request.form[Update] = ''
         request.form['field.foo'] = u'r foo'
         request.form['field.bar'] = u'r bar'
-        request.form['field.baz'] = u'r baz'
+        request.form['field.getbaz'] = u'r baz'
         request.form['field.a'] = u'c a'
 
         message = v.update()
@@ -152,7 +181,7 @@
         self.assertEqual(c.bar, u'r bar')
         self.assertEqual(c.a  , u'c a')
         self.assertEqual(c.b  , None)
-        self.assertEqual(c.baz, u'r baz')
+        self.assertEqual(c.getbaz(), u'r baz')
 
         # Verify that calling update multiple times has no effect
 
@@ -162,7 +191,7 @@
         self.assertEqual(c.bar, u'c bar')
         self.assertEqual(c.a  , u'c a')
         self.assertEqual(c.b  , u'c b')
-        self.assertEqual(c.baz, u'c baz')
+        self.assertEqual(c.getbaz(), u'c baz')