[wwwsearch-commits] r17947 - wwwsearch/ClientForm/trunk

jjlee at codespeak.net jjlee at codespeak.net
Wed Sep 28 21:40:11 CEST 2005


Author: jjlee
Date: Wed Sep 28 21:40:10 2005
New Revision: 17947

Modified:
   wwwsearch/ClientForm/trunk/ClientForm.py
   wwwsearch/ClientForm/trunk/test.py
Log:
Implement disabled item behaviour backwards-compatibility; For non-backwards compatible forms, make setting disabled item selected state always raise AttributeError

Modified: wwwsearch/ClientForm/trunk/ClientForm.py
==============================================================================
--- wwwsearch/ClientForm/trunk/ClientForm.py	(original)
+++ wwwsearch/ClientForm/trunk/ClientForm.py	Wed Sep 28 21:40:10 2005
@@ -33,6 +33,10 @@
 #   -item label matching is strict
 #   -turning off individual items allowed even if disabled
 # Check old test suite passes!
+# Deprecate by_label in set/get_value()
+# Add .set/get_value_by_label() to HTMLForm
+# Remove by_label arg from .get() and add label arg
+# Merge .items_from*() methods into new .get_items() function
 
 # XXX
 # Add some more functional tests
@@ -1395,8 +1399,7 @@
 
     def __setattr__(self, name, value):
         if name == "selected":
-            if bool(value) != bool(self._selected):
-                self._control._set_selected_state(self, value)
+            self._control._set_selected_state(self, value)
         elif name == "disabled":
             self.__dict__["disabled"] = bool(value)
         else:
@@ -1643,10 +1646,12 @@
         if self.readonly:
             raise AttributeError("control '%s' is readonly" % self.name)
         action == bool(action)
-        #compat = self._form.backwards_compat
-        if item.disabled:
+        compat = self._form.backwards_compat
+        if not compat and item.disabled:
             raise AttributeError("item is disabled")
-        elif action != item.selected:
+        else:
+            if compat and item.disabled and action:
+                raise AttributeError("item is disabled")
             if self.multiple:
                 item.__dict__["_selected"] = action
             else:
@@ -1784,6 +1789,8 @@
 
     def __getattr__(self, name):
         if name == "value":
+            if self._form.backwards_compat:
+                return [o.name for o in self.items if o.selected]
             return [o.name for o in self.items if
                     not o.disabled and o.selected]
         else:

Modified: wwwsearch/ClientForm/trunk/test.py
==============================================================================
--- wwwsearch/ClientForm/trunk/test.py	(original)
+++ wwwsearch/ClientForm/trunk/test.py	Wed Sep 28 21:40:10 2005
@@ -497,6 +497,10 @@
 
 class DisabledTests(TestCase):
     def testOptgroup(self):
+        for compat in [False, True]:
+            self._testOptgroup(compat)
+
+    def _testOptgroup(self, compat):
         file = StringIO(
 """<form action="abc" name="myform">
 
@@ -544,9 +548,10 @@
 
 </form>""")
 
-        def get_control(name, file=file):
+        def get_control(name, file=file, compat=compat):
             file.seek(0)
-            forms = ClientForm.ParseFile(file, "http://localhost/")
+            forms = ClientForm.ParseFile(file, "http://localhost/",
+                                         backwards_compat=compat)
             form = forms[0]
             return form.find_control(name)
 
@@ -566,23 +571,27 @@
 
         # ...multi selection
         control = get_control("foo")
+        if compat:
+            extra = ["7"]
+        else:
+            extra = []
         # disabled items are not part of the submitted value, so "7" not
         # included (they are not "successful":
         # http://www.w3.org/TR/REC-html40/interact/forms.html#successful-controls
         # ).  This behavior was confirmed in Firefox 1.0.4 at least.
-        self.assertEqual(control.value, [])
+        self.assertEqual(control.value, []+extra)
         control.value = ["1"]
-        self.assertEqual(control.value, ["1"])
+        self.assertEqual(control.value, ["1"]+extra)
         control = get_control("foo")
         self.assertRaises(AttributeError, setattr, control, 'value', ['8'])
-        self.assertEqual(control.value, [])
+        self.assertEqual(control.value, []+extra)
         # even though 7 is set already, attempt to set it fails
         self.assertRaises(AttributeError, setattr, control, 'value', ['7'])
         control.value = ["1", "3"]
-        self.assertEqual(control.value, ["1", "3"])
+        self.assertEqual(control.value, ["1", "3"]+extra)
         control = get_control("foo")
         self.assertRaises(AttributeError, setattr, control, 'value', ['1', '7'])
-        self.assertEqual(control.value, [])
+        self.assertEqual(control.value, []+extra)
         # enable all items
         control.set_all_items_disabled(False)
         control.value = ['1', '7']
