Merge lp:~noskcaj/ubuntu/trusty/webtest/merge into lp:ubuntu/trusty/webtest
- Trusty (14.04)
- merge
- Merge into trusty
Proposed by
Jackson Doak
Status: | Merged |
---|---|
Merge reported by: | Martin Pitt |
Merged at revision: | not available |
Proposed branch: | lp:~noskcaj/ubuntu/trusty/webtest/merge |
Merge into: | lp:ubuntu/trusty/webtest |
Diff against target: |
356 lines (+163/-15) 9 files modified
CHANGELOG.rst (+14/-0) PKG-INFO (+1/-1) WebTest.egg-info/PKG-INFO (+1/-1) debian/changelog (+25/-0) docs/changelog.txt (+14/-0) docs/forms.txt (+16/-0) setup.py (+1/-1) tests/test_forms.py (+23/-0) webtest/forms.py (+68/-12) |
To merge this branch: | bzr merge lp:~noskcaj/ubuntu/trusty/webtest/merge |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Pitt | Approve | ||
Review via email:
|
Commit message
Description of the change
New upstream bugfix release
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CHANGELOG.rst' |
2 | --- CHANGELOG.rst 2014-01-20 12:45:19 +0000 |
3 | +++ CHANGELOG.rst 2014-03-07 23:00:45 +0000 |
4 | @@ -1,6 +1,20 @@ |
5 | News |
6 | ==== |
7 | |
8 | +2.0.14 (2014-01-23) |
9 | +------------------- |
10 | + |
11 | +- Allow `.select()` on <select>s and <select multiple>s. |
12 | + [Markus Bertheau] |
13 | + |
14 | + |
15 | +2.0.13 (2014-01-23) |
16 | +------------------- |
17 | + |
18 | +- Allow selecting <select> options by text |
19 | + [Markus Bertheau] |
20 | + |
21 | + |
22 | 2.0.12 (2014-01-17) |
23 | ------------------- |
24 | |
25 | |
26 | === modified file 'PKG-INFO' |
27 | --- PKG-INFO 2014-01-20 12:45:19 +0000 |
28 | +++ PKG-INFO 2014-03-07 23:00:45 +0000 |
29 | @@ -1,6 +1,6 @@ |
30 | Metadata-Version: 1.1 |
31 | Name: WebTest |
32 | -Version: 2.0.12 |
33 | +Version: 2.0.14 |
34 | Summary: Helper to test WSGI applications |
35 | Home-page: http://webtest.pythonpaste.org/ |
36 | Author: Gael Pasgrimaud |
37 | |
38 | === modified file 'WebTest.egg-info/PKG-INFO' |
39 | --- WebTest.egg-info/PKG-INFO 2014-01-20 12:45:19 +0000 |
40 | +++ WebTest.egg-info/PKG-INFO 2014-03-07 23:00:45 +0000 |
41 | @@ -1,6 +1,6 @@ |
42 | Metadata-Version: 1.1 |
43 | Name: WebTest |
44 | -Version: 2.0.12 |
45 | +Version: 2.0.14 |
46 | Summary: Helper to test WSGI applications |
47 | Home-page: http://webtest.pythonpaste.org/ |
48 | Author: Gael Pasgrimaud |
49 | |
50 | === modified file 'debian/changelog' |
51 | --- debian/changelog 2014-01-20 12:45:19 +0000 |
52 | +++ debian/changelog 2014-03-07 23:00:45 +0000 |
53 | @@ -1,9 +1,34 @@ |
54 | +webtest (2.0.14-1ubuntu1) trusty; urgency=medium |
55 | + |
56 | + * Merge from Debian unstable. Remaining changes: |
57 | + - d/control: Demote python-lxml and python-pyquery to Suggests. |
58 | + |
59 | + -- Jackson Doak <noskcaj@ubuntu.com> Sat, 08 Mar 2014 09:36:06 +1100 |
60 | + |
61 | +webtest (2.0.14-1) unstable; urgency=medium |
62 | + |
63 | + * New upstream release |
64 | + |
65 | + -- Piotr Ożarowski <piotr@debian.org> Thu, 23 Jan 2014 23:12:31 +0100 |
66 | + |
67 | +webtest (2.0.12-1) unstable; urgency=medium |
68 | + |
69 | + * New upstream release |
70 | + |
71 | + -- Piotr Ożarowski <piotr@debian.org> Wed, 22 Jan 2014 22:32:04 +0100 |
72 | + |
73 | webtest (2.0.12-0ubuntu1) trusty; urgency=medium |
74 | |
75 | * New usptream version. |
76 | |
77 | -- Chuck Short <zulcss@ubuntu.com> Mon, 20 Jan 2014 12:45:19 -0500 |
78 | |
79 | +webtest (2.0.11-1) unstable; urgency=medium |
80 | + |
81 | + * New upstream release |
82 | + |
83 | + -- Piotr Ożarowski <piotr@debian.org> Sun, 12 Jan 2014 19:26:17 +0100 |
84 | + |
85 | webtest (2.0.10-2ubuntu1) trusty; urgency=low |
86 | |
87 | * Merge from Debian unstable. Remaining changes: |
88 | |
89 | === modified file 'docs/changelog.txt' |
90 | --- docs/changelog.txt 2014-01-20 12:45:19 +0000 |
91 | +++ docs/changelog.txt 2014-03-07 23:00:45 +0000 |
92 | @@ -1,6 +1,20 @@ |
93 | News |
94 | ==== |
95 | |
96 | +2.0.14 (2014-01-23) |
97 | +------------------- |
98 | + |
99 | +- Allow `.select()` on <select>s and <select multiple>s. |
100 | + [Markus Bertheau] |
101 | + |
102 | + |
103 | +2.0.13 (2014-01-23) |
104 | +------------------- |
105 | + |
106 | +- Allow selecting <select> options by text |
107 | + [Markus Bertheau] |
108 | + |
109 | + |
110 | 2.0.12 (2014-01-17) |
111 | ------------------- |
112 | |
113 | |
114 | === modified file 'docs/forms.txt' |
115 | --- docs/forms.txt 2014-01-20 12:45:19 +0000 |
116 | +++ docs/forms.txt 2014-03-07 23:00:45 +0000 |
117 | @@ -96,6 +96,22 @@ |
118 | ['option2', 'option3'] |
119 | >>> form['multiple'] = ['option1'] |
120 | |
121 | +You can select an option by its text with ``.select()``: |
122 | + |
123 | +.. code-block:: python |
124 | + |
125 | + >>> form['select'].select(text="Option 2") |
126 | + >>> print(form['select'].value) |
127 | + option2 |
128 | + |
129 | +For select multiple use ``.select_multiple()``: |
130 | + |
131 | +.. code-block:: python |
132 | + |
133 | + >>> form['multiple'].select_multiple(texts=["Option 1", "Option 2"]) |
134 | + >>> print(form['multiple'].value) # doctest: +SKIP |
135 | + ['option1', 'option2'] |
136 | + |
137 | Select fields can only be set to valid values (i.e., values in an ``<option>``) |
138 | but you can also use ``.force_value()`` to enter values not present in an |
139 | option. |
140 | |
141 | === modified file 'setup.py' |
142 | --- setup.py 2014-01-20 12:45:19 +0000 |
143 | +++ setup.py 2014-03-07 23:00:45 +0000 |
144 | @@ -5,7 +5,7 @@ |
145 | from setuptools import setup |
146 | from setuptools import find_packages |
147 | |
148 | -version = '2.0.12' |
149 | +version = '2.0.14' |
150 | |
151 | tests_require = ['nose', 'coverage', 'mock', 'PasteDeploy', 'WSGIProxy2', 'pyquery'] |
152 | opt_install_requires = [] |
153 | |
154 | === modified file 'tests/test_forms.py' |
155 | --- tests/test_forms.py 2014-01-20 12:45:19 +0000 |
156 | +++ tests/test_forms.py 2014-03-07 23:00:45 +0000 |
157 | @@ -520,6 +520,17 @@ |
158 | display = single_form.submit("button") |
159 | self.assertIn("<p>You selected 6</p>", display, display) |
160 | |
161 | + res = app.get('/') |
162 | + single_form = res.forms["single_select_form"] |
163 | + self.assertRaises(ValueError, single_form.select, "single", "5", |
164 | + text="Five") |
165 | + self.assertRaises(ValueError, single_form.select, "single", |
166 | + text="Three") |
167 | + single_form.select("single", text="Seven") |
168 | + self.assertEqual(single_form["single"].value, "7") |
169 | + display = single_form.submit("button") |
170 | + self.assertIn("<p>You selected 7</p>", display, display) |
171 | + |
172 | def test_single_select_forced_value(self): |
173 | app = webtest.TestApp(select_app) |
174 | res = app.get('/') |
175 | @@ -591,6 +602,18 @@ |
176 | display = multiple_form.submit("button") |
177 | self.assertIn("<p>You selected 9</p>", display, display) |
178 | |
179 | + res = app.get('/') |
180 | + multiple_form = res.forms["multiple_select_form"] |
181 | + self.assertRaises(ValueError, multiple_form.select_multiple, |
182 | + "multiple", |
183 | + ["8", "10"], texts=["Eight", "Ten"]) |
184 | + self.assertRaises(ValueError, multiple_form.select_multiple, |
185 | + "multiple", texts=["Twelve"]) |
186 | + multiple_form.select_multiple("multiple", |
187 | + texts=["Eight", "Nine", "Ten"]) |
188 | + display = multiple_form.submit("button") |
189 | + self.assertIn("<p>You selected 8, 9, 10</p>", display, display) |
190 | + |
191 | def test_multiple_select_forced_values(self): |
192 | app = webtest.TestApp(select_app) |
193 | res = app.get('/') |
194 | |
195 | === modified file 'webtest/forms.py' |
196 | --- webtest/forms.py 2014-01-20 12:45:19 +0000 |
197 | +++ webtest/forms.py 2014-03-07 23:00:45 +0000 |
198 | @@ -112,10 +112,28 @@ |
199 | """ |
200 | self._forced_value = value |
201 | |
202 | + def select(self, value=None, text=None): |
203 | + if value is not None and text is not None: |
204 | + raise ValueError("Specify only one of value and text.") |
205 | + |
206 | + if text is not None: |
207 | + value = self._get_value_for_text(text) |
208 | + |
209 | + self.value = value |
210 | + |
211 | + def _get_value_for_text(self, text): |
212 | + for i, (option_value, checked, option_text) in enumerate(self.options): |
213 | + if option_text == utils.stringify(text): |
214 | + return option_value |
215 | + |
216 | + raise ValueError("Option with text %r not found (from %s)" |
217 | + % (text, ', '.join( |
218 | + [repr(t) for o, c, t in self.options]))) |
219 | + |
220 | def value__set(self, value): |
221 | if self._forced_value is not NoValue: |
222 | self._forced_value = NoValue |
223 | - for i, (option, checked) in enumerate(self.options): |
224 | + for i, (option, checked, text) in enumerate(self.options): |
225 | if option == utils.stringify(value): |
226 | self.selectedIndex = i |
227 | break |
228 | @@ -123,7 +141,7 @@ |
229 | raise ValueError( |
230 | "Option %r not found (from %s)" |
231 | % (value, ', '.join( |
232 | - [repr(o) for o, c in self.options]))) |
233 | + [repr(o) for o, c, t in self.options]))) |
234 | |
235 | def value__get(self): |
236 | if self._forced_value is not NoValue: |
237 | @@ -131,7 +149,7 @@ |
238 | elif self.selectedIndex is not None: |
239 | return self.options[self.selectedIndex][0] |
240 | else: |
241 | - for option, checked in self.options: |
242 | + for option, checked, text in self.options: |
243 | if checked: |
244 | return option |
245 | else: |
246 | @@ -158,10 +176,35 @@ |
247 | self._forced_values = values |
248 | self.selectedIndices = [] |
249 | |
250 | + def select_multiple(self, value=None, texts=None): |
251 | + if value is not None and texts is not None: |
252 | + raise ValueError("Specify only one of value and texts.") |
253 | + |
254 | + if texts is not None: |
255 | + value = self._get_value_for_texts(texts) |
256 | + |
257 | + self.value = value |
258 | + |
259 | + def _get_value_for_texts(self, texts): |
260 | + str_texts = [utils.stringify(text) for text in texts] |
261 | + value = [] |
262 | + for i, (option, checked, text) in enumerate(self.options): |
263 | + if text in str_texts: |
264 | + value.append(option) |
265 | + str_texts.remove(text) |
266 | + |
267 | + if str_texts: |
268 | + raise ValueError( |
269 | + "Option(s) %r not found (from %s)" |
270 | + % (', '.join(str_texts), |
271 | + ', '.join([repr(t) for o, c, t in self.options]))) |
272 | + |
273 | + return value |
274 | + |
275 | def value__set(self, values): |
276 | str_values = [utils.stringify(value) for value in values] |
277 | self.selectedIndices = [] |
278 | - for i, (option, checked) in enumerate(self.options): |
279 | + for i, (option, checked, text) in enumerate(self.options): |
280 | if option in str_values: |
281 | self.selectedIndices.append(i) |
282 | str_values.remove(option) |
283 | @@ -169,7 +212,7 @@ |
284 | raise ValueError( |
285 | "Option(s) %r not found (from %s)" |
286 | % (', '.join(str_values), |
287 | - ', '.join([repr(o) for o, c in self.options]))) |
288 | + ', '.join([repr(o) for o, c, t in self.options]))) |
289 | |
290 | def value__get(self): |
291 | selected_values = [] |
292 | @@ -178,7 +221,7 @@ |
293 | for i in self.selectedIndices] |
294 | elif not self._forced_values: |
295 | selected_values = [] |
296 | - for option, checked in self.options: |
297 | + for option, checked, text in self.options: |
298 | if checked: |
299 | selected_values.append(option) |
300 | if self._forced_values: |
301 | @@ -197,7 +240,7 @@ |
302 | if self.selectedIndex is not None: |
303 | return self.options[self.selectedIndex][0] |
304 | else: |
305 | - for option, checked in self.options: |
306 | + for option, checked, text in self.options: |
307 | if checked: |
308 | return option |
309 | else: |
310 | @@ -413,7 +456,8 @@ |
311 | assert isinstance(field, |
312 | self.FieldClass.classes['radio']) |
313 | field.options.append((attrs.get('value'), |
314 | - 'checked' in attrs)) |
315 | + 'checked' in attrs, |
316 | + None)) |
317 | continue |
318 | elif tag_type == 'file': |
319 | if 'value' in attrs: |
320 | @@ -426,7 +470,8 @@ |
321 | if tag == 'select': |
322 | for option in node('option'): |
323 | field.options.append((option.attrs.get('value', option.text), |
324 | - 'selected' in option.attrs)) |
325 | + 'selected' in option.attrs, |
326 | + option.text)) |
327 | |
328 | self.field_order = field_order |
329 | self.fields = fields |
330 | @@ -516,12 +561,23 @@ |
331 | return self[name] |
332 | return fields[index] |
333 | |
334 | - def select(self, name, value, index=None): |
335 | - """Like ``.set()``, except also confirms the target is a ``<select>``. |
336 | + def select(self, name, value=None, text=None, index=None): |
337 | + """Like ``.set()``, except also confirms the target is a ``<select>`` |
338 | + and allows selecting options by text. |
339 | """ |
340 | field = self.get(name, index=index) |
341 | assert isinstance(field, Select) |
342 | - field.value = value |
343 | + |
344 | + field.select(value, text) |
345 | + |
346 | + def select_multiple(self, name, value=None, texts=None, index=None): |
347 | + """Like ``.set()``, except also confirms the target is a |
348 | + ``<select multiple>`` and allows selecting options by text. |
349 | + """ |
350 | + field = self.get(name, index=index) |
351 | + assert isinstance(field, MultipleSelect) |
352 | + |
353 | + field.select_multiple(value, texts) |
354 | |
355 | def submit(self, name=None, index=None, value=None, **args): |
356 | """Submits the form. If ``name`` is given, then also select that |
Sponsored, thanks!