Merge lp:~noskcaj/ubuntu/vivid/webtest/merge into lp:ubuntu/vivid/webtest

Proposed by Jackson Doak
Status: Needs review
Proposed branch: lp:~noskcaj/ubuntu/vivid/webtest/merge
Merge into: lp:ubuntu/vivid/webtest
Diff against target: 444 lines (+213/-10)
17 files modified
CHANGELOG.rst (+15/-0)
PKG-INFO (+1/-1)
WebTest.egg-info/PKG-INFO (+1/-1)
WebTest.egg-info/requires.txt (+1/-1)
debian/changelog (+14/-0)
debian/control (+1/-1)
docs/changelog.rst (+15/-0)
docs/testapp.rst (+2/-1)
setup.cfg (+1/-1)
setup.py (+1/-1)
tests/test_app.py (+28/-0)
tests/test_forms.py (+10/-0)
tox.ini (+2/-0)
webtest/app.py (+39/-1)
webtest/compat.py (+78/-0)
webtest/forms.py (+3/-1)
webtest/http.py (+1/-1)
To merge this branch: bzr merge lp:~noskcaj/ubuntu/vivid/webtest/merge
Reviewer Review Type Date Requested Status
Daniel Holbach (community) Approve
Review via email: mp+239652@code.launchpad.net

Description of the change

Merge from debian

To post a comment you must log in.
Revision history for this message
Daniel Holbach (dholbach) wrote :

Thanks. Uploaded.

review: Approve
Revision history for this message
Daniel Holbach (dholbach) wrote :

Rejected by Brian Murray: Missing SRU information, seems to be a mistargetted sync

24. By Jackson Doak

Fix target release

Revision history for this message
Jackson Doak (noskcaj) wrote :

Fixed

On Mon, Nov 10, 2014 at 7:33 PM, Daniel Holbach <email address hidden>
wrote:

> Rejected by Brian Murray: Missing SRU information, seems to be a
> mistargetted sync
> --
>
> https://code.launchpad.net/~noskcaj/ubuntu/vivid/webtest/merge/+merge/239652
> You are the owner of lp:~noskcaj/ubuntu/vivid/webtest/merge.
>

Revision history for this message
Daniel Holbach (dholbach) wrote :

Uploaded again.

Unmerged revisions

24. By Jackson Doak

Fix target release

23. By Jackson Doak

* Merge from Debian unstable. Remaining changes:
  - d/control: Demote python-lxml and python-pyquery to Suggests.
* New upstream release
* Standards-Version bumped to 3.9.6 (no changes needed)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CHANGELOG.rst' (properties changed: -x to +x)
2--- CHANGELOG.rst 2014-05-26 07:06:41 +0000
3+++ CHANGELOG.rst 2014-11-10 08:54:22 +0000
4@@ -1,6 +1,21 @@
5 News
6 ====
7
8+2.0.16 (2014-09-19)
9+-------------------
10+
11+- Fixed #110. Forced values for Radio inputs are no longer ignored by value
12+ property on get.
13+ [bayprogrammer]
14+
15+- Added method TestApp.set_parser_features to change the parser_features used
16+ by BeautifulSoup.
17+ [tomasmoreyra]
18+
19+- Added app.set_cookie
20+ [luhn]
21+
22+
23 2.0.15 (2014-04-17)
24 -------------------
25
26
27=== modified file 'PKG-INFO'
28--- PKG-INFO 2014-05-26 07:06:41 +0000
29+++ PKG-INFO 2014-11-10 08:54:22 +0000
30@@ -1,6 +1,6 @@
31 Metadata-Version: 1.1
32 Name: WebTest
33-Version: 2.0.15
34+Version: 2.0.16
35 Summary: Helper to test WSGI applications
36 Home-page: http://webtest.pythonpaste.org/
37 Author: Gael Pasgrimaud
38
39=== modified file 'WebTest.egg-info/PKG-INFO'
40--- WebTest.egg-info/PKG-INFO 2014-05-26 07:06:41 +0000
41+++ WebTest.egg-info/PKG-INFO 2014-11-10 08:54:22 +0000
42@@ -1,6 +1,6 @@
43 Metadata-Version: 1.1
44 Name: WebTest
45-Version: 2.0.15
46+Version: 2.0.16
47 Summary: Helper to test WSGI applications
48 Home-page: http://webtest.pythonpaste.org/
49 Author: Gael Pasgrimaud
50
51=== modified file 'WebTest.egg-info/requires.txt'
52--- WebTest.egg-info/requires.txt 2014-05-26 07:06:41 +0000
53+++ WebTest.egg-info/requires.txt 2014-11-10 08:54:22 +0000
54@@ -9,4 +9,4 @@
55 mock
56 PasteDeploy
57 WSGIProxy2
58-pyquery
59\ No newline at end of file
60+pyquery
61
62=== modified file 'debian/changelog'
63--- debian/changelog 2014-05-26 07:06:41 +0000
64+++ debian/changelog 2014-11-10 08:54:22 +0000
65@@ -1,3 +1,17 @@
66+webtest (2.0.16-1ubuntu1) vivid; urgency=medium
67+
68+ * Merge from Debian unstable. Remaining changes:
69+ - d/control: Demote python-lxml and python-pyquery to Suggests.
70+
71+ -- Jackson Doak <noskcaj@ubuntu.com> Sun, 26 Oct 2014 14:27:29 +1100
72+
73+webtest (2.0.16-1) unstable; urgency=medium
74+
75+ * New upstream release
76+ * Standards-Version bumped to 3.9.6 (no changes needed)
77+
78+ -- Piotr Ożarowski <piotr@debian.org> Thu, 25 Sep 2014 21:45:51 +0200
79+
80 webtest (2.0.15-1ubuntu1) utopic; urgency=medium
81
82 * Merge from Debian unstable. Remaining changes:
83
84=== modified file 'debian/control'
85--- debian/control 2014-01-06 10:23:25 +0000
86+++ debian/control 2014-11-10 08:54:22 +0000
87@@ -12,7 +12,7 @@
88 python-sphinx (>= 1.0.7+dfsg-1~), python-six, python-bs4, python-waitress,
89 # tests
90 # python-unittest2, python-pyquery
91-Standards-Version: 3.9.5
92+Standards-Version: 3.9.6
93 X-Python-Version: >=2.6
94 Homepage: http://pythonpaste.org/webtest/
95 Vcs-Svn: svn://anonscm.debian.org/python-modules/packages/webtest/trunk/
96
97=== modified file 'docs/changelog.rst' (properties changed: -x to +x)
98--- docs/changelog.rst 2014-05-05 22:05:28 +0000
99+++ docs/changelog.rst 2014-11-10 08:54:22 +0000
100@@ -1,6 +1,21 @@
101 News
102 ====
103
104+2.0.16 (2014-09-19)
105+-------------------
106+
107+- Fixed #110. Forced values for Radio inputs are no longer ignored by value
108+ property on get.
109+ [bayprogrammer]
110+
111+- Added method TestApp.set_parser_features to change the parser_features used
112+ by BeautifulSoup.
113+ [tomasmoreyra]
114+
115+- Added app.set_cookie
116+ [luhn]
117+
118+
119 2.0.15 (2014-04-17)
120 -------------------
121
122
123=== modified file 'docs/contributing.rst' (properties changed: -x to +x)
124=== modified file 'docs/testapp.rst'
125--- docs/testapp.rst 2014-05-05 22:05:28 +0000
126+++ docs/testapp.rst 2014-11-10 08:54:22 +0000
127@@ -146,6 +146,7 @@
128
129 To indicate another status is expected, use the keyword argument
130 ``status=404`` to (for example) check that it is a 404 status, or
131-``status="*"`` to allow any status.
132+``status="*"`` to allow any status, or ``status="400 Custom Bad Request"``
133+to use custom reason phrase.
134
135 If you expect errors to be printed, use ``expect_errors=True``.
136
137=== modified file 'setup.cfg'
138--- setup.cfg 2014-05-05 22:05:28 +0000
139+++ setup.cfg 2014-11-10 08:54:22 +0000
140@@ -8,7 +8,7 @@
141 doctest-extension = rst
142 doctest-fixtures = _fixt
143 include = docs
144-exclude = (changelog|contributing).rst
145+exclude = (CHANGELOG|contributing).rst
146 cover-package = webtest
147 with-coverage = 1
148 doctest-options = +ELLIPSIS,+NORMALIZE_WHITESPACE
149
150=== modified file 'setup.py'
151--- setup.py 2014-05-26 07:06:41 +0000
152+++ setup.py 2014-11-10 08:54:22 +0000
153@@ -5,7 +5,7 @@
154 from setuptools import setup
155 from setuptools import find_packages
156
157-version = '2.0.15'
158+version = '2.0.16'
159
160 install_requires = [
161 'six',
162
163=== modified file 'tests/test_app.py'
164--- tests/test_app.py 2014-05-05 22:05:28 +0000
165+++ tests/test_app.py 2014-11-10 08:54:22 +0000
166@@ -109,6 +109,13 @@
167 self.assertEqual(self.check_status('200 Ok', None), None)
168 self.assertRaises(webtest.AppError, self.check_status, '400 Ok')
169
170+ def test_check_status_with_custom_reason(self):
171+ self.assertEqual(self.check_status('200 Ok', '200 Ok'), None)
172+ self.assertRaises(webtest.AppError,
173+ self.check_status, '200 Ok', '200 Good Response')
174+ self.assertRaises(webtest.AppError,
175+ self.check_status, '200 Ok', '400 Bad Request')
176+
177
178 class TestParserFeature(unittest.TestCase):
179
180@@ -166,6 +173,27 @@
181
182 class TestCookies(unittest.TestCase):
183
184+ def test_set_cookie(self):
185+ def cookie_app(environ, start_response):
186+ req = Request(environ)
187+ self.assertEqual(req.cookies['foo'], 'bar')
188+ self.assertEqual(req.cookies['fizz'], ';bar=baz')
189+
190+ status = to_bytes("200 OK")
191+ body = ''
192+ headers = [
193+ ('Content-Type', 'text/html'),
194+ ('Content-Length', str(len(body))),
195+ ]
196+ start_response(status, headers)
197+ return [to_bytes(body)]
198+
199+ app = webtest.TestApp(cookie_app)
200+ app.set_cookie('foo', 'bar')
201+ app.set_cookie('fizz', ';bar=baz') # Make sure we're escaping.
202+ app.get('/')
203+ app.reset()
204+
205 def test_preserves_cookies(self):
206 def cookie_app(environ, start_response):
207 req = Request(environ)
208
209=== modified file 'tests/test_forms.py'
210--- tests/test_forms.py 2014-05-26 07:06:41 +0000
211+++ tests/test_forms.py 2014-11-10 08:54:22 +0000
212@@ -176,6 +176,16 @@
213 self.assertEqual(form['foo'].value, 'bar')
214 self.assertEqual(form.submit_fields(), [('foo', 'bar')])
215
216+ def test_force_radio_input(self):
217+ app = self.callFUT()
218+ res = app.get('/form.html')
219+
220+ form = res.forms['radio_input_form']
221+
222+ form['foo'].force_value('fido')
223+ self.assertEqual(form['foo'].value, 'fido')
224+ self.assertEqual(form.submit_fields(), [('foo', 'fido')])
225+
226 def test_input_unicode(self):
227 app = self.callFUT('form_unicode_inputs.html')
228 res = app.get('/form.html')
229
230=== modified file 'tox.ini'
231--- tox.ini 2014-05-05 22:05:28 +0000
232+++ tox.ini 2014-11-10 08:54:22 +0000
233@@ -8,6 +8,8 @@
234 {envbindir}/nosetests --with-xunit --xunit-file=nosetests-{envname}.xml []
235 {envbindir}/coverage xml -o coverage-{envname}.xml webtest/*.py
236 setenv =
237+ LC_ALL=C
238+ LANG=C
239 SELENIUM_DRIVER=firefox
240 COVERAGE_FILE=.coverage.{envname}
241
242
243=== modified file 'webtest/app.py'
244--- webtest/app.py 2014-05-26 07:06:41 +0000
245+++ webtest/app.py 2014-11-10 08:54:22 +0000
246@@ -28,6 +28,7 @@
247 from webtest.compat import urlparse
248 from webtest.compat import urlencode
249 from webtest.compat import to_bytes
250+from webtest.compat import escape_cookie_value
251 from webtest.response import TestResponse
252 from webtest import forms
253 from webtest import lint
254@@ -143,6 +144,7 @@
255 def __init__(self, app, extra_environ=None, relative_to=None,
256 use_unicode=True, cookiejar=None, parser_features=None,
257 json_encoder=None, lint=True):
258+
259 if 'WEBTEST_TARGET_URL' in os.environ:
260 app = os.environ['WEBTEST_TARGET_URL']
261 if isinstance(app, string_types):
262@@ -218,6 +220,32 @@
263 def cookies(self):
264 return dict([(cookie.name, cookie.value) for cookie in self.cookiejar])
265
266+ def set_cookie(self, name, value):
267+ """
268+ Sets a cookie to be passed through with requests.
269+
270+ """
271+ value = escape_cookie_value(value)
272+ cookie = http_cookiejar.Cookie(
273+ version=0,
274+ name=name,
275+ value=value,
276+ port=None,
277+ port_specified=False,
278+ domain='.localhost',
279+ domain_specified=True,
280+ domain_initial_dot=False,
281+ path='/',
282+ path_specified=True,
283+ secure=False,
284+ expires=None,
285+ discard=False,
286+ comment=None,
287+ comment_url=None,
288+ rest=None
289+ )
290+ self.cookiejar.set_cookie(cookie)
291+
292 def reset(self):
293 """
294 Resets the state of the application; currently just clears
295@@ -225,6 +253,13 @@
296 """
297 self.cookiejar.clear()
298
299+ def set_parser_features(self, parser_features):
300+ """
301+ Changes the parser used by BeautifulSoup. See its documentation to
302+ know the supported parsers.
303+ """
304+ self.RequestClass.ResponseClass.parser_features = parser_features
305+
306 def get(self, url, params=None, headers=None, extra_environ=None,
307 status=None, expect_errors=False, xhr=False):
308 """
309@@ -530,7 +565,7 @@
310 expect_errors=expect_errors,
311 )
312
313- def do_request(self, req, status, expect_errors):
314+ def do_request(self, req, status=None, expect_errors=None):
315 """
316 Executes the given webob Request (``req``), with the expected
317 ``status``. Generally :meth:`~webtest.TestApp.get` and
318@@ -608,6 +643,9 @@
319 if (isinstance(status, string_types) and '*' in status):
320 if re.match(fnmatch.translate(status), res_status, re.I):
321 return
322+ if isinstance(status, string_types):
323+ if status == res_status:
324+ return
325 if isinstance(status, (list, tuple)):
326 if res.status_int not in status:
327 raise AppError(
328
329=== modified file 'webtest/compat.py'
330--- webtest/compat.py 2013-10-02 19:37:14 +0000
331+++ webtest/compat.py 2014-11-10 08:54:22 +0000
332@@ -39,3 +39,81 @@
333 from collections import OrderedDict
334 except ImportError: # pragma: no cover
335 from ordereddict import OrderedDict # noqa
336+
337+
338+def escape_cookie_value(value):
339+ """
340+ Escapes a value so that it can be safely stored in a cookie.
341+
342+ """
343+ return '"' + ''.join(
344+ COOKIE_ESCAPE_CHAR_MAP.get(x, x) for x in value
345+ ) + '"'
346+
347+
348+# A list of illegal characters in a cookie and the escaped equivalent.
349+# Taken from Python's cookie module.
350+COOKIE_ESCAPE_CHAR_MAP = {
351+ '\000' : '\\000', '\001' : '\\001', '\002' : '\\002',
352+ '\003' : '\\003', '\004' : '\\004', '\005' : '\\005',
353+ '\006' : '\\006', '\007' : '\\007', '\010' : '\\010',
354+ '\011' : '\\011', '\012' : '\\012', '\013' : '\\013',
355+ '\014' : '\\014', '\015' : '\\015', '\016' : '\\016',
356+ '\017' : '\\017', '\020' : '\\020', '\021' : '\\021',
357+ '\022' : '\\022', '\023' : '\\023', '\024' : '\\024',
358+ '\025' : '\\025', '\026' : '\\026', '\027' : '\\027',
359+ '\030' : '\\030', '\031' : '\\031', '\032' : '\\032',
360+ '\033' : '\\033', '\034' : '\\034', '\035' : '\\035',
361+ '\036' : '\\036', '\037' : '\\037',
362+
363+ # Because of the way browsers really handle cookies (as opposed
364+ # to what the RFC says) we also encode , and ;
365+
366+ ',' : '\\054', ';' : '\\073',
367+
368+ '"' : '\\"', '\\' : '\\\\',
369+
370+ '\177' : '\\177', '\200' : '\\200', '\201' : '\\201',
371+ '\202' : '\\202', '\203' : '\\203', '\204' : '\\204',
372+ '\205' : '\\205', '\206' : '\\206', '\207' : '\\207',
373+ '\210' : '\\210', '\211' : '\\211', '\212' : '\\212',
374+ '\213' : '\\213', '\214' : '\\214', '\215' : '\\215',
375+ '\216' : '\\216', '\217' : '\\217', '\220' : '\\220',
376+ '\221' : '\\221', '\222' : '\\222', '\223' : '\\223',
377+ '\224' : '\\224', '\225' : '\\225', '\226' : '\\226',
378+ '\227' : '\\227', '\230' : '\\230', '\231' : '\\231',
379+ '\232' : '\\232', '\233' : '\\233', '\234' : '\\234',
380+ '\235' : '\\235', '\236' : '\\236', '\237' : '\\237',
381+ '\240' : '\\240', '\241' : '\\241', '\242' : '\\242',
382+ '\243' : '\\243', '\244' : '\\244', '\245' : '\\245',
383+ '\246' : '\\246', '\247' : '\\247', '\250' : '\\250',
384+ '\251' : '\\251', '\252' : '\\252', '\253' : '\\253',
385+ '\254' : '\\254', '\255' : '\\255', '\256' : '\\256',
386+ '\257' : '\\257', '\260' : '\\260', '\261' : '\\261',
387+ '\262' : '\\262', '\263' : '\\263', '\264' : '\\264',
388+ '\265' : '\\265', '\266' : '\\266', '\267' : '\\267',
389+ '\270' : '\\270', '\271' : '\\271', '\272' : '\\272',
390+ '\273' : '\\273', '\274' : '\\274', '\275' : '\\275',
391+ '\276' : '\\276', '\277' : '\\277', '\300' : '\\300',
392+ '\301' : '\\301', '\302' : '\\302', '\303' : '\\303',
393+ '\304' : '\\304', '\305' : '\\305', '\306' : '\\306',
394+ '\307' : '\\307', '\310' : '\\310', '\311' : '\\311',
395+ '\312' : '\\312', '\313' : '\\313', '\314' : '\\314',
396+ '\315' : '\\315', '\316' : '\\316', '\317' : '\\317',
397+ '\320' : '\\320', '\321' : '\\321', '\322' : '\\322',
398+ '\323' : '\\323', '\324' : '\\324', '\325' : '\\325',
399+ '\326' : '\\326', '\327' : '\\327', '\330' : '\\330',
400+ '\331' : '\\331', '\332' : '\\332', '\333' : '\\333',
401+ '\334' : '\\334', '\335' : '\\335', '\336' : '\\336',
402+ '\337' : '\\337', '\340' : '\\340', '\341' : '\\341',
403+ '\342' : '\\342', '\343' : '\\343', '\344' : '\\344',
404+ '\345' : '\\345', '\346' : '\\346', '\347' : '\\347',
405+ '\350' : '\\350', '\351' : '\\351', '\352' : '\\352',
406+ '\353' : '\\353', '\354' : '\\354', '\355' : '\\355',
407+ '\356' : '\\356', '\357' : '\\357', '\360' : '\\360',
408+ '\361' : '\\361', '\362' : '\\362', '\363' : '\\363',
409+ '\364' : '\\364', '\365' : '\\365', '\366' : '\\366',
410+ '\367' : '\\367', '\370' : '\\370', '\371' : '\\371',
411+ '\372' : '\\372', '\373' : '\\373', '\374' : '\\374',
412+ '\375' : '\\375', '\376' : '\\376', '\377' : '\\377'
413+ }
414
415=== modified file 'webtest/forms.py'
416--- webtest/forms.py 2014-05-26 07:06:41 +0000
417+++ webtest/forms.py 2014-11-10 08:54:22 +0000
418@@ -237,7 +237,9 @@
419 """Field representing ``<input type="radio">``"""
420
421 def value__get(self):
422- if self.selectedIndex is not None:
423+ if self._forced_value is not NoValue:
424+ return self._forced_value
425+ elif self.selectedIndex is not None:
426 return self.options[self.selectedIndex][0]
427 else:
428 for option, checked, text in self.options:
429
430=== modified file 'webtest/http.py'
431--- webtest/http.py 2014-05-05 22:05:28 +0000
432+++ webtest/http.py 2014-11-10 08:54:22 +0000
433@@ -30,10 +30,10 @@
434 """Perform a request until the server reply"""
435 if retries < 0:
436 return 0
437- conn = http_client.HTTPConnection(host, port, timeout=timeout)
438 time.sleep(.3)
439 for i in range(retries):
440 try:
441+ conn = http_client.HTTPConnection(host, int(port), timeout=timeout)
442 conn.request('GET', path_info)
443 res = conn.getresponse()
444 return res.status

Subscribers

People subscribed via source and target branches

to all changes: