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

jjlee at codespeak.net jjlee at codespeak.net
Sat Oct 8 22:22:24 CEST 2005


Author: jjlee
Date: Sat Oct  8 22:22:23 2005
New Revision: 18296

Modified:
   wwwsearch/ClientForm/trunk/ClientForm.py
   wwwsearch/ClientForm/trunk/test.py
Log:
Fix single-select .fixup() behaviour; Fix empty value assigment in backwards_compat case

Modified: wwwsearch/ClientForm/trunk/ClientForm.py
==============================================================================
--- wwwsearch/ClientForm/trunk/ClientForm.py	(original)
+++ wwwsearch/ClientForm/trunk/ClientForm.py	Sat Oct  8 22:22:23 2005
@@ -1827,8 +1827,9 @@
         if value is None or isstringlike(value):
             raise TypeError("ListControl, must set a sequence")
         if not value:
+            compat = self._form.backwards_compat
             for o in self.items:
-                if not o.disabled:
+                if not o.disabled or compat:
                     o.selected = False
         elif self.multiple:
             self._multiple_set_value(value)
@@ -1847,7 +1848,8 @@
                 raise ItemNotFoundError(
                     "insufficient items with name %r" % name)
             else:
-                raise AttributeError("disabled item with name %s" % name)
+                raise AttributeError(
+                    "insufficient non-disabled items with name %s" % name)
         on = []
         off = []
         for o in items:
@@ -1858,13 +1860,16 @@
         return on, off
 
     def _single_set_value(self, value):
+        assert len(value) == 1
         on, off = self._get_items(value[0])
+        assert len(on) <= 1
         if not on:
             off[0].selected = True
 
     def _multiple_set_value(self, value):
         turn_on = []  # transactional-ish
-        turn_off = [item for item in self.items if item.selected and not item.disabled]
+        turn_off = [item for item in self.items if
+                    item.selected and not item.disabled]
         names = {}
         for nn in value:
             if nn in names.keys():
@@ -2129,7 +2134,10 @@
 
     def fixup(self):
         ListControl.fixup(self)
-        found = [o for o in self.items if o.selected and not o.disabled]
+        # Firefox doesn't exclude disabled items from those considered here
+        # (i.e. from 'found', for both brances of the if below).  Note that IE
+        # doesn't support the disabled attribute on OPTIONs at all.
+        found = [o for o in self.items if o.selected]
         if not found:
             if not self.multiple or self._select_default:
                 for o in self.items:

Modified: wwwsearch/ClientForm/trunk/test.py
==============================================================================
--- wwwsearch/ClientForm/trunk/test.py	(original)
+++ wwwsearch/ClientForm/trunk/test.py	Sat Oct  8 22:22:23 2005
@@ -448,10 +448,12 @@
         pairs = form.click_pairs()
         self.assert_(pairs == [("foo", "on"), ("bar", "on"), ("submit", "")])
 
-    def testBadSingleSelect(self):
+    def testSingleSelectFixup(self):
         # HTML 4.01 section 17.6.1: single selection SELECT controls shouldn't
         # have > 1 item selected, but if they do, not more than one should end
         # up selected.
+        # In fact, testing really obscure stuff here, which follows Firefox
+        # 1.0.7 -- IE doesn't even support disabled OPTIONs.
         file = StringIO("""<form action="./bad.html">
 
 <select name="spam">
@@ -459,17 +461,39 @@
   <option selected>2</option>
 </select>
 
-<input type="submit" name="submit">
+<select name="cow">
+  <option selected>1</option>
+  <option disabled selected>2</option>
+</select>
+
+<select name="moo">
+  <option selected disabled>1</option>
+  <option>2</option>
+</select>
+
+<select name="nnn">
+  <option disabled>1</option>
+  <option>2</option>
+  <option>3</option>
+</select>
+
 </form>
 """)
         forms = ClientForm.ParseFile(file, "http://localhost/",
                                      backwards_compat=False)
         form = forms[0]
-        hide_deprecations()
-        self.assert_(form.possible_items("spam") == ["1", "2"])
-        reset_deprecations()
-        nr_selected = len(form.find_control("spam").pairs())
-        self.assert_(nr_selected == 1)
+        # deselect all but last item if more than one were selected...
+        spam = form.find_control("spam")
+        self.assertEqual([ii.name for ii in spam.items if ii.selected], ["2"])
+        # ...even if it's disabled
+        cow = form.find_control("cow")
+        self.assertEqual([ii.name for ii in cow.items if ii.selected], ["2"])
+        # exactly one selected item is OK even if it's disabled
+        moo = form.find_control("moo")
+        self.assertEqual([ii.name for ii in moo.items if ii.selected], ["1"])
+        # if nothing was selected choose the first non-disabled item
+        moo = form.find_control("nnn")
+        self.assertEqual([ii.name for ii in moo.items if ii.selected], ["2"])
 
     def testSelectDefault(self):
         file = StringIO(
@@ -666,14 +690,20 @@
 
         # ...single-selection
         control = get_control("bar")
-        # 7 is selected but disabled, so 1 is selected by browser
-        self.assertEqual(control.value, ['1'])
+        # 7 is selected but disabled
+        if compat:
+            value = ["7"]
+        else:
+            value = []
+        self.assertEqual(control.value, value)
+        self.assertEqual(
+            [ii.name for ii in control.items if ii.selected], ["7"])
         control.value = ["2"]
 
         control = get_control("bar")
         def assign_8(control=control): control.value = ["8"]
         self.assertRaises(AttributeError, assign_8)
-        self.assertEqual(control.value, ['1'])
+        self.assertEqual(control.value, value)
         def assign_7(control=control): control.value = ["7"]
         self.assertRaises(AttributeError, assign_7)
         # enable all items
@@ -724,9 +754,9 @@
         control.set_item_disabled(True, "7")
         self.assert_(control.get_item_disabled("7"))
         self.assertRaises(AttributeError, control.set, True, "7")
-        self.assertEqual(control.value, ['1'])
+        self.assertEqual(control.value, value)
         control.set_item_disabled(False, "7")
-        self.assertEqual(control.value, ['1'])
+        self.assertEqual(control.value, ["7"])
         self.assert_(not control.get_item_disabled("7"))
         control.set(True, "7")
         control.set(False, "7")
@@ -2259,6 +2289,39 @@
                     c.get_value_by_label(),
                     ["Loaf of Bread", "Loaf of Bread"])
 
+    def testClearValue(self):
+        # regression test: follow ClientForm 0.1 behaviour
+        # assigning [] to value is implemented as a special case
+        f = StringIO("""\
+<form>
+    <select multiple name="s">
+        <option disabled selected>a</option>
+        <option selected>b</option>
+    </select>
+</form>
+""")
+        for kwds, backwards_compat in [
+                ({}, True),
+                ({"backwards_compat": True}, True),
+                ({"backwards_compat": False}, False),
+                ]:
+            hide_deprecations()
+            form = ClientForm.ParseFile(f, "http://localhost/", **kwds)[0]
+            reset_deprecations()
+            f.seek(0)
+            cc = form.find_control("s")
+            if backwards_compat:
+                self.assertEqual(cc.value, ["a", "b"])
+                cc.value = []
+                self.assertEqual(
+                    [ii.name for ii in cc.items if ii.selected], [])
+            else:
+                self.assertEqual(cc.value, ["b"])
+                cc.value = []
+                # first is disabled, so no need to deselect
+                self.assertEqual(
+                    [ii.name for ii in cc.items if ii.selected], ["a"])
+
     def testSearchByLabel(self):
         f = StringIO("""\
 <form>


More information about the wwwsearch-commits mailing list