@@ -592,15 +601,27 @@
         hide_deprecations()
         for name in 7, 8, 10:
             self.assert_(control.get_item_disabled(str(name)))
-            # a disabled option is never "successful" (see above) so never in
-            # value
-            self.assert_(str(name) not in control.value)
-            # a disabled option always is always upset if you try to set it
-            self.assertRaises(AttributeError, control.set, True, str(name))
-            self.assertRaises(AttributeError, control.set, False, str(name))
-            self.assertRaises(AttributeError, control.toggle, str(name))
-            # still not in value
-            self.assert_(str(name) not in control.value)
+            if not compat:
+                # a disabled option is never "successful" (see above) so never
+                # in value
+                self.assert_(str(name) not in control.value)
+                # a disabled option always is always upset if you try to set it
+                self.assertRaises(AttributeError, control.set, True, str(name))
+                self.assert_(str(name) not in control.value)
+                self.assertRaises(AttributeError, control.set, False, str(name))
+                self.assert_(str(name) not in control.value)
+                self.assertRaises(AttributeError, control.toggle, str(name))
+                self.assert_(str(name) not in control.value)
+            else:
+                self.assertRaises(AttributeError, control.set, True, str(name))
+                control.set(False, str(name))
+                self.assert_(str(name) not in control.value)
+                control.set(False, str(name))
+                self.assert_(str(name) not in control.value)
+                self.assertRaises(AttributeError, control.toggle, str(name))
+                self.assert_(str(name) not in control.value)
+                self.assertRaises(AttributeError, control.set, True, str(name))
+                self.assert_(str(name) not in control.value)
 
         control = get_control("foo")
         for name in 1, 2, 3, 4, 5, 6, 9:
@@ -648,15 +669,27 @@
         hide_deprecations()
         for name in 7, 8, 10:
             self.assert_(control.get_item_disabled(str(name)))
-            # a disabled option is never "successful" (see above) so never in
-            # value
-            self.assert_(str(name) not in control.value)
-            # a disabled option always is always upset if you try to set it
-            self.assertRaises(AttributeError, control.set, True, str(name))
-            self.assertRaises(AttributeError, control.set, False, str(name))
-            self.assertRaises(AttributeError, control.toggle, str(name))
-            # still not in value
-            self.assert_(str(name) not in control.value)
+            if not compat:
+                # a disabled option is never "successful" (see above) so never in
+                # value
+                self.assert_(str(name) not in control.value)
+                # a disabled option always is always upset if you try to set it
+                self.assertRaises(AttributeError, control.set, True, str(name))
+                self.assert_(str(name) not in control.value)
+                self.assertRaises(AttributeError, control.set, False, str(name))
+                self.assert_(str(name) not in control.value)
+                self.assertRaises(AttributeError, control.toggle, str(name))
+                self.assert_(str(name) not in control.value)
+            else:
+                self.assertRaises(AttributeError, control.set, True, str(name))
+                control.set(False, str(name))
+                self.assert_(str(name) != control.value)
+                control.set(False, str(name))
+                self.assert_(str(name) != control.value)
+                self.assertRaises(AttributeError, control.toggle, str(name))
+                self.assert_(str(name) != control.value)
+                self.assertRaises(AttributeError, control.set, True, str(name))
+                self.assert_(str(name) != control.value)
 
         control = get_control("bar")
         for name in 1, 2, 3, 4, 5, 6, 9:
@@ -697,6 +730,9 @@
 
 # XXX single select
     def testDisabledSelect(self):
+        for compat in [False, True]:
+           self._testDisabledSelect(compat)
+    def _testDisabledSelect(self, compat):
         file = StringIO(
 """<form action="abc" name="myform">
 
@@ -726,7 +762,8 @@
 
 </form>
 """)    
-        forms = ClientForm.ParseFile(file, "http://localhost/")
+        forms = ClientForm.ParseFile(file, "http://localhost/",
+                                     backwards_compat=compat)
         form = forms[0]
         for name, control_disabled, item_disabled in [
             ("foo", False, False),
@@ -766,6 +803,9 @@
         reset_deprecations()
 
     def testDisabledCheckbox(self):
+        for compat in False, True:
+            self._testDisabledCheckbox(self)
+    def _testDisabledCheckbox(self, compat):
         file = StringIO(
 """<form action="abc" name="myform">
 
@@ -782,7 +822,8 @@
 <input type="checkbox" name="baz" value="3" disabled></input>
 
 </form>""")
-        forms = ClientForm.ParseFile(file, "http://localhost/")
+        forms = ClientForm.ParseFile(file, "http://localhost/",
+                                     backwards_compat=compat)
         form = forms[0]
         for name, control_disabled, item_disabled in [
             ("foo", False, False),
@@ -1798,6 +1839,12 @@
                 self.assertRaises(AmbiguityError, fc, label="Book")
 
     def test_deselect_disabled(self):
+        def get_new_form(f, compat):
+            f.seek(0)
+            form = ClientForm.ParseFile(f, "http://example.com/")[0]
+            form.backwards_compat = compat
+            return form
+
         f = StringIO("""\
 <form>
     <input type="checkbox" name="p" value="a" disabled checked></input>
@@ -1805,42 +1852,98 @@
     <input type="checkbox" name="p" value="c"></input>
 </form>
 """)
-        def new_form():
-            f.seek(0)
-            form = ClientForm.ParseFile(f, "http://example.com/")[0]
-            form.backwards_compat = compat
-            ctl = form.find_control("p")
-            a = ctl.get("a")
-            return form, ctl, a
         for compat in [False]:#True, False:
-            form, ctl, a = new_form()
+            def new_form(compat=compat, f=f, get_new_form=get_new_form):
+                form = get_new_form(f, compat)
+                ctl = form.find_control("p")
+                a = ctl.get("a")
+                return ctl, a
+            ctl, a = new_form()
             ctl.value = ["b"]
 
             # :-((
             if compat:
                 # rationale: allowed to deselect, but not select, disabled
                 # items
-                form, ctl, a = new_form()
+                ctl, a = new_form()
                 self.assertRaises(AttributeError, setattr, a, "selected", True)
                 self.assertRaises(AttributeError, setattr, ctl, "value", ["a"])
                 a.selected = False
-                form, ctl, a = new_form()
+                ctl, a = new_form()
                 ctl.value = ["b"]
+                self.assertEqual(a.selected, False)
+                self.assertEqual(ctl.value, ["b"])
+                ctl, a = new_form()
+                self.assertRaises(AttributeError,
+                                  setattr, ctl, "value", ["a", "b"])
             else:
+
                 # rationale: Setting an individual item's selected state to its
                 # present value is a no-op, as is setting the whole control
                 # value where an item name doesn't appear in the new value, but
-                # that item is disabled anyway.  However, if the item's state
-                # does change, both selecting and deselecting are disallowed
-                # for disabled items.
-                form, ctl, a = new_form()
-                a.selected = True
-                form, ctl, a = new_form()
-                #ctl.value = ["a"]
+                # that item is disabled anyway (but an item name that does
+                # appear in the new value is treated an explicit request that
+                # that item name get sent to the server).  However, if the
+                # item's state does change, both selecting and deselecting are
+                # disallowed for disabled items.
+
+                ctl, a = new_form()
+                self.assertRaises(AttributeError,
+                                  setattr, a, "selected", True)
+                ctl, a = new_form()
+                self.assertRaises(AttributeError, setattr, ctl, "value", ["a"])
+                ctl, a = new_form()
+                self.assertRaises(AttributeError,
+                                  setattr, a, "selected", False)
+                ctl.value = ["b"]
+                self.assertEqual(a.selected, True)
+                self.assertEqual(ctl.value, ["b"])
+                ctl, a = new_form()
+                self.assertRaises(AttributeError,
+                                  setattr, ctl, "value", ["a", "b"])
+
+        f = StringIO("""\
+<form>
+    <input type="radio" name="p" value="a" disabled checked></input>
+    <input type="radio" name="p" value="b"></input>
+    <input type="radio" name="p" value="c"></input>
+</form>
+""")
+
+        for compat in [False]:#True, False:
+            def new_form(compat=compat, f=f, get_new_form=get_new_form):
+                form = get_new_form(f, compat)
+                ctl = form.find_control("p")
+                a = ctl.get("a")
+                return ctl, a
+            ctl, a = new_form()
+            ctl.value = ["b"]
+
+            if compat:
+                ctl, a = new_form()
+                self.assertRaises(AttributeError, setattr, a, "selected", True)
+                self.assertRaises(AttributeError, setattr, ctl, "value", ["a"])
+                a.selected = False
+                ctl, a = new_form()
+                ctl.value = ["b"]
+                self.assertEqual(a.selected, False)
+                self.assertEqual(ctl.value, ["b"])
+                ctl, a = new_form()
+                self.assertRaises(ItemCountError,
+                                  setattr, ctl, "value", ["a", "b"])
+            else:
+                ctl, a = new_form()
+                self.assertRaises(AttributeError, setattr, a, "selected", True)
+                ctl, a = new_form()
                 self.assertRaises(AttributeError, setattr, ctl, "value", ["a"])
-                form, ctl, a = new_form()
+                ctl, a = new_form()
                 self.assertRaises(AttributeError, setattr, a, "selected", False)
                 ctl.value = ["b"]
+                self.assertEqual(a.selected, False)
+                self.assertEqual(ctl.value, ["b"])
+                ctl, a = new_form()
+                self.assertRaises(ItemCountError,
+                                  setattr, ctl, "value", ["a", "b"])
 
     def test_click(self):
         file = StringIO(


More information about the wwwsearch-commits mailing